diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_bmcconfig.py b/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_bmcconfig.py index b0fe244b3..b7ae94bed 100644 --- a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_bmcconfig.py +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_bmcconfig.py @@ -18,49 +18,6 @@ logger = logging.getLogger('xcatagent') RSPCONFIG_GET_NETINFO=['ip', 'netmask', 'gateway', 'vlan', 'ipsrc', 'hostname'] RSPCONFIG_SET_NETINFO=['ip', 'netmask', 'gateway', 'vlan'] -RSPCONFIG_APIS = { - 'autoreboot' : { - 'baseurl': "/control/host0/auto_reboot/", - 'set_url': "attr/AutoReboot", - 'get_url': "attr/AutoReboot", - 'display_name': "BMC AutoReboot", - }, - 'powersupplyredundancy':{ - 'baseurl': "/sensors/chassis/PowerSupplyRedundancy/", - 'set_url': "/action/setValue", - 'get_url': "/action/getValue", - 'get_method': 'POST', - 'get_data': '[]', - 'display_name': "BMC PowerSupplyRedundancy", - 'attr_values': { - 'disabled': "Disables", - 'enabled': "Enabled", - }, - }, - 'powerrestorepolicy': { - 'baseurl': "/control/host0/power_restore_policy/", - 'set_url': "attr/PowerRestorePolicy", - 'get_url': "attr/PowerRestorePolicy", - 'display_name': "BMC PowerRestorePolicy", - 'attr_values': { - 'restore': "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore", - 'always_on': "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn", - 'always_off': "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff", - }, - }, - 'bootmode': { - 'baseurl': "/control/host0/boot/", - 'set_url': "attr/BootMode", - 'get_url': "attr/BootMode", - 'display_name':"BMC BootMode", - 'attr_values': { - 'regular': "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular", - 'safe': "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe", - 'setup': "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup", - }, - }, -} - class OpenBMCBmcConfigTask(ParallelNodesCommand): def dump_list(self, **kw): @@ -85,20 +42,18 @@ class OpenBMCBmcConfigTask(ParallelNodesCommand): return self.callback.info("set_ipdhcp") def get_attributes(self, attributes, **kw): - netinfo_dict={'ip':False, 'ipsrc':False, 'netmask':False, - 'gateway':False, 'vlan':False, 'hostname':False} - getnet=0 + netinfo_dict={} for attr in attributes: if attr in RSPCONFIG_GET_NETINFO: netinfo_dict[attr]=True getnet=1 - elif RSPCONFIG_APIS.has_key(attr): - return self._get_apis_values(attr, **kw) + elif openbmc.RSPCONFIG_APIS.has_key(attr): + self._get_apis_values(attr, **kw) else: - return self.callback.error("get_attributes can not deal with attr %s" % attr) - if getnet: - self._get_netinfo(netinfo_dict['ip'], netinfo_dict['ipsrc'], netinfo_dict['netmask'], - netinfo_dict['gateway'], netinfo_dict['vlan'], netinfo_dict['hostname'], **kw) + self.callback.error("get_attributes can not deal with attr %s" % attr) + if len(netinfo_dict): + self._get_netinfo(netinfo_dict.has_key('ip'), netinfo_dict.has_key('ipsrc'), netinfo_dict.has_key('netmask'), + netinfo_dict.has_key('gateway'), netinfo_dict.has_key('vlan'), netinfo_dict.has_key('hostname'), **kw) def set_attributes(self, attributes, **kw): netinfo_dict={'vlan':False} @@ -107,13 +62,13 @@ class OpenBMCBmcConfigTask(ParallelNodesCommand): if k in RSPCONFIG_SET_NETINFO: netinfo_dict[k] = v elif k == 'hostname': - return self._set_hostname(v, **kw) - elif RSPCONFIG_APIS.has_key(k): - return self._set_apis_values(k, v, **kw) + self._set_hostname(v, **kw) + elif openbmc.RSPCONFIG_APIS.has_key(k): + self._set_apis_values(k, v, **kw) else: return self.callback.error("set_attributes unsupported attribute:%s" % k) - if (not netinfo_dict['ip']) or (not netinfo_dict['netmask']) or (not netinfo_dict['gateway']): - return self.callback.error("set_attributes miss either ip, netmask or gateway to set network information") + if len(netinfo_dict) > 1 and (not netinfo_dict.has_key('ip') or not netinfo_dict.has_key('netmask') or not netinfo_dict.has_key('gateway')): + self.callback.info("set_attributes miss either ip, netmask or gateway to set network information") else: self._set_netinfo(netinfo_dict['ip'], netinfo_dict['netmask'], netinfo_dict['gateway'], netinfo_dict['vlan']) @@ -128,50 +83,29 @@ class OpenBMCBmcConfigTask(ParallelNodesCommand): def _set_apis_values(self, key, value, **kw): node = kw['node'] - attr_info = RSPCONFIG_APIS[key] - if not attr_info.has_key('set_url'): - return self.callback.error("config %s failed, not url available" % key) - set_url = attr_info['baseurl']+attr_info['set_url'] - obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, debugmode=self.debugmode, verbose=self.verbose) - - if attr_info.has_key('attr_values') and attr_info['attr_values'].has_key(value): - data = attr_info['attr_values'][value] - else: - data = value - try: obmc.login() - obmc.request('PUT', set_url, payload={"data": data}, cmd="set_%s" % key) + obmc.set_apis_values(key, value) except (SelfServerException, SelfClientException) as e: self.callback.info("%s: %s" % (node, e.message)) - self.callback.info("%s: BMC Setting %s..." % (node, attr_info['display_name'])) + self.callback.info("%s: BMC Setting %s..." % (node, openbmc.RSPCONFIG_APIS[key]['display_name'])) def _get_apis_values(self, key, **kw): node = kw['node'] - attr_info = RSPCONFIG_APIS[key] - if not attr_info.has_key('get_url'): - return self.callback.error("Reading %s failed, not url available" % key) - get_url = attr_info['baseurl']+attr_info['get_url'] obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, debugmode=self.debugmode, verbose=self.verbose) try: obmc.login() - method = 'GET' - if attr_info.has_key('get_method'): - method = attr_info['get_method'] - data = None - if attr_info.has_key('get_data'): - data={"data": attr_info['get_data']} - value = obmc.request(method, get_url, payload=data, cmd="get_%s" % key) - str_value = '0.'+str(value) - result = '%s: %s: %s' % (node, attr_info['display_name'], str_value.split('.')[-1]) + value = obmc.get_apis_values(key) except (SelfServerException, SelfClientException) as e: - result = '%s: %s' % (node, e.message) + self.callback.info('%s: %s' % (node, e.message)) + str_value = '0.'+str(value) + result = '%s: %s: %s' % (node, openbmc.RSPCONFIG_APIS[key]['display_name'], str_value.split('.')[-1]) self.callback.info(result) def _set_netinfo(self, ip, netmask, gateway, vlan=False, **kw): diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py index caa8c3cda..f4dc3e3a0 100644 --- a/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py @@ -139,6 +139,49 @@ FIRM_URLS = { } } +RSPCONFIG_APIS = { + 'autoreboot' : { + 'baseurl': "/control/host0/auto_reboot/", + 'set_url': "attr/AutoReboot", + 'get_url': "attr/AutoReboot", + 'display_name': "BMC AutoReboot", + }, + 'powersupplyredundancy':{ + 'baseurl': "/sensors/chassis/PowerSupplyRedundancy/", + 'set_url': "/action/setValue", + 'get_url': "/action/getValue", + 'get_method': 'POST', + 'get_data': '[]', + 'display_name': "BMC PowerSupplyRedundancy", + 'attr_values': { + 'disabled': "Disables", + 'enabled': "Enabled", + }, + }, + 'powerrestorepolicy': { + 'baseurl': "/control/host0/power_restore_policy/", + 'set_url': "attr/PowerRestorePolicy", + 'get_url': "attr/PowerRestorePolicy", + 'display_name': "BMC PowerRestorePolicy", + 'attr_values': { + 'restore': "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore", + 'always_on': "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn", + 'always_off': "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff", + }, + }, + 'bootmode': { + 'baseurl': "/control/host0/boot/", + 'set_url': "attr/BootMode", + 'get_url': "attr/BootMode", + 'display_name':"BMC BootMode", + 'attr_values': { + 'regular': "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular", + 'safe': "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe", + 'setup': "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup", + }, + }, +} + RESULT_OK = 'ok' RESULT_FAIL = 'fail' @@ -404,6 +447,31 @@ class OpenBMCRest(object): return bool(func_list), fw_dict + def set_apis_values(self, key, value): + attr_info = RSPCONFIG_APIS[key] + if not attr_info.has_key('set_url'): + raise SelfServerException("config %s failed, not url available" % key) + set_url = attr_info['baseurl']+attr_info['set_url'] + if attr_info.has_key('attr_values') and attr_info['attr_values'].has_key(value): + data = attr_info['attr_values'][value] + else: + data = value + self.request('PUT', set_url, payload={"data": data}, cmd="set_%s" % key) + + def get_apis_values(self, key): + attr_info = RSPCONFIG_APIS[key] + if not attr_info.has_key('get_url'): + raise SelfServerException("Reading %s failed, not url available" % key) + get_url = attr_info['baseurl']+attr_info['get_url'] + + method = 'GET' + if attr_info.has_key('get_method'): + method = attr_info['get_method'] + data = None + if attr_info.has_key('get_data'): + data={"data": attr_info['get_data']} + return self.request(method, get_url, payload=data, cmd="get_%s" % key) + class OpenBMCImage(object): def __init__(self, rawid, data=None): self.id = rawid.split('/')[-1] diff --git a/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py b/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py index b28d27ba2..6f56625cc 100644 --- a/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py +++ b/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py @@ -10,7 +10,7 @@ import time import sys import gevent import re -from docopt import docopt +from docopt import docopt,DocoptExit from common import utils from common import exceptions as xcat_exception @@ -95,14 +95,14 @@ Handle rspconfig operations. Usage: rspconfig -h|--help - rspconfig -V|--verbose - rspconfig dump [[-l|--list] | [-g|--generate] | [-c|--clear ] | [-d|--download ]] - rspconfig sshcfg - rspconfig ip=dhcp - rspconfig get [...] - rspconfig set [...] + rspconfig dump [[-l|--list] | [-g|--generate] | [-c|--clear ] | [-d|--download ]] [-V|--verbose] + rspconfig sshcfg [-V|--verbose] + rspconfig ip=dhcp [-V|--verbose] + rspconfig get [...] [-V|--verbose] + rspconfig set [...] [-V|--verbose] Options: + -V,--verbose Show verbose message -l,--list List are dump files -g,--generate Trigger a new dump file -c,--clear The id of file to clear or all if specify 'all' @@ -668,16 +668,14 @@ class OpenBMCManager(base.BaseManager): DefaultPowerManager().set_power_state(runner, power_state=action) def rspconfig(self, nodesinfo, args): try: - new_args=[] - for a in args: - new_a = a.encode('utf-8') - new_args.append(new_a) - opts=docopt(RSPCONFIG_USAGE, argv=new_args) - self.verbose=opts.pop('--verbose') + opts=docopt(RSPCONFIG_USAGE, argv=args) + except DocoptExit as e: + self.messager.error("Failed to parse args by docopt: %s" % e) + return except Exception as e: self.messager.error("Failed to parse arguments for rspconfig: %s" % args) return - + self.verbose=opts.pop('--verbose') runner = OpenBMCBmcConfigTask(nodesinfo, callback=self.messager, debugmode=self.debugmode, verbose=self.verbose) if opts['dump']: @@ -697,10 +695,8 @@ class OpenBMCManager(base.BaseManager): DefaultBmcConfigManager().set_ipdhcp(runner) elif opts['get']: unsupport_list=list(set(opts['']) - set(RSPCONFIG_GET_OPTIONS)) - for attr in opts['']: - if attr not in RSPCONFIG_GET_OPTIONS: - self.messager.error("The attribute %s is not supported to get" % attr) if len(unsupport_list) > 0: + self.messager.error("Have unsupported option: %s" % unsupport_args) return else: DefaultBmcConfigManager().get_attributes(runner, opts['']) diff --git a/xCAT-openbmc-py/lib/python/agent/xcatagent/server.py b/xCAT-openbmc-py/lib/python/agent/xcatagent/server.py index 86a6867de..f9b16bda4 100644 --- a/xCAT-openbmc-py/lib/python/agent/xcatagent/server.py +++ b/xCAT-openbmc-py/lib/python/agent/xcatagent/server.py @@ -92,8 +92,12 @@ class Server(object): if not hasattr(manager, req['command']): messager.error("command %s is not supported" % req['command']) func = getattr(manager, req['command']) + # translate unicode string to normal string to avoid docopt error + new_args=[] + for a in req['args']: + new_args.append(a.encode('utf-8')) # call the function in the specified manager - func(req['nodeinfo'], req['args']) + func(req['nodeinfo'], new_args) # after the method returns, the request should be handled # completely, close the socket for client if not self.standalone: