Add deploy_steps to baremetal node provisioning

Story: 2008043
Task: 41825
Change-Id: Ic44d3dfeb6d68875951feabbc480461f5db5d22a
This commit is contained in:
Aija Jauntēva 2021-04-09 09:14:54 -04:00
parent 2c5200748d
commit c206d4b7f2
5 changed files with 60 additions and 9 deletions

View File

@ -76,6 +76,9 @@ RESET_INTERFACES_VERSION = '1.45'
CONFIG_DRIVE_DICT_VERSION = '1.56'
"""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:

View File

@ -327,7 +327,7 @@ class Proxy(proxy.Proxy):
def set_node_provision_state(self, node, target, config_drive=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.
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
seconds) to wait for the expected state to be reached. The value of
``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`
:raises: ValueError if ``config_drive``, ``clean_steps`` or
``rescue_password`` are provided with an invalid ``target``.
:raises: ValueError if ``config_drive``, ``clean_steps``,
``deploy_steps`` or ``rescue_password`` are provided with an
invalid ``target``.
"""
res = self._get_resource(_node.Node, node)
return res.set_provision_state(self, target, config_drive=config_drive,
clean_steps=clean_steps,
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):
"""Set node boot device

View File

@ -91,8 +91,8 @@ class Node(_common.ListMixin, resource.Resource):
is_maintenance='maintenance',
)
# The retired and retired_reason fields introduced in 1.61 (Ussuri).
_max_microversion = '1.61'
# Provision state deploy_steps introduced in 1.69 (Wallaby).
_max_microversion = '1.69'
# Properties
#: 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,
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.
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 timeout: Timeout (in seconds) to wait for the target state to be
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.
:raises: ValueError if ``config_drive``, ``clean_steps`` or
``rescue_password`` are provided with an invalid ``target``.
:raises: ValueError if ``config_drive``, ``clean_steps``,
``deploy_steps`` or ``rescue_password`` are provided with an
invalid ``target``.
:raises: :class:`~openstack.exceptions.ResourceFailure` if the node
reaches an error state while waiting for the state.
:raises: :class:`~openstack.exceptions.ResourceTimeout` if timeout
@ -388,6 +391,9 @@ class Node(_common.ListMixin, resource.Resource):
elif target == 'rebuild':
version = _common.CONFIG_DRIVE_REBUILD_VERSION
if deploy_steps:
version = _common.DEPLOY_STEPS_VERSION
version = self._assert_microversion_for(session, 'commit', version)
body = {'target': target}
@ -404,6 +410,12 @@ class Node(_common.ListMixin, resource.Resource):
'"clean" target')
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 target != 'rescue':
raise ValueError('Rescue password can only be provided with '

View File

@ -296,6 +296,34 @@ class TestNodeSetProvisionState(base.TestCase):
headers=mock.ANY, microversion='1.56',
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, '_get_session', lambda self, x: x)

View File

@ -0,0 +1,4 @@
---
features:
- |
Adds ``deploy_steps`` to baremetal node provisioning.