mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-03 21:02:34 +00:00 
			
		
		
		
	Merge master branch to RHEL 8 branch (#5953)
* rpower for redfish support * rsetboot for redfish support * recover * modify depending on discussion and comments * refine test case xcatd_start (#5932) * Update small text in the diskful support example for cuda_power9_setup Fix small issue mentioned in 5852 * rsetboot for redfish support * Fix issue 5933: xCAT-openbmc-py build failed * Fix remoteshell compatibility with custom Match (#5936) If a user has a custom Match directive, remoteshell would create an invalid configuration. Fix by ensuring we are outside of a match context by doing Match all explicitly. * fix issue PR #5936 resulted in remoteshell failed in rhels6.10 #5944 * refine xcat-inventory backend testcase (#5946) * add test case for issue 3602: confignetwork cannot work when regular expression is used in nics table * add lsdef to get more debug info * Revert "fix issue PR #5936 resulted in remoteshell failed in rhels6.10 #5944" * revert PR Fix remoteshell compatibility with custom Match #5936
This commit is contained in:
		@@ -189,7 +189,7 @@ xCAT includes a script, ``cuda_power9_setup`` as example, to help user handle th
 | 
			
		||||
Diskful osimage
 | 
			
		||||
^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
For diskful deployment, there is no need to change the osimage definition. Instead, add this postscript to your compute node postbootscrtips list. ::
 | 
			
		||||
For diskful deployment, there is no need to change the osimage definition. Instead, add this postscript to your compute node postscripts list. ::
 | 
			
		||||
 | 
			
		||||
    chdef p9compute -p postscripts=cuda_power9_setup
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,4 +2,5 @@ opt/xcat/lib/python/agent
 | 
			
		||||
opt/xcat/lib/python/agent/xcatagent
 | 
			
		||||
opt/xcat/lib/python/agent/common
 | 
			
		||||
opt/xcat/lib/python/agent/hwctl
 | 
			
		||||
opt/xcat/lib/python/agent/hwctl/executor
 | 
			
		||||
opt/xcat/lib/python/agent/hwctl/openbmc
 | 
			
		||||
opt/xcat/lib/python/agent/hwctl/redfish
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										123
									
								
								xCAT-openbmc-py/lib/python/agent/hwctl/redfish/redfish_power.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								xCAT-openbmc-py/lib/python/agent/hwctl/redfish/redfish_power.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
			
		||||
#!/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')
 | 
			
		||||
 | 
			
		||||
POWER_STATE_DB = {
 | 
			
		||||
    "on"      : "powering-on",
 | 
			
		||||
    "off"     : "powering-off",
 | 
			
		||||
    "boot"    : "powering-on",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class RedfishPowerTask(ParallelNodesCommand):
 | 
			
		||||
    """Executor for power-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()
 | 
			
		||||
            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')) 
 | 
			
		||||
@@ -15,8 +15,8 @@ from hwctl import redfish_client as redfish
 | 
			
		||||
import logging
 | 
			
		||||
logger = logging.getLogger('xcatagent')
 | 
			
		||||
 | 
			
		||||
class RedfishPowerTask(ParallelNodesCommand):
 | 
			
		||||
    """Executor for power-related actions."""
 | 
			
		||||
class RedfishBootTask(ParallelNodesCommand):
 | 
			
		||||
    """Executor for setboot-related actions."""
 | 
			
		||||
 | 
			
		||||
    def get_state(self, **kw):
 | 
			
		||||
 | 
			
		||||
@@ -27,8 +27,25 @@ class RedfishPowerTask(ParallelNodesCommand):
 | 
			
		||||
        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
 | 
			
		||||
        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)
 | 
			
		||||
@@ -19,8 +19,42 @@ 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',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
manager_reset_string = '#Manager.Reset'
 | 
			
		||||
system_reset_string = '#ComputerSystem.Reset'
 | 
			
		||||
reset_type_string = 'ResetType@Redfish.AllowableValues'
 | 
			
		||||
 | 
			
		||||
BOOTSOURCE_SET_STATE = {
 | 
			
		||||
    "cd"     : "Cd",
 | 
			
		||||
    "def"    : "None",
 | 
			
		||||
    "default": "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'}
 | 
			
		||||
@@ -119,7 +153,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 +164,126 @@ 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_string][reset_type_string]
 | 
			
		||||
            target_url = data['Actions'][manager_reset_string]['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('Unsupported 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'][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)
 | 
			
		||||
 | 
			
		||||
        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('Unsupported option: %s' % state)
 | 
			
		||||
 | 
			
		||||
        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('Unsupported 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')
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,10 @@ 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.redfish.redfish_setboot import RedfishBootTask
 | 
			
		||||
from hwctl.power import DefaultPowerManager
 | 
			
		||||
from hwctl.setboot import DefaultBootManager
 | 
			
		||||
 | 
			
		||||
from xcatagent import base
 | 
			
		||||
import logging
 | 
			
		||||
@@ -30,9 +32,13 @@ 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')
 | 
			
		||||
 | 
			
		||||
# 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)
 | 
			
		||||
@@ -50,7 +56,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 +79,51 @@ 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)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
 
 | 
			
		||||
@@ -36,12 +36,14 @@ install -d $RPM_BUILD_ROOT/%{prefix}/lib/python/agent
 | 
			
		||||
install -d $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/xcatagent
 | 
			
		||||
install -d $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/common
 | 
			
		||||
install -d $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/hwctl
 | 
			
		||||
install -d $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/hwctl/executor
 | 
			
		||||
install -d $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/hwctl/openbmc
 | 
			
		||||
install -d $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/hwctl/redfish
 | 
			
		||||
install -m755 lib/python/agent/*.py $RPM_BUILD_ROOT/%{prefix}/lib/python/agent
 | 
			
		||||
install -m644 lib/python/agent/xcatagent/*.py $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/xcatagent
 | 
			
		||||
install -m644 lib/python/agent/common/*.py $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/common
 | 
			
		||||
install -m644 lib/python/agent/hwctl/*.py $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/hwctl
 | 
			
		||||
install -m644 lib/python/agent/hwctl/executor/*.py $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/hwctl/executor
 | 
			
		||||
install -m644 lib/python/agent/hwctl/openbmc/*.py $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/hwctl/openbmc/
 | 
			
		||||
install -m644 lib/python/agent/hwctl/redfish/*.py $RPM_BUILD_ROOT/%{prefix}/lib/python/agent/hwctl/redfish/
 | 
			
		||||
 | 
			
		||||
%ifnos linux
 | 
			
		||||
rm -rf $RPM_BUILD_ROOT/%{prefix}/lib/python/agent
 | 
			
		||||
 
 | 
			
		||||
@@ -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/));
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										181
									
								
								xCAT-server/lib/xcat/plugins/redfish.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								xCAT-server/lib/xcat/plugins/redfish.pm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,181 @@
 | 
			
		||||
#!/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 = xCAT::AGENT::parse_node_info($noderange, "redfish", \%node_info, $callback);
 | 
			
		||||
    $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" ]);
 | 
			
		||||
        }
 | 
			
		||||
    } 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" ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
1;
 | 
			
		||||
							
								
								
									
										47
									
								
								xCAT-test/autotest/testcase/confignetwork/cases1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								xCAT-test/autotest/testcase/confignetwork/cases1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
start:confignetwork_secondarynic_third_regex_updatenode
 | 
			
		||||
description:this case is to verify if confignetwork could config serveral nics with regex patten.This case is to verify defect 3602.
 | 
			
		||||
label:others,network
 | 
			
		||||
cmd:lsdef $$CN;if [ $? -eq 0 ]; then lsdef -l $$CN -z >/tmp/CN.standa ;fi
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:xdsh $$CN "rm -rf /tmp/backupnet/"
 | 
			
		||||
cmd:xdsh $$CN "mkdir -p /tmp/backupnet/"
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:if grep SUSE /etc/*release;then xdsh $$CN "cp -f /etc/sysconfig/network/ifcfg-* /tmp/backupnet/"; elif grep -E "Red Hat|CentOS" /etc/*release;then xdsh $$CN "cp -f /etc/sysconfig/network-scripts/ifcfg-* /tmp/backupnet/"; elif grep Ubuntu /etc/*release;then xdsh $$CN "cp -f /etc/network/interfaces.d/* /tmp/backupnet/";else echo "Sorry,this is not supported os"; fi
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:mkdef -t network -o 30_0_0_0-255_255_0_0 net=30.0.0.0 mask=255.0.0.0 mgtifname=$$SECONDNIC
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:mkdef -t network -o 40_0_0_0-255_255_0_0 net=40.0.0.0 mask=255.0.0.0 mgtifname=$$THIRDNIC
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:chdef $$CN nicips.$$SECONDNIC="|\D+\d+\D+\d+\D+\d+\D+(\d+)|30.0.0.(\$1/1000+9)|" nictypes.$$SECONDNIC=Ethernet nicnetworks.$$SECONDNIC="30_0_0_0-255_255_0_0"
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:chdef $$CN nicips.$$THIRDNIC="|\D+\d+\D+\d+\D+\d+\D+(\d+)|40.0.0.(\$1/1000+8)|" nictypes.$$THIRDNIC=Ethernet nicnetworks.$$THIRDNIC="40_0_0_0-255_255_0_0"
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:lsdef $$CN
 | 
			
		||||
cmd:cp /etc/hosts /etc/hosts.bak
 | 
			
		||||
cmd:rc==0
 | 
			
		||||
cmd:makehosts $$CN
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:cat /etc/hosts
 | 
			
		||||
check:output=~$$CN-$$SECONDNIC
 | 
			
		||||
check:output=~$$CN-$$THIRDNIC
 | 
			
		||||
cmd:updatenode $$CN -P confignetwork
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:if grep SUSE /etc/*release;then xdsh $$CN "grep 30.0.0.9 /etc/sysconfig/network/ifcfg-$$SECONDNIC"; elif grep -E "Red Hat|CentOS" /etc/*release;then xdsh $$CN  "grep 30.0.0.9 /etc/sysconfig/network-scripts/ifcfg-$$SECONDNIC"; elif grep Ubuntu /etc/*release;then xdsh $$CN "grep 30.0.0.9 /etc/network/interfaces.d/$$SECONDNIC";else echo "Sorry,this is not supported os"; fi
 | 
			
		||||
check:output=~30.0.0.9
 | 
			
		||||
cmd:if grep SUSE /etc/*release;then xdsh $$CN "grep 40.0.0.8 /etc/sysconfig/network/ifcfg-$$THIRDNIC"; elif grep -E "Red Hat|CentOS" /etc/*release;then xdsh $$CN  "grep 40.0.0.8 /etc/sysconfig/network-scripts/ifcfg-$$THIRDNIC"; elif grep Ubuntu /etc/*release;then xdsh $$CN "grep 40.0.0.8 /etc/network/interfaces.d/$$THIRDNIC";else echo "Sorry,this is not supported os"; fi
 | 
			
		||||
check:output=~40.0.0.8
 | 
			
		||||
cmd:rmdef -t network -o 30_0_0_0-255_255_0_0
 | 
			
		||||
cmd:rmdef -t network -o 40_0_0_0-255_255_0_0
 | 
			
		||||
cmd:if grep SUSE /etc/*release;then xdsh $$CN "rm -rf /etc/sysconfig/network/ifcfg-$$SECONDNIC"; elif grep -E "Red Hat|CentOS" /etc/*release;then xdsh $$CN "rm -rf /etc/sysconfig/network-scripts/ifcfg-$$SECONDNIC"; elif grep Ubuntu /etc/*release;then xdsh $$CN "rm -rf /etc/network/interfaces.d/$$SECONDNIC";else echo "Sorry,this is not supported os"; fi
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:if grep SUSE /etc/*release;then xdsh $$CN "rm -rf /etc/sysconfig/network/ifcfg-$$THIRDNIC"; elif grep -E "Red Hat|CentOS" /etc/*release;then xdsh $$CN "rm -rf /etc/sysconfig/network-scripts/ifcfg-$$THIRDNIC"; elif grep Ubuntu /etc/*release;then xdsh $$CN "rm -rf /etc/network/interfaces.d/$$THIRDNIC";else echo "Sorry,this is not supported os"; fi
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:xdsh $$CN "ip addr del 30.0.0.9/8 dev $$SECONDNIC"
 | 
			
		||||
cmd:xdsh $$CN "ip addr del 40.0.0.8/8 dev $$THIRDNIC"
 | 
			
		||||
cmd:if [ -e /tmp/CN.standa ]; then rmdef $$CN; cat /tmp/CN.standa | mkdef -z; rm -rf /tmp/CN.standa; fi
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:mv -f /etc/hosts.bak /etc/hosts
 | 
			
		||||
cmd:if grep SUSE /etc/*release;then xdsh $$CN "cp -f /tmp/backupnet/* /etc/sysconfig/network/"; elif grep -E "Red Hat|CentOS" /etc/*release;then xdsh $$CN "cp -f /tmp/backupnet/* /etc/sysconfig/network-scripts/"; elif grep Ubuntu /etc/*release;then xdsh $$CN "cp -f /tmp/backupnet/* /etc/network/interfaces.d/";else echo "Sorry,this is not supported os"; fi
 | 
			
		||||
cmd:xdsh $$CN "rm -rf /tmp/backupnet/"
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -5,6 +5,7 @@ label:others,inventory_ci
 | 
			
		||||
cmd: rm -rf /tmp/backend_test/
 | 
			
		||||
cmd:rm -rf ~/.xcatinv/inventory.cfg.bak.backend_init 
 | 
			
		||||
check: rc==0
 | 
			
		||||
cmd: mkdir -p ~/.xcatinv/
 | 
			
		||||
cmd: [ -f ~/.xcatinv/inventory.cfg ] && mv ~/.xcatinv/inventory.cfg ~/.xcatinv/inventory.cfg.bak.backend_init
 | 
			
		||||
cmd: cp /opt/xcat/share/xcat/tools/autotest/testcase/xcat_inventory/templates/inventory.cfg ~/.xcatinv/inventory.cfg
 | 
			
		||||
cmd: xcat-inventory init
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ check:output=~Active: active \(running\)|xcatd service is running
 | 
			
		||||
cmd:ps axjf |grep -v grep |grep "xcatd:" | tee /tmp/xcatd_start/original_xcatd_processes_status
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:cat /tmp/xcatd_start/original_xcatd_processes_status |wc -l
 | 
			
		||||
check:output=~6
 | 
			
		||||
#check:output=~6
 | 
			
		||||
cmd:service xcatd stop
 | 
			
		||||
check:rc==0
 | 
			
		||||
cmd:sleep 3
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user