baremetal: implement set_node_power_state in the proxy
This call was implemented in the shade part, but not in the baremetal proxy. This change implements it, and makes the share part use it. As a side effect, soft power actions (from API 1.27) are now supported. Change-Id: I6f2f0aa7717c0f9423d6a3ddc163c4fc0d8152d0
This commit is contained in:
parent
dc092757d1
commit
b7b7353e55
@ -22,6 +22,7 @@ Node Operations
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.get_node
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.find_node
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.nodes
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.set_node_power_state
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.set_node_provision_state
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.wait_for_nodes_provision_state
|
||||
.. automethod:: openstack.baremetal.v1._proxy.Proxy.wait_for_node_reservation
|
||||
|
@ -339,6 +339,19 @@ class Proxy(proxy.Proxy):
|
||||
{'nodes': ', '.join(n.id for n in remaining),
|
||||
'target': expected_state})
|
||||
|
||||
def set_node_power_state(self, node, target):
|
||||
"""Run an action modifying node's power state.
|
||||
|
||||
This call is asynchronous, it will return success as soon as the Bare
|
||||
Metal service acknowledges the request.
|
||||
|
||||
:param node: The value can be the name or ID of a node or a
|
||||
:class:`~openstack.baremetal.v1.node.Node` instance.
|
||||
:param target: Target power state, e.g. "rebooting", "power on".
|
||||
See the Bare Metal service documentation for available actions.
|
||||
"""
|
||||
self._get_resource(_node.Node, node).set_power_state(self, target)
|
||||
|
||||
def wait_for_node_reservation(self, node, timeout=None):
|
||||
"""Wait for a lock on the node to be released.
|
||||
|
||||
|
@ -457,6 +457,41 @@ class Node(_common.ListMixin, resource.Resource):
|
||||
"the last error is %(error)s" %
|
||||
{'node': self.id, 'error': self.last_error})
|
||||
|
||||
# TODO(dtantsur): waiting for power state
|
||||
def set_power_state(self, session, target):
|
||||
"""Run an action modifying this node's power state.
|
||||
|
||||
This call is asynchronous, it will return success as soon as the Bare
|
||||
Metal service acknowledges the request.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
:type session: :class:`~keystoneauth1.adapter.Adapter`
|
||||
:param target: Target power state, e.g. "rebooting", "power on".
|
||||
See the Bare Metal service documentation for available actions.
|
||||
"""
|
||||
session = self._get_session(session)
|
||||
|
||||
if target.startswith("soft "):
|
||||
version = '1.27'
|
||||
else:
|
||||
version = None
|
||||
|
||||
version = utils.pick_microversion(session, version)
|
||||
|
||||
# TODO(dtantsur): server timeout support
|
||||
body = {'target': target}
|
||||
|
||||
request = self._prepare_request(requires_id=True)
|
||||
request.url = utils.urljoin(request.url, 'states', 'power')
|
||||
response = session.put(
|
||||
request.url, json=body,
|
||||
headers=request.headers, microversion=version,
|
||||
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
|
||||
|
||||
msg = ("Failed to set power state for bare metal node {node} "
|
||||
"to {target}".format(node=self.id, target=target))
|
||||
exceptions.raise_from_response(response, error_message=msg)
|
||||
|
||||
def attach_vif(self, session, vif_id, retry_on_conflict=True):
|
||||
"""Attach a VIF to the node.
|
||||
|
||||
|
@ -10141,40 +10141,6 @@ class _OpenStackCloudMixin(_normalize.Normalizer):
|
||||
"""
|
||||
self.set_machine_maintenance_state(name_or_id, False)
|
||||
|
||||
def _set_machine_power_state(self, name_or_id, state):
|
||||
"""Set machine power state to on or off
|
||||
|
||||
This private method allows a user to turn power on or off to
|
||||
a node via the Baremetal API.
|
||||
|
||||
:params string name_or_id: A string representing the baremetal
|
||||
node to have power turned to an "on"
|
||||
state.
|
||||
:params string state: A value of "on", "off", or "reboot" that is
|
||||
passed to the baremetal API to be asserted to
|
||||
the machine. In the case of the "reboot" state,
|
||||
Ironic will return the host to the "on" state.
|
||||
|
||||
:raises: OpenStackCloudException on operation error or.
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
msg = ("Error setting machine power state to {state} on node "
|
||||
"{node}").format(state=state, node=name_or_id)
|
||||
url = '/nodes/{name_or_id}/states/power'.format(name_or_id=name_or_id)
|
||||
if 'reboot' in state:
|
||||
desired_state = 'rebooting'
|
||||
else:
|
||||
desired_state = 'power {state}'.format(state=state)
|
||||
payload = {'target': desired_state}
|
||||
_utils._call_client_and_retry(self._baremetal_client.put,
|
||||
url,
|
||||
retry_on=[409, 503],
|
||||
json=payload,
|
||||
error_message=msg,
|
||||
microversion="1.6")
|
||||
return None
|
||||
|
||||
def set_machine_power_on(self, name_or_id):
|
||||
"""Activate baremetal machine power
|
||||
|
||||
@ -10188,7 +10154,7 @@ class _OpenStackCloudMixin(_normalize.Normalizer):
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
self._set_machine_power_state(name_or_id, 'on')
|
||||
self.baremetal.set_node_power_state(name_or_id, 'power on')
|
||||
|
||||
def set_machine_power_off(self, name_or_id):
|
||||
"""De-activate baremetal machine power
|
||||
@ -10203,7 +10169,7 @@ class _OpenStackCloudMixin(_normalize.Normalizer):
|
||||
|
||||
:returns:
|
||||
"""
|
||||
self._set_machine_power_state(name_or_id, 'off')
|
||||
self.baremetal.set_node_power_state(name_or_id, 'power off')
|
||||
|
||||
def set_machine_power_reboot(self, name_or_id):
|
||||
"""De-activate baremetal machine power
|
||||
@ -10220,7 +10186,7 @@ class _OpenStackCloudMixin(_normalize.Normalizer):
|
||||
|
||||
:returns: None
|
||||
"""
|
||||
self._set_machine_power_state(name_or_id, 'reboot')
|
||||
self.baremetal.set_node_power_state(name_or_id, 'rebooting')
|
||||
|
||||
def activate_node(self, uuid, configdrive=None,
|
||||
wait=False, timeout=1200):
|
||||
|
@ -117,6 +117,19 @@ class TestBareMetalNode(base.BaseBaremetalTest):
|
||||
wait=True)
|
||||
self.assertEqual(node.provision_state, 'available')
|
||||
|
||||
def test_node_power_state(self):
|
||||
node = self.create_node()
|
||||
self.assertIsNone(node.power_state)
|
||||
|
||||
self.conn.baremetal.set_node_power_state(node, 'power on')
|
||||
node = self.conn.baremetal.get_node(node.id)
|
||||
# Fake nodes react immediately to power requests.
|
||||
self.assertEqual('power on', node.power_state)
|
||||
|
||||
self.conn.baremetal.set_node_power_state(node, 'power off')
|
||||
node = self.conn.baremetal.get_node(node.id)
|
||||
self.assertEqual('power off', node.power_state)
|
||||
|
||||
def test_node_validate(self):
|
||||
node = self.create_node()
|
||||
# Fake hardware passes validation for all interfaces
|
||||
|
@ -487,3 +487,31 @@ class TestNodeWaitForReservation(base.TestCase):
|
||||
self.node.wait_for_reservation,
|
||||
self.session, timeout=0.001)
|
||||
mock_fetch.assert_called_with(self.node, self.session)
|
||||
|
||||
|
||||
@mock.patch.object(exceptions, 'raise_from_response', mock.Mock())
|
||||
class TestNodeSetPowerState(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNodeSetPowerState, self).setUp()
|
||||
self.node = node.Node(**FAKE)
|
||||
self.session = mock.Mock(spec=adapter.Adapter,
|
||||
default_microversion=None)
|
||||
|
||||
def test_power_on(self):
|
||||
self.node.set_power_state(self.session, 'power on')
|
||||
self.session.put.assert_called_once_with(
|
||||
'nodes/%s/states/power' % FAKE['uuid'],
|
||||
json={'target': 'power on'},
|
||||
headers=mock.ANY,
|
||||
microversion=None,
|
||||
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
|
||||
|
||||
def test_soft_power_on(self):
|
||||
self.node.set_power_state(self.session, 'soft power off')
|
||||
self.session.put.assert_called_once_with(
|
||||
'nodes/%s/states/power' % FAKE['uuid'],
|
||||
json={'target': 'soft power off'},
|
||||
headers=mock.ANY,
|
||||
microversion='1.27',
|
||||
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
|
||||
|
Loading…
x
Reference in New Issue
Block a user