From 7ce5108422145307d9dc712073e7f99237d79960 Mon Sep 17 00:00:00 2001 From: xuweibj Date: Wed, 19 Dec 2018 03:34:04 -0500 Subject: [PATCH 1/4] rpower for redfish support --- .../agent/hwctl/executor/redfish_power.py | 89 +++++++ .../lib/python/agent/hwctl/redfish_client.py | 99 ++++++- .../lib/python/agent/xcatagent/redfish.py | 15 +- xCAT-server/lib/xcat/plugins/redfish.pm | 242 ++++++++++++++++++ 4 files changed, 441 insertions(+), 4 deletions(-) create mode 100644 xCAT-server/lib/xcat/plugins/redfish.pm diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_power.py b/xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_power.py index 75b6e079d..00325b994 100644 --- a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_power.py +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_power.py @@ -15,6 +15,12 @@ from hwctl import redfish_client as redfish import logging logger = logging.getLogger('xcatagent') +POWER_STATE_DB = { + "on" : "powering-on", + "off" : "powering-off", + "boot" : "powering-on", +} + class RedfishPowerTask(ParallelNodesCommand): """Executor for power-related actions.""" @@ -27,8 +33,91 @@ class RedfishPowerTask(ParallelNodesCommand): state = 'Unknown' try: rf.login() + chassis_state = rf.get_chassis_power_state() + if chassis_state == 'On': + state = rf.get_systems_power_state().lower() + else: + state = chassis_state.lower() self.callback.info('%s: %s' % (node, state)) except (SelfServerException, SelfClientException) as e: self.callback.error(e.message, node) return state + + def get_bmcstate (self, **kw): + + node = kw['node'] + rf = redfish.RedfishRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, + debugmode=self.debugmode, verbose=self.verbose) + + state = 'Unknown' + try: + rf.login() + state = rf.get_bmc_state().lower() + self.callback.info('%s: %s' % (node, state)) + except (SelfServerException, SelfClientException) as e: + self.callback.error(e.message, node) + return state + + def set_state(self, state, **kw): + + node = kw['node'] + rf = redfish.RedfishRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, + debugmode=self.debugmode, verbose=self.verbose) + + try: + rf.login() + rf.set_power_state(state) + new_status = POWER_STATE_DB.get(state, '') + self.callback.info('%s: %s' % (node, state)) + if new_status: + self.callback.update_node_attributes('status', node, new_status) + except (SelfServerException, SelfClientException) as e: + self.callback.error(e.message, node) + + def reboot(self, optype='boot', **kw): + + node = kw['node'] + rf = redfish.RedfishRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, + debugmode=self.debugmode, verbose=self.verbose) + resettype = 'boot' + + try: + rf.login() + chassis_state = rf.get_chassis_power_state() + if chassis_state == 'Off': + status = chassis_state + else: + status = rf.get_systems_power_state() + + if status == 'Off': + if optype == 'reset': + return self.callback.info('%s: %s' % (node, status.lower())) + else: + resettype = 'on' + + rf.set_power_state(resettype) + new_status = POWER_STATE_DB.get(optype, '') + self.callback.info('%s: %s' % (node, optype)) + if new_status: + self.callback.update_node_attributes('status', node, new_status) + except (SelfServerException, SelfClientException) as e: + self.callback.error(e.message, node) + + def reboot_bmc(self, optype='warm', **kw): + + node = kw['node'] + rf = redfish.RedfishRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, + debugmode=self.debugmode, verbose=self.verbose) + + try: + rf.login() + except (SelfServerException, SelfClientException) as e: + return self.callback.error(e.message, node) + + try: + rf.reboot_bmc(optype) + except (SelfServerException, SelfClientException) as e: + self.callback.error(e.message, node) + else: + self.callback.info('%s: %s' % (node, 'bmcreboot')) diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py b/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py index 9e01def8f..463d7e3b9 100644 --- a/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py @@ -19,8 +19,19 @@ logger = logging.getLogger('xcatagent') HTTP_PROTOCOL = "https://" PROJECT_URL = "/redfish/v1" +CHASSIS_URL = PROJECT_URL + "/Chassis" +MANAGER_URL = PROJECT_URL + "/Managers" +SYSTEMS_URL = PROJECT_URL + "/Systems" SESSION_URL = PROJECT_URL + "/SessionService/Sessions" +BMC_RESET_TYPE = "ForceRestart" + +POWER_RESET_TYPE = { + 'boot' : 'ForceRestart', + 'off' : 'ForceOff', + 'on' : 'ForceOn', +} + class RedfishRest(object): headers = {'Content-Type': 'application/json'} @@ -119,7 +130,10 @@ class RedfishRest(object): if cmd == 'login' and not 'X-Auth-Token' in resp.headers: raise SelfServerException('Login Failed: Did not get Session Token from response') - self._print_record_log('%s %s' % (code, data['Name']), cmd) + if 'Name' in data: + self._print_record_log('%s %s' % (code, data['Name']), cmd) + elif 'error' in data: + self._print_record_log('%s %s' % (code, data['error']['Message']), cmd) return data def login(self): @@ -127,3 +141,86 @@ class RedfishRest(object): payload = { "UserName": self.username, "Password": self.password } self.request('POST', SESSION_URL, payload=payload, timeout=20, cmd='login') + def _get_members(self, url): + + data = self.request('GET', url, cmd='get_members') + try: + return data['Members'] + except KeyError as e: + raise SelfServerException('Get KeyError %s' % e.message) + + def get_bmc_state(self): + + members = self._get_members(MANAGER_URL) + target_url = members[0]['@odata.id'] + data = self.request('GET', target_url, cmd='get_bmc_state') + try: + return data['PowerState'] + except KeyError as e: + raise SelfServerException('Get KeyError %s' % e.message) + + def get_chassis_power_state(self): + + members = self._get_members(CHASSIS_URL) + target_url = members[0]['@odata.id'] + data = self.request('GET', target_url, cmd='get_chassis_power_state') + try: + return data['PowerState'] + except KeyError as e: + raise SelfServerException('Get KeyError %s' % e.message) + + def get_systems_power_state(self): + + members = self._get_members(SYSTEMS_URL) + target_url = members[0]['@odata.id'] + data = self.request('GET', target_url, cmd='get_systems_power_state') + try: + return data['PowerState'] + except KeyError as e: + raise SelfServerException('Get KeyError %s' % e.message) + + def _get_bmc_actions(self): + + members = self._get_members(MANAGER_URL) + target_url = members[0]['@odata.id'] + data = self.request('GET', target_url, cmd='get_bmc_actions') + try: + actions = data['Actions']['#Manager.Reset']['ResetType@Redfish.AllowableValues'] + target_url = data['Actions']['#Manager.Reset']['target'] + except KeyError as e: + raise SelfServerException('Get KeyError %s' % e.message) + + return (target_url, actions) + + def reboot_bmc(self, optype='warm'): + + target_url, actions = self._get_bmc_actions() + if BMC_RESET_TYPE not in actions: + raise SelfClientException('Unsupport option: %s' % BMC_RESET_TYPE) + + data = { "ResetType": BMC_RESET_TYPE } + return self.request('POST', target_url, payload=data, cmd='set_bmc_state') + + def _get_power_actions(self): + + members = self._get_members(SYSTEMS_URL) + target_url = members[0]['@odata.id'] + data = self.request('GET', target_url, cmd='get_power_actions') + try: + actions = data['Actions']['#ComputerSystem.Reset']['ResetType@Redfish.AllowableValues'] + target_url = data['Actions']['#ComputerSystem.Reset']['target'] + except KeyError as e: + raise SelfServerException('Get KeyError %s' % e.message) + + return (target_url, actions) + + def set_power_state(self, state): + + target_url, actions = self._get_power_actions() + if POWER_RESET_TYPE[state] not in actions: + raise SelfClientException('Unsupport option: %s' % state) + + data = { "ResetType": POWER_RESET_TYPE[state] } + return self.request('POST', target_url, payload=data, cmd='set_power_state') + + diff --git a/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py b/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py index 1e37e9493..f9ec0e9d1 100644 --- a/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py +++ b/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py @@ -30,7 +30,7 @@ VERBOSE = False # global variables of rpower POWER_REBOOT_OPTIONS = ('boot', 'reset') -POWER_SET_OPTIONS = ('on', 'off', 'bmcreboot', 'softoff') +POWER_SET_OPTIONS = ('on', 'off', 'bmcreboot') POWER_GET_OPTIONS = ('bmcstate', 'state', 'stat', 'status') class RedfishManager(base.BaseManager): @@ -50,7 +50,7 @@ class RedfishManager(base.BaseManager): # 1, parse args rpower_usage = """ Usage: - rpower [-V|--verbose] [boot|bmcreboot|bmcstate|off|on|reset|softoff|stat|state|status] + rpower [-V|--verbose] [boot|bmcreboot|bmcstate|off|on|reset|stat|state|status] Options: -V --verbose rpower verbose mode. @@ -73,5 +73,14 @@ class RedfishManager(base.BaseManager): # 3, run the subcommands runner = RedfishPowerTask(nodesinfo, callback=self.messager, debugmode=self.debugmode, verbose=self.verbose) - DefaultPowerManager().get_power_state(runner) + if action == 'bmcstate': + DefaultPowerManager().get_bmc_state(runner) + elif action == 'bmcreboot': + DefaultPowerManager().reboot_bmc(runner) + elif action in POWER_GET_OPTIONS: + DefaultPowerManager().get_power_state(runner) + elif action in POWER_REBOOT_OPTIONS: + DefaultPowerManager().reboot(runner, optype=action) + else: + DefaultPowerManager().set_power_state(runner, power_state=action) diff --git a/xCAT-server/lib/xcat/plugins/redfish.pm b/xCAT-server/lib/xcat/plugins/redfish.pm new file mode 100644 index 000000000..984860e79 --- /dev/null +++ b/xCAT-server/lib/xcat/plugins/redfish.pm @@ -0,0 +1,242 @@ +#!/usr/bin/perl +### IBM(c) 2017 EPL license http://www.eclipse.org/legal/epl-v10.html + +package xCAT_plugin::redfish; + +BEGIN + { + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; + } +use lib "$::XCATROOT/lib/perl"; +use strict; +use warnings "all"; + +use Getopt::Long; +use xCAT::Usage; +use xCAT::SvrUtils; +use xCAT::AGENT; +use Data::Dumper; + +#------------------------------------------------------- + +=head3 handled_commands + + Return list of commands handled by this plugin + +=cut + +#------------------------------------------------------- + +sub handled_commands { + return { + rbeacon => 'nodehm:mgt', + reventlog => 'nodehm:mgt', + rinv => 'nodehm:mgt', + rpower => 'nodehm:mgt', + rsetboot => 'nodehm:mgt', + rspconfig => 'nodehm:mgt', + rvitals => 'nodehm:mgt', + }; +} + +my %node_info = (); +my $callback; +$::VERBOSE = 0; + +#------------------------------------------------------- + +=head3 preprocess_request + + preprocess the command + +=cut + +#------------------------------------------------------- + +sub preprocess_request { + my $request = shift; + $callback = shift; + my $command = $request->{command}->[0]; + my $noderange = $request->{node}; + my $extrargs = $request->{arg}; + my @exargs = ($request->{arg}); + my @requests; + + if (ref($extrargs)) { + @exargs = @$extrargs; + } + + my $usage_string = xCAT::Usage->parseCommand($command, @exargs); + if ($usage_string) { + $callback->({ data => [$usage_string] }); + $request = {}; + return; + } + + my $parse_result = parse_args($command, $extrargs, $noderange); + if (ref($parse_result) eq 'ARRAY') { + my $error_data; + foreach my $node (@$noderange) { + $error_data .= "\n" if ($error_data); + $error_data .= "$node: Error: " . "$parse_result->[1]"; + } + $callback->({ errorcode => [$parse_result->[0]], data => [$error_data] }); + $request = {}; + return; + } + + my $sn = xCAT::ServiceNodeUtils->get_ServiceNode($noderange, "xcat", "MN"); + foreach my $snkey (keys %$sn) { + my $reqcopy = {%$request}; + $reqcopy->{node} = $sn->{$snkey}; + $reqcopy->{'_xcatdest'} = $snkey; + $reqcopy->{_xcatpreprocessed}->[0] = 1; + push @requests, $reqcopy; + } + + return \@requests; +} + +#------------------------------------------------------- + +=head3 process_request + + Process the command + +=cut + +#------------------------------------------------------- + +sub process_request { + my $request = shift; + $callback = shift; + + if (!xCAT::AGENT::exists_python_agent()) { + xCAT::MsgUtils->message("E", { data => ["The xCAT Python agent does not exist. Check if xCAT-openbmc-py package is installed on management node and service nodes."] }, $callback); + return; + } + + my $noderange = $request->{node}; + my $check = parse_node_info($noderange); + $callback->({ errorcode => [$check] }) if ($check); + return unless(%node_info); + + my $pid = xCAT::AGENT::start_python_agent(); + if (!defined($pid)) { + xCAT::MsgUtils->message("E", { data => ["Failed to start the xCAT Python agent. Check /var/log/xcat/cluster.log for more information."] }, $callback); + return; + } + + xCAT::AGENT::submit_agent_request($pid, $request, "redfish", \%node_info, $callback); + xCAT::AGENT::wait_agent($pid, $callback); +} + +#------------------------------------------------------- + +=head3 parse_args + + Parse the command line options and operands + +=cut + +#------------------------------------------------------- + +sub parse_args { + my $command = shift; + my $extrargs = shift; + my $noderange = shift; + my $subcommand = undef; + + unless (GetOptions( + 'V|verbose' => \$::VERBOSE, + )) { + return ([ 1, "Error parsing arguments." ]); + } + + if (scalar(@ARGV) >= 2 and ($command =~ /rbeacon|rpower|rvitals/)) { + return ([ 1, "Only one option is supported at the same time for $command" ]); + } elsif (scalar(@ARGV) == 0 and $command =~ /rbeacon|rspconfig|rpower/) { + return ([ 1, "No option specified for $command" ]); + } else { + $subcommand = $ARGV[0]; + } + + if ($command eq "rpower") { + unless ($subcommand =~ /^on$|^off$|^reset$|^boot$|^bmcreboot$|^bmcstate$|^status$|^stat$|^state$/) { + return ([ 1, "Unsupported command: $command $subcommand" ]); + } + } else { + return ([ 1, "Unsupported command: $command" ]); + } +} + +#------------------------------------------------------- + +=head3 parse_node_info + + Parse the node information: bmc, bmcip, username, password + +=cut + +#------------------------------------------------------- + +sub parse_node_info { + my $noderange = shift; + my $rst = 0; + + my $passwd_table = xCAT::Table->new('passwd'); + my $passwd_hash = $passwd_table->getAttribs({ 'key' => 'redfish' }, qw(username password)); + + my $my_table = xCAT::Table->new('openbmc'); + my $my_hash = $my_table->getNodesAttribs(\@$noderange, ['bmc', 'username', 'password']); + + foreach my $node (@$noderange) { + if (defined($my_hash->{$node}->[0])) { + if ($my_hash->{$node}->[0]->{'bmc'}) { + $node_info{$node}{bmc} = $my_hash->{$node}->[0]->{'bmc'}; + $node_info{$node}{bmcip} = xCAT::NetworkUtils::getNodeIPaddress($my_hash->{$node}->[0]->{'bmc'}); + } + unless($node_info{$node}{bmc}) { + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute bmc", $callback, $node); + delete $node_info{$node}; + $rst = 1; + next; + } + unless($node_info{$node}{bmcip}) { + xCAT::SvrUtils::sendmsg("Error: Unable to resolve ip address for bmc: $node_info{$node}{bmc}", $callback, $node); + delete $node_info{$node}; + $rst = 1; + next; + } + if ($my_hash->{$node}->[0]->{'username'}) { + $node_info{$node}{username} = $my_hash->{$node}->[0]->{'username'}; + } elsif ($passwd_hash and $passwd_hash->{username}) { + $node_info{$node}{username} = $passwd_hash->{username}; + } else { + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute username", $callback, $node); + delete $node_info{$node}; + $rst = 1; + next; + } + + if ($my_hash->{$node}->[0]->{'password'}) { + $node_info{$node}{password} = $my_hash->{$node}->[0]->{'password'}; + } elsif ($passwd_hash and $passwd_hash->{password}) { + $node_info{$node}{password} = $passwd_hash->{password}; + } else { + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute password", $callback, $node); + delete $node_info{$node}; + $rst = 1; + next; + } + } else { + xCAT::SvrUtils::sendmsg("Error: Unable to get information from openbmc table", $callback, $node); + $rst = 1; + next; + } + } + + return $rst; +} + +1; From 1f1696862121d8edb74e8e9dcec09252fdc660ac Mon Sep 17 00:00:00 2001 From: xuweibj Date: Fri, 21 Dec 2018 00:28:11 -0500 Subject: [PATCH 2/4] rsetboot for redfish support --- .../agent/hwctl/executor/redfish_setboot.py | 51 +++++++++++++++++ .../lib/python/agent/hwctl/redfish_client.py | 57 +++++++++++++++++++ .../lib/python/agent/xcatagent/redfish.py | 43 ++++++++++++++ xCAT-server/lib/xcat/plugins/redfish.pm | 8 +++ 4 files changed, 159 insertions(+) create mode 100644 xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_setboot.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_setboot.py b/xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_setboot.py new file mode 100644 index 000000000..d80f9515a --- /dev/null +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_setboot.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +############################################################################### +# IBM(c) 2018 EPL license http://www.eclipse.org/legal/epl-v10.html +############################################################################### +# -*- coding: utf-8 -*- +# +from __future__ import print_function +import gevent +import time + +from common.task import ParallelNodesCommand +from common.exceptions import SelfClientException, SelfServerException +from hwctl import redfish_client as redfish + +import logging +logger = logging.getLogger('xcatagent') + +class RedfishBootTask(ParallelNodesCommand): + """Executor for setboot-related actions.""" + + def get_state(self, **kw): + + node = kw['node'] + rf = redfish.RedfishRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, + debugmode=self.debugmode, verbose=self.verbose) + + state = 'Unknown' + try: + rf.login() + state = rf.get_boot_state() + self.callback.info('%s: %s' % (node, state)) + + except (SelfServerException, SelfClientException) as e: + self.callback.error(e.message, node) + + return state + + def set_state(self, setboot_state, persistant, **kw): + + node = kw['node'] + rf = redfish.RedfishRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, + debugmode=self.debugmode, verbose=self.verbose) + + try: + rf.login() + rf.set_boot_state(persistant, setboot_state) + state = rf.get_boot_state() + self.callback.info('%s: %s' % (node, state)) + + except (SelfServerException, SelfClientException) as e: + self.callback.error(e.message, node) diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py b/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py index 463d7e3b9..a3cb838d5 100644 --- a/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py @@ -32,6 +32,24 @@ POWER_RESET_TYPE = { 'on' : 'ForceOn', } +BOOTSOURCE_SET_STATE = { + "cd" : "Cd", + "def" : "None", + "floppy": "Floppy", + "hd" : 'Hdd', + "net" : "Pxe", + "setup" : "BiosSetup", +} + +BOOTSOURCE_GET_STATE = { + "BiosSetup": "BIOS Setup", + "Floppy" : "Floppy", + "Cd" : "CD/DVD", + "Hdd" : "Hard Drive", + "None" : "boot override inactive", + "Pxe" : "Network", +} + class RedfishRest(object): headers = {'Content-Type': 'application/json'} @@ -223,4 +241,43 @@ class RedfishRest(object): data = { "ResetType": POWER_RESET_TYPE[state] } return self.request('POST', target_url, payload=data, cmd='set_power_state') + def get_boot_state(self): + members = self._get_members(SYSTEMS_URL) + target_url = members[0]['@odata.id'] + data = self.request('GET', target_url, cmd='get_boot_state') + try: + boot_enable = data['Boot']['BootSourceOverrideEnabled'] + if boot_enable == 'Disabled': + return 'boot override inactive' + bootsource = data['Boot']['BootSourceOverrideTarget'] + return BOOTSOURCE_GET_STATE.get(bootsource, bootsource) + except KeyError as e: + raise SelfServerException('Get KeyError %s' % e.message) + + def _get_boot_actions(self): + + members = self._get_members(SYSTEMS_URL) + target_url = members[0]['@odata.id'] + data = self.request('GET', target_url, cmd='get_boot_actions') + try: + actions = data['Boot']['BootSourceOverrideTarget@Redfish.AllowableValues'] + except KeyError as e: + raise SelfServerException('Get KeyError %s' % e.message) + + return (target_url, actions) + + def set_boot_state(self, persistant, state): + + target_url, actions = self._get_boot_actions() + target_data = BOOTSOURCE_SET_STATE[state] + if target_data not in actions: + raise SelfClientException('Unsupport option: %s' % state) + + boot_enable = 'Once' + if persistant: + boot_enable = 'Continuous' + if target_data == 'None': + boot_enable = 'Disabled' + data = {'Boot': {'BootSourceOverrideEnabled': boot_enable, "BootSourceOverrideTarget": target_data} } + return self.request('PATCH', target_url, payload=data, cmd='set_boot_state') diff --git a/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py b/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py index f9ec0e9d1..2ecb33b5b 100644 --- a/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py +++ b/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py @@ -14,7 +14,9 @@ from docopt import docopt,DocoptExit from common import utils from common import exceptions as xcat_exception from hwctl.executor.redfish_power import RedfishPowerTask +from hwctl.executor.redfish_setboot import RedfishBootTask from hwctl.power import DefaultPowerManager +from hwctl.setboot import DefaultBootManager from xcatagent import base import logging @@ -33,6 +35,10 @@ POWER_REBOOT_OPTIONS = ('boot', 'reset') POWER_SET_OPTIONS = ('on', 'off', 'bmcreboot') POWER_GET_OPTIONS = ('bmcstate', 'state', 'stat', 'status') +# global variables of rsetboot +SETBOOT_GET_OPTIONS = ('stat', '') +SETBOOT_SET_OPTIONS = ('cd', 'def', 'default', 'floppy', 'hd', 'net', 'setup') + class RedfishManager(base.BaseManager): def __init__(self, messager, cwd, nodes=None, envs=None): super(RedfishManager, self).__init__(messager, cwd) @@ -84,3 +90,40 @@ class RedfishManager(base.BaseManager): else: DefaultPowerManager().set_power_state(runner, power_state=action) + + def rsetboot(self, nodesinfo, args): + + # 1, parse args + if not args: + args = ['stat'] + + rsetboot_usage = """ + Usage: + rsetboot [-V|--verbose] [cd|def|default|floppy||hd|net|stat|setup] [-p] + + Options: + -V --verbose rsetboot verbose mode. + -p persistant boot source. + """ + + try: + opts = docopt(rsetboot_usage, argv=args) + + self.verbose = opts.pop('--verbose') + action_type = opts.pop('-p') + action = [k for k,v in opts.items() if v][0] + except Exception as e: + self.messager.error("Failed to parse arguments for rsetboot: %s" % args) + return + + # 2, validate the args + if action not in (SETBOOT_GET_OPTIONS + SETBOOT_SET_OPTIONS): + self.messager.error("Not supported subcommand for rsetboot: %s" % action) + return + + # 3, run the subcommands + runner = RedfishBootTask(nodesinfo, callback=self.messager, debugmode=self.debugmode, verbose=self.verbose) + if action in SETBOOT_GET_OPTIONS: + DefaultBootManager().get_boot_state(runner) + else: + DefaultBootManager().set_boot_state(runner, setboot_state=action, persistant=action_type) diff --git a/xCAT-server/lib/xcat/plugins/redfish.pm b/xCAT-server/lib/xcat/plugins/redfish.pm index 984860e79..fe8cd4d15 100644 --- a/xCAT-server/lib/xcat/plugins/redfish.pm +++ b/xCAT-server/lib/xcat/plugins/redfish.pm @@ -165,6 +165,14 @@ sub parse_args { unless ($subcommand =~ /^on$|^off$|^reset$|^boot$|^bmcreboot$|^bmcstate$|^status$|^stat$|^state$/) { return ([ 1, "Unsupported command: $command $subcommand" ]); } + } elsif ($command eq "rsetboot") { + my $persistant; + GetOptions('p' => \$persistant); + return ([ 1, "Only one option is supported at the same time for $command" ]) if (@ARGV > 1); + $subcommand = "stat" if (!defined($ARGV[0])); + unless ($subcommand =~ /^net$|^hd$|^cd$|^def$|^default$|^stat$|^setup$|^floppy$/) { + return ([ 1, "Unsupported command: $command $subcommand" ]); + } } else { return ([ 1, "Unsupported command: $command" ]); } From fae4c21d8f34e1a2c42a49976fe88d8b410348c5 Mon Sep 17 00:00:00 2001 From: xuweibj Date: Fri, 21 Dec 2018 00:35:44 -0500 Subject: [PATCH 3/4] recover --- .../agent/hwctl/executor/redfish_setboot.py | 51 ---------------- .../lib/python/agent/hwctl/redfish_client.py | 58 ------------------- .../lib/python/agent/xcatagent/redfish.py | 42 -------------- xCAT-server/lib/xcat/plugins/redfish.pm | 8 --- 4 files changed, 159 deletions(-) delete mode 100644 xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_setboot.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_setboot.py b/xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_setboot.py deleted file mode 100644 index d80f9515a..000000000 --- a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_setboot.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python -############################################################################### -# IBM(c) 2018 EPL license http://www.eclipse.org/legal/epl-v10.html -############################################################################### -# -*- coding: utf-8 -*- -# -from __future__ import print_function -import gevent -import time - -from common.task import ParallelNodesCommand -from common.exceptions import SelfClientException, SelfServerException -from hwctl import redfish_client as redfish - -import logging -logger = logging.getLogger('xcatagent') - -class RedfishBootTask(ParallelNodesCommand): - """Executor for setboot-related actions.""" - - def get_state(self, **kw): - - node = kw['node'] - rf = redfish.RedfishRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, - debugmode=self.debugmode, verbose=self.verbose) - - state = 'Unknown' - try: - rf.login() - state = rf.get_boot_state() - self.callback.info('%s: %s' % (node, state)) - - except (SelfServerException, SelfClientException) as e: - self.callback.error(e.message, node) - - return state - - def set_state(self, setboot_state, persistant, **kw): - - node = kw['node'] - rf = redfish.RedfishRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, - debugmode=self.debugmode, verbose=self.verbose) - - try: - rf.login() - rf.set_boot_state(persistant, setboot_state) - state = rf.get_boot_state() - self.callback.info('%s: %s' % (node, state)) - - except (SelfServerException, SelfClientException) as e: - self.callback.error(e.message, node) diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py b/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py index a3cb838d5..cb1d21f60 100644 --- a/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py @@ -32,24 +32,6 @@ POWER_RESET_TYPE = { 'on' : 'ForceOn', } -BOOTSOURCE_SET_STATE = { - "cd" : "Cd", - "def" : "None", - "floppy": "Floppy", - "hd" : 'Hdd', - "net" : "Pxe", - "setup" : "BiosSetup", -} - -BOOTSOURCE_GET_STATE = { - "BiosSetup": "BIOS Setup", - "Floppy" : "Floppy", - "Cd" : "CD/DVD", - "Hdd" : "Hard Drive", - "None" : "boot override inactive", - "Pxe" : "Network", -} - class RedfishRest(object): headers = {'Content-Type': 'application/json'} @@ -241,43 +223,3 @@ class RedfishRest(object): data = { "ResetType": POWER_RESET_TYPE[state] } return self.request('POST', target_url, payload=data, cmd='set_power_state') - def get_boot_state(self): - - members = self._get_members(SYSTEMS_URL) - target_url = members[0]['@odata.id'] - data = self.request('GET', target_url, cmd='get_boot_state') - try: - boot_enable = data['Boot']['BootSourceOverrideEnabled'] - if boot_enable == 'Disabled': - return 'boot override inactive' - bootsource = data['Boot']['BootSourceOverrideTarget'] - return BOOTSOURCE_GET_STATE.get(bootsource, bootsource) - except KeyError as e: - raise SelfServerException('Get KeyError %s' % e.message) - - def _get_boot_actions(self): - - members = self._get_members(SYSTEMS_URL) - target_url = members[0]['@odata.id'] - data = self.request('GET', target_url, cmd='get_boot_actions') - try: - actions = data['Boot']['BootSourceOverrideTarget@Redfish.AllowableValues'] - except KeyError as e: - raise SelfServerException('Get KeyError %s' % e.message) - - return (target_url, actions) - - def set_boot_state(self, persistant, state): - - target_url, actions = self._get_boot_actions() - target_data = BOOTSOURCE_SET_STATE[state] - if target_data not in actions: - raise SelfClientException('Unsupport option: %s' % state) - - boot_enable = 'Once' - if persistant: - boot_enable = 'Continuous' - if target_data == 'None': - boot_enable = 'Disabled' - data = {'Boot': {'BootSourceOverrideEnabled': boot_enable, "BootSourceOverrideTarget": target_data} } - return self.request('PATCH', target_url, payload=data, cmd='set_boot_state') diff --git a/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py b/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py index 2ecb33b5b..7bbc81381 100644 --- a/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py +++ b/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py @@ -14,7 +14,6 @@ from docopt import docopt,DocoptExit from common import utils from common import exceptions as xcat_exception from hwctl.executor.redfish_power import RedfishPowerTask -from hwctl.executor.redfish_setboot import RedfishBootTask from hwctl.power import DefaultPowerManager from hwctl.setboot import DefaultBootManager @@ -35,10 +34,6 @@ POWER_REBOOT_OPTIONS = ('boot', 'reset') POWER_SET_OPTIONS = ('on', 'off', 'bmcreboot') POWER_GET_OPTIONS = ('bmcstate', 'state', 'stat', 'status') -# global variables of rsetboot -SETBOOT_GET_OPTIONS = ('stat', '') -SETBOOT_SET_OPTIONS = ('cd', 'def', 'default', 'floppy', 'hd', 'net', 'setup') - class RedfishManager(base.BaseManager): def __init__(self, messager, cwd, nodes=None, envs=None): super(RedfishManager, self).__init__(messager, cwd) @@ -90,40 +85,3 @@ class RedfishManager(base.BaseManager): else: DefaultPowerManager().set_power_state(runner, power_state=action) - - def rsetboot(self, nodesinfo, args): - - # 1, parse args - if not args: - args = ['stat'] - - rsetboot_usage = """ - Usage: - rsetboot [-V|--verbose] [cd|def|default|floppy||hd|net|stat|setup] [-p] - - Options: - -V --verbose rsetboot verbose mode. - -p persistant boot source. - """ - - try: - opts = docopt(rsetboot_usage, argv=args) - - self.verbose = opts.pop('--verbose') - action_type = opts.pop('-p') - action = [k for k,v in opts.items() if v][0] - except Exception as e: - self.messager.error("Failed to parse arguments for rsetboot: %s" % args) - return - - # 2, validate the args - if action not in (SETBOOT_GET_OPTIONS + SETBOOT_SET_OPTIONS): - self.messager.error("Not supported subcommand for rsetboot: %s" % action) - return - - # 3, run the subcommands - runner = RedfishBootTask(nodesinfo, callback=self.messager, debugmode=self.debugmode, verbose=self.verbose) - if action in SETBOOT_GET_OPTIONS: - DefaultBootManager().get_boot_state(runner) - else: - DefaultBootManager().set_boot_state(runner, setboot_state=action, persistant=action_type) diff --git a/xCAT-server/lib/xcat/plugins/redfish.pm b/xCAT-server/lib/xcat/plugins/redfish.pm index fe8cd4d15..984860e79 100644 --- a/xCAT-server/lib/xcat/plugins/redfish.pm +++ b/xCAT-server/lib/xcat/plugins/redfish.pm @@ -165,14 +165,6 @@ sub parse_args { unless ($subcommand =~ /^on$|^off$|^reset$|^boot$|^bmcreboot$|^bmcstate$|^status$|^stat$|^state$/) { return ([ 1, "Unsupported command: $command $subcommand" ]); } - } elsif ($command eq "rsetboot") { - my $persistant; - GetOptions('p' => \$persistant); - return ([ 1, "Only one option is supported at the same time for $command" ]) if (@ARGV > 1); - $subcommand = "stat" if (!defined($ARGV[0])); - unless ($subcommand =~ /^net$|^hd$|^cd$|^def$|^default$|^stat$|^setup$|^floppy$/) { - return ([ 1, "Unsupported command: $command $subcommand" ]); - } } else { return ([ 1, "Unsupported command: $command" ]); } From a8eab805fddba0b77793b153b4cac7dfd553669a Mon Sep 17 00:00:00 2001 From: xuweibj Date: Mon, 7 Jan 2019 21:55:16 -0500 Subject: [PATCH 4/4] modify depending on discussion and comments --- .../hwctl/{executor => openbmc}/__init__.py | 0 .../{executor => openbmc}/openbmc_beacon.py | 0 .../openbmc_bmcconfig.py | 0 .../{executor => openbmc}/openbmc_eventlog.py | 0 .../{executor => openbmc}/openbmc_flash.py | 0 .../openbmc_inventory.py | 0 .../{executor => openbmc}/openbmc_power.py | 0 .../{executor => openbmc}/openbmc_sensor.py | 0 .../{executor => openbmc}/openbmc_setboot.py | 0 .../python/agent/hwctl/redfish/__init__.py | 0 .../{executor => redfish}/redfish_power.py | 0 .../lib/python/agent/hwctl/redfish_client.py | 16 +++-- .../lib/python/agent/xcatagent/openbmc.py | 14 ++-- .../lib/python/agent/xcatagent/redfish.py | 3 +- xCAT-server/lib/perl/xCAT/AGENT.pm | 71 +++++++++++++++++++ xCAT-server/lib/xcat/plugins/openbmc2.pm | 70 +----------------- xCAT-server/lib/xcat/plugins/redfish.pm | 71 +------------------ 17 files changed, 91 insertions(+), 154 deletions(-) rename xCAT-openbmc-py/lib/python/agent/hwctl/{executor => openbmc}/__init__.py (100%) rename xCAT-openbmc-py/lib/python/agent/hwctl/{executor => openbmc}/openbmc_beacon.py (100%) rename xCAT-openbmc-py/lib/python/agent/hwctl/{executor => openbmc}/openbmc_bmcconfig.py (100%) rename xCAT-openbmc-py/lib/python/agent/hwctl/{executor => openbmc}/openbmc_eventlog.py (100%) rename xCAT-openbmc-py/lib/python/agent/hwctl/{executor => openbmc}/openbmc_flash.py (100%) rename xCAT-openbmc-py/lib/python/agent/hwctl/{executor => openbmc}/openbmc_inventory.py (100%) rename xCAT-openbmc-py/lib/python/agent/hwctl/{executor => openbmc}/openbmc_power.py (100%) rename xCAT-openbmc-py/lib/python/agent/hwctl/{executor => openbmc}/openbmc_sensor.py (100%) rename xCAT-openbmc-py/lib/python/agent/hwctl/{executor => openbmc}/openbmc_setboot.py (100%) create mode 100644 xCAT-openbmc-py/lib/python/agent/hwctl/redfish/__init__.py rename xCAT-openbmc-py/lib/python/agent/hwctl/{executor => redfish}/redfish_power.py (100%) diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/__init__.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/__init__.py similarity index 100% rename from xCAT-openbmc-py/lib/python/agent/hwctl/executor/__init__.py rename to xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/__init__.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_beacon.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_beacon.py similarity index 100% rename from xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_beacon.py rename to xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_beacon.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_bmcconfig.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_bmcconfig.py similarity index 100% rename from xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_bmcconfig.py rename to xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_bmcconfig.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_eventlog.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_eventlog.py similarity index 100% rename from xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_eventlog.py rename to xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_eventlog.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_flash.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_flash.py similarity index 100% rename from xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_flash.py rename to xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_flash.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_inventory.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_inventory.py similarity index 100% rename from xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_inventory.py rename to xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_inventory.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_power.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_power.py similarity index 100% rename from xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_power.py rename to xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_power.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_sensor.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_sensor.py similarity index 100% rename from xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_sensor.py rename to xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_sensor.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_setboot.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_setboot.py similarity index 100% rename from xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_setboot.py rename to xCAT-openbmc-py/lib/python/agent/hwctl/openbmc/openbmc_setboot.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/redfish/__init__.py b/xCAT-openbmc-py/lib/python/agent/hwctl/redfish/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_power.py b/xCAT-openbmc-py/lib/python/agent/hwctl/redfish/redfish_power.py similarity index 100% rename from xCAT-openbmc-py/lib/python/agent/hwctl/executor/redfish_power.py rename to xCAT-openbmc-py/lib/python/agent/hwctl/redfish/redfish_power.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py b/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py index cb1d21f60..b8321d07b 100644 --- a/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/redfish_client.py @@ -32,6 +32,10 @@ POWER_RESET_TYPE = { 'on' : 'ForceOn', } +manager_reset_string = '#Manager.Reset' +system_reset_string = '#ComputerSystem.Reset' +reset_type_string = 'ResetType@Redfish.AllowableValues' + class RedfishRest(object): headers = {'Content-Type': 'application/json'} @@ -185,8 +189,8 @@ class RedfishRest(object): target_url = members[0]['@odata.id'] data = self.request('GET', target_url, cmd='get_bmc_actions') try: - actions = data['Actions']['#Manager.Reset']['ResetType@Redfish.AllowableValues'] - target_url = data['Actions']['#Manager.Reset']['target'] + actions = data['Actions'][manager_reset_string][reset_type_string] + target_url = data['Actions'][manager_reset_string]['target'] except KeyError as e: raise SelfServerException('Get KeyError %s' % e.message) @@ -196,7 +200,7 @@ class RedfishRest(object): target_url, actions = self._get_bmc_actions() if BMC_RESET_TYPE not in actions: - raise SelfClientException('Unsupport option: %s' % BMC_RESET_TYPE) + raise SelfClientException('Unsupported option: %s' % BMC_RESET_TYPE) data = { "ResetType": BMC_RESET_TYPE } return self.request('POST', target_url, payload=data, cmd='set_bmc_state') @@ -207,8 +211,8 @@ class RedfishRest(object): target_url = members[0]['@odata.id'] data = self.request('GET', target_url, cmd='get_power_actions') try: - actions = data['Actions']['#ComputerSystem.Reset']['ResetType@Redfish.AllowableValues'] - target_url = data['Actions']['#ComputerSystem.Reset']['target'] + actions = data['Actions'][system_reset_string][reset_type_string] + target_url = data['Actions'][system_reset_string]['target'] except KeyError as e: raise SelfServerException('Get KeyError %s' % e.message) @@ -218,7 +222,7 @@ class RedfishRest(object): target_url, actions = self._get_power_actions() if POWER_RESET_TYPE[state] not in actions: - raise SelfClientException('Unsupport option: %s' % state) + raise SelfClientException('Unsupported option: %s' % state) data = { "ResetType": POWER_RESET_TYPE[state] } return self.request('POST', target_url, payload=data, cmd='set_power_state') diff --git a/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py b/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py index 080ddef5e..3b96dca62 100644 --- a/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py +++ b/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py @@ -14,13 +14,13 @@ from docopt import docopt,DocoptExit from common import utils from common import exceptions as xcat_exception -from hwctl.executor.openbmc_beacon import OpenBMCBeaconTask -from hwctl.executor.openbmc_setboot import OpenBMCBootTask -from hwctl.executor.openbmc_flash import OpenBMCFlashTask -from hwctl.executor.openbmc_inventory import OpenBMCInventoryTask -from hwctl.executor.openbmc_power import OpenBMCPowerTask -from hwctl.executor.openbmc_sensor import OpenBMCSensorTask -from hwctl.executor.openbmc_eventlog import OpenBMCEventlogTask +from hwctl.openbmc.openbmc_beacon import OpenBMCBeaconTask +from hwctl.openbmc.openbmc_setboot import OpenBMCBootTask +from hwctl.openbmc.openbmc_flash import OpenBMCFlashTask +from hwctl.openbmc.openbmc_inventory import OpenBMCInventoryTask +from hwctl.openbmc.openbmc_power import OpenBMCPowerTask +from hwctl.openbmc.openbmc_sensor import OpenBMCSensorTask +from hwctl.openbmc.openbmc_eventlog import OpenBMCEventlogTask from hwctl.beacon import DefaultBeaconManager from hwctl.setboot import DefaultBootManager from hwctl.flash import DefaultFlashManager diff --git a/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py b/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py index 7bbc81381..322f651cc 100644 --- a/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py +++ b/xCAT-openbmc-py/lib/python/agent/xcatagent/redfish.py @@ -13,9 +13,8 @@ from docopt import docopt,DocoptExit from common import utils from common import exceptions as xcat_exception -from hwctl.executor.redfish_power import RedfishPowerTask +from hwctl.redfish.redfish_power import RedfishPowerTask from hwctl.power import DefaultPowerManager -from hwctl.setboot import DefaultBootManager from xcatagent import base import logging diff --git a/xCAT-server/lib/perl/xCAT/AGENT.pm b/xCAT-server/lib/perl/xCAT/AGENT.pm index aee201cbe..c44ea71d7 100644 --- a/xCAT-server/lib/perl/xCAT/AGENT.pm +++ b/xCAT-server/lib/perl/xCAT/AGENT.pm @@ -33,6 +33,77 @@ my %module_type = ( "redfish" => "Redfish", ); +#------------------------------------------------------- + +=head3 parse_node_info + + Parse the node information: bmc, bmcip, username, password + +=cut + +#------------------------------------------------------- +sub parse_node_info { + my $noderange = shift; + my $module = shift; + my $node_info_ref = shift; + my $callback = shift; + my $rst = 0; + + my $passwd_table = xCAT::Table->new('passwd'); + my $passwd_hash = $passwd_table->getAttribs({ 'key' => $module }, qw(username password)); + + my $openbmc_table = xCAT::Table->new('openbmc'); + my $openbmc_hash = $openbmc_table->getNodesAttribs(\@$noderange, ['bmc', 'username', 'password']); + + foreach my $node (@$noderange) { + if (defined($openbmc_hash->{$node}->[0])) { + if ($openbmc_hash->{$node}->[0]->{'bmc'}) { + $node_info_ref->{$node}->{bmc} = $openbmc_hash->{$node}->[0]->{'bmc'}; + $node_info_ref->{$node}->{bmcip} = xCAT::NetworkUtils::getNodeIPaddress($openbmc_hash->{$node}->[0]->{'bmc'}); + } + unless($node_info_ref->{$node}->{bmc}) { + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute bmc", $callback, $node); + delete $node_info_ref->{$node}; + $rst = 1; + next; + } + unless($node_info_ref->{$node}->{bmcip}) { + xCAT::SvrUtils::sendmsg("Error: Unable to resolve ip address for bmc: $node_info_ref->{$node}->{bmc}", $callback, $node); + delete $node_info_ref->{$node}; + $rst = 1; + next; + } + if ($openbmc_hash->{$node}->[0]->{'username'}) { + $node_info_ref->{$node}->{username} = $openbmc_hash->{$node}->[0]->{'username'}; + } elsif ($passwd_hash and $passwd_hash->{username}) { + $node_info_ref->{$node}->{username} = $passwd_hash->{username}; + } else { + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute username", $callback, $node); + delete $node_info_ref->{$node}; + $rst = 1; + next; + } + + if ($openbmc_hash->{$node}->[0]->{'password'}) { + $node_info_ref->{$node}->{password} = $openbmc_hash->{$node}->[0]->{'password'}; + } elsif ($passwd_hash and $passwd_hash->{password}) { + $node_info_ref->{$node}->{password} = $passwd_hash->{password}; + } else { + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute password", $callback, $node); + delete $node_info_ref->{$node}; + $rst = 1; + next; + } + } else { + xCAT::SvrUtils::sendmsg("Error: Unable to get information from openbmc table", $callback, $node); + $rst = 1; + next; + } + } + + return $rst; +} + sub acquire_lock { my $ppid = shift; $ppid = shift if (($ppid) && ($ppid =~ /AGENT/)); diff --git a/xCAT-server/lib/xcat/plugins/openbmc2.pm b/xCAT-server/lib/xcat/plugins/openbmc2.pm index a70a2f5ee..4a73fdcfb 100644 --- a/xCAT-server/lib/xcat/plugins/openbmc2.pm +++ b/xCAT-server/lib/xcat/plugins/openbmc2.pm @@ -141,7 +141,7 @@ sub process_request { } my $noderange = $request->{node}; - my $check = parse_node_info($noderange); + my $check = xCAT::AGENT::parse_node_info($noderange, "openbmc", \%node_info, $callback); if (&refactor_args($request)) { xCAT::MsgUtils->message("E", { data => ["Failed to refactor arguments"] }, $callback); return; @@ -418,74 +418,6 @@ sub parse_args { #------------------------------------------------------- -=head3 parse_node_info - - Parse the node information: bmc, bmcip, username, password - -=cut - -#------------------------------------------------------- -sub parse_node_info { - my $noderange = shift; - my $rst = 0; - - my $passwd_table = xCAT::Table->new('passwd'); - my $passwd_hash = $passwd_table->getAttribs({ 'key' => 'openbmc' }, qw(username password)); - - my $openbmc_table = xCAT::Table->new('openbmc'); - my $openbmc_hash = $openbmc_table->getNodesAttribs(\@$noderange, ['bmc', 'username', 'password']); - - foreach my $node (@$noderange) { - if (defined($openbmc_hash->{$node}->[0])) { - if ($openbmc_hash->{$node}->[0]->{'bmc'}) { - $node_info{$node}{bmc} = $openbmc_hash->{$node}->[0]->{'bmc'}; - $node_info{$node}{bmcip} = xCAT::NetworkUtils::getNodeIPaddress($openbmc_hash->{$node}->[0]->{'bmc'}); - } - unless($node_info{$node}{bmc}) { - xCAT::SvrUtils::sendmsg("Error: Unable to get attribute bmc", $callback, $node); - delete $node_info{$node}; - $rst = 1; - next; - } - unless($node_info{$node}{bmcip}) { - xCAT::SvrUtils::sendmsg("Error: Unable to resolve ip address for bmc: $node_info{$node}{bmc}", $callback, $node); - delete $node_info{$node}; - $rst = 1; - next; - } - if ($openbmc_hash->{$node}->[0]->{'username'}) { - $node_info{$node}{username} = $openbmc_hash->{$node}->[0]->{'username'}; - } elsif ($passwd_hash and $passwd_hash->{username}) { - $node_info{$node}{username} = $passwd_hash->{username}; - } else { - xCAT::SvrUtils::sendmsg("Error: Unable to get attribute username", $callback, $node); - delete $node_info{$node}; - $rst = 1; - next; - } - - if ($openbmc_hash->{$node}->[0]->{'password'}) { - $node_info{$node}{password} = $openbmc_hash->{$node}->[0]->{'password'}; - } elsif ($passwd_hash and $passwd_hash->{password}) { - $node_info{$node}{password} = $passwd_hash->{password}; - } else { - xCAT::SvrUtils::sendmsg("Error: Unable to get attribute password", $callback, $node); - delete $node_info{$node}; - $rst = 1; - next; - } - } else { - xCAT::SvrUtils::sendmsg("Error: Unable to get information from openbmc table", $callback, $node); - $rst = 1; - next; - } - } - - return $rst; -} - -#------------------------------------------------------- - =head3 refactor_args refractor args to be easily dealt by python client diff --git a/xCAT-server/lib/xcat/plugins/redfish.pm b/xCAT-server/lib/xcat/plugins/redfish.pm index 984860e79..491512a7d 100644 --- a/xCAT-server/lib/xcat/plugins/redfish.pm +++ b/xCAT-server/lib/xcat/plugins/redfish.pm @@ -117,7 +117,7 @@ sub process_request { } my $noderange = $request->{node}; - my $check = parse_node_info($noderange); + my $check = xCAT::AGENT::parse_node_info($noderange, "redfish", \%node_info, $callback); $callback->({ errorcode => [$check] }) if ($check); return unless(%node_info); @@ -170,73 +170,4 @@ sub parse_args { } } -#------------------------------------------------------- - -=head3 parse_node_info - - Parse the node information: bmc, bmcip, username, password - -=cut - -#------------------------------------------------------- - -sub parse_node_info { - my $noderange = shift; - my $rst = 0; - - my $passwd_table = xCAT::Table->new('passwd'); - my $passwd_hash = $passwd_table->getAttribs({ 'key' => 'redfish' }, qw(username password)); - - my $my_table = xCAT::Table->new('openbmc'); - my $my_hash = $my_table->getNodesAttribs(\@$noderange, ['bmc', 'username', 'password']); - - foreach my $node (@$noderange) { - if (defined($my_hash->{$node}->[0])) { - if ($my_hash->{$node}->[0]->{'bmc'}) { - $node_info{$node}{bmc} = $my_hash->{$node}->[0]->{'bmc'}; - $node_info{$node}{bmcip} = xCAT::NetworkUtils::getNodeIPaddress($my_hash->{$node}->[0]->{'bmc'}); - } - unless($node_info{$node}{bmc}) { - xCAT::SvrUtils::sendmsg("Error: Unable to get attribute bmc", $callback, $node); - delete $node_info{$node}; - $rst = 1; - next; - } - unless($node_info{$node}{bmcip}) { - xCAT::SvrUtils::sendmsg("Error: Unable to resolve ip address for bmc: $node_info{$node}{bmc}", $callback, $node); - delete $node_info{$node}; - $rst = 1; - next; - } - if ($my_hash->{$node}->[0]->{'username'}) { - $node_info{$node}{username} = $my_hash->{$node}->[0]->{'username'}; - } elsif ($passwd_hash and $passwd_hash->{username}) { - $node_info{$node}{username} = $passwd_hash->{username}; - } else { - xCAT::SvrUtils::sendmsg("Error: Unable to get attribute username", $callback, $node); - delete $node_info{$node}; - $rst = 1; - next; - } - - if ($my_hash->{$node}->[0]->{'password'}) { - $node_info{$node}{password} = $my_hash->{$node}->[0]->{'password'}; - } elsif ($passwd_hash and $passwd_hash->{password}) { - $node_info{$node}{password} = $passwd_hash->{password}; - } else { - xCAT::SvrUtils::sendmsg("Error: Unable to get attribute password", $callback, $node); - delete $node_info{$node}; - $rst = 1; - next; - } - } else { - xCAT::SvrUtils::sendmsg("Error: Unable to get information from openbmc table", $callback, $node); - $rst = 1; - next; - } - } - - return $rst; -} - 1;