Merge "Implemented start_power_state_change In Conductor"

This commit is contained in:
Jenkins 2013-09-24 21:28:44 +00:00 committed by Gerrit Code Review
commit f0a25ff7e1
4 changed files with 171 additions and 11 deletions

View File

@ -2,6 +2,7 @@
# coding=utf-8
# Copyright 2013 Hewlett-Packard Development Company, L.P.
# Copyright 2013 International Business Machines Corporation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -127,12 +128,48 @@ class ConductorManager(service.PeriodicService):
def start_power_state_change(self, context, node_obj, new_state):
"""RPC method to encapsulate changes to a node's state.
Perform actions such as power on and power off.
Perform actions such as power on, power off. It waits for the power
action to finish, then if succesful, it updates the power_state for
the node with the new power state.
TODO
:param context: an admin context
:param node_obj: an RPC-style node object
:param new_state: the desired power state of the node
:param context: an admin context.
:param node_obj: an RPC-style node object.
:param new_state: the desired power state of the node.
:raises: InvalidParameterValue when the wrong state is specified
or the wrong driver info is specified.
:raises: NodeInWrongPowerState when the node is in the state.
that cannot perform and requested power action.
:raises: other exceptins by the node's power driver if something
wrong during the power action.
:
"""
pass
node_id = node_obj.get('uuid')
LOG.debug("RPC start_power_state_change called for node %s."
" The desired new state is %s." % (node_id, new_state))
with task_manager.acquire(node_id, shared=False) as task:
# an exception will be raised if validate fails.
task.driver.power.validate(node_obj)
curr_state = task.driver.power.get_power_state(task, node_obj)
if curr_state == new_state:
raise exception.NodeInWrongPowerState(node=node_id,
pstate=curr_state)
# set the target_power_state.
# This will expose to other processes and clients that the work
# is in progress
node_obj['target_power_state'] = new_state
node_obj.save(context)
#take power action, set the power_state to error if fails
try:
task.driver.power.set_power_state(task, node_obj, new_state)
except exception.IronicException:
node_obj['power_state'] = states.ERROR
node_obj.save(context)
raise
# update the node power states
node_obj['power_state'] = new_state
node_obj['target_power_state'] = states.NOSTATE
node_obj.save(context)

View File

@ -213,8 +213,8 @@ class IPMIPower(base.PowerInterface):
elif pstate == states.POWER_OFF:
state = _power_off(driver_info)
else:
raise exception.IronicException(_(
"set_power_state called with invalid power state."))
raise exception.InvalidParameterValue(_("set_power_state called "
"with invalid power state %s.") % pstate)
if state != pstate:
raise exception.PowerStateFailure(pstate=pstate)

View File

@ -309,8 +309,8 @@ class SSHPower(base.PowerInterface):
elif pstate == states.POWER_OFF:
state = _power_off(ssh_obj, driver_info)
else:
raise exception.IronicException(_(
"set_power_state called with invalid power state."))
raise exception.InvalidParameterValue(_("set_power_state called "
"with invalid power state %s.") % pstate)
if state != pstate:
raise exception.PowerStateFailure(pstate=pstate)

View File

@ -2,6 +2,7 @@
# coding=utf-8
# Copyright 2013 Hewlett-Packard Development Company, L.P.
# Copyright 2013 International Business Machines Corporation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -150,3 +151,125 @@ class ManagerTestCase(base.DbTestCase):
def test_update_node_unassociate_instance(self):
# TODO(deva)
pass
def test_start_power_state_change_power_on(self):
"""Test if start_power_state to turn node power on
is successful or not.
"""
ndict = utils.get_test_node(driver='fake',
power_state=states.POWER_OFF)
node = self.dbapi.create_node(ndict)
self.mox.StubOutWithMock(self.driver.power, 'get_power_state')
self.driver.power.get_power_state(mox.IgnoreArg(), node).\
AndReturn(states.POWER_OFF)
self.mox.ReplayAll()
self.service.start_power_state_change(self.context,
node, states.POWER_ON)
self.mox.VerifyAll()
self.assertEqual(node['power_state'], states.POWER_ON)
self.assertEqual(node['target_power_state'], None)
def test_start_power_state_change_power_off(self):
"""Test if start_power_state to turn node power off
is successful or not.
"""
ndict = utils.get_test_node(driver='fake',
power_state=states.POWER_ON)
node = self.dbapi.create_node(ndict)
self.mox.StubOutWithMock(self.driver.power, 'get_power_state')
self.driver.power.get_power_state(mox.IgnoreArg(), node).\
AndReturn(states.POWER_ON)
self.mox.ReplayAll()
self.service.start_power_state_change(self.context, node,
states.POWER_OFF)
self.mox.VerifyAll()
self.assertEqual(node['power_state'], states.POWER_OFF)
self.assertEqual(node['target_power_state'], None)
def test_start_power_state_change_already_locked(self):
"""Test if an exception is thrown when applying an exclusive
lock to the node failed.
"""
ndict = utils.get_test_node(driver='fake',
power_state=states.POWER_ON)
node = self.dbapi.create_node(ndict)
# check if the node is locked
with task_manager.acquire(node['id'], shared=False):
self.assertRaises(exception.NodeLocked,
self.service.start_power_state_change,
self.context,
node,
states.POWER_ON)
def test_start_power_state_change_invalid_state(self):
"""Test if an NodeInWrongPowerState exception is thrown
when the node is in an invalid state to perform current operation.
"""
ndict = utils.get_test_node(driver='fake',
power_state=states.POWER_ON)
node = self.dbapi.create_node(ndict)
self.mox.StubOutWithMock(self.driver.power, 'get_power_state')
self.driver.power.get_power_state(mox.IgnoreArg(), node).\
AndReturn(states.POWER_ON)
self.mox.ReplayAll()
self.assertRaises(exception.NodeInWrongPowerState,
self.service.start_power_state_change,
self.context,
node,
states.POWER_ON)
self.mox.VerifyAll()
def test_start_power_state_change_invalid_driver_info(self):
"""Test if an exception is thrown when the driver validation is
failed.
"""
ndict = utils.get_test_node(driver='fake',
power_state=states.POWER_ON)
node = self.dbapi.create_node(ndict)
self.mox.StubOutWithMock(self.driver.power, 'validate')
self.driver.power.validate(node).\
AndRaise(exception.InvalidParameterValue(
'wrong power driver info'))
self.mox.ReplayAll()
self.assertRaises(exception.InvalidParameterValue,
self.service.start_power_state_change,
self.context,
node,
states.POWER_ON)
self.mox.VerifyAll()
def test_start_power_state_change_set_power_failure(self):
"""Test if an exception is thrown when the set_power call is
failed.
"""
ndict = utils.get_test_node(driver='fake',
power_state=states.POWER_OFF)
node = self.dbapi.create_node(ndict)
self.mox.StubOutWithMock(self.driver.power, 'get_power_state')
self.mox.StubOutWithMock(self.driver.power, 'set_power_state')
self.driver.power.get_power_state(mox.IgnoreArg(), node).\
AndReturn(states.POWER_OFF)
self.driver.power.set_power_state(mox.IgnoreArg(), node,
states.POWER_ON).\
AndRaise(Exception('error returned from the power driver.'))
self.mox.ReplayAll()
self.assertRaises(Exception,
self.service.start_power_state_change,
self.context,
node,
states.POWER_ON)
self.mox.VerifyAll()