diff options
author | Zuul <zuul@review.opendev.org> | 2021-01-26 12:25:26 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2021-01-26 12:25:26 +0000 |
commit | 2a7871d060ecaef8b0bba48a5481a3a1bb24669f (patch) | |
tree | 12182858d4d64f4b5404a5bbd17b1e87b633e271 /ironic/drivers | |
parent | 8612c06d4ad5f9a6d6c442c67a959348cec756e2 (diff) | |
parent | b6f4587f0bdfc2f4b5736db1c9f89639ef2e09a7 (diff) | |
download | ironic-2a7871d060ecaef8b0bba48a5481a3a1bb24669f.tar.gz |
Merge "Common framework for configuring secure boot"
Diffstat (limited to 'ironic/drivers')
-rw-r--r-- | ironic/drivers/base.py | 34 | ||||
-rw-r--r-- | ironic/drivers/modules/boot_mode_utils.py | 52 | ||||
-rw-r--r-- | ironic/drivers/modules/pxe_base.py | 3 |
3 files changed, 89 insertions, 0 deletions
diff --git a/ironic/drivers/base.py b/ironic/drivers/base.py index baf5a5579..7d137f9c4 100644 --- a/ironic/drivers/base.py +++ b/ironic/drivers/base.py @@ -972,6 +972,40 @@ class ManagementInterface(BaseInterface): raise exception.UnsupportedDriverExtension( driver=task.node.driver, extension='get_boot_mode') + def get_secure_boot_state(self, task): + """Get the current secure boot state for the node. + + NOTE: Not all drivers support this method. Older hardware + may not implement that. + + :param task: A task from TaskManager. + :raises: MissingParameterValue if a required parameter is missing + :raises: DriverOperationError or its derivative in case + of driver runtime error. + :raises: UnsupportedDriverExtension if secure boot is + not supported by the driver or the hardware + :returns: Boolean + """ + raise exception.UnsupportedDriverExtension( + driver=task.node.driver, extension='get_secure_boot_state') + + def set_secure_boot_state(self, task, state): + """Set the current secure boot state for the node. + + NOTE: Not all drivers support this method. Older hardware + may not implement that. + + :param task: A task from TaskManager. + :param state: A new state as a boolean. + :raises: MissingParameterValue if a required parameter is missing + :raises: DriverOperationError or its derivative in case + of driver runtime error. + :raises: UnsupportedDriverExtension if secure boot is + not supported by the driver or the hardware + """ + raise exception.UnsupportedDriverExtension( + driver=task.node.driver, extension='set_secure_boot_state') + @abc.abstractmethod def get_sensors_data(self, task): """Get sensors data method. diff --git a/ironic/drivers/modules/boot_mode_utils.py b/ironic/drivers/modules/boot_mode_utils.py index eea09d1c0..6eebe50aa 100644 --- a/ironic/drivers/modules/boot_mode_utils.py +++ b/ironic/drivers/modules/boot_mode_utils.py @@ -14,11 +14,13 @@ # under the License. from oslo_log import log as logging +from oslo_utils import excutils from ironic.common import boot_modes from ironic.common import exception from ironic.common.i18n import _ from ironic.common import utils as common_utils +from ironic.conductor import task_manager from ironic.conductor import utils as manager_utils from ironic.conf import CONF from ironic.drivers import utils as driver_utils @@ -296,3 +298,53 @@ def get_boot_mode(node): 'bios': boot_modes.LEGACY_BIOS, 'uefi': boot_modes.UEFI}) return CONF.deploy.default_boot_mode + + +@task_manager.require_exclusive_lock +def configure_secure_boot_if_needed(task): + """Configures secure boot if it has been requested for the node.""" + if not is_secure_boot_requested(task.node): + return + + try: + task.driver.management.set_secure_boot_state(task, True) + except exception.UnsupportedDriverExtension: + # TODO(dtantsur): make a failure in Xena + LOG.warning('Secure boot was requested for node %(node)s but its ' + 'management interface %(driver)s does not support it. ' + 'This warning will become an error in a future release.', + {'node': task.node.uuid, + 'driver': task.node.management_interface}) + except Exception as exc: + with excutils.save_and_reraise_exception(): + LOG.error('Failed to configure secure boot for node %(node)s: ' + '%(error)s', + {'node': task.node.uuid, 'error': exc}, + exc_info=not isinstance(exc, exception.IronicException)) + else: + LOG.info('Secure boot has been enabled for node %s', task.node.uuid) + + +@task_manager.require_exclusive_lock +def deconfigure_secure_boot_if_needed(task): + """Deconfigures secure boot if it has been requested for the node.""" + if not is_secure_boot_requested(task.node): + return + + try: + task.driver.management.set_secure_boot_state(task, False) + except exception.UnsupportedDriverExtension: + # NOTE(dtantsur): don't make it a hard failure to allow tearing down + # misconfigured nodes. + LOG.debug('Secure boot was requested for node %(node)s but its ' + 'management interface %(driver)s does not support it.', + {'node': task.node.uuid, + 'driver': task.node.management_interface}) + except Exception as exc: + with excutils.save_and_reraise_exception(): + LOG.error('Failed to deconfigure secure boot for node %(node)s: ' + '%(error)s', + {'node': task.node.uuid, 'error': exc}, + exc_info=not isinstance(exc, exception.IronicException)) + else: + LOG.info('Secure boot has been disabled for node %s', task.node.uuid) diff --git a/ironic/drivers/modules/pxe_base.py b/ironic/drivers/modules/pxe_base.py index 5d9ac49ba..0944e7d4e 100644 --- a/ironic/drivers/modules/pxe_base.py +++ b/ironic/drivers/modules/pxe_base.py @@ -133,6 +133,8 @@ class PXEBaseMixin(object): pxe_utils.clean_up_pxe_env(task, images_info, ipxe_enabled=self.ipxe_enabled) + boot_mode_utils.deconfigure_secure_boot_if_needed(task) + @METRICS.timer('PXEBaseMixin.prepare_ramdisk') def prepare_ramdisk(self, task, ramdisk_params): """Prepares the boot of Ironic ramdisk using PXE. @@ -240,6 +242,7 @@ class PXEBaseMixin(object): :returns: None """ boot_mode_utils.sync_boot_mode(task) + boot_mode_utils.configure_secure_boot_if_needed(task) node = task.node boot_option = deploy_utils.get_boot_option(node) |