From a1c48b6f85b93fd7eb27209e4c9830ba7010c94b Mon Sep 17 00:00:00 2001 From: Penghui Cui Date: Wed, 22 Sep 2021 16:20:26 +0800 Subject: [PATCH] Support extention for set_power/get_power 1. support extention handle in plugins 2. add log for bug locating 3. refactor to avoid duplicate code. Change-Id: I3aa607034d9f3f9f336df3c07f5a7968b6651718 --- pyghmi/ipmi/command.py | 51 ++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/pyghmi/ipmi/command.py b/pyghmi/ipmi/command.py index 890a3415..b75e8a07 100644 --- a/pyghmi/ipmi/command.py +++ b/pyghmi/ipmi/command.py @@ -16,6 +16,8 @@ """This represents the low layer message framing portion of IPMI""" from itertools import chain +import json +import logging import os import socket import struct @@ -152,6 +154,7 @@ class Command(object): keepalive=True): # TODO(jbjohnso): accept tuples and lists of each parameter for mass # operations without pushing the async complexities up the stack + self.logger = logging.getLogger(__name__) self.onlogon = onlogon self.bmc = bmc self._sdrcachedir = None @@ -336,14 +339,19 @@ class Command(object): :raises: IpmiException on an error :returns: dict -- A dict describing the response retrieved """ + self.oem_init() + + if hasattr(self._oem, 'set_power'): + return self._oem.set_power(powerstate) + + if hasattr(self._oem, 'process_power_state'): + powerstate = self._oem.process_power_state(powerstate) + if powerstate not in power_states: raise exc.InvalidParameterValue( "Unknown power state %s requested" % powerstate) newpowerstate = powerstate - response = self.raw_command(netfn=0, command=1) - if 'error' in response: - raise exc.IpmiException(response['error']) - oldpowerstate = 'on' if (response['data'][0] & 1) else 'off' + oldpowerstate = self._get_power_state() if oldpowerstate == newpowerstate: return {'powerstate': oldpowerstate} if newpowerstate == 'boot': @@ -351,6 +359,8 @@ class Command(object): response = self.raw_command( netfn=0, command=2, data=[power_states[newpowerstate]]) if 'error' in response: + self.logger.error('error while setting power:{0}'.format( + json.dumps(response))) raise exc.IpmiException(response['error']) lastresponse = {'pendingpowerstate': newpowerstate} waitattempts = 300 @@ -363,18 +373,32 @@ class Command(object): waitpowerstate = newpowerstate currpowerstate = None while currpowerstate != waitpowerstate and waitattempts > 0: - response = self.raw_command(netfn=0, command=1, delay_xmit=1) - if 'error' in response: - raise exc.IpmiException(response['error']) - currpowerstate = 'on' if (response['data'][0] & 1) else 'off' + self.logger.debug( + 'checking state, current:{}, expected:{}'.format( + currpowerstate, waitpowerstate)) + currpowerstate = self._get_power_state() waitattempts -= 1 if currpowerstate != waitpowerstate: + self.logger.error( + 'set power failed, current:{}, expected:{}'.format( + currpowerstate, waitpowerstate)) raise exc.IpmiException( "System did not accomplish power state change") return {'powerstate': currpowerstate} else: return lastresponse + def _get_power_state(self): + response = self.raw_command(netfn=0, command=1, delay_xmit=1) + if 'error' in response: + self.logger.error('error while getting power:{0}'.format( + json.dumps(response))) + raise exc.IpmiException(response['error']) + assert (response['command'] == 1 and response['netfn'] == 1) + curr_power_state = 'on' if (response['data'][0] & 1) else 'off' + + return curr_power_state + def get_video_launchdata(self): """Get data required to launch a remote video session to target. @@ -522,12 +546,11 @@ class Command(object): :returns: dict -- {'powerstate': value} """ - response = self.raw_command(netfn=0, command=1) - if 'error' in response: - raise exc.IpmiException(response['error']) - assert (response['command'] == 1 and response['netfn'] == 1) - powerstate = 'on' if (response['data'][0] & 1) else 'off' - return {'powerstate': powerstate} + self.oem_init() + if hasattr(self._oem, 'get_power'): + return {'powerstate': self._oem.get_power()} + + return {'powerstate': self._get_power_state()} def set_identify(self, on=True, duration=None): """Request identify light