Add support for changing baremetal node's boot_mode and secure_boot states
depends-on: https://review.opendev.org/c/openstack/ironic/+/800084 Story: 2008567 Task: 41709 Change-Id: I941a84f36ce79c4cbd0968f4120c66d59091fdd9
This commit is contained in:
parent
4d4eafa761
commit
116d875c04
@ -79,6 +79,9 @@ CONFIG_DRIVE_DICT_VERSION = '1.56'
|
||||
DEPLOY_STEPS_VERSION = '1.69'
|
||||
"""API version in which deploy_steps was added to node provisioning."""
|
||||
|
||||
CHANGE_BOOT_MODE_VERSION = '1.76'
|
||||
"""API version in which boot_mode and secure_boot states can be changed"""
|
||||
|
||||
|
||||
class ListMixin:
|
||||
|
||||
|
@ -408,6 +408,27 @@ class Proxy(proxy.Proxy):
|
||||
res = self._get_resource(_node.Node, node)
|
||||
return res.set_boot_device(self, boot_device, persistent=persistent)
|
||||
|
||||
def set_node_boot_mode(self, node, target):
|
||||
"""Make a request to change node's boot mode
|
||||
|
||||
:param node: The value can be the name or ID of a node or a
|
||||
:class:`~openstack.baremetal.v1.node.Node` instance.
|
||||
:param target: Boot mode to set for node, one of either 'uefi'/'bios'.
|
||||
"""
|
||||
res = self._get_resource(_node.Node, node)
|
||||
return res.set_boot_mode(self, target)
|
||||
|
||||
def set_node_secure_boot(self, node, target):
|
||||
"""Make a request to change node's secure boot state
|
||||
|
||||
:param node: The value can be the name or ID of a node or a
|
||||
:class:`~openstack.baremetal.v1.node.Node` instance.
|
||||
:param target: Boolean indicating secure boot state to set.
|
||||
True/False corresponding to 'on'/'off' respectively.
|
||||
"""
|
||||
res = self._get_resource(_node.Node, node)
|
||||
return res.set_secure_boot(self, target)
|
||||
|
||||
def wait_for_nodes_provision_state(self, nodes, expected_state,
|
||||
timeout=None,
|
||||
abort_on_failed_state=True,
|
||||
|
@ -91,8 +91,8 @@ class Node(_common.ListMixin, resource.Resource):
|
||||
is_maintenance='maintenance',
|
||||
)
|
||||
|
||||
# Node states boot_mode and secure_boot introduced in 1.75 (Xena).
|
||||
_max_microversion = '1.75'
|
||||
# Ability to change boot_mode and secure_boot, introduced in 1.76 (Xena).
|
||||
_max_microversion = '1.76'
|
||||
|
||||
# Properties
|
||||
#: The UUID of the allocation associated with this node. Added in API
|
||||
@ -853,6 +853,67 @@ class Node(_common.ListMixin, resource.Resource):
|
||||
.format(node=self.id))
|
||||
exceptions.raise_from_response(response, error_message=msg)
|
||||
|
||||
def set_boot_mode(self, session, target):
|
||||
"""Make a request to change node's boot mode
|
||||
|
||||
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.
|
||||
:param target: Boot mode to set for node, one of either 'uefi'/'bios'.
|
||||
:raises: ValueError if ``target`` is not one of 'uefi or 'bios'.
|
||||
"""
|
||||
session = self._get_session(session)
|
||||
version = utils.pick_microversion(session,
|
||||
_common.CHANGE_BOOT_MODE_VERSION)
|
||||
request = self._prepare_request(requires_id=True)
|
||||
request.url = utils.urljoin(request.url, 'states', 'boot_mode')
|
||||
if target not in ('uefi', 'bios'):
|
||||
raise ValueError("Unrecognized boot mode %s."
|
||||
"Boot mode should be one of 'uefi' or 'bios'."
|
||||
% target)
|
||||
body = {'target': target}
|
||||
|
||||
response = session.put(
|
||||
request.url, json=body,
|
||||
headers=request.headers, microversion=version,
|
||||
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
|
||||
|
||||
msg = ("Failed to change boot mode for node {node}"
|
||||
.format(node=self.id))
|
||||
exceptions.raise_from_response(response, error_message=msg)
|
||||
|
||||
def set_secure_boot(self, session, target):
|
||||
"""Make a request to change node's secure boot 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.
|
||||
:param bool target: Boolean indicating secure boot state to set.
|
||||
True/False corresponding to 'on'/'off' respectively.
|
||||
:raises: ValueError if ``target`` is not boolean.
|
||||
"""
|
||||
session = self._get_session(session)
|
||||
version = utils.pick_microversion(session,
|
||||
_common.CHANGE_BOOT_MODE_VERSION)
|
||||
request = self._prepare_request(requires_id=True)
|
||||
request.url = utils.urljoin(request.url, 'states', 'secure_boot')
|
||||
if not isinstance(target, bool):
|
||||
raise ValueError("Invalid target %s. It should be True or False "
|
||||
"corresponding to secure boot state 'on' or 'off'"
|
||||
% target)
|
||||
body = {'target': target}
|
||||
|
||||
response = session.put(
|
||||
request.url, json=body,
|
||||
headers=request.headers, microversion=version,
|
||||
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
|
||||
|
||||
msg = ("Failed to change secure boot state for {node}"
|
||||
.format(node=self.id))
|
||||
exceptions.raise_from_response(response, error_message=msg)
|
||||
|
||||
def add_trait(self, session, trait):
|
||||
"""Add a trait to a node.
|
||||
|
||||
|
@ -764,6 +764,54 @@ class TestNodeSetBootDevice(base.TestCase):
|
||||
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
|
||||
|
||||
|
||||
@mock.patch.object(utils, 'pick_microversion', lambda session, v: v)
|
||||
@mock.patch.object(node.Node, 'fetch', lambda self, session: self)
|
||||
@mock.patch.object(exceptions, 'raise_from_response', mock.Mock())
|
||||
class TestNodeSetBootMode(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNodeSetBootMode, self).setUp()
|
||||
self.node = node.Node(**FAKE)
|
||||
self.session = mock.Mock(spec=adapter.Adapter,
|
||||
default_microversion='1.1')
|
||||
|
||||
def test_node_set_boot_mode(self):
|
||||
self.node.set_boot_mode(self.session, 'uefi')
|
||||
self.session.put.assert_called_once_with(
|
||||
'nodes/%s/states/boot_mode' % self.node.id,
|
||||
json={'target': 'uefi'},
|
||||
headers=mock.ANY, microversion=mock.ANY,
|
||||
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
|
||||
|
||||
def test_node_set_boot_mode_invalid_mode(self):
|
||||
self.assertRaises(ValueError,
|
||||
self.node.set_boot_mode, self.session, 'invalid-efi')
|
||||
|
||||
|
||||
@mock.patch.object(utils, 'pick_microversion', lambda session, v: v)
|
||||
@mock.patch.object(node.Node, 'fetch', lambda self, session: self)
|
||||
@mock.patch.object(exceptions, 'raise_from_response', mock.Mock())
|
||||
class TestNodeSetSecureBoot(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNodeSetSecureBoot, self).setUp()
|
||||
self.node = node.Node(**FAKE)
|
||||
self.session = mock.Mock(spec=adapter.Adapter,
|
||||
default_microversion='1.1')
|
||||
|
||||
def test_node_set_secure_boot(self):
|
||||
self.node.set_secure_boot(self.session, True)
|
||||
self.session.put.assert_called_once_with(
|
||||
'nodes/%s/states/secure_boot' % self.node.id,
|
||||
json={'target': True},
|
||||
headers=mock.ANY, microversion=mock.ANY,
|
||||
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
|
||||
|
||||
def test_node_set_secure_boot_invalid_none(self):
|
||||
self.assertRaises(ValueError,
|
||||
self.node.set_secure_boot, self.session, None)
|
||||
|
||||
|
||||
@mock.patch.object(utils, 'pick_microversion', lambda session, v: v)
|
||||
@mock.patch.object(node.Node, 'fetch', lambda self, session: self)
|
||||
@mock.patch.object(exceptions, 'raise_from_response', mock.Mock())
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add support for changing node states ``boot_mode`` and ``secure_boot``
|
||||
in sync with functionality introduced in API 1.76.
|
Loading…
Reference in New Issue
Block a user