Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Init a failed controller #13

Closed
ulmitov opened this issue Apr 27, 2023 · 13 comments · Fixed by #11
Closed

Init a failed controller #13

ulmitov opened this issue Apr 27, 2023 · 13 comments · Fixed by #11
Assignees
Labels
bug Something isn't working

Comments

@ulmitov
Copy link

ulmitov commented Apr 27, 2023

Hi,

Having this kind of controller:

COMMAND: storcli64 /c0 show J
RC:
0
STDOUT:
{
"Controllers":[
{
	"Command Status" : {
		"CLI Version" : "007.2309.0000.0000 Sep 16, 2022",
		"Operating system" : "Linux 5.4.0-99-generic",
		"Controller" : 0,
		"Status" : "Failure",
		"Description" : "None",
		"Detailed Status" : [
			{
				"Ctrl" : 0,
				"Status" : "Failed",
				"ErrCd" : 59,
				"ErrMsg" : "Incomplete foreign configuration"
			}
		]
	},
	"Response Data" : {
		"Product Name" : "AVAGO JBOD",

Trying to init it with pystorcli:

In [2]: import pystorcli as pp

In [3]: c=pp.controller.Controllers()

In [4]: c.ids
Out[4]: [0]

In [5]: x=c.get_ctl(0)
---------------------------------------------------------------------------
StorCliMissingError                       Traceback (most recent call last)
Cell In[5], line 1
----> 1 x=c.get_ctl(0)

File /usr/local/lib/python3.8/dist-packages/pystorcli/controller/__init__.py:478, in Controllers.get_ctl(self, ctl_id)
    468 def get_ctl(self, ctl_id: int) -> Optional[Controller]:
    469     """Get controller object by id
    470 
    471     Args:
   (...)
    476         (:obj:Controller): controller object
    477     """
--> 478     for ctl in self:
    479         if ctl.id == ctl_id:
    480             return ctl

File /usr/local/lib/python3.8/dist-packages/pystorcli/controller/__init__.py:457, in Controllers._ctls(self)
    454 @ property
    455 def _ctls(self):
    456     for ctl_id in self._ctl_ids:
--> 457         yield Controller(ctl_id=ctl_id, binary=self._binary)

File /usr/local/lib/python3.8/dist-packages/pystorcli/controller/__init__.py:71, in Controller.__init__(self, ctl_id, binary)
     68 self._storcli = StorCLI(binary)
     69 self._name = '/c{0}'.format(self._ctl_id)
---> 71 self._exist()

File /usr/local/lib/python3.8/dist-packages/pystorcli/controller/__init__.py:85, in Controller._exist(self)
     83     self._run(['show'])
     84 except exc.StorCliCmdError:
---> 85     raise exc.StorCliMissingError(
     86         self.__class__.__name__, self._name) from None

StorCliMissingError: Object 'Controller' doesnt exist: /c0

The exception is saying that object does not exist.
But the real exception should be:

In [9]: c._storcli.run(['/c0', 'show'])
---------------------------------------------------------------------------
StorCliCmdError                           Traceback (most recent call last)
Cell In[9], line 1
----> 1 c._storcli.run(['/c0', 'show'])

File /usr/local/lib/python3.8/dist-packages/pystorcli/storcli.py:184, in StorCLI.run(self, args, stdout, stderr, **kwargs)
    182 try:
    183     ret_json = json.loads(ret.stdout)
--> 184     self.check_response_status(cmd, ret_json)
    185     ret.check_returncode()
    186     if self.cache_enable:

File /usr/local/lib/python3.8/dist-packages/pystorcli/storcli.py:144, in StorCLI.check_response_status(cmd, out)
    142 if cmd_status['Status'] == 'Failure':
    143     if 'Detailed Status' in cmd_status:
--> 144         raise exc.StorCliCmdError(
    145             cmd, "{0}".format(cmd_status['Detailed Status']))
    146     else:
    147         raise exc.StorCliCmdError(cmd, "{0}".format(cmd_status))

StorCliCmdError: Command '/usr/sbin/storcli64 /c0 show J' error: [{'Ctrl': 0, 'Status': 'Failed', 'ErrCd': 59, 'ErrMsg': 'Incomplete foreign configuration'}]

On the other hand, the controller exists and maybe pystorcli should create the object (although controller has status failed).
Since we can make it healthy:

In [10]: c._storcli.run(['/c0/fall', 'del'])
Out[10]: 
{'Controllers': [{'Command Status': {'CLI Version': '007.2309.0000.0000 Sep 16, 2022',
    'Operating system': 'Linux 5.4.0-99-generic',
    'Controller': 0,
    'Status': 'Success',
    'Description': 'Operation on foreign configuration Succeeded'},
   'Response Data': {'Total Foreign PDs': 0}}]}

In [11]: c._storcli.run(['/c0', 'show'])
Out[11]: 
{'Controllers': [{'Command Status': {'CLI Version': '007.2309.0000.0000 Sep 16, 2022',
    'Operating system': 'Linux 5.4.0-99-generic',
    'Controller': 0,
    'Status': 'Success',
    'Description': 'None'},
   'Response Data': {'Product Name': 'AVAGO JBOD',

But if pystorcli will not create an object this would not be possible.
Now the init is passing:

In [12]: x=c.get_ctl(0)

In [13]: x
Out[13]: <pystorcli.controller.Controller at 0x7f3601a33cd0>
@ralequi ralequi self-assigned this Apr 27, 2023
@ralequi ralequi added the bug Something isn't working label Apr 27, 2023
@ulmitov
Copy link
Author

ulmitov commented Apr 27, 2023

Also, how to handle this kind of case:
when trying to get fall, sometimes the FC's have some kind of invalid state
and storcli returns 'Status': 'Failure', 'Description': 'Incomplete foreign configuration
In this case pystorcli raises an exception:

    out = self.controller._run(['/fall', 'show'], verify=False)
/usr/local/lib/python3.9/site-packages/pystorcli/controller/__init__.py:79: in _run
    return self._storcli.run(args, **kwargs)
/usr/local/lib/python3.9/site-packages/pystorcli/storcli.py:184: in run
    self.check_response_status(cmd, ret_json)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cmd = ['storcli64', '/c0', '/fall', 'show', 'J']
out = {'Controllers': [{'Command Status': {'CLI Version': '007.2309.0000.0000 Sep 16, 2022', 'Controller': 0, 'Description':...g system': 'Linux 5.4.0-99-generic', ...}, 'Response Data': {'Total Foreign PDs': 15, 'Total Locked Foreign PDs': 0}}]}

    @staticmethod
    def check_response_status(cmd, out):
        """Check ouput command line status from storcli.
    
        Args:
            cmd (list of str): full command line
            out (dict): output from command line
    
        Raises:
            StorCliCmdError
        """
        cmd_status = common.response_cmd(out)
        if cmd_status['Status'] == 'Failure':
            if 'Detailed Status' in cmd_status:
                raise exc.StorCliCmdError(
                    cmd, "{0}".format(cmd_status['Detailed Status']))
            else:
>               raise exc.StorCliCmdError(cmd, "{0}".format(cmd_status))
E               pystorcli.exc.StorCliCmdError: Command 'storcli64 /c0 /fall show J' error: {'CLI Version': '007.2309.0000.0000 Sep 16, 2022', 'Operating system': 'Linux 5.4.0-99-generic', 'Controller': 0, 'Status': 'Failure', 'Description': 'Incomplete foreign configuration'}

/usr/local/lib/python3.9/site-packages/pystorcli/storcli.py:147: StorCliCmdError

But there is no way to issue controller._run(['/fall', 'show'] with a flag to skip raising exception.
So the only way is to have a try except on this command, and if it failed to clear the FC. Which is ok for me, but maybe some kind of skip exception arg would be handy here

@ralequi ralequi linked a pull request Apr 27, 2023 that will close this issue
@ralequi
Copy link
Member

ralequi commented Apr 27, 2023

Totally agree with "On the other hand, the controller exists and maybe pystorcli should create the object (although controller has status failed)."

@ralequi
Copy link
Member

ralequi commented Apr 27, 2023

Thank you @ulmitov
I have uploaded a partial fix to develop branch...

However, I don't know if it is enough to handle this scenario (probably don't)... ¿Could you please try and copy the command outputs in case of error?

Thanks!

@ulmitov
Copy link
Author

ulmitov commented Apr 28, 2023

@ralequi Ok, thanks a lot, will try to check it next week.
BTW, do you know if is there some arcconf module for python ?

@ralequi
Copy link
Member

ralequi commented Apr 28, 2023

Sorry, but I don't have such HW so didn't searched nor tried to create anything related...

The "hardware world" is "hard", not many people involved (even less that uses python/high level programing langs).

If you find something interesting out there and we can find some interest on "mix" under a solo "raid-controlling-python-package" we'll be able to have something much better than (inherit) "tool-wrappers".

@ulmitov
Copy link
Author

ulmitov commented Apr 28, 2023

Besides this one i couldn't find anything better, nicely started, but not really working
https://github.com/MarkusFreitag/python-arcconf/tree/master/pyarcconf
For now i did not get to my arcconf tasks, but I will probably try to use it and make better

@ulmitov
Copy link
Author

ulmitov commented May 3, 2023

So in order to have a single raid py package, the design of the 3 packages should be similar. Specifically:

  1. the cmd runner - is pretty much the same for all 3, but pysmart has the better one (subprocess.popen is preferable over subprocess.run)
  2. the design pattern - pystorcli uses singleton when creating the StorCLI object. while pysmart just creates it once and then passes to all rest of objects (somewhat a factory design). I think the factory is much better.

Do you agree with those assumptions?)
Going to modify the arcconf in those two points

@ralequi
Copy link
Member

ralequi commented May 3, 2023

Yeah, absolutely.

I'm agree that pysmart model is better than pystorcli too, should migrate it...

@ulmitov
Copy link
Author

ulmitov commented May 3, 2023

Great!

@ulmitov
Copy link
Author

ulmitov commented May 3, 2023

https://github.com/ulmitov/pyarcconf
For now got it working with my HBA

@ulmitov
Copy link
Author

ulmitov commented May 4, 2023

Regarding the controller init fix, took the develop version, this is the case now:

In [6]: x=c.get_ctl(0)
---------------------------------------------------------------------------
StorCliMissingError                       Traceback (most recent call last)
Cell In[6], line 1
----> 1 x=c.get_ctl(0)

File /usr/local/lib/python3.8/dist-packages/pystorcli/controller/__init__.py:478, in Controllers.get_ctl(self, ctl_id)
    468 def get_ctl(self, ctl_id: int) -> Optional[Controller]:
    469     """Get controller object by id
    470 
    471     Args:
   (...)
    476         (:obj:Controller): controller object
    477     """
--> 478     for ctl in self:
    479         if ctl.id == ctl_id:
    480             return ctl

File /usr/local/lib/python3.8/dist-packages/pystorcli/controller/__init__.py:457, in Controllers._ctls(self)
    454 @ property
    455 def _ctls(self):
    456     for ctl_id in self._ctl_ids:
--> 457         yield Controller(ctl_id=ctl_id, binary=self._binary)

File /usr/local/lib/python3.8/dist-packages/pystorcli/controller/__init__.py:71, in Controller.__init__(self, ctl_id, binary)
     68 self._storcli = StorCLI(binary)
     69 self._name = '/c{0}'.format(self._ctl_id)
---> 71 self._exist()

File /usr/local/lib/python3.8/dist-packages/pystorcli/controller/__init__.py:85, in Controller._exist(self)
     83     self._run(['show'])
     84 except exc.StorCliCmdError:
---> 85     raise exc.StorCliMissingError(
     86         self.__class__.__name__, self._name) from None

StorCliMissingError: Object 'Controller' doesnt exist: /c0

@ralequi
Copy link
Member

ralequi commented May 4, 2023

My fault, please, recheck

@ulmitov
Copy link
Author

ulmitov commented May 4, 2023

The fix works great, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants