diff --git a/ironic/common/pxe_utils.py b/ironic/common/pxe_utils.py index 07529865f9..34f79ada84 100644 --- a/ironic/common/pxe_utils.py +++ b/ironic/common/pxe_utils.py @@ -25,6 +25,7 @@ from ironic.common import dhcp_factory from ironic.common import exception from ironic.common.i18n import _ from ironic.common import utils +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import deploy_utils CONF = cfg.CONF @@ -227,7 +228,7 @@ def create_pxe_config(task, pxe_options, template=None): _ensure_config_dirs_exist(task.node.uuid) pxe_config_file_path = get_pxe_config_file_path(task.node.uuid) - is_uefi_boot_mode = (deploy_utils.get_boot_mode_for_deploy(task.node) + is_uefi_boot_mode = (boot_mode_utils.get_boot_mode_for_deploy(task.node) == 'uefi') # grub bootloader panics with '{}' around any of its tags in its @@ -287,7 +288,7 @@ def clean_up_pxe_config(task): """ LOG.debug("Cleaning up PXE config for node %s", task.node.uuid) - is_uefi_boot_mode = (deploy_utils.get_boot_mode_for_deploy(task.node) + is_uefi_boot_mode = (boot_mode_utils.get_boot_mode_for_deploy(task.node) == 'uefi') if is_uefi_boot_mode and not CONF.pxe.ipxe_enabled: api = dhcp_factory.DHCPFactory().provider diff --git a/ironic/drivers/modules/agent.py b/ironic/drivers/modules/agent.py index f78c744d71..c8c861f8b9 100644 --- a/ironic/drivers/modules/agent.py +++ b/ironic/drivers/modules/agent.py @@ -32,6 +32,7 @@ from ironic.conductor import utils as manager_utils from ironic.conf import CONF from ironic.drivers import base from ironic.drivers.modules import agent_base_vendor +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import deploy_utils @@ -215,7 +216,7 @@ class AgentDeployMixin(agent_base_vendor.AgentDeployMixin): for label in PARTITION_IMAGE_LABELS: image_info[label] = node.instance_info.get(label) boot_option = deploy_utils.get_boot_option(node) - boot_mode = deploy_utils.get_boot_mode_for_deploy(node) + boot_mode = boot_mode_utils.get_boot_mode_for_deploy(node) if boot_mode: image_info['deploy_boot_mode'] = boot_mode else: @@ -310,7 +311,7 @@ class AgentDeployMixin(agent_base_vendor.AgentDeployMixin): efi_sys_uuid = None if not iwdi: - if deploy_utils.get_boot_mode_for_deploy(node) == 'uefi': + if boot_mode_utils.get_boot_mode_for_deploy(node) == 'uefi': efi_sys_uuid = ( self._get_uuid_from_result(task, 'efi_system_partition_uuid')) diff --git a/ironic/drivers/modules/boot_mode_utils.py b/ironic/drivers/modules/boot_mode_utils.py index acddf898ec..aab53f63e0 100644 --- a/ironic/drivers/modules/boot_mode_utils.py +++ b/ironic/drivers/modules/boot_mode_utils.py @@ -14,12 +14,14 @@ # under the License. from oslo_log import log as logging +from oslo_serialization import jsonutils +import six from ironic.common import exception from ironic.common.i18n import _ from ironic.conductor import utils as manager_utils from ironic.conf import CONF -from ironic.drivers.modules import deploy_utils +from ironic.drivers import utils as driver_utils LOG = logging.getLogger(__name__) @@ -98,7 +100,7 @@ def sync_boot_mode(task): LOG.debug("Cannot determine node %(uuid)s boot mode: %(error)s", {'uuid': node.uuid, 'error': ex}) - ironic_boot_mode = deploy_utils.get_boot_mode_for_deploy(node) + ironic_boot_mode = get_boot_mode_for_deploy(node) # NOTE(etingof): the outcome of the branching that follows is that # the new boot mode may be set in 'driver_internal_info/deploy_boot_mode' @@ -146,3 +148,159 @@ def sync_boot_mode(task): # underlying hardware type does not support setting boot mode as # it seems to be a hopeless misconfiguration _set_boot_mode_on_bm(task, ironic_boot_mode, fail_if_unsupported=True) + + +def parse_instance_info_capabilities(node): + """Parse the instance_info capabilities. + + One way of having these capabilities set is via Nova, where the + capabilities are defined in the Flavor extra_spec and passed to + Ironic by the Nova Ironic driver. + + NOTE: Although our API fully supports JSON fields, to maintain the + backward compatibility with Juno the Nova Ironic driver is sending + it as a string. + + :param node: a single Node. + :raises: InvalidParameterValue if the capabilities string is not a + dictionary or is malformed. + :returns: A dictionary with the capabilities if found, otherwise an + empty dictionary. + """ + + def parse_error(): + error_msg = (_('Error parsing capabilities from Node %s instance_info ' + 'field. A dictionary or a "jsonified" dictionary is ' + 'expected.') % node.uuid) + raise exception.InvalidParameterValue(error_msg) + + capabilities = node.instance_info.get('capabilities', {}) + if isinstance(capabilities, six.string_types): + try: + capabilities = jsonutils.loads(capabilities) + except (ValueError, TypeError): + parse_error() + + if not isinstance(capabilities, dict): + parse_error() + + return capabilities + + +def is_secure_boot_requested(node): + """Returns True if secure_boot is requested for deploy. + + This method checks node property for secure_boot and returns True + if it is requested. + + :param node: a single Node. + :raises: InvalidParameterValue if the capabilities string is not a + dictionary or is malformed. + :returns: True if secure_boot is requested. + """ + + capabilities = parse_instance_info_capabilities(node) + sec_boot = capabilities.get('secure_boot', 'false').lower() + + return sec_boot == 'true' + + +def is_trusted_boot_requested(node): + """Returns True if trusted_boot is requested for deploy. + + This method checks instance property for trusted_boot and returns True + if it is requested. + + :param node: a single Node. + :raises: InvalidParameterValue if the capabilities string is not a + dictionary or is malformed. + :returns: True if trusted_boot is requested. + """ + + capabilities = parse_instance_info_capabilities(node) + trusted_boot = capabilities.get('trusted_boot', 'false').lower() + + return trusted_boot == 'true' + + +def get_boot_mode_for_deploy(node): + """Returns the boot mode that would be used for deploy. + + This method returns boot mode to be used for deploy. + It returns 'uefi' if 'secure_boot' is set to 'true' or returns 'bios' if + 'trusted_boot' is set to 'true' in 'instance_info/capabilities' of node. + Otherwise it returns value of 'boot_mode' in 'properties/capabilities' + of node if set. If that is not set, it returns boot mode in + 'internal_driver_info/deploy_boot_mode' for the node. + If that is not set, it returns boot mode in + 'instance_info/deploy_boot_mode' for the node. + It would return None if boot mode is present neither in 'capabilities' of + node 'properties' nor in node's 'internal_driver_info' nor in node's + 'instance_info' (which could also be None). + + :param node: an ironic node object. + :returns: 'bios', 'uefi' or None + :raises: InvalidParameterValue, if the node boot mode disagrees with + the boot mode set to node properties/capabilities + """ + + if is_secure_boot_requested(node): + LOG.debug('Deploy boot mode is uefi for %s.', node.uuid) + return 'uefi' + + if is_trusted_boot_requested(node): + # TODO(lintan) Trusted boot also supports uefi, but at the moment, + # it should only boot with bios. + LOG.debug('Deploy boot mode is bios for %s.', node.uuid) + return 'bios' + + # NOTE(etingof): + # The search for a boot mode should be in the priority order: + # + # 1) instance_info + # 2) properties.capabilities + # 3) driver_internal_info + # + # Because: + # + # (1) can be deleted before teardown + # (3) will never be touched if node properties/capabilities + # are still present. + # (2) becomes operational default as the last resort + + instance_info = node.instance_info + + cap_boot_mode = driver_utils.get_node_capability(node, 'boot_mode') + + boot_mode = instance_info.get('deploy_boot_mode') + if boot_mode is None: + boot_mode = cap_boot_mode + if cap_boot_mode is None: + driver_internal_info = node.driver_internal_info + boot_mode = driver_internal_info.get('deploy_boot_mode') + + if not boot_mode: + return + + boot_mode = boot_mode.lower() + + # NOTE(etingof): + # Make sure that the ultimate boot_mode agrees with the one set to + # node properties/capabilities. This locks down node to use only + # boot mode specified in properties/capabilities. + # TODO(etingof): this logic will have to go away when we switch to traits + if cap_boot_mode: + cap_boot_mode = cap_boot_mode.lower() + if cap_boot_mode != boot_mode: + msg = (_("Node %(uuid)s boot mode %(boot_mode)s violates " + "node properties/capabilities %(caps)s") % + {'uuid': node.uuid, + 'boot_mode': boot_mode, + 'caps': cap_boot_mode}) + LOG.error(msg) + raise exception.InvalidParameterValue(msg) + + LOG.debug('Deploy boot mode is %(boot_mode)s for %(node)s.', + {'boot_mode': boot_mode, 'node': node.uuid}) + + return boot_mode diff --git a/ironic/drivers/modules/deploy_utils.py b/ironic/drivers/modules/deploy_utils.py index 911d73fa07..a4315f188c 100644 --- a/ironic/drivers/modules/deploy_utils.py +++ b/ironic/drivers/modules/deploy_utils.py @@ -24,7 +24,6 @@ from ironic_lib import disk_utils from ironic_lib import metrics_utils from oslo_concurrency import processutils from oslo_log import log as logging -from oslo_serialization import jsonutils from oslo_utils import excutils from oslo_utils import netutils from oslo_utils import strutils @@ -40,15 +39,16 @@ from ironic.common import utils from ironic.conductor import utils as manager_utils from ironic.conf import CONF from ironic.drivers.modules import agent_client +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import image_cache from ironic.drivers import utils as driver_utils from ironic import objects - # TODO(Faizan): Move this logic to common/utils.py and deprecate # rootwrap_config. # This is required to set the default value of ironic_lib option # only if rootwrap_config does not contain the default value. + if CONF.rootwrap_config != '/etc/ironic/rootwrap.conf': root_helper = 'sudo ironic-rootwrap %s' % CONF.rootwrap_config CONF.set_default('root_helper', root_helper, 'ironic_lib') @@ -560,43 +560,6 @@ def get_single_nic_with_vif_port_id(task): return port.address -def parse_instance_info_capabilities(node): - """Parse the instance_info capabilities. - - One way of having these capabilities set is via Nova, where the - capabilities are defined in the Flavor extra_spec and passed to - Ironic by the Nova Ironic driver. - - NOTE: Although our API fully supports JSON fields, to maintain the - backward compatibility with Juno the Nova Ironic driver is sending - it as a string. - - :param node: a single Node. - :raises: InvalidParameterValue if the capabilities string is not a - dictionary or is malformed. - :returns: A dictionary with the capabilities if found, otherwise an - empty dictionary. - """ - - def parse_error(): - error_msg = (_('Error parsing capabilities from Node %s instance_info ' - 'field. A dictionary or a "jsonified" dictionary is ' - 'expected.') % node.uuid) - raise exception.InvalidParameterValue(error_msg) - - capabilities = node.instance_info.get('capabilities', {}) - if isinstance(capabilities, six.string_types): - try: - capabilities = jsonutils.loads(capabilities) - except (ValueError, TypeError): - parse_error() - - if not isinstance(capabilities, dict): - parse_error() - - return capabilities - - def agent_get_clean_steps(task, interface=None, override_priorities=None): """Get the list of cached clean steps from the agent. @@ -713,42 +676,6 @@ def try_set_boot_device(task, device, persistent=True): "the boot device manually.", task.node.uuid) -def is_secure_boot_requested(node): - """Returns True if secure_boot is requested for deploy. - - This method checks node property for secure_boot and returns True - if it is requested. - - :param node: a single Node. - :raises: InvalidParameterValue if the capabilities string is not a - dictionary or is malformed. - :returns: True if secure_boot is requested. - """ - - capabilities = parse_instance_info_capabilities(node) - sec_boot = capabilities.get('secure_boot', 'false').lower() - - return sec_boot == 'true' - - -def is_trusted_boot_requested(node): - """Returns True if trusted_boot is requested for deploy. - - This method checks instance property for trusted_boot and returns True - if it is requested. - - :param node: a single Node. - :raises: InvalidParameterValue if the capabilities string is not a - dictionary or is malformed. - :returns: True if trusted_boot is requested. - """ - - capabilities = parse_instance_info_capabilities(node) - trusted_boot = capabilities.get('trusted_boot', 'false').lower() - - return trusted_boot == 'true' - - def get_disk_label(node): """Return the disk label requested for deploy, if any. @@ -757,93 +684,10 @@ def get_disk_label(node): dictionary or is malformed. :returns: the disk label or None if no disk label was specified. """ - capabilities = parse_instance_info_capabilities(node) + capabilities = boot_mode_utils.parse_instance_info_capabilities(node) return capabilities.get('disk_label') -def get_boot_mode_for_deploy(node): - """Returns the boot mode that would be used for deploy. - - This method returns boot mode to be used for deploy. - It returns 'uefi' if 'secure_boot' is set to 'true' or returns 'bios' if - 'trusted_boot' is set to 'true' in 'instance_info/capabilities' of node. - Otherwise it returns value of 'boot_mode' in 'properties/capabilities' - of node if set. If that is not set, it returns boot mode in - 'driver_internal_info/deploy_boot_mode' for the node. - If that is not set, it returns boot mode in - 'instance_info/deploy_boot_mode' for the node. - It would return None if boot mode is present neither in 'capabilities' of - node 'properties' nor in node's 'driver_internal_info' nor in node's - 'instance_info' (which could also be None). - - :param node: an ironic node object. - :returns: 'bios', 'uefi' or None - :raises: InvalidParameterValue, if the node boot mode disagrees with - the boot mode set to node properties/capabilities - """ - - if is_secure_boot_requested(node): - LOG.debug('Deploy boot mode is uefi for %s.', node.uuid) - return 'uefi' - - if is_trusted_boot_requested(node): - # TODO(lintan) Trusted boot also supports uefi, but at the moment, - # it should only boot with bios. - LOG.debug('Deploy boot mode is bios for %s.', node.uuid) - return 'bios' - - # NOTE(etingof): - # The search for a boot mode should be in the priority order: - # - # 1) instance_info - # 2) properties.capabilities - # 3) driver_internal_info - # - # Because: - # - # (1) can be deleted before teardown - # (3) will never be touched if node properties/capabilities - # are still present. - # (2) becomes operational default as the last resort - - instance_info = node.instance_info - - cap_boot_mode = driver_utils.get_node_capability(node, 'boot_mode') - - boot_mode = instance_info.get('deploy_boot_mode') - if boot_mode is None: - boot_mode = cap_boot_mode - if cap_boot_mode is None: - driver_internal_info = node.driver_internal_info - boot_mode = driver_internal_info.get('deploy_boot_mode') - - if not boot_mode: - return - - boot_mode = boot_mode.lower() - - # NOTE(etingof): - # Make sure that the ultimate boot_mode agrees with the one set to - # node properties/capabilities. This locks down node to use only - # boot mode specified in properties/capabilities. - # TODO(etingof): this logic will have to go away when we switch to traits - if cap_boot_mode: - cap_boot_mode = cap_boot_mode.lower() - if cap_boot_mode != boot_mode: - msg = (_("Node %(uuid)s boot mode %(boot_mode)s violates " - "node properties/capabilities %(caps)s") % - {'uuid': node.uuid, - 'boot_mode': boot_mode, - 'caps': cap_boot_mode}) - LOG.error(msg) - raise exception.InvalidParameterValue(msg) - - LOG.debug('Deploy boot mode is %(boot_mode)s for %(node)s.', - {'boot_mode': boot_mode, 'node': node.uuid}) - - return boot_mode - - def get_pxe_boot_file(node): """Return the PXE boot file name requested for deploy. @@ -916,7 +760,7 @@ def validate_capabilities(node): 'value': value, 'valid_values': ', '.join(valid_values)}) # Validate capability_name in node's instance_info/['capabilities'] - capabilities = parse_instance_info_capabilities(node) + capabilities = boot_mode_utils.parse_instance_info_capabilities(node) value = capabilities.get(capability_name) if value and (value not in valid_values): @@ -988,7 +832,7 @@ def get_boot_option(node): :returns: A string representing the boot option type. Defaults to 'netboot'. """ - capabilities = parse_instance_info_capabilities(node) + capabilities = boot_mode_utils.parse_instance_info_capabilities(node) return capabilities.get('boot_option', get_default_boot_option()).lower() @@ -1385,3 +1229,12 @@ def is_iscsi_boot(task): except exception.VolumeTargetNotFound: return False return False + + +# NOTE(etingof): retain original location of these funcs for compatibility +is_secure_boot_requested = boot_mode_utils.is_secure_boot_requested +is_trusted_boot_requested = boot_mode_utils.is_trusted_boot_requested +get_boot_mode_for_deploy = boot_mode_utils.get_boot_mode_for_deploy +parse_instance_info_capabilities = ( + boot_mode_utils.parse_instance_info_capabilities +) diff --git a/ironic/drivers/modules/ilo/boot.py b/ironic/drivers/modules/ilo/boot.py index 9be7a06c8b..4ef880f478 100644 --- a/ironic/drivers/modules/ilo/boot.py +++ b/ironic/drivers/modules/ilo/boot.py @@ -35,6 +35,7 @@ from ironic.common import states from ironic.common import swift from ironic.conductor import utils as manager_utils from ironic.drivers import base +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import deploy_utils from ironic.drivers.modules.ilo import common as ilo_common from ironic.drivers.modules import pxe @@ -184,7 +185,7 @@ def _get_boot_iso(task, root_uuid): # Option 3 - Create boot_iso from kernel/ramdisk, upload to Swift # or web server and provide its name. deploy_iso_uuid = deploy_info['ilo_deploy_iso'] - boot_mode = deploy_utils.get_boot_mode_for_deploy(task.node) + boot_mode = boot_mode_utils.get_boot_mode_for_deploy(task.node) boot_iso_object_name = _get_boot_iso_object_name(task.node) kernel_params = CONF.pxe.pxe_append_params with tempfile.NamedTemporaryFile(dir=CONF.tempdir) as fileobj: @@ -368,7 +369,7 @@ def prepare_node_for_deploy(task): # Need to update boot mode that will be used during deploy, if one is # not provided. # Since secure boot was disabled, we are in 'uefi' boot mode. - if deploy_utils.get_boot_mode_for_deploy(task.node) is None: + if boot_mode_utils.get_boot_mode_for_deploy(task.node) is None: instance_info = task.node.instance_info instance_info['deploy_boot_mode'] = 'uefi' task.node.instance_info = instance_info @@ -503,7 +504,7 @@ class IloVirtualMediaBoot(base.BootInterface): ilo_common.cleanup_vmedia_boot(task) - boot_mode = deploy_utils.get_boot_mode_for_deploy(task.node) + boot_mode = boot_mode_utils.get_boot_mode_for_deploy(task.node) if deploy_utils.is_iscsi_boot(task): # It will set iSCSI info onto iLO @@ -671,7 +672,7 @@ class IloPXEBoot(pxe.PXEBoot): # Need to enable secure boot, if being requested ilo_common.update_secure_boot_mode(task, True) - boot_mode = deploy_utils.get_boot_mode_for_deploy(task.node) + boot_mode = boot_mode_utils.get_boot_mode_for_deploy(task.node) if deploy_utils.is_iscsi_boot(task) and boot_mode == 'uefi': # Need to set 'ilo_uefi_iscsi_boot' param for clean up diff --git a/ironic/drivers/modules/ilo/common.py b/ironic/drivers/modules/ilo/common.py index bc78e189d7..a851cf2bb2 100644 --- a/ironic/drivers/modules/ilo/common.py +++ b/ironic/drivers/modules/ilo/common.py @@ -36,6 +36,7 @@ from ironic.common import swift from ironic.common import utils from ironic.conductor import utils as manager_utils from ironic.conf import CONF +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import deploy_utils ilo_client = importutils.try_import('proliantutils.ilo.client') @@ -483,7 +484,7 @@ def update_boot_mode(task): """ node = task.node - boot_mode = deploy_utils.get_boot_mode_for_deploy(node) + boot_mode = boot_mode_utils.get_boot_mode_for_deploy(node) # No boot mode found. Check if default_boot_mode is defined if not boot_mode and (CONF.ilo.default_boot_mode in ['bios', 'uefi']): diff --git a/ironic/drivers/modules/ipmitool.py b/ironic/drivers/modules/ipmitool.py index 51cea29ff3..5c50ef82ea 100644 --- a/ironic/drivers/modules/ipmitool.py +++ b/ironic/drivers/modules/ipmitool.py @@ -53,8 +53,8 @@ from ironic.conductor import task_manager from ironic.conductor import utils as cond_utils from ironic.conf import CONF from ironic.drivers import base +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import console_utils -from ironic.drivers.modules import deploy_utils from ironic.drivers import utils as driver_utils @@ -944,7 +944,7 @@ class IPMIManagement(base.ManagementInterface): # uefi mode, this will work with newer and older versions of the # ipmitool utility. Also see: # https://bugs.launchpad.net/ironic/+bug/1611306 - boot_mode = deploy_utils.get_boot_mode_for_deploy(task.node) + boot_mode = boot_mode_utils.get_boot_mode_for_deploy(task.node) if persistent and boot_mode == 'uefi': raw_cmd = ('0x00 0x08 0x05 0xe0 %s 0x00 0x00 0x00' % BOOT_DEVICE_HEXA_MAP[device]) diff --git a/ironic/drivers/modules/irmc/boot.py b/ironic/drivers/modules/irmc/boot.py index 5350e8f0e6..4c385e9c9f 100644 --- a/ironic/drivers/modules/irmc/boot.py +++ b/ironic/drivers/modules/irmc/boot.py @@ -34,6 +34,7 @@ from ironic.common import states from ironic.conductor import utils as manager_utils from ironic.conf import CONF from ironic.drivers import base +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import deploy_utils from ironic.drivers.modules.irmc import common as irmc_common from ironic.drivers.modules.irmc import management as irmc_management @@ -289,7 +290,7 @@ def _prepare_boot_iso(task, root_uuid): deploy_iso_filename = _get_iso_name(task.node, label='deploy') deploy_iso = ('file://' + os.path.join( CONF.irmc.remote_image_share_root, deploy_iso_filename)) - boot_mode = deploy_utils.get_boot_mode_for_deploy(task.node) + boot_mode = boot_mode_utils.get_boot_mode_for_deploy(task.node) kernel_params = CONF.pxe.pxe_append_params boot_iso_filename = _get_iso_name(task.node, label='boot') diff --git a/ironic/drivers/modules/iscsi_deploy.py b/ironic/drivers/modules/iscsi_deploy.py index 392837022c..05fac5029b 100644 --- a/ironic/drivers/modules/iscsi_deploy.py +++ b/ironic/drivers/modules/iscsi_deploy.py @@ -33,6 +33,7 @@ from ironic.conductor import utils as manager_utils from ironic.conf import CONF from ironic.drivers import base from ironic.drivers.modules import agent_base_vendor +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import deploy_utils from ironic.drivers.modules import image_cache @@ -349,7 +350,7 @@ def _get_boot_mode(node): :param node: A single Node. :returns: A string representing the boot mode type. Defaults to 'bios'. """ - boot_mode = deploy_utils.get_boot_mode_for_deploy(node) + boot_mode = boot_mode_utils.get_boot_mode_for_deploy(node) if boot_mode: return boot_mode return "bios" diff --git a/ironic/drivers/modules/pxe.py b/ironic/drivers/modules/pxe.py index f2310c64e2..6dc9478821 100644 --- a/ironic/drivers/modules/pxe.py +++ b/ironic/drivers/modules/pxe.py @@ -281,7 +281,7 @@ def _build_service_pxe_config(task, instance_image_info, iwdi = node.driver_internal_info.get('is_whole_disk_image') deploy_utils.switch_pxe_config( pxe_config_path, root_uuid_or_disk_id, - deploy_utils.get_boot_mode_for_deploy(node), + boot_mode_utils.get_boot_mode_for_deploy(node), iwdi, deploy_utils.is_trusted_boot_requested(node), deploy_utils.is_iscsi_boot(task)) @@ -354,7 +354,7 @@ def _get_volume_pxe_options(task): def validate_boot_parameters_for_trusted_boot(node): """Check if boot parameters are valid for trusted boot.""" - boot_mode = deploy_utils.get_boot_mode_for_deploy(node) + boot_mode = boot_mode_utils.get_boot_mode_for_deploy(node) boot_option = deploy_utils.get_boot_option(node) is_whole_disk_image = node.driver_internal_info.get('is_whole_disk_image') # 'is_whole_disk_image' is not supported by trusted boot, because there is @@ -614,7 +614,7 @@ class PXEBoot(base.BootInterface): task, pxe_options, pxe_config_template) deploy_utils.switch_pxe_config( pxe_config_path, None, - deploy_utils.get_boot_mode_for_deploy(node), False, + boot_mode_utils.get_boot_mode_for_deploy(node), False, iscsi_boot=True) boot_device = boot_devices.PXE diff --git a/ironic/tests/unit/drivers/modules/ilo/test_boot.py b/ironic/tests/unit/drivers/modules/ilo/test_boot.py index 2eab8f044d..c94cf6c383 100644 --- a/ironic/tests/unit/drivers/modules/ilo/test_boot.py +++ b/ironic/tests/unit/drivers/modules/ilo/test_boot.py @@ -31,6 +31,7 @@ from ironic.common import states from ironic.common import swift from ironic.conductor import task_manager from ironic.conductor import utils as manager_utils +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import deploy_utils from ironic.drivers.modules.ilo import boot as ilo_boot from ironic.drivers.modules.ilo import common as ilo_common @@ -141,7 +142,7 @@ class IloBootPrivateMethodsTestCase(db_base.DbTestCase): boot_iso_expected = u'glance://uui\u0111' self.assertEqual(boot_iso_expected, boot_iso_actual) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy', + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy', spec_set=True, autospec=True) @mock.patch.object(ilo_boot.LOG, 'error', spec_set=True, autospec=True) @mock.patch.object(images, 'get_image_properties', spec_set=True, @@ -1056,7 +1057,7 @@ class IloVirtualMediaBootTestCase(db_base.DbTestCase): autospec=True) @mock.patch.object(deploy_utils, 'is_iscsi_boot', spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy', + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy', spec_set=True, autospec=True) @mock.patch.object(ilo_management.IloManagement, 'set_iscsi_boot_target', spec_set=True, autospec=True) @@ -1093,7 +1094,7 @@ class IloVirtualMediaBootTestCase(db_base.DbTestCase): autospec=True) @mock.patch.object(deploy_utils, 'is_iscsi_boot', spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy', + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy', spec_set=True, autospec=True) def test_prepare_instance_boot_from_volume_bios( self, get_boot_mode_mock, @@ -1226,7 +1227,7 @@ class IloPXEBootTestCase(db_base.DbTestCase): @mock.patch.object(deploy_utils, 'is_iscsi_boot', spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy', + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy', spec_set=True, autospec=True) @mock.patch.object(ilo_common, 'update_secure_boot_mode', spec_set=True, autospec=True) @@ -1252,7 +1253,7 @@ class IloPXEBootTestCase(db_base.DbTestCase): @mock.patch.object(deploy_utils, 'is_iscsi_boot', spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy', + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy', spec_set=True, autospec=True) @mock.patch.object(ilo_common, 'update_secure_boot_mode', spec_set=True, autospec=True) @@ -1278,7 +1279,7 @@ class IloPXEBootTestCase(db_base.DbTestCase): @mock.patch.object(deploy_utils, 'is_iscsi_boot', spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy', + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy', spec_set=True, autospec=True) @mock.patch.object(ilo_management.IloManagement, 'set_iscsi_boot_target', spec_set=True, autospec=True) diff --git a/ironic/tests/unit/drivers/modules/irmc/test_boot.py b/ironic/tests/unit/drivers/modules/irmc/test_boot.py index 1382624828..9c10f671d7 100644 --- a/ironic/tests/unit/drivers/modules/irmc/test_boot.py +++ b/ironic/tests/unit/drivers/modules/irmc/test_boot.py @@ -34,6 +34,7 @@ from ironic.common import images from ironic.common import states from ironic.conductor import task_manager from ironic.conductor import utils as manager_utils +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import deploy_utils from ironic.drivers.modules.irmc import boot as irmc_boot from ironic.drivers.modules.irmc import common as irmc_common @@ -391,8 +392,8 @@ class IRMCDeployPrivateMethodsTestCase(db_base.DbTestCase): self.assertEqual(expected, actual) @mock.patch.object(images, 'create_boot_iso', spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy', spec_set=True, - autospec=True) + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy', + spec_set=True, autospec=True) @mock.patch.object(images, 'get_image_properties', spec_set=True, autospec=True) @mock.patch.object(images, 'fetch', spec_set=True, @@ -419,8 +420,8 @@ class IRMCDeployPrivateMethodsTestCase(db_base.DbTestCase): task.node.driver_internal_info['irmc_boot_iso']) @mock.patch.object(images, 'create_boot_iso', spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy', spec_set=True, - autospec=True) + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy', + spec_set=True, autospec=True) @mock.patch.object(images, 'get_image_properties', spec_set=True, autospec=True) @mock.patch.object(images, 'fetch', spec_set=True, @@ -460,8 +461,8 @@ class IRMCDeployPrivateMethodsTestCase(db_base.DbTestCase): task.node.driver_internal_info['irmc_boot_iso']) @mock.patch.object(images, 'create_boot_iso', spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy', spec_set=True, - autospec=True) + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy', + spec_set=True, autospec=True) @mock.patch.object(images, 'get_image_properties', spec_set=True, autospec=True) @mock.patch.object(images, 'fetch', spec_set=True, diff --git a/ironic/tests/unit/drivers/modules/test_agent.py b/ironic/tests/unit/drivers/modules/test_agent.py index 22db83147c..91b81527ce 100644 --- a/ironic/tests/unit/drivers/modules/test_agent.py +++ b/ironic/tests/unit/drivers/modules/test_agent.py @@ -29,6 +29,7 @@ from ironic.drivers import base as drivers_base from ironic.drivers.modules import agent from ironic.drivers.modules import agent_base_vendor from ironic.drivers.modules import agent_client +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import deploy_utils from ironic.drivers.modules import fake from ironic.drivers.modules.network import flat as flat_network @@ -1034,7 +1035,8 @@ class TestAgentDeploy(db_base.DbTestCase): self.assertEqual(states.NOSTATE, task.node.target_provision_state) @mock.patch.object(agent.LOG, 'warning', spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy', autospec=True) + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy', + autospec=True) @mock.patch.object(agent.AgentDeployMixin, '_get_uuid_from_result', autospec=True) @mock.patch.object(manager_utils, 'node_power_action', autospec=True) @@ -1119,7 +1121,8 @@ class TestAgentDeploy(db_base.DbTestCase): self.assertEqual(states.ACTIVE, task.node.target_provision_state) @mock.patch.object(agent.LOG, 'warning', spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy', autospec=True) + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy', + autospec=True) @mock.patch.object(agent.AgentDeployMixin, '_get_uuid_from_result', autospec=True) @mock.patch.object(manager_utils, 'node_power_action', autospec=True) diff --git a/ironic/tests/unit/drivers/modules/test_deploy_utils.py b/ironic/tests/unit/drivers/modules/test_deploy_utils.py index 12e5135cfd..8f3fbe26db 100644 --- a/ironic/tests/unit/drivers/modules/test_deploy_utils.py +++ b/ironic/tests/unit/drivers/modules/test_deploy_utils.py @@ -35,6 +35,7 @@ from ironic.common import utils as common_utils from ironic.conductor import task_manager from ironic.conductor import utils as manager_utils from ironic.drivers.modules import agent_client +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import deploy_utils as utils from ironic.drivers.modules import fake from ironic.drivers.modules import image_cache @@ -1357,34 +1358,34 @@ class ParseInstanceInfoCapabilitiesTestCase(tests_base.TestCase): properties = {'capabilities': 'boot_mode:uefi,cap2:value2'} self.node.properties = properties - result = utils.get_boot_mode_for_deploy(self.node) + result = boot_mode_utils.get_boot_mode_for_deploy(self.node) self.assertEqual('uefi', result) def test_get_boot_mode_for_deploy_using_instance_info_cap(self): instance_info = {'capabilities': {'secure_boot': 'True'}} self.node.instance_info = instance_info - result = utils.get_boot_mode_for_deploy(self.node) + result = boot_mode_utils.get_boot_mode_for_deploy(self.node) self.assertEqual('uefi', result) instance_info = {'capabilities': {'trusted_boot': 'True'}} self.node.instance_info = instance_info - result = utils.get_boot_mode_for_deploy(self.node) + result = boot_mode_utils.get_boot_mode_for_deploy(self.node) self.assertEqual('bios', result) instance_info = {'capabilities': {'trusted_boot': 'True'}, 'capabilities': {'secure_boot': 'True'}} self.node.instance_info = instance_info - result = utils.get_boot_mode_for_deploy(self.node) + result = boot_mode_utils.get_boot_mode_for_deploy(self.node) self.assertEqual('uefi', result) def test_get_boot_mode_for_deploy_using_instance_info(self): instance_info = {'deploy_boot_mode': 'bios'} self.node.instance_info = instance_info - result = utils.get_boot_mode_for_deploy(self.node) + result = boot_mode_utils.get_boot_mode_for_deploy(self.node) self.assertEqual('bios', result) def test_validate_boot_mode_capability(self): diff --git a/ironic/tests/unit/drivers/modules/test_ipmitool.py b/ironic/tests/unit/drivers/modules/test_ipmitool.py index b607bcd274..009f87c404 100644 --- a/ironic/tests/unit/drivers/modules/test_ipmitool.py +++ b/ironic/tests/unit/drivers/modules/test_ipmitool.py @@ -42,8 +42,8 @@ from ironic.common import states from ironic.common import utils from ironic.conductor import task_manager import ironic.conf +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import console_utils -from ironic.drivers.modules import deploy_utils from ironic.drivers.modules import ipmitool as ipmi from ironic.drivers import utils as driver_utils from ironic.tests import base @@ -1974,7 +1974,7 @@ class IPMIToolDriverTestCase(Base): self.management.set_boot_device, task, boot_devices.PXE) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy') + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy') @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True) def test_management_interface_set_boot_device_uefi(self, mock_exec, mock_boot_mode): @@ -1990,7 +1990,7 @@ class IPMIToolDriverTestCase(Base): ] mock_exec.assert_has_calls(mock_calls) - @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy') + @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy') @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True) def test_management_interface_set_boot_device_uefi_and_persistent( self, mock_exec, mock_boot_mode):