mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-21 19:22:05 +00:00
176 lines
6.2 KiB
Python
176 lines
6.2 KiB
Python
#!/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 openbmc
|
|
|
|
import logging
|
|
logger = logging.getLogger('xcatagent')
|
|
|
|
|
|
POWER_STATE_DB = {
|
|
"on" : "powering-on",
|
|
"off" : "powering-off",
|
|
"softoff" : "powering-off",
|
|
"boot" : "powering-on",
|
|
"reset" : "powering-on",
|
|
}
|
|
class OpenBMCPowerTask(ParallelNodesCommand):
|
|
"""Executor for power-related actions."""
|
|
|
|
def _determine_state(self, states):
|
|
|
|
chassis_state = states.get('chassis')
|
|
host_state = states.get('host')
|
|
state = 'Unknown'
|
|
if chassis_state == 'Off':
|
|
state = chassis_state
|
|
|
|
elif chassis_state == 'On':
|
|
if host_state == 'Off':
|
|
state = 'chassison'
|
|
elif host_state in ['Quiesced', 'Running']:
|
|
state = host_state
|
|
else:
|
|
state = 'Unexpected host state=%s' % host_state
|
|
else:
|
|
state = 'Unexpected chassis state=%s' % chassis_state
|
|
return state
|
|
|
|
def get_state(self, **kw):
|
|
|
|
node = kw['node']
|
|
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback,
|
|
debugmode=self.debugmode, verbose=self.verbose)
|
|
state = 'Unknown'
|
|
try:
|
|
obmc.login()
|
|
states = obmc.list_power_states()
|
|
state = self._determine_state(states)
|
|
result = '%s: %s' % (node, openbmc.RPOWER_STATES.get(state, state))
|
|
|
|
except SelfServerException as e:
|
|
result = '%s: %s' % (node, e.message)
|
|
except SelfClientException as e:
|
|
result = '%s: %s' % (node, e.message)
|
|
|
|
self.callback.info(result)
|
|
return state
|
|
|
|
def get_bmcstate(self, **kw):
|
|
|
|
node = kw['node']
|
|
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback,
|
|
debugmode=self.debugmode, verbose=self.verbose)
|
|
bmc_not_ready = bmc_state = 'NotReady'
|
|
try:
|
|
obmc.login()
|
|
state = obmc.get_bmc_state()
|
|
bmc_state = state.get('bmc')
|
|
|
|
if bmc_state != 'Ready':
|
|
bmc_state = bmc_not_ready
|
|
|
|
result = '%s: %s' % (node, openbmc.RPOWER_STATES.get(bmc_state, bmc_state))
|
|
|
|
except SelfServerException, SelfClientException:
|
|
# There is no response when BMC is not ready
|
|
result = '%s: %s' % (node, openbmc.RPOWER_STATES[bmc_not_ready])
|
|
|
|
self.callback.info(result)
|
|
return bmc_state
|
|
|
|
def set_state(self, state, **kw):
|
|
|
|
node = kw['node']
|
|
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback,
|
|
debugmode=self.debugmode, verbose=self.verbose)
|
|
try:
|
|
obmc.login()
|
|
ret = obmc.set_power_state(state)
|
|
new_status = POWER_STATE_DB.get(state, '')
|
|
|
|
result = '%s: %s' % (node, state)
|
|
if new_status:
|
|
self.callback.update_node_attributes('status', node, new_status)
|
|
except (SelfServerException, SelfClientException) as e:
|
|
result = '%s: %s' % (node, e.message)
|
|
|
|
self.callback.info(result)
|
|
|
|
|
|
def reboot(self, optype='boot', **kw):
|
|
|
|
node = kw['node']
|
|
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback,
|
|
debugmode=self.debugmode, verbose=self.verbose)
|
|
try:
|
|
obmc.login()
|
|
states = obmc.list_power_states()
|
|
status = self._determine_state(states)
|
|
|
|
new_status =''
|
|
if optype == 'reset' and status in ['Off', 'chassison']:
|
|
status = openbmc.RPOWER_STATES['Off']
|
|
result = '%s: %s' % (node, status)
|
|
else:
|
|
if status not in ['Off', 'off']:
|
|
obmc.set_power_state('off')
|
|
self.callback.update_node_attributes('status', node, POWER_STATE_DB['off'])
|
|
|
|
off_flag = False
|
|
start_timeStamp = int(time.time())
|
|
for i in range (0, 30):
|
|
states = obmc.list_power_states()
|
|
status = self._determine_state(states)
|
|
if openbmc.RPOWER_STATES.get(status) == 'off':
|
|
off_flag = True
|
|
break
|
|
gevent.sleep( 2 )
|
|
|
|
end_timeStamp = int(time.time())
|
|
|
|
if not off_flag:
|
|
error = 'Error: Sent power-off command but state did not change ' \
|
|
'to off after waiting %s seconds. (State= %s).' % (end_timeStamp - start_timeStamp, status)
|
|
raise SelfServerException(error)
|
|
|
|
ret = obmc.set_power_state('on')
|
|
self.callback.update_node_attributes('status', node, POWER_STATE_DB['on'])
|
|
|
|
result = '%s: %s' % (node, optype)
|
|
|
|
except (SelfServerException, SelfClientException) as e:
|
|
result = '%s: %s' % (node, e.message)
|
|
|
|
self.callback.info(result)
|
|
|
|
|
|
def reboot_bmc(self, optype='warm', **kw):
|
|
|
|
node = kw['node']
|
|
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback,
|
|
debugmode=self.debugmode, verbose=self.verbose)
|
|
new_status = ''
|
|
try:
|
|
obmc.login()
|
|
except (SelfServerException, SelfClientException) as e:
|
|
result = '%s: %s' % (node, e.message)
|
|
else:
|
|
try:
|
|
obmc.reboot_bmc(optype)
|
|
except (SelfServerException, SelfClientException) as e:
|
|
result = '%s: %s' % (node, e.message)
|
|
else:
|
|
result = '%s: %s' % (node, openbmc.RPOWER_STATES['bmcreboot'])
|
|
self.callback.info(result)
|
|
|