Add deploy_steps to baremetal node provisioning
Story: 2008043 Task: 41825 Change-Id: Ic44d3dfeb6d68875951feabbc480461f5db5d22a
This commit is contained in:
@@ -76,6 +76,9 @@ RESET_INTERFACES_VERSION = '1.45'
|
|||||||
CONFIG_DRIVE_DICT_VERSION = '1.56'
|
CONFIG_DRIVE_DICT_VERSION = '1.56'
|
||||||
"""API version in which configdrive can be a dictionary."""
|
"""API version in which configdrive can be a dictionary."""
|
||||||
|
|
||||||
|
DEPLOY_STEPS_VERSION = '1.69'
|
||||||
|
"""API version in which deploy_steps was added to node provisioning."""
|
||||||
|
|
||||||
|
|
||||||
class ListMixin:
|
class ListMixin:
|
||||||
|
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ class Proxy(proxy.Proxy):
|
|||||||
|
|
||||||
def set_node_provision_state(self, node, target, config_drive=None,
|
def set_node_provision_state(self, node, target, config_drive=None,
|
||||||
clean_steps=None, rescue_password=None,
|
clean_steps=None, rescue_password=None,
|
||||||
wait=False, timeout=None):
|
wait=False, timeout=None, deploy_steps=None):
|
||||||
"""Run an action modifying node's provision state.
|
"""Run an action modifying node's provision state.
|
||||||
|
|
||||||
This call is asynchronous, it will return success as soon as the Bare
|
This call is asynchronous, it will return success as soon as the Bare
|
||||||
@@ -350,16 +350,20 @@ class Proxy(proxy.Proxy):
|
|||||||
:param timeout: If ``wait`` is set to ``True``, specifies how much (in
|
:param timeout: If ``wait`` is set to ``True``, specifies how much (in
|
||||||
seconds) to wait for the expected state to be reached. The value of
|
seconds) to wait for the expected state to be reached. The value of
|
||||||
``None`` (the default) means no client-side timeout.
|
``None`` (the default) means no client-side timeout.
|
||||||
|
:param deploy_steps: Deploy steps to execute, only valid for ``active``
|
||||||
|
and ``rebuild`` target.
|
||||||
|
|
||||||
:returns: The updated :class:`~openstack.baremetal.v1.node.Node`
|
:returns: The updated :class:`~openstack.baremetal.v1.node.Node`
|
||||||
:raises: ValueError if ``config_drive``, ``clean_steps`` or
|
:raises: ValueError if ``config_drive``, ``clean_steps``,
|
||||||
``rescue_password`` are provided with an invalid ``target``.
|
``deploy_steps`` or ``rescue_password`` are provided with an
|
||||||
|
invalid ``target``.
|
||||||
"""
|
"""
|
||||||
res = self._get_resource(_node.Node, node)
|
res = self._get_resource(_node.Node, node)
|
||||||
return res.set_provision_state(self, target, config_drive=config_drive,
|
return res.set_provision_state(self, target, config_drive=config_drive,
|
||||||
clean_steps=clean_steps,
|
clean_steps=clean_steps,
|
||||||
rescue_password=rescue_password,
|
rescue_password=rescue_password,
|
||||||
wait=wait, timeout=timeout)
|
wait=wait, timeout=timeout,
|
||||||
|
deploy_steps=deploy_steps)
|
||||||
|
|
||||||
def set_node_boot_device(self, node, boot_device, persistent=False):
|
def set_node_boot_device(self, node, boot_device, persistent=False):
|
||||||
"""Set node boot device
|
"""Set node boot device
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ class Node(_common.ListMixin, resource.Resource):
|
|||||||
is_maintenance='maintenance',
|
is_maintenance='maintenance',
|
||||||
)
|
)
|
||||||
|
|
||||||
# The retired and retired_reason fields introduced in 1.61 (Ussuri).
|
# Provision state deploy_steps introduced in 1.69 (Wallaby).
|
||||||
_max_microversion = '1.61'
|
_max_microversion = '1.69'
|
||||||
|
|
||||||
# Properties
|
# Properties
|
||||||
#: The UUID of the allocation associated with this node. Added in API
|
#: The UUID of the allocation associated with this node. Added in API
|
||||||
@@ -346,7 +346,7 @@ class Node(_common.ListMixin, resource.Resource):
|
|||||||
|
|
||||||
def set_provision_state(self, session, target, config_drive=None,
|
def set_provision_state(self, session, target, config_drive=None,
|
||||||
clean_steps=None, rescue_password=None,
|
clean_steps=None, rescue_password=None,
|
||||||
wait=False, timeout=None):
|
wait=False, timeout=None, deploy_steps=None):
|
||||||
"""Run an action modifying this node's provision state.
|
"""Run an action modifying this node's provision state.
|
||||||
|
|
||||||
This call is asynchronous, it will return success as soon as the Bare
|
This call is asynchronous, it will return success as soon as the Bare
|
||||||
@@ -366,10 +366,13 @@ class Node(_common.ListMixin, resource.Resource):
|
|||||||
:param wait: Whether to wait for the target state to be reached.
|
:param wait: Whether to wait for the target state to be reached.
|
||||||
:param timeout: Timeout (in seconds) to wait for the target state to be
|
:param timeout: Timeout (in seconds) to wait for the target state to be
|
||||||
reached. If ``None``, wait without timeout.
|
reached. If ``None``, wait without timeout.
|
||||||
|
:param deploy_steps: Deploy steps to execute, only valid for ``active``
|
||||||
|
and ``rebuild`` target.
|
||||||
|
|
||||||
:return: This :class:`Node` instance.
|
:return: This :class:`Node` instance.
|
||||||
:raises: ValueError if ``config_drive``, ``clean_steps`` or
|
:raises: ValueError if ``config_drive``, ``clean_steps``,
|
||||||
``rescue_password`` are provided with an invalid ``target``.
|
``deploy_steps`` or ``rescue_password`` are provided with an
|
||||||
|
invalid ``target``.
|
||||||
:raises: :class:`~openstack.exceptions.ResourceFailure` if the node
|
:raises: :class:`~openstack.exceptions.ResourceFailure` if the node
|
||||||
reaches an error state while waiting for the state.
|
reaches an error state while waiting for the state.
|
||||||
:raises: :class:`~openstack.exceptions.ResourceTimeout` if timeout
|
:raises: :class:`~openstack.exceptions.ResourceTimeout` if timeout
|
||||||
@@ -388,6 +391,9 @@ class Node(_common.ListMixin, resource.Resource):
|
|||||||
elif target == 'rebuild':
|
elif target == 'rebuild':
|
||||||
version = _common.CONFIG_DRIVE_REBUILD_VERSION
|
version = _common.CONFIG_DRIVE_REBUILD_VERSION
|
||||||
|
|
||||||
|
if deploy_steps:
|
||||||
|
version = _common.DEPLOY_STEPS_VERSION
|
||||||
|
|
||||||
version = self._assert_microversion_for(session, 'commit', version)
|
version = self._assert_microversion_for(session, 'commit', version)
|
||||||
|
|
||||||
body = {'target': target}
|
body = {'target': target}
|
||||||
@@ -404,6 +410,12 @@ class Node(_common.ListMixin, resource.Resource):
|
|||||||
'"clean" target')
|
'"clean" target')
|
||||||
body['clean_steps'] = clean_steps
|
body['clean_steps'] = clean_steps
|
||||||
|
|
||||||
|
if deploy_steps is not None:
|
||||||
|
if target not in ('active', 'rebuild'):
|
||||||
|
raise ValueError('Deploy steps can only be provided with '
|
||||||
|
'"deploy" and "rebuild" target')
|
||||||
|
body['deploy_steps'] = deploy_steps
|
||||||
|
|
||||||
if rescue_password is not None:
|
if rescue_password is not None:
|
||||||
if target != 'rescue':
|
if target != 'rescue':
|
||||||
raise ValueError('Rescue password can only be provided with '
|
raise ValueError('Rescue password can only be provided with '
|
||||||
|
|||||||
@@ -296,6 +296,34 @@ class TestNodeSetProvisionState(base.TestCase):
|
|||||||
headers=mock.ANY, microversion='1.56',
|
headers=mock.ANY, microversion='1.56',
|
||||||
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
|
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
|
||||||
|
|
||||||
|
def test_deploy_with_deploy_steps(self):
|
||||||
|
deploy_steps = [{'interface': 'deploy', 'step': 'upgrade_fw'}]
|
||||||
|
result = self.node.set_provision_state(
|
||||||
|
self.session, 'active',
|
||||||
|
deploy_steps=deploy_steps)
|
||||||
|
|
||||||
|
self.assertIs(result, self.node)
|
||||||
|
self.session.put.assert_called_once_with(
|
||||||
|
'nodes/%s/states/provision' % self.node.id,
|
||||||
|
json={'target': 'active', 'deploy_steps': deploy_steps},
|
||||||
|
headers=mock.ANY, microversion='1.69',
|
||||||
|
retriable_status_codes=_common.RETRIABLE_STATUS_CODES
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_rebuild_with_deploy_steps(self):
|
||||||
|
deploy_steps = [{'interface': 'deploy', 'step': 'upgrade_fw'}]
|
||||||
|
result = self.node.set_provision_state(
|
||||||
|
self.session, 'rebuild',
|
||||||
|
deploy_steps=deploy_steps)
|
||||||
|
|
||||||
|
self.assertIs(result, self.node)
|
||||||
|
self.session.put.assert_called_once_with(
|
||||||
|
'nodes/%s/states/provision' % self.node.id,
|
||||||
|
json={'target': 'rebuild', 'deploy_steps': deploy_steps},
|
||||||
|
headers=mock.ANY, microversion='1.69',
|
||||||
|
retriable_status_codes=_common.RETRIABLE_STATUS_CODES
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock.patch.object(node.Node, '_translate_response', mock.Mock())
|
@mock.patch.object(node.Node, '_translate_response', mock.Mock())
|
||||||
@mock.patch.object(node.Node, '_get_session', lambda self, x: x)
|
@mock.patch.object(node.Node, '_get_session', lambda self, x: x)
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds ``deploy_steps`` to baremetal node provisioning.
|
||||||
Reference in New Issue
Block a user