2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-21 19:22:05 +00:00
2018-02-01 13:36:22 +08:00

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)