diff options
Diffstat (limited to 'ironic')
55 files changed, 448 insertions, 1711 deletions
diff --git a/ironic/api/controllers/v1/node.py b/ironic/api/controllers/v1/node.py index 2ef369e13..dab134258 100644 --- a/ironic/api/controllers/v1/node.py +++ b/ironic/api/controllers/v1/node.py @@ -1172,8 +1172,16 @@ def _get_chassis_uuid(node): """ if not node.chassis_id: return - chassis = objects.Chassis.get_by_id(api.request.context, node.chassis_id) - return chassis.uuid + try: + chassis = objects.Chassis.get_by_id(api.request.context, + node.chassis_id) + return chassis.uuid + except exception.ChassisNotFound: + # NOTE(TheJulia): This is a case where multiple threads are racing + # and the chassis was not found... or somebody edited the database + # directly. Regardless, operationally, there is no chassis, and we + # return as there is nothing to actually return to the API consumer. + return def _replace_chassis_uuid_with_id(node_dict): diff --git a/ironic/common/pxe_utils.py b/ironic/common/pxe_utils.py index 88c55d6d7..40ad98217 100644 --- a/ironic/common/pxe_utils.py +++ b/ironic/common/pxe_utils.py @@ -681,8 +681,10 @@ def get_instance_image_info(task, ipxe_enabled=False): def _get_image_properties(): nonlocal image_properties if not image_properties: - glance_service = service.GlanceImageService(context=ctx) - image_properties = glance_service.show( + i_service = service.get_image_service( + d_info['image_source'], + context=ctx) + image_properties = i_service.show( d_info['image_source'])['properties'] labels = ('kernel', 'ramdisk') @@ -691,10 +693,13 @@ def get_instance_image_info(task, ipxe_enabled=False): # we won't use any of them. We'll use the values specified # with the image, which we assume have been set. _get_image_properties() - for label in labels: - i_info[label] = str(image_properties[label + '_id']) - node.instance_info = i_info - node.save() + if image_properties: + # This is intended for Glance usage, but all image properties + # should be routed through the image service request routing. + for label in labels: + i_info[label] = str(image_properties[label + '_id']) + node.instance_info = i_info + node.save() anaconda_labels = () if deploy_utils.get_boot_option(node) == 'kickstart': diff --git a/ironic/conductor/verify.py b/ironic/conductor/verify.py index 50180e2b8..812472b83 100644 --- a/ironic/conductor/verify.py +++ b/ironic/conductor/verify.py @@ -63,7 +63,7 @@ def do_node_verify(task): except Exception as e: error = ('Node %(node)s failed verify step %(step)s ' 'with unexpected error: %(err)s' % - {'node': node.uuid, 'step': node.verify_step, + {'node': node.uuid, 'step': step['step'], 'err': e}) utils.verifying_error_handler( task, error, diff --git a/ironic/conf/default.py b/ironic/conf/default.py index 66555d146..0e3c32bd1 100644 --- a/ironic/conf/default.py +++ b/ironic/conf/default.py @@ -111,7 +111,7 @@ driver_opts = [ cfg.StrOpt('default_console_interface', help=_DEFAULT_IFACE_HELP.format('console')), cfg.ListOpt('enabled_deploy_interfaces', - default=['direct'], + default=['direct', 'ramdisk'], help=_ENABLED_IFACE_HELP.format('deploy')), cfg.StrOpt('default_deploy_interface', help=_DEFAULT_IFACE_HELP.format('deploy')), diff --git a/ironic/conf/deploy.py b/ironic/conf/deploy.py index 7a7fb37d7..6ae080c83 100644 --- a/ironic/conf/deploy.py +++ b/ironic/conf/deploy.py @@ -120,18 +120,6 @@ opts = [ mutable=True, help=_('Whether to power off a node after deploy failure. ' 'Defaults to True.')), - cfg.StrOpt('default_boot_option', - choices=[('netboot', _('boot from a network')), - ('local', _('local boot'))], - default='local', - mutable=True, - help=_('Default boot option to use when no boot option is ' - 'requested in node\'s driver_info. Defaults to ' - '"local". Prior to the Ussuri release, the default ' - 'was "netboot".'), - deprecated_for_removal=True, - deprecated_reason=_('Support for network boot will be removed ' - 'after the Yoga release.')), cfg.StrOpt('default_boot_mode', choices=[(boot_modes.UEFI, _('UEFI boot mode')), (boot_modes.LEGACY_BIOS, _('Legacy BIOS boot mode'))], diff --git a/ironic/conf/molds.py b/ironic/conf/molds.py index 4cec1749a..53724598e 100644 --- a/ironic/conf/molds.py +++ b/ironic/conf/molds.py @@ -26,11 +26,11 @@ opts = [ cfg.StrOpt('password', help=_('Password for "http" Basic auth. By default set ' 'empty.')), - cfg.StrOpt('retry_attempts', + cfg.IntOpt('retry_attempts', default=3, help=_('Retry attempts for saving or getting configuration ' 'molds.')), - cfg.StrOpt('retry_interval', + cfg.IntOpt('retry_interval', default=3, help=_('Retry interval for saving or getting configuration ' 'molds.')) diff --git a/ironic/drivers/modules/agent.py b/ironic/drivers/modules/agent.py index c171f81b1..1c0f5465e 100644 --- a/ironic/drivers/modules/agent.py +++ b/ironic/drivers/modules/agent.py @@ -16,7 +16,6 @@ from urllib import parse as urlparse from ironic_lib import metrics_utils from oslo_log import log -from oslo_utils import excutils from oslo_utils import units from ironic.common import exception @@ -325,33 +324,7 @@ class CustomAgentDeploy(agent_base.AgentBaseMixin, agent_base.AgentDeployMixin, if node.provision_state == states.DEPLOYING: # Validate network interface to ensure that it supports boot # options configured on the node. - try: - task.driver.network.validate(task) - except exception.InvalidParameterValue: - # For 'neutron' network interface validation will fail - # if node is using 'netboot' boot option while provisioning - # a whole disk image. Updating 'boot_option' in node's - # 'instance_info' to 'local for backward compatibility. - # TODO(stendulker): Fail here once the default boot - # option is local. - # NOTE(TheJulia): Fixing the default boot mode only - # masks the failure as the lack of a user definition - # can be perceived as both an invalid configuration and - # reliance upon the default configuration. The reality - # being that in most scenarios, users do not want network - # booting, so the changed default should be valid. - with excutils.save_and_reraise_exception(reraise=False) as ctx: - instance_info = node.instance_info - capabilities = utils.parse_instance_info_capabilities(node) - if 'boot_option' not in capabilities: - capabilities['boot_option'] = 'local' - instance_info['capabilities'] = capabilities - node.instance_info = instance_info - node.save() - # Re-validate the network interface - task.driver.network.validate(task) - else: - ctx.reraise = True + task.driver.network.validate(task) # Determine if this is a fast track sequence fast_track_deploy = manager_utils.is_fast_track(task) if fast_track_deploy: @@ -597,13 +570,6 @@ class AgentDeploy(CustomAgentDeploy): iwdi = task.node.driver_internal_info.get('is_whole_disk_image') cpu_arch = task.node.properties.get('cpu_arch') - # If `boot_option` is set to `netboot`, PXEBoot.prepare_instance() - # would need root_uuid of the whole disk image to add it into the - # pxe config to perform chain boot. - # IPA would have returned us the 'root_uuid_or_disk_id' if image - # being provisioned is a whole disk image. IPA would also provide us - # 'efi_system_partition_uuid' if the image being provisioned is a - # partition image. # In case of local boot using partition image, we need both # 'root_uuid_or_disk_id' and 'efi_system_partition_uuid' to configure # bootloader for local boot. diff --git a/ironic/drivers/modules/agent_base.py b/ironic/drivers/modules/agent_base.py index 582c36d90..ff2a454ea 100644 --- a/ironic/drivers/modules/agent_base.py +++ b/ironic/drivers/modules/agent_base.py @@ -1217,12 +1217,12 @@ class AgentDeployMixin(HeartbeatMixin, AgentOobStepsMixin): """ node = task.node - if deploy_utils.get_boot_option(node) == "local": - # Install the boot loader - self.configure_local_boot( - task, root_uuid=root_uuid, - efi_system_part_uuid=efi_sys_uuid, - prep_boot_part_uuid=prep_boot_part_uuid) + # Install the boot loader + self.configure_local_boot( + task, root_uuid=root_uuid, + efi_system_part_uuid=efi_sys_uuid, + prep_boot_part_uuid=prep_boot_part_uuid) + try: task.driver.boot.prepare_instance(task) except Exception as e: diff --git a/ironic/drivers/modules/agent_config.template b/ironic/drivers/modules/agent_config.template deleted file mode 100644 index bf9f5f4b4..000000000 --- a/ironic/drivers/modules/agent_config.template +++ /dev/null @@ -1,13 +0,0 @@ -default deploy - -label deploy -kernel {{ pxe_options.deployment_aki_path }} -append initrd={{ pxe_options.deployment_ari_path }} text {{ pxe_options.pxe_append_params }} - -label boot_partition -kernel {{ pxe_options.aki_path }} -append initrd={{ pxe_options.ari_path }} root={{ ROOT }} ro text {{ pxe_options.pxe_append_params|default("", true) }} - -label boot_whole_disk -COM32 chain.c32 -append mbr:{{ DISK_IDENTIFIER }} diff --git a/ironic/drivers/modules/ansible/deploy.py b/ironic/drivers/modules/ansible/deploy.py index cd3f4c68f..d7cf49412 100644 --- a/ironic/drivers/modules/ansible/deploy.py +++ b/ironic/drivers/modules/ansible/deploy.py @@ -396,12 +396,6 @@ class AnsibleDeploy(agent_base.HeartbeatMixin, task.driver.boot.validate(task) node = task.node - iwdi = node.driver_internal_info.get('is_whole_disk_image') - if not iwdi and deploy_utils.get_boot_option(node) == "netboot": - raise exception.InvalidParameterValue(_( - "Node %(node)s is configured to use the ansible deploy " - "interface, which does not support netboot.") % - {'node': node.uuid}) params = {} image_source = node.instance_info.get('image_source') diff --git a/ironic/drivers/modules/boot.ipxe b/ironic/drivers/modules/boot.ipxe index 4ed58497c..95d95686a 100644 --- a/ironic/drivers/modules/boot.ipxe +++ b/ironic/drivers/modules/boot.ipxe @@ -10,6 +10,12 @@ isset ${net${netid}/mac} || goto loop_done echo Attempting to boot from MAC ${net${netid}/mac:hexhyp} chain {{ ipxe_for_mac_uri }}${net${netid}/mac:hexhyp} || goto loop +# If we've got here the chained config returned success +# suggesting "sanboot" in boot_whole_disk failed (some UEFI cases) +# exit 0 so the bios continues to the next device +echo Exiting pxe config to allow boot to continue on next device +exit 0 + :loop_done {% if ipxe_fallback_script -%} chain {{ ipxe_fallback_script }} | goto boot_failed diff --git a/ironic/drivers/modules/deploy_utils.py b/ironic/drivers/modules/deploy_utils.py index bcefd2323..399dfa68f 100644 --- a/ironic/drivers/modules/deploy_utils.py +++ b/ironic/drivers/modules/deploy_utils.py @@ -55,7 +55,6 @@ LOG = logging.getLogger(__name__) METRICS = metrics_utils.get_metrics_logger(__name__) SUPPORTED_CAPABILITIES = { - 'boot_option': ('local', 'netboot', 'ramdisk', 'kickstart'), 'boot_mode': ('bios', 'uefi'), 'secure_boot': ('true', 'false'), 'disk_label': ('msdos', 'gpt'), @@ -159,6 +158,9 @@ def _replace_disk_identifier(path, disk_identifier): # NOTE(TheJulia): This should likely be migrated to pxe_utils. +# TODO(dtantsur): with the removal of netboot, root_uuid_or_disk_id and +# the logic of replacing ROOT can be dropped, while is_whole_disk_image can +# be renamed to something like netboot_fallback. def switch_pxe_config(path, root_uuid_or_disk_id, boot_mode, is_whole_disk_image, iscsi_boot=False, ramdisk_boot=False, ipxe_enabled=False, @@ -616,17 +618,11 @@ def get_boot_option(node): :returns: A string representing the boot option type. Defaults to configuration setting [deploy]default_boot_mode. """ - - # NOTE(TheJulia): Software raid always implies local deployment - if is_software_raid(node): - return 'local' if is_anaconda_deploy(node): return 'kickstart' if is_ramdisk_deploy(node): return 'ramdisk' - capabilities = utils.parse_instance_info_capabilities(node) - return capabilities.get('boot_option', - CONF.deploy.default_boot_option).lower() + return 'local' # FIXME(dtantsur): relying on deploy interface name is an anti-pattern. diff --git a/ironic/drivers/modules/ilo/boot.py b/ironic/drivers/modules/ilo/boot.py index 7f5c5adcf..e29852981 100644 --- a/ironic/drivers/modules/ilo/boot.py +++ b/ironic/drivers/modules/ilo/boot.py @@ -320,7 +320,7 @@ class IloVirtualMediaBoot(base.BootInterface): except exception.ImageRefValidationFailed: with excutils.save_and_reraise_exception(): LOG.error("Virtual media deploy with 'ramdisk' " - "boot_option accepts only Glance images or " + "deploy accepts only Glance images or " "HTTP(S) URLs as " "instance_info['boot_iso']. Either %s " "is not a valid HTTP(S) URL or is not " @@ -460,21 +460,8 @@ class IloVirtualMediaBoot(base.BootInterface): boot_devices.CDROM, persistent=True) else: - # Boot from disk every time if the image deployed is - # a whole disk image. - node = task.node - iwdi = node.driver_internal_info.get('is_whole_disk_image') - if deploy_utils.get_boot_option(node) == "local" or iwdi: - manager_utils.node_set_boot_device(task, boot_devices.DISK, - persistent=True) - else: - drv_int_info = node.driver_internal_info - root_uuid_or_disk_id = drv_int_info.get('root_uuid_or_disk_id') - if root_uuid_or_disk_id: - self._configure_vmedia_boot(task, root_uuid_or_disk_id) - else: - LOG.warning("The UUID for the root partition could not " - "be found for node %s", node.uuid) + manager_utils.node_set_boot_device(task, boot_devices.DISK, + persistent=True) # Set boot mode ilo_common.update_boot_mode(task) # Need to enable secure boot, if being requested @@ -590,8 +577,7 @@ class IloPXEBoot(pxe.PXEBoot): """Prepares the boot of instance. This method prepares the boot of the instance after reading - relevant information from the node's instance_info. In case of netboot, - it updates the dhcp entries and switches the PXE config. In case of + relevant information from the node's instance_info. In case of localboot, it cleans up the PXE config. In case of 'boot from volume', it updates the iSCSI info onto iLO and sets the node to boot from 'UefiTarget' boot device. @@ -683,8 +669,7 @@ class IloiPXEBoot(ipxe.iPXEBoot): """Prepares the boot of instance. This method prepares the boot of the instance after reading - relevant information from the node's instance_info. In case of netboot, - it updates the dhcp entries and switches the PXE config. In case of + relevant information from the node's instance_info. In case of localboot, it cleans up the PXE config. In case of 'boot from volume', it updates the iSCSI info onto iLO and sets the node to boot from 'UefiTarget' boot device. @@ -904,7 +889,7 @@ class IloUefiHttpsBoot(base.BootInterface): except exception.ImageRefValidationFailed: with excutils.save_and_reraise_exception(): LOG.error("UEFI-HTTPS boot with 'ramdisk' " - "boot_option accepts only Glance images or " + "deploy accepts only Glance images or " "HTTPS URLs as " "instance_info['boot_iso']. Either %s " "is not a valid HTTPS URL or is not " diff --git a/ironic/drivers/modules/ilo/power.py b/ironic/drivers/modules/ilo/power.py index ee8fcc794..a1363fb52 100644 --- a/ironic/drivers/modules/ilo/power.py +++ b/ironic/drivers/modules/ilo/power.py @@ -44,9 +44,8 @@ def _attach_boot_iso_if_needed(task): This method checks the instance info of the baremetal node for a boot iso. If the instance info has a value of key 'boot_iso', - it indicates that 'boot_option' is 'netboot'. Therefore it attaches - the boot ISO on the baremetal node and then sets the node to boot from - virtual media cdrom. + it indicates ramdisk deploy. Therefore it attaches the boot ISO on the + baremetal node and then sets the node to boot from virtual media cdrom. :param task: a TaskManager instance containing the node to act on. """ diff --git a/ironic/drivers/modules/ipxe_config.template b/ironic/drivers/modules/ipxe_config.template index bca63c982..650083869 100644 --- a/ironic/drivers/modules/ipxe_config.template +++ b/ironic/drivers/modules/ipxe_config.template @@ -25,12 +25,6 @@ echo Powering off in 30 seconds. sleep 30 poweroff -:boot_partition -imgfree -kernel {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ pxe_options.aki_path }} root={{ ROOT }} ro text {{ pxe_options.pxe_append_params|default("", true) }} initrd=ramdisk || goto boot_partition -initrd {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ pxe_options.ari_path }} || goto boot_partition -boot - :boot_anaconda imgfree kernel {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ pxe_options.aki_path }} text {{ pxe_options.pxe_append_params|default("", true) }} inst.ks={{ pxe_options.ks_cfg_url }} {% if pxe_options.repo_url %}inst.repo={{ pxe_options.repo_url }}{% else %}inst.stage2={{ pxe_options.stage2_url }}{% endif %} initrd=ramdisk || goto boot_anaconda @@ -72,4 +66,4 @@ goto boot_iscsi {%- endif %} :boot_whole_disk -sanboot --no-describe +sanboot --no-describe || exit 0 diff --git a/ironic/drivers/modules/irmc/boot.py b/ironic/drivers/modules/irmc/boot.py index 84964bd2f..11153a6f1 100644 --- a/ironic/drivers/modules/irmc/boot.py +++ b/ironic/drivers/modules/irmc/boot.py @@ -376,9 +376,8 @@ def attach_boot_iso_if_needed(task): This method checks the instance info of the bare metal node for a boot ISO. If the instance info has a value of key 'boot_iso', - it indicates that 'boot_option' is 'netboot'. Threfore it attaches - the boot ISO on the bare metal node and then sets the node to boot from - virtual media cdrom. + it indicates ramdisk deploy. Therefore it attaches the boot ISO on the bare + metal node and then sets the node to boot from virtual media cdrom. :param task: a TaskManager instance containing the node to act on. :raises: IRMCOperationError if attaching virtual media failed. diff --git a/ironic/drivers/modules/network/neutron.py b/ironic/drivers/modules/network/neutron.py index 3e4dcbfd6..2693b603e 100644 --- a/ironic/drivers/modules/network/neutron.py +++ b/ironic/drivers/modules/network/neutron.py @@ -20,9 +20,7 @@ from oslo_log import log from ironic.common import exception from ironic.common.i18n import _ from ironic.common import neutron -from ironic.common import states from ironic.drivers import base -from ironic.drivers.modules import deploy_utils from ironic.drivers.modules.network import common LOG = log.getLogger(__name__) @@ -61,15 +59,6 @@ class NeutronNetwork(common.NeutronVIFPortIDMixin, """ self.get_cleaning_network_uuid(task) self.get_provisioning_network_uuid(task) - node = task.node - if (node.provision_state == states.DEPLOYING - and node.driver_internal_info.get('is_whole_disk_image') - and deploy_utils.get_boot_option(node) == 'netboot'): - error_msg = (_('The node %s cannot perform "local" boot for ' - 'whole disk image when node is using "neutron" ' - 'network and is configured with "netboot" boot ' - 'option.') % node.uuid) - raise exception.InvalidParameterValue(error_msg) def _add_network(self, task, network, security_groups, process): # If we have left over ports from a previous process, remove them diff --git a/ironic/drivers/modules/pxe_base.py b/ironic/drivers/modules/pxe_base.py index a8a768b8b..daa90ba8d 100644 --- a/ironic/drivers/modules/pxe_base.py +++ b/ironic/drivers/modules/pxe_base.py @@ -261,50 +261,6 @@ class PXEBaseMixin(object): anaconda_boot=(boot_option == "kickstart")) boot_device = boot_devices.PXE - elif boot_option != "local": - if task.driver.storage.should_write_image(task): - # Make sure that the instance kernel/ramdisk is cached. - # This is for the takeover scenario for active nodes. - instance_image_info = pxe_utils.get_instance_image_info( - task, ipxe_enabled=self.ipxe_enabled) - pxe_utils.cache_ramdisk_kernel(task, instance_image_info, - ipxe_enabled=self.ipxe_enabled) - - # If it's going to PXE boot we need to update the DHCP server - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=self.ipxe_enabled, ip_version=4) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=self.ipxe_enabled, ip_version=6) - provider = dhcp_factory.DHCPFactory() - provider.update_dhcp(task, dhcp_opts) - - iwdi = task.node.driver_internal_info.get('is_whole_disk_image') - try: - root_uuid_or_disk_id = task.node.driver_internal_info[ - 'root_uuid_or_disk_id' - ] - except KeyError: - if not task.driver.storage.should_write_image(task): - pass - elif not iwdi: - LOG.warning("The UUID for the root partition can't be " - "found, unable to switch the pxe config from " - "deployment mode to service (boot) mode for " - "node %(node)s", {"node": task.node.uuid}) - else: - LOG.warning("The disk id for the whole disk image can't " - "be found, unable to switch the pxe config " - "from deployment mode to service (boot) mode " - "for node %(node)s. Booting the instance " - "from disk.", {"node": task.node.uuid}) - pxe_utils.clean_up_pxe_config( - task, ipxe_enabled=self.ipxe_enabled) - boot_device = boot_devices.DISK - else: - pxe_utils.build_service_pxe_config( - task, instance_image_info, root_uuid_or_disk_id, - ipxe_enabled=self.ipxe_enabled) - boot_device = boot_devices.PXE else: # NOTE(dtantsur): create a PXE configuration as a safety net for # hardware uncapable of persistent boot. If on a reboot it will try diff --git a/ironic/drivers/modules/pxe_config.template b/ironic/drivers/modules/pxe_config.template index 9b773b2ba..bf4cec11a 100644 --- a/ironic/drivers/modules/pxe_config.template +++ b/ironic/drivers/modules/pxe_config.template @@ -5,12 +5,6 @@ kernel {{ pxe_options.deployment_aki_path }} append initrd={{ pxe_options.deployment_ari_path }} selinux=0 troubleshoot=0 text {{ pxe_options.pxe_append_params|default("", true) }} ipappend 2 - -label boot_partition -kernel {{ pxe_options.aki_path }} -append initrd={{ pxe_options.ari_path }} root={{ ROOT }} ro text {{ pxe_options.pxe_append_params|default("", true) }} - - label boot_whole_disk COM32 chain.c32 append mbr:{{ DISK_IDENTIFIER }} diff --git a/ironic/drivers/modules/pxe_grub_config.template b/ironic/drivers/modules/pxe_grub_config.template index d33cbb8cd..d8fc48673 100644 --- a/ironic/drivers/modules/pxe_grub_config.template +++ b/ironic/drivers/modules/pxe_grub_config.template @@ -7,11 +7,6 @@ menuentry "deploy" { initrdefi {{ pxe_options.deployment_ari_path }} } -menuentry "boot_partition" { - linuxefi {{ pxe_options.aki_path }} root={{ ROOT }} ro text {{ pxe_options.pxe_append_params|default("", true) }} boot_server={{pxe_options.tftp_server}} - initrdefi {{ pxe_options.ari_path }} -} - menuentry "boot_ramdisk" { linuxefi {{ pxe_options.aki_path }} root=/dev/ram0 text {{ pxe_options.pxe_append_params|default("", true) }} {{ pxe_options.ramdisk_opts|default('', true) }} initrdefi {{ pxe_options.ari_path }} diff --git a/ironic/drivers/modules/redfish/raid.py b/ironic/drivers/modules/redfish/raid.py index 77abdef0e..809ec59c6 100644 --- a/ironic/drivers/modules/redfish/raid.py +++ b/ironic/drivers/modules/redfish/raid.py @@ -693,6 +693,7 @@ def update_raid_config(node): """ system = redfish_utils.get_system(node) logical_disks = [] + vol_no_raid_type = [] for stor in system.storage.get_members(): for vol in stor.volumes.get_members(): if vol.raid_type: @@ -705,7 +706,14 @@ def update_raid_config(node): key for key, value in RAID_LEVELS.items() if value['raid_type'] == vol.raid_type.value) } - logical_disks.append(logical_disk) + logical_disks.append(logical_disk) + else: + vol_no_raid_type.append(vol.identity) + + if vol_no_raid_type: + LOG.warning("Unable to update raid_config for volumes missing RAID " + "type: %(vol_no_raid_type)s", + {'vol_no_raid_type': ", ".join(vol_no_raid_type)}) raid_common.update_raid_info(node, {'logical_disks': logical_disks}) diff --git a/ironic/tests/base.py b/ironic/tests/base.py index ba43461b6..4b34ef0a4 100644 --- a/ironic/tests/base.py +++ b/ironic/tests/base.py @@ -159,7 +159,7 @@ class TestCase(oslo_test_base.BaseTestCase): values = ['fake'] if iface == 'deploy': - values.extend(['direct', 'anaconda']) + values.extend(['direct', 'ramdisk', 'anaconda']) elif iface == 'boot': values.append('pxe') elif iface == 'storage': diff --git a/ironic/tests/unit/api/controllers/v1/test_node.py b/ironic/tests/unit/api/controllers/v1/test_node.py index 3c913834e..d7a3d474e 100644 --- a/ironic/tests/unit/api/controllers/v1/test_node.py +++ b/ironic/tests/unit/api/controllers/v1/test_node.py @@ -600,6 +600,23 @@ class TestListNodes(test_api_base.BaseApiTest): self.assertCountEqual(['driver_info', 'links'], data) self.assertEqual('******', data['driver_info']['fake_password']) + def test_get_one_with_deleted_chassis(self): + node = obj_utils.create_test_node(self.context, + chassis_id=self.chassis.id) + with mock.patch.object(self.dbapi, + 'get_chassis_by_id', + autospec=True) as mock_gc: + # Explicitly return a chassis not found, and make sure the API + # hides this from the API consumer as this is likely just an + # in-flight deletion across multiple DB sessions or different + # API surfaces (or, just slow DB replication.) + mock_gc.side_effect = exception.ChassisNotFound( + chassis=self.chassis.id) + data = self.get_json( + '/nodes/%s' % node.uuid, + headers={api_base.Version.string: str(api_v1.max_version())}) + self.assertIsNone(data['chassis_uuid']) + def test_get_network_interface_fields_invalid_api_version(self): node = obj_utils.create_test_node(self.context, chassis_id=self.chassis.id) diff --git a/ironic/tests/unit/api/test_audit.py b/ironic/tests/unit/api/test_audit.py index d85ed3e85..cedeabf17 100644 --- a/ironic/tests/unit/api/test_audit.py +++ b/ironic/tests/unit/api/test_audit.py @@ -35,7 +35,7 @@ class TestAuditMiddleware(base.BaseApiTest): @mock.patch.object(audit, 'AuditMiddleware', autospec=True) def test_enable_audit_request(self, mock_audit): - CONF.audit.enabled = True + CONF.set_override('enabled', True, 'audit') self._make_app() mock_audit.assert_called_once_with( mock.ANY, @@ -44,14 +44,13 @@ class TestAuditMiddleware(base.BaseApiTest): @mock.patch.object(audit, 'AuditMiddleware', autospec=True) def test_enable_audit_request_error(self, mock_audit): - CONF.audit.enabled = True + CONF.set_override('enabled', True, 'audit') mock_audit.side_effect = IOError("file access error") - self.assertRaises(exception.InputFileError, self._make_app) @mock.patch.object(audit, 'AuditMiddleware', autospec=True) def test_disable_audit_request(self, mock_audit): - CONF.audit.enabled = False + CONF.set_override('enabled', False, 'audit') self._make_app() self.assertFalse(mock_audit.called) diff --git a/ironic/tests/unit/api/test_ospmiddleware.py b/ironic/tests/unit/api/test_ospmiddleware.py index 555251dd7..f814d5688 100644 --- a/ironic/tests/unit/api/test_ospmiddleware.py +++ b/ironic/tests/unit/api/test_ospmiddleware.py @@ -32,12 +32,12 @@ class TestOsprofilerWsgiMiddleware(base.BaseApiTest): @mock.patch.object(web, 'WsgiMiddleware', autospec=True) def test_enable_osp_wsgi_request(self, mock_ospmiddleware): - CONF.profiler.enabled = True + CONF.set_override('enabled', True, 'profiler') self._make_app() mock_ospmiddleware.assert_called_once_with(mock.ANY) @mock.patch.object(web, 'WsgiMiddleware', autospec=True) def test_disable_osp_wsgi_request(self, mock_ospmiddleware): - CONF.profiler.enabled = False + CONF.set_override('enabled', False, 'profiler') self._make_app() self.assertFalse(mock_ospmiddleware.called) diff --git a/ironic/tests/unit/common/test_molds.py b/ironic/tests/unit/common/test_molds.py index bd2c37e47..810dd61bc 100644 --- a/ironic/tests/unit/common/test_molds.py +++ b/ironic/tests/unit/common/test_molds.py @@ -38,7 +38,7 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): mock_session = mock.Mock() mock_session.get_token.return_value = 'token' mock_swift.return_value = mock_session - cfg.CONF.molds.storage = 'swift' + cfg.CONF.set_override('storage', 'swift', 'molds') url = 'https://example.com/file1' data = {'key': 'value'} @@ -54,7 +54,7 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): mock_session = mock.Mock() mock_session.get_token.return_value = None mock_swift.return_value = mock_session - cfg.CONF.molds.storage = 'swift' + cfg.CONF.set_override('storage', 'swift', 'molds') url = 'https://example.com/file1' data = {'key': 'value'} @@ -66,9 +66,9 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'put', autospec=True) def test_save_configuration_http(self, mock_put): - cfg.CONF.molds.storage = 'http' - cfg.CONF.molds.user = 'user' - cfg.CONF.molds.password = 'password' + cfg.CONF.set_override('storage', 'http', 'molds') + cfg.CONF.set_override('user', 'user', 'molds') + cfg.CONF.set_override('password', 'password', 'molds') url = 'https://example.com/file1' data = {'key': 'value'} @@ -81,9 +81,9 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'put', autospec=True) def test_save_configuration_http_noauth(self, mock_put): - cfg.CONF.molds.storage = 'http' - cfg.CONF.molds.user = None - cfg.CONF.molds.password = None + cfg.CONF.set_override('storage', 'http', 'molds') + cfg.CONF.set_override('user', None, 'molds') + cfg.CONF.set_override('password', None, 'molds') url = 'https://example.com/file1' data = {'key': 'value'} @@ -95,9 +95,9 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'put', autospec=True) def test_save_configuration_http_error(self, mock_put): - cfg.CONF.molds.storage = 'http' - cfg.CONF.molds.user = 'user' - cfg.CONF.molds.password = 'password' + cfg.CONF.set_override('storage', 'http', 'molds') + cfg.CONF.set_override('user', 'user', 'molds') + cfg.CONF.set_override('password', 'password', 'molds') response = mock.MagicMock() response.status_code = 404 response.raise_for_status.side_effect = requests.exceptions.HTTPError @@ -116,11 +116,11 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'put', autospec=True) def test_save_configuration_connection_error(self, mock_put): - cfg.CONF.molds.storage = 'http' - cfg.CONF.molds.user = 'user' - cfg.CONF.molds.password = 'password' - cfg.CONF.molds.retry_interval = 0 - cfg.CONF.molds.retry_attempts = 3 + cfg.CONF.set_override('storage', 'http', 'molds') + cfg.CONF.set_override('user', 'user', 'molds') + cfg.CONF.set_override('password', 'password', 'molds') + cfg.CONF.set_override('retry_interval', 0, 'molds') + cfg.CONF.set_override('retry_attempts', 3, 'molds') response = mock.MagicMock() mock_put.side_effect = [ requests.exceptions.ConnectTimeout, @@ -137,11 +137,11 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'put', autospec=True) def test_save_configuration_connection_error_exceeded(self, mock_put): - cfg.CONF.molds.storage = 'http' - cfg.CONF.molds.user = 'user' - cfg.CONF.molds.password = 'password' - cfg.CONF.molds.retry_interval = 0 - cfg.CONF.molds.retry_attempts = 2 + cfg.CONF.set_override('storage', 'http', 'molds') + cfg.CONF.set_override('user', 'user', 'molds') + cfg.CONF.set_override('password', 'password', 'molds') + cfg.CONF.set_override('retry_interval', 0, 'molds') + cfg.CONF.set_override('retry_attempts', 2, 'molds') mock_put.side_effect = [ requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError] @@ -164,7 +164,7 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): mock_session = mock.Mock() mock_session.get_token.return_value = 'token' mock_swift.return_value = mock_session - cfg.CONF.molds.storage = 'swift' + cfg.CONF.set_override('storage', 'swift', 'molds') response = mock.MagicMock() response.status_code = 200 response.content = "{'key': 'value'}" @@ -185,7 +185,7 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): mock_session = mock.Mock() mock_session.get_token.return_value = None mock_swift.return_value = mock_session - cfg.CONF.molds.storage = 'swift' + cfg.CONF.set_override('storage', 'swift', 'molds') url = 'https://example.com/file1' with task_manager.acquire(self.context, self.node.uuid) as task: @@ -196,9 +196,9 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'get', autospec=True) def test_get_configuration_http(self, mock_get): - cfg.CONF.molds.storage = 'http' - cfg.CONF.molds.user = 'user' - cfg.CONF.molds.password = 'password' + cfg.CONF.set_override('storage', 'http', 'molds') + cfg.CONF.set_override('user', 'user', 'molds') + cfg.CONF.set_override('password', 'password', 'molds') response = mock.MagicMock() response.status_code = 200 response.content = "{'key': 'value'}" @@ -215,9 +215,9 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'get', autospec=True) def test_get_configuration_http_noauth(self, mock_get): - cfg.CONF.molds.storage = 'http' - cfg.CONF.molds.user = None - cfg.CONF.molds.password = None + cfg.CONF.set_override('storage', 'http', 'molds') + cfg.CONF.set_override('user', None, 'molds') + cfg.CONF.set_override('password', None, 'molds') response = mock.MagicMock() response.status_code = 200 response.content = "{'key': 'value'}" @@ -233,9 +233,9 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'get', autospec=True) def test_get_configuration_http_error(self, mock_get): - cfg.CONF.molds.storage = 'http' - cfg.CONF.molds.user = 'user' - cfg.CONF.molds.password = 'password' + cfg.CONF.set_override('storage', 'http', 'molds') + cfg.CONF.set_override('user', 'user', 'molds') + cfg.CONF.set_override('password', 'password', 'molds') response = mock.MagicMock() response.status_code = 404 response.raise_for_status.side_effect = requests.exceptions.HTTPError @@ -253,11 +253,11 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'get', autospec=True) def test_get_configuration_connection_error(self, mock_get): - cfg.CONF.molds.storage = 'http' - cfg.CONF.molds.user = 'user' - cfg.CONF.molds.password = 'password' - cfg.CONF.molds.retry_interval = 0 - cfg.CONF.molds.retry_attempts = 3 + cfg.CONF.set_override('storage', 'http', 'molds') + cfg.CONF.set_override('user', 'user', 'molds') + cfg.CONF.set_override('password', 'password', 'molds') + cfg.CONF.set_override('retry_interval', 0, 'molds') + cfg.CONF.set_override('retry_attempts', 3, 'molds') response = mock.MagicMock() mock_get.side_effect = [ requests.exceptions.ConnectTimeout, @@ -274,11 +274,11 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'get', autospec=True) def test_get_configuration_mold_connection_error_exceeded(self, mock_get): - cfg.CONF.molds.storage = 'http' - cfg.CONF.molds.user = 'user' - cfg.CONF.molds.password = 'password' - cfg.CONF.molds.retry_interval = 0 - cfg.CONF.molds.retry_attempts = 2 + cfg.CONF.set_override('storage', 'http', 'molds') + cfg.CONF.set_override('user', 'user', 'molds') + cfg.CONF.set_override('password', 'password', 'molds') + cfg.CONF.set_override('retry_interval', 0, 'molds') + cfg.CONF.set_override('retry_attempts', 2, 'molds') mock_get.side_effect = [ requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError] @@ -296,7 +296,7 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'get', autospec=True) def test_get_configuration_empty(self, mock_get): - cfg.CONF.molds.storage = 'http' + cfg.CONF.set_override('storage', 'http', 'molds') response = mock.MagicMock() response.status_code = 200 response.content = '' @@ -309,7 +309,7 @@ class ConfigurationMoldTestCase(db_base.DbTestCase): @mock.patch.object(requests, 'get', autospec=True) def test_get_configuration_invalid_json(self, mock_get): - cfg.CONF.molds.storage = 'http' + cfg.CONF.set_override('storage', 'http', 'molds') response = mock.MagicMock() response.status_code = 200 response.content = 'not json' diff --git a/ironic/tests/unit/common/test_pxe_utils.py b/ironic/tests/unit/common/test_pxe_utils.py index c6dc9bffa..037ad7449 100644 --- a/ironic/tests/unit/common/test_pxe_utils.py +++ b/ironic/tests/unit/common/test_pxe_utils.py @@ -27,6 +27,7 @@ from oslo_utils import uuidutils from ironic.common import exception from ironic.common.glance_service import image_service +from ironic.common import image_service as base_image_service from ironic.common import pxe_utils from ironic.common import states from ironic.common import utils @@ -1295,25 +1296,6 @@ class PXEInterfacesTestCase(db_base.DbTestCase): self.assertEqual('instance_ramdisk_uuid', task.node.instance_info['ramdisk']) - def test_get_instance_image_info(self): - # Tests when 'is_whole_disk_image' exists in driver_internal_info - # NOTE(TheJulia): The method being tested is primarily geared for - # only netboot operation as the information should only need to be - # looked up again during network booting. - self.config(group="deploy", default_boot_option="netboot") - self._test_get_instance_image_info() - - def test_get_instance_image_info_without_is_whole_disk_image(self): - # NOTE(TheJulia): The method being tested is primarily geared for - # only netboot operation as the information should only need to be - # looked up again during network booting. - self.config(group="deploy", default_boot_option="netboot") - # Tests when 'is_whole_disk_image' doesn't exists in - # driver_internal_info - del self.node.driver_internal_info['is_whole_disk_image'] - self.node.save() - self._test_get_instance_image_info() - @mock.patch('ironic.drivers.modules.deploy_utils.get_boot_option', return_value='local', autospec=True) def test_get_instance_image_info_localboot(self, boot_opt_mock): @@ -1465,6 +1447,65 @@ class PXEInterfacesTestCase(db_base.DbTestCase): @mock.patch('ironic.drivers.modules.deploy_utils.get_boot_option', return_value='kickstart', autospec=True) + @mock.patch.object(base_image_service.HttpImageService, 'show', + autospec=True) + def test_get_instance_image_info_with_kickstart_url_http( + self, image_show_mock, boot_opt_mock): + properties = {'properties': {}} + expected_info = {'ramdisk': + ('http://fake.url/ramdisk', + os.path.join(CONF.pxe.tftp_root, + self.node.uuid, + 'ramdisk')), + 'kernel': + ('http://fake.url/kernel', + os.path.join(CONF.pxe.tftp_root, + self.node.uuid, + 'kernel')), + 'ks_template': + (CONF.anaconda.default_ks_template, + os.path.join(CONF.deploy.http_root, + self.node.uuid, + 'ks.cfg.template')), + 'ks_cfg': + ('', + os.path.join(CONF.deploy.http_root, + self.node.uuid, + 'ks.cfg'))} + image_show_mock.return_value = properties + self.context.auth_token = 'fake' + with task_manager.acquire(self.context, self.node.uuid, + shared=True) as task: + dii = task.node.driver_internal_info + dii['is_source_a_path'] = True + task.node.driver_internal_info = dii + i_info = task.node.instance_info + i_info['image_source'] = 'http://fake.url/path' + i_info['kernel'] = 'http://fake.url/kernel' + i_info['ramdisk'] = 'http://fake.url/ramdisk' + task.node.instance_info = i_info + task.node.save() + image_info = pxe_utils.get_instance_image_info( + task, ipxe_enabled=False) + self.assertEqual(expected_info, image_info) + # In the absense of kickstart template in both instance_info and + # image default kickstart template is used + self.assertEqual(CONF.anaconda.default_ks_template, + image_info['ks_template'][0]) + calls = [mock.call(task.node), mock.call(task.node)] + boot_opt_mock.assert_has_calls(calls) + # Instance info gets presedence over kickstart template on the + # image + properties['properties'] = {'ks_template': 'glance://template_id'} + task.node.instance_info['ks_template'] = 'https://server/fake.tmpl' + image_show_mock.return_value = properties + image_info = pxe_utils.get_instance_image_info( + task, ipxe_enabled=False) + self.assertEqual('https://server/fake.tmpl', + image_info['ks_template'][0]) + + @mock.patch('ironic.drivers.modules.deploy_utils.get_boot_option', + return_value='kickstart', autospec=True) @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) def test_get_instance_image_info_kickstart_stage2_missing( self, image_show_mock, boot_opt_mock): diff --git a/ironic/tests/unit/conductor/test_manager.py b/ironic/tests/unit/conductor/test_manager.py index b433aa4a5..378d65f15 100644 --- a/ironic/tests/unit/conductor/test_manager.py +++ b/ironic/tests/unit/conductor/test_manager.py @@ -7319,7 +7319,6 @@ class DoNodeAdoptionTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): mock_take_over.assert_called_once_with(task.driver.deploy, task) self.assertFalse(mock_start_console.called) mock_boot_validate.assert_not_called() - self.assertNotIn('is_whole_disk_image', task.node.driver_internal_info) @mock.patch('ironic.common.image_service.HttpImageService.validate_href', autospec=True) @@ -7328,26 +7327,23 @@ class DoNodeAdoptionTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): @mock.patch('ironic.drivers.modules.fake.FakeBoot.validate', autospec=True) @mock.patch('ironic.drivers.modules.fake.FakeConsole.start_console', autospec=True) - @mock.patch('ironic.drivers.modules.fake.FakeDeploy.take_over', + @mock.patch('ironic.drivers.modules.ramdisk.RamdiskDeploy.take_over', autospec=True) - @mock.patch('ironic.drivers.modules.fake.FakeDeploy.prepare', + @mock.patch('ironic.drivers.modules.ramdisk.RamdiskDeploy.prepare', autospec=True) - def test__do_adoption_with_netboot(self, - mock_prepare, - mock_take_over, - mock_start_console, - mock_boot_validate, - mock_power_validate, - mock_validate_href): + def test__do_adoption_ramdisk_deploy(self, + mock_prepare, + mock_take_over, + mock_start_console, + mock_boot_validate, + mock_power_validate, + mock_validate_href): """Test a successful node adoption""" self._start_service() node = obj_utils.create_test_node( self.context, driver='fake-hardware', - provision_state=states.ADOPTING, - instance_info={ - 'capabilities': {'boot_option': 'netboot'}, - 'image_source': 'http://127.0.0.1/image', - }) + deploy_interface='ramdisk', + provision_state=states.ADOPTING) task = task_manager.TaskManager(self.context, node.uuid) self.service._do_adoption(task) @@ -7360,10 +7356,6 @@ class DoNodeAdoptionTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): mock_take_over.assert_called_once_with(task.driver.deploy, task) self.assertFalse(mock_start_console.called) mock_boot_validate.assert_called_once_with(task.driver.boot, task) - self.assertTrue(task.node.driver_internal_info.get( - 'is_whole_disk_image')) - mock_validate_href.assert_called_once_with(mock.ANY, - 'http://127.0.0.1/image') @mock.patch('ironic.drivers.modules.fake.FakeBoot.validate', autospec=True) @mock.patch('ironic.drivers.modules.fake.FakeConsole.start_console', @@ -7410,9 +7402,9 @@ class DoNodeAdoptionTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): @mock.patch('ironic.drivers.modules.fake.FakeBoot.validate', autospec=True) @mock.patch('ironic.drivers.modules.fake.FakeConsole.start_console', autospec=True) - @mock.patch('ironic.drivers.modules.fake.FakeDeploy.take_over', + @mock.patch('ironic.drivers.modules.ramdisk.RamdiskDeploy.take_over', autospec=True) - @mock.patch('ironic.drivers.modules.fake.FakeDeploy.prepare', + @mock.patch('ironic.drivers.modules.ramdisk.RamdiskDeploy.prepare', autospec=True) def test__do_adoption_boot_validate_failure(self, mock_prepare, @@ -7428,10 +7420,8 @@ class DoNodeAdoptionTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase): self._start_service() node = obj_utils.create_test_node( self.context, driver='fake-hardware', - provision_state=states.ADOPTING, - instance_info={ - 'capabilities': {'boot_option': 'netboot'}, - }) + deploy_interface='ramdisk', + provision_state=states.ADOPTING) task = task_manager.TaskManager(self.context, node.uuid) self.service._do_adoption(task) diff --git a/ironic/tests/unit/drivers/boot-fallback.ipxe b/ironic/tests/unit/drivers/boot-fallback.ipxe index bf8ab414c..ada2646a6 100644 --- a/ironic/tests/unit/drivers/boot-fallback.ipxe +++ b/ironic/tests/unit/drivers/boot-fallback.ipxe @@ -10,6 +10,12 @@ isset ${net${netid}/mac} || goto loop_done echo Attempting to boot from MAC ${net${netid}/mac:hexhyp} chain pxelinux.cfg/${net${netid}/mac:hexhyp} || goto loop +# If we've got here the chained config returned success +# suggesting "sanboot" in boot_whole_disk failed (some UEFI cases) +# exit 0 so the bios continues to the next device +echo Exiting pxe config to allow boot to continue on next device +exit 0 + :loop_done chain inspector.ipxe | goto boot_failed diff --git a/ironic/tests/unit/drivers/boot.ipxe b/ironic/tests/unit/drivers/boot.ipxe index aa8ee9e51..006bcb4aa 100644 --- a/ironic/tests/unit/drivers/boot.ipxe +++ b/ironic/tests/unit/drivers/boot.ipxe @@ -10,6 +10,12 @@ isset ${net${netid}/mac} || goto loop_done echo Attempting to boot from MAC ${net${netid}/mac:hexhyp} chain pxelinux.cfg/${net${netid}/mac:hexhyp} || goto loop +# If we've got here the chained config returned success +# suggesting "sanboot" in boot_whole_disk failed (some UEFI cases) +# exit 0 so the bios continues to the next device +echo Exiting pxe config to allow boot to continue on next device +exit 0 + :loop_done echo PXE boot failed! No configuration found for any of the present NICs. echo Press any key to reboot... diff --git a/ironic/tests/unit/drivers/ipxe_config.template b/ironic/tests/unit/drivers/ipxe_config.template index 70f8a03f1..3005a73d1 100644 --- a/ironic/tests/unit/drivers/ipxe_config.template +++ b/ironic/tests/unit/drivers/ipxe_config.template @@ -25,12 +25,6 @@ echo Powering off in 30 seconds. sleep 30 poweroff -:boot_partition -imgfree -kernel http://1.2.3.4:1234/kernel root={{ ROOT }} ro text test_param initrd=ramdisk || goto boot_partition -initrd http://1.2.3.4:1234/ramdisk || goto boot_partition -boot - :boot_anaconda imgfree kernel http://1.2.3.4:1234/kernel text test_param inst.ks=http://fake/ks.cfg inst.stage2=http://fake/stage2 initrd=ramdisk || goto boot_anaconda @@ -44,4 +38,4 @@ initrd http://1.2.3.4:1234/ramdisk || goto boot_ramdisk boot :boot_whole_disk -sanboot --no-describe +sanboot --no-describe || exit 0 diff --git a/ironic/tests/unit/drivers/ipxe_config_boot_from_anaconda.template b/ironic/tests/unit/drivers/ipxe_config_boot_from_anaconda.template index 7963b3883..0c2812e85 100644 --- a/ironic/tests/unit/drivers/ipxe_config_boot_from_anaconda.template +++ b/ironic/tests/unit/drivers/ipxe_config_boot_from_anaconda.template @@ -25,12 +25,6 @@ echo Powering off in 30 seconds. sleep 30 poweroff -:boot_partition -imgfree -kernel http://1.2.3.4:1234/kernel root={{ ROOT }} ro text test_param initrd=ramdisk || goto boot_partition -initrd http://1.2.3.4:1234/ramdisk || goto boot_partition -boot - :boot_anaconda imgfree kernel http://1.2.3.4:1234/kernel text test_param inst.ks=http://fake/ks.cfg inst.repo=http://1.2.3.4/path/to/os/ initrd=ramdisk || goto boot_anaconda @@ -44,4 +38,4 @@ initrd http://1.2.3.4:1234/ramdisk || goto boot_ramdisk boot :boot_whole_disk -sanboot --no-describe +sanboot --no-describe || exit 0 diff --git a/ironic/tests/unit/drivers/ipxe_config_boot_from_iso.template b/ironic/tests/unit/drivers/ipxe_config_boot_from_iso.template index c7133c7b6..9c889854d 100644 --- a/ironic/tests/unit/drivers/ipxe_config_boot_from_iso.template +++ b/ironic/tests/unit/drivers/ipxe_config_boot_from_iso.template @@ -25,12 +25,6 @@ echo Powering off in 30 seconds. sleep 30 poweroff -:boot_partition -imgfree -kernel http://1.2.3.4:1234/kernel root={{ ROOT }} ro text test_param initrd=ramdisk || goto boot_partition -initrd http://1.2.3.4:1234/ramdisk || goto boot_partition -boot - :boot_anaconda imgfree kernel http://1.2.3.4:1234/kernel text test_param inst.ks=http://fake/ks.cfg inst.stage2=http://fake/stage2 initrd=ramdisk || goto boot_anaconda @@ -42,4 +36,4 @@ imgfree sanboot http://1.2.3.4:1234/uuid/iso :boot_whole_disk -sanboot --no-describe +sanboot --no-describe || exit 0 diff --git a/ironic/tests/unit/drivers/ipxe_config_boot_from_ramdisk.template b/ironic/tests/unit/drivers/ipxe_config_boot_from_ramdisk.template index 70f8a03f1..3005a73d1 100644 --- a/ironic/tests/unit/drivers/ipxe_config_boot_from_ramdisk.template +++ b/ironic/tests/unit/drivers/ipxe_config_boot_from_ramdisk.template @@ -25,12 +25,6 @@ echo Powering off in 30 seconds. sleep 30 poweroff -:boot_partition -imgfree -kernel http://1.2.3.4:1234/kernel root={{ ROOT }} ro text test_param initrd=ramdisk || goto boot_partition -initrd http://1.2.3.4:1234/ramdisk || goto boot_partition -boot - :boot_anaconda imgfree kernel http://1.2.3.4:1234/kernel text test_param inst.ks=http://fake/ks.cfg inst.stage2=http://fake/stage2 initrd=ramdisk || goto boot_anaconda @@ -44,4 +38,4 @@ initrd http://1.2.3.4:1234/ramdisk || goto boot_ramdisk boot :boot_whole_disk -sanboot --no-describe +sanboot --no-describe || exit 0 diff --git a/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_extra_volume.template b/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_extra_volume.template index 0a872804a..ee619b53e 100644 --- a/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_extra_volume.template +++ b/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_extra_volume.template @@ -25,12 +25,6 @@ echo Powering off in 30 seconds. sleep 30 poweroff -:boot_partition -imgfree -kernel http://1.2.3.4:1234/kernel root={{ ROOT }} ro text test_param initrd=ramdisk || goto boot_partition -initrd http://1.2.3.4:1234/ramdisk || goto boot_partition -boot - :boot_anaconda imgfree kernel http://1.2.3.4:1234/kernel text test_param inst.ks=http://fake/ks.cfg inst.stage2=http://fake/stage2 initrd=ramdisk || goto boot_anaconda @@ -62,4 +56,4 @@ sleep 10 goto boot_iscsi :boot_whole_disk -sanboot --no-describe +sanboot --no-describe || exit 0 diff --git a/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_multipath.template b/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_multipath.template index 571216e39..ede0283c6 100644 --- a/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_multipath.template +++ b/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_multipath.template @@ -25,12 +25,6 @@ echo Powering off in 30 seconds. sleep 30 poweroff -:boot_partition -imgfree -kernel http://1.2.3.4:1234/kernel root={{ ROOT }} ro text test_param initrd=ramdisk || goto boot_partition -initrd http://1.2.3.4:1234/ramdisk || goto boot_partition -boot - :boot_anaconda imgfree kernel http://1.2.3.4:1234/kernel text test_param inst.ks=http://fake/ks.cfg inst.stage2=http://fake/stage2 initrd=ramdisk || goto boot_anaconda @@ -59,4 +53,4 @@ sleep 10 goto boot_iscsi :boot_whole_disk -sanboot --no-describe +sanboot --no-describe || exit 0 diff --git a/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_no_extra_volumes.template b/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_no_extra_volumes.template index 6b7a4394d..61fbec756 100644 --- a/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_no_extra_volumes.template +++ b/ironic/tests/unit/drivers/ipxe_config_boot_from_volume_no_extra_volumes.template @@ -25,12 +25,6 @@ echo Powering off in 30 seconds. sleep 30 poweroff -:boot_partition -imgfree -kernel http://1.2.3.4:1234/kernel root={{ ROOT }} ro text test_param initrd=ramdisk || goto boot_partition -initrd http://1.2.3.4:1234/ramdisk || goto boot_partition -boot - :boot_anaconda imgfree kernel http://1.2.3.4:1234/kernel text test_param inst.ks=http://fake/ks.cfg inst.stage2=http://fake/stage2 initrd=ramdisk || goto boot_anaconda @@ -59,4 +53,4 @@ sleep 10 goto boot_iscsi :boot_whole_disk -sanboot --no-describe +sanboot --no-describe || exit 0 diff --git a/ironic/tests/unit/drivers/ipxe_config_timeout.template b/ironic/tests/unit/drivers/ipxe_config_timeout.template index 2458f010b..af00f5490 100644 --- a/ironic/tests/unit/drivers/ipxe_config_timeout.template +++ b/ironic/tests/unit/drivers/ipxe_config_timeout.template @@ -25,12 +25,6 @@ echo Powering off in 30 seconds. sleep 30 poweroff -:boot_partition -imgfree -kernel --timeout 120 http://1.2.3.4:1234/kernel root={{ ROOT }} ro text test_param initrd=ramdisk || goto boot_partition -initrd --timeout 120 http://1.2.3.4:1234/ramdisk || goto boot_partition -boot - :boot_anaconda imgfree kernel --timeout 120 http://1.2.3.4:1234/kernel text test_param inst.ks=http://fake/ks.cfg inst.stage2=http://fake/stage2 initrd=ramdisk || goto boot_anaconda @@ -44,4 +38,4 @@ initrd --timeout 120 http://1.2.3.4:1234/ramdisk || goto boot_ramdisk boot :boot_whole_disk -sanboot --no-describe +sanboot --no-describe || exit 0 diff --git a/ironic/tests/unit/drivers/modules/ansible/test_deploy.py b/ironic/tests/unit/drivers/modules/ansible/test_deploy.py index ed9199575..3f295c4d9 100644 --- a/ironic/tests/unit/drivers/modules/ansible/test_deploy.py +++ b/ironic/tests/unit/drivers/modules/ansible/test_deploy.py @@ -623,24 +623,6 @@ class TestAnsibleDeploy(AnsibleDeployTestCaseBase): {'instance_info.image_source': INSTANCE_INFO['image_source']}, mock.ANY) - @mock.patch.object(deploy_utils, 'get_boot_option', - return_value='netboot', autospec=True) - @mock.patch.object(pxe.PXEBoot, 'validate', autospec=True) - def test_validate_not_iwdi_netboot(self, pxe_boot_validate_mock, - get_boot_mock): - driver_internal_info = dict(DRIVER_INTERNAL_INFO) - driver_internal_info['is_whole_disk_image'] = False - self.node.driver_internal_info = driver_internal_info - self.node.save() - - with task_manager.acquire( - self.context, self.node['uuid'], shared=False) as task: - self.assertRaises(exception.InvalidParameterValue, - self.driver.validate, task) - pxe_boot_validate_mock.assert_called_once_with( - task.driver.boot, task) - get_boot_mock.assert_called_once_with(task.node) - @mock.patch.object(ansible_deploy, '_calculate_memory_req', autospec=True, return_value=2000) @mock.patch.object(utils, 'node_power_action', autospec=True) diff --git a/ironic/tests/unit/drivers/modules/ilo/test_boot.py b/ironic/tests/unit/drivers/modules/ilo/test_boot.py index 128f603c5..8aa6f78da 100644 --- a/ironic/tests/unit/drivers/modules/ilo/test_boot.py +++ b/ironic/tests/unit/drivers/modules/ilo/test_boot.py @@ -116,9 +116,9 @@ class IloBootCommonMethodsTestCase(test_common.BaseIloTest): self.assertEqual(expected_driver_info, actual_driver_info) def test_parse_driver_info_deploy_config(self): - CONF.conductor.deploy_kernel = 'kernel' - CONF.conductor.deploy_ramdisk = 'ramdisk' - CONF.conductor.bootloader = 'bootloader' + CONF.set_override('deploy_kernel', 'kernel', 'conductor') + CONF.set_override('deploy_ramdisk', 'ramdisk', 'conductor') + CONF.set_override('bootloader', 'bootloader', 'conductor') expected_driver_info = {'deploy_kernel': 'kernel', 'deploy_ramdisk': 'ramdisk', 'bootloader': 'bootloader', @@ -128,10 +128,9 @@ class IloBootCommonMethodsTestCase(test_common.BaseIloTest): self.assertEqual(expected_driver_info, actual_driver_info) def test_parse_driver_info_rescue_config(self): - CONF.conductor.rescue_kernel = 'kernel' - CONF.conductor.rescue_ramdisk = 'ramdisk' - CONF.conductor.bootloader = 'bootloader' - + CONF.set_override('rescue_kernel', 'kernel', 'conductor') + CONF.set_override('rescue_ramdisk', 'ramdisk', 'conductor') + CONF.set_override('bootloader', 'bootloader', 'conductor') expected_driver_info = {'rescue_kernel': 'kernel', 'rescue_ramdisk': 'ramdisk', 'bootloader': 'bootloader', @@ -141,9 +140,8 @@ class IloBootCommonMethodsTestCase(test_common.BaseIloTest): self.assertEqual(expected_driver_info, actual_driver_info) def test_parse_driver_info_bootloader_none(self): - CONF.conductor.deploy_kernel = 'kernel' - CONF.conductor.deploy_ramdisk = 'ramdisk' - + CONF.set_override('deploy_kernel', 'kernel', 'conductor') + CONF.set_override('deploy_ramdisk', 'ramdisk', 'conductor') self.assertRaisesRegex(exception.MissingParameterValue, 'bootloader', ilo_boot.parse_driver_info, self.node) @@ -452,14 +450,14 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest): spec_set=True, autospec=True) @mock.patch.object(service_utils, 'is_glance_image', spec_set=True, autospec=True) - def test_validate_ramdisk_boot_option_glance(self, is_glance_image_mock, - validate_href_mock, - val_driver_info_mock): + def test_validate_ramdisk_deploy_glance(self, is_glance_image_mock, + validate_href_mock, + val_driver_info_mock): instance_info = self.node.instance_info boot_iso = '6b2f0c0c-79e8-4db6-842e-43c9764204af' instance_info['boot_iso'] = boot_iso - instance_info['capabilities'] = '{"boot_option": "ramdisk"}' self.node.instance_info = instance_info + self.node.deploy_interface = 'ramdisk' self.node.save() with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: @@ -475,14 +473,14 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest): spec_set=True, autospec=True) @mock.patch.object(service_utils, 'is_glance_image', spec_set=True, autospec=True) - def test_validate_ramdisk_boot_option_webserver(self, is_glance_image_mock, - validate_href_mock, - val_driver_info_mock): + def test_validate_ramdisk_deploy_webserver(self, is_glance_image_mock, + validate_href_mock, + val_driver_info_mock): instance_info = self.node.instance_info boot_iso = 'http://myserver/boot.iso' instance_info['boot_iso'] = boot_iso - instance_info['capabilities'] = '{"boot_option": "ramdisk"}' self.node.instance_info = instance_info + self.node.deploy_interface = 'ramdisk' self.node.save() with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: @@ -499,18 +497,18 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest): spec_set=True, autospec=True) @mock.patch.object(service_utils, 'is_glance_image', spec_set=True, autospec=True) - def test_validate_ramdisk_boot_option_webserver_exc(self, - is_glance_image_mock, - validate_href_mock, - val_driver_info_mock, - log_mock): + def test_validate_ramdisk_deploy_webserver_exc(self, + is_glance_image_mock, + validate_href_mock, + val_driver_info_mock, + log_mock): instance_info = self.node.instance_info validate_href_mock.side_effect = exception.ImageRefValidationFailed( image_href='http://myserver/boot.iso', reason='fail') boot_iso = 'http://myserver/boot.iso' instance_info['boot_iso'] = boot_iso - instance_info['capabilities'] = '{"boot_option": "ramdisk"}' self.node.instance_info = instance_info + self.node.deploy_interface = 'ramdisk' self.node.save() with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: @@ -523,7 +521,7 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest): is_glance_image_mock.assert_called_once_with(boot_iso) validate_href_mock.assert_called_once_with(mock.ANY, boot_iso) self.assertFalse(val_driver_info_mock.called) - self.assertIn("Virtual media deploy with 'ramdisk' boot_option " + self.assertIn("Virtual media deploy with 'ramdisk' deploy " "accepts only Glance images or HTTP(S) URLs as " "instance_info['boot_iso'].", log_mock.call_args[0][0]) @@ -857,7 +855,7 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest): autospec=True) @mock.patch.object(ilo_common, 'cleanup_vmedia_boot', spec_set=True, autospec=True) - def _test_prepare_instance_whole_disk_image( + def test_prepare_instance_whole_disk_image( self, cleanup_vmedia_boot_mock, set_boot_device_mock, update_boot_mode_mock, update_secure_boot_mode_mock, is_iscsi_boot_mock): @@ -877,41 +875,31 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest): self.assertIsNone(task.node.driver_internal_info.get( 'ilo_uefi_iscsi_boot')) - def test_prepare_instance_whole_disk_image_local(self): - self.node.instance_info = {'capabilities': '{"boot_option": "local"}'} - self.node.save() - self._test_prepare_instance_whole_disk_image() - - def test_prepare_instance_whole_disk_image(self): - self._test_prepare_instance_whole_disk_image() - @mock.patch.object(deploy_utils, 'is_iscsi_boot', spec_set=True, autospec=True) @mock.patch.object(boot_mode_utils, 'configure_secure_boot_if_needed', spec_set=True, autospec=True) @mock.patch.object(ilo_common, 'update_boot_mode', spec_set=True, autospec=True) - @mock.patch.object(ilo_boot.IloVirtualMediaBoot, - '_configure_vmedia_boot', spec_set=True, + @mock.patch.object(manager_utils, 'node_set_boot_device', spec_set=True, autospec=True) @mock.patch.object(ilo_common, 'cleanup_vmedia_boot', spec_set=True, autospec=True) def test_prepare_instance_partition_image( - self, cleanup_vmedia_boot_mock, configure_vmedia_mock, + self, cleanup_vmedia_boot_mock, set_boot_device_mock, update_boot_mode_mock, update_secure_boot_mode_mock, is_iscsi_boot_mock): self.node.driver_internal_info = {'root_uuid_or_disk_id': ( "12312642-09d3-467f-8e09-12385826a123")} - self.node.instance_info = { - 'capabilities': {'boot_option': 'netboot'}} self.node.save() is_iscsi_boot_mock.return_value = False with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: task.driver.boot.prepare_instance(task) cleanup_vmedia_boot_mock.assert_called_once_with(task) - configure_vmedia_mock.assert_called_once_with( - mock.ANY, task, "12312642-09d3-467f-8e09-12385826a123") + set_boot_device_mock.assert_called_once_with(task, + boot_devices.DISK, + persistent=True) update_boot_mode_mock.assert_called_once_with(task) update_secure_boot_mode_mock.assert_called_once_with(task) self.assertIsNone(task.node.driver_internal_info.get( @@ -998,9 +986,7 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest): cleanup_vmedia_boot_mock): with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: - instance_info = task.node.instance_info - instance_info['capabilities'] = '{"boot_option": "ramdisk"}' - task.node.instance_info = instance_info + task.node.deploy_interface = 'ramdisk' task.node.save() is_iscsi_boot_mock.return_value = False url = 'http://myserver/boot.iso' @@ -1377,7 +1363,7 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase): self.config(enabled_hardware_types=['ilo5'], enabled_boot_interfaces=['ilo-uefi-https'], enabled_console_interfaces=['ilo'], - enabled_deploy_interfaces=['direct'], + enabled_deploy_interfaces=['direct', 'ramdisk'], enabled_inspect_interfaces=['ilo'], enabled_management_interfaces=['ilo5'], enabled_power_interfaces=['ilo'], @@ -1653,16 +1639,16 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase): spec_set=True, autospec=True) @mock.patch.object(service_utils, 'is_glance_image', spec_set=True, autospec=True) - def test_validate_ramdisk_boot_option_glance(self, is_glance_image_mock, - validate_href_mock, - val_driver_info_mock, - get_boot_mock): + def test_validate_ramdisk_deploy_glance(self, is_glance_image_mock, + validate_href_mock, + val_driver_info_mock, + get_boot_mock): get_boot_mock.return_value = 'UEFI' instance_info = self.node.instance_info boot_iso = '6b2f0c0c-79e8-4db6-842e-43c9764204af' instance_info['boot_iso'] = boot_iso - instance_info['capabilities'] = '{"boot_option": "ramdisk"}' self.node.instance_info = instance_info + self.node.deploy_interface = 'ramdisk' self.node.save() with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: @@ -1680,16 +1666,16 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase): spec_set=True, autospec=True) @mock.patch.object(service_utils, 'is_glance_image', spec_set=True, autospec=True) - def test_validate_ramdisk_boot_option_webserver(self, is_glance_image_mock, - validate_href_mock, - val_driver_info_mock, - get_boot_mock): + def test_validate_ramdisk_deploy_webserver(self, is_glance_image_mock, + validate_href_mock, + val_driver_info_mock, + get_boot_mock): get_boot_mock.return_value = 'UEFI' instance_info = self.node.instance_info boot_iso = 'http://myserver/boot.iso' instance_info['boot_iso'] = boot_iso - instance_info['capabilities'] = '{"boot_option": "ramdisk"}' self.node.instance_info = instance_info + self.node.deploy_interface = 'ramdisk' self.node.save() with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: @@ -1708,7 +1694,7 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase): spec_set=True, autospec=True) @mock.patch.object(service_utils, 'is_glance_image', spec_set=True, autospec=True) - def test_validate_ramdisk_boot_option_webserver_exc( + def test_validate_ramdisk_deploy_webserver_exc( self, is_glance_image_mock, validate_href_mock, val_driver_info_mock, log_mock, get_boot_mock): @@ -1718,8 +1704,8 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase): image_href='http://myserver/boot.iso', reason='fail') boot_iso = 'http://myserver/boot.iso' instance_info['boot_iso'] = boot_iso - instance_info['capabilities'] = '{"boot_option": "ramdisk"}' self.node.instance_info = instance_info + self.node.deploy_interface = 'ramdisk' self.node.save() with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: @@ -1732,7 +1718,7 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase): is_glance_image_mock.assert_called_once_with(boot_iso) validate_href_mock.assert_called_once_with(mock.ANY, boot_iso) self.assertFalse(val_driver_info_mock.called) - self.assertIn("UEFI-HTTPS boot with 'ramdisk' boot_option " + self.assertIn("UEFI-HTTPS boot with 'ramdisk' deploy " "accepts only Glance images or HTTPS URLs as " "instance_info['boot_iso'].", log_mock.call_args[0][0]) @@ -1902,7 +1888,7 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase): spec_set=True, autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', spec_set=True, autospec=True) - def _test_prepare_instance_local_or_whole_disk_image( + def test_prepare_instance_local_or_whole_disk_image( self, set_boot_device_mock, parse_deploy_mock, prepare_iso_mock, setup_uefi_https_mock, cleanup_iso_mock, update_secureboot_mock): @@ -1919,16 +1905,6 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase): prepare_iso_mock.assert_not_called() setup_uefi_https_mock.assert_not_called() - def test_prepare_instance_image_local(self): - self.node.instance_info = {'capabilities': '{"boot_option": "local"}'} - self.node.save() - self._test_prepare_instance_local_or_whole_disk_image() - - def test_prepare_instance_whole_disk_image(self): - self.node.driver_internal_info = {'is_whole_disk_image': True} - self.node.save() - self._test_prepare_instance_local_or_whole_disk_image() - @mock.patch.object(boot_mode_utils, 'configure_secure_boot_if_needed', spec_set=True, autospec=True) @mock.patch.object(image_utils, 'cleanup_iso_image', spec_set=True, @@ -1937,41 +1913,30 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase): spec_set=True, autospec=True) @mock.patch.object(image_utils, 'prepare_boot_iso', spec_set=True, autospec=True) - @mock.patch.object(ilo_boot.IloUefiHttpsBoot, '_parse_deploy_info', - spec_set=True, autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', spec_set=True, autospec=True) def test_prepare_instance_partition_image( self, set_boot_device_mock, - parse_deploy_mock, prepare_iso_mock, setup_uefi_https_mock, + prepare_iso_mock, setup_uefi_https_mock, cleanup_iso_mock, update_secureboot_mock): - self.node.instance_info = { - 'capabilities': '{"boot_option": "netboot"}' - } self.node.driver_internal_info = { 'root_uuid_or_disk_id': ( "12312642-09d3-467f-8e09-12385826a123") } self.node.driver_internal_info.update({'is_whole_disk_image': False}) self.node.save() - d_info = {'a': 'x', 'b': 'y'} - parse_deploy_mock.return_value = d_info - prepare_iso_mock.return_value = "recreated-iso" with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: task.driver.boot.prepare_instance(task) cleanup_iso_mock.assert_called_once_with(task) - set_boot_device_mock.assert_not_called() - parse_deploy_mock.assert_called_once_with(mock.ANY, task.node) - prepare_iso_mock.assert_called_once_with( - task, d_info, root_uuid='12312642-09d3-467f-8e09-12385826a123') + set_boot_device_mock.assert_called_once_with(task, + boot_devices.DISK, + persistent=True) + prepare_iso_mock.assert_not_called() update_secureboot_mock.assert_called_once_with(task) - setup_uefi_https_mock.assert_called_once_with( - task, "recreated-iso", True) - self.assertEqual(task.node.instance_info['boot_iso'], - "recreated-iso") + setup_uefi_https_mock.assert_not_called() @mock.patch.object(boot_mode_utils, 'configure_secure_boot_if_needed', spec_set=True, autospec=True) @@ -1998,9 +1963,7 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase): with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: - instance_info = task.node.instance_info - instance_info['capabilities'] = '{"boot_option": "ramdisk"}' - task.node.instance_info = instance_info + task.node.deploy_interface = 'ramdisk' task.node.save() task.driver.boot.prepare_instance(task) diff --git a/ironic/tests/unit/drivers/modules/ilo/test_common.py b/ironic/tests/unit/drivers/modules/ilo/test_common.py index 605124b69..352eb0837 100644 --- a/ironic/tests/unit/drivers/modules/ilo/test_common.py +++ b/ironic/tests/unit/drivers/modules/ilo/test_common.py @@ -434,8 +434,8 @@ class IloCommonMethodsTestCase(BaseIloTest): tempfile_mock.return_value = mock_image_file_handle self.config(use_web_server_for_images=True, group='ilo') deploy_args = {'arg1': 'val1', 'arg2': 'val2'} - CONF.deploy.http_url = "http://abc.com/httpboot" - CONF.deploy.http_root = "/httpboot" + CONF.set_override('http_url', 'http://abc.com/httpboot', 'deploy') + CONF.set_override('http_root', '/httpboot', 'deploy') with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: @@ -676,8 +676,8 @@ class IloCommonMethodsTestCase(BaseIloTest): swift_obj_mock = swift_api_mock.return_value boot_iso = 'swift:object-name' swift_obj_mock.get_temp_url.return_value = 'image_url' - CONF.ilo.swift_ilo_container = 'ilo_cont' - CONF.ilo.swift_object_expiry_timeout = 1 + CONF.set_override('swift_ilo_container', 'ilo_cont', 'ilo') + CONF.set_override('swift_object_expiry_timeout', 1, 'ilo') with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: ilo_common.setup_vmedia_for_boot(task, boot_iso) @@ -704,7 +704,7 @@ class IloCommonMethodsTestCase(BaseIloTest): def test_cleanup_vmedia_boot(self, get_name_mock, swift_api_mock, eject_mock): swift_obj_mock = swift_api_mock.return_value - CONF.ilo.swift_ilo_container = 'ilo_cont' + CONF.set_override('swift_ilo_container', 'ilo_cont', 'ilo') get_name_mock.return_value = 'image-node-uuid' @@ -727,7 +727,7 @@ class IloCommonMethodsTestCase(BaseIloTest): exc = exception.SwiftOperationError('error') swift_obj_mock = swift_api_mock.return_value swift_obj_mock.delete_object.side_effect = exc - CONF.ilo.swift_ilo_container = 'ilo_cont' + CONF.set_override('swift_ilo_container', 'ilo_cont', 'ilo') get_name_mock.return_value = 'image-node-uuid' @@ -752,7 +752,7 @@ class IloCommonMethodsTestCase(BaseIloTest): exc = exception.SwiftObjectNotFoundError('error') swift_obj_mock = swift_api_mock.return_value swift_obj_mock.delete_object.side_effect = exc - CONF.ilo.swift_ilo_container = 'ilo_cont' + CONF.set_override('swift_ilo_container', 'ilo_cont', 'ilo') get_name_mock.return_value = 'image-node-uuid' @@ -771,7 +771,7 @@ class IloCommonMethodsTestCase(BaseIloTest): def test_cleanup_vmedia_boot_for_webserver(self, destroy_image_mock, eject_mock): - CONF.ilo.use_web_server_for_images = True + CONF.set_override('use_web_server_for_images', True, 'ilo') with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: @@ -932,8 +932,8 @@ class IloCommonMethodsTestCase(BaseIloTest): autospec=True) def test_copy_image_to_web_server(self, copy_mock, chmod_mock): - CONF.deploy.http_url = "http://x.y.z.a/webserver/" - CONF.deploy.http_root = "/webserver" + CONF.set_override('http_url', 'http://x.y.z.a/webserver/', 'deploy') + CONF.set_override('http_root', '/webserver', 'deploy') expected_url = "http://x.y.z.a/webserver/image-UUID" source = 'tmp_image_file' destination = "image-UUID" @@ -949,8 +949,8 @@ class IloCommonMethodsTestCase(BaseIloTest): autospec=True) def test_copy_image_to_web_server_fails(self, copy_mock, chmod_mock): - CONF.deploy.http_url = "http://x.y.z.a/webserver/" - CONF.deploy.http_root = "/webserver" + CONF.set_override('http_url', 'http://x.y.z.a/webserver/', 'deploy') + CONF.set_override('http_root', '/webserver', 'deploy') source = 'tmp_image_file' destination = "image-UUID" image_path = "/webserver/image-UUID" @@ -965,8 +965,8 @@ class IloCommonMethodsTestCase(BaseIloTest): @mock.patch.object(ilo_common, 'ironic_utils', autospec=True) def test_remove_image_from_web_server(self, utils_mock): # | GIVEN | - CONF.deploy.http_url = "http://x.y.z.a/webserver/" - CONF.deploy.http_root = "/webserver" + CONF.set_override('http_url', 'http://x.y.z.a/webserver/', 'deploy') + CONF.set_override('http_root', '/webserver', 'deploy') object_name = 'tmp_image_file' # | WHEN | ilo_common.remove_image_from_web_server(object_name) @@ -1076,7 +1076,7 @@ class IloCommonMethodsTestCase(BaseIloTest): def test_destroy_floppy_image_from_web_server(self, get_floppy_name_mock, utils_mock): get_floppy_name_mock.return_value = 'image-uuid' - CONF.deploy.http_root = "/webserver/" + CONF.set_override('http_root', '/webserver/', 'deploy') with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: ilo_common.destroy_floppy_image_from_web_server(task.node) @@ -1220,7 +1220,7 @@ class IloCommonMethodsTestCase(BaseIloTest): autospec=True) def test__get_certificate_file_list_none(self, path_exists_mock): cl = None - CONF.webserver_verify_ca = '/file/path' + CONF.set_override('webserver_verify_ca', '/file/path') path_exists_mock.return_value = True expected = ['/file/path'] actual = ilo_common._get_certificate_file_list(cl) @@ -1230,7 +1230,7 @@ class IloCommonMethodsTestCase(BaseIloTest): autospec=True) def test__get_certificate_file_list_empty(self, path_exists_mock): cl = [] - CONF.webserver_verify_ca = '/file/path' + CONF.set_override('webserver_verify_ca', '/file/path') path_exists_mock.return_value = True expected = ['/file/path'] actual = ilo_common._get_certificate_file_list(cl) @@ -1240,7 +1240,7 @@ class IloCommonMethodsTestCase(BaseIloTest): autospec=True) def test__get_certificate_file_list_empty_no_path(self, path_exists_mock): cl = [] - CONF.webserver_verify_ca = '/file/path' + CONF.set_override('webserver_verify_ca', '/file/path') path_exists_mock.return_value = False expected = [] actual = ilo_common._get_certificate_file_list(cl) @@ -1248,14 +1248,14 @@ class IloCommonMethodsTestCase(BaseIloTest): def test__get_certificate_file_list(self): cl = ['file/path/a', 'file/path/b'] - CONF.webserver_verify_ca = '/file/path/c' + CONF.set_override('webserver_verify_ca', '/file/path/c') expected = cl actual = ilo_common._get_certificate_file_list(cl) self.assertEqual(expected, actual) def test__get_certificate_file_list_string_type(self): cl = 'file/path/a' - CONF.webserver_verify_ca = '/file/path/c' + CONF.set_override('webserver_verify_ca', '/file/path/c') self.assertRaisesRegex(exception.InvalidParameterValue, "List of files is .* \"<class 'str'>\" .*", ilo_common._get_certificate_file_list, cl) @@ -1355,7 +1355,7 @@ class IloCommonMethodsTestCase(BaseIloTest): autospec=True) def test_add_certificates_raises_ilo_error(self, get_ilo_object_mock, get_cl_mock): - CONF.webserver_verify_ca = False + CONF.set_override('webserver_verify_ca', False) ilo_mock_object = get_ilo_object_mock.return_value c_l = ['/file/path/a', '/file/path/b'] get_cl_mock.return_value = c_l diff --git a/ironic/tests/unit/drivers/modules/irmc/test_boot.py b/ironic/tests/unit/drivers/modules/irmc/test_boot.py index 1822b9965..cd367cef0 100644 --- a/ironic/tests/unit/drivers/modules/irmc/test_boot.py +++ b/ironic/tests/unit/drivers/modules/irmc/test_boot.py @@ -74,13 +74,14 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): def setUp(self): super(IRMCDeployPrivateMethodsTestCase, self).setUp() - CONF.irmc.remote_image_share_root = '/remote_image_share_root' - CONF.irmc.remote_image_server = '10.20.30.40' - CONF.irmc.remote_image_share_type = 'NFS' - CONF.irmc.remote_image_share_name = 'share' - CONF.irmc.remote_image_user_name = 'admin' - CONF.irmc.remote_image_user_password = 'admin0' - CONF.irmc.remote_image_user_domain = 'local' + CONF.set_override('remote_image_share_root', + '/remote_image_share_root', 'irmc') + CONF.set_override('remote_image_server', '10.20.30.40', 'irmc') + CONF.set_override('remote_image_share_type', 'NFS', 'irmc') + CONF.set_override('remote_image_share_name', 'share', 'irmc') + CONF.set_override('remote_image_user_name', 'admin', 'irmc') + CONF.set_override('remote_image_user_password', 'admin0', 'irmc') + CONF.set_override('remote_image_user_domain', 'local', 'irmc') @mock.patch.object(os.path, 'isdir', spec_set=True, autospec=True) def test__parse_config_option(self, isdir_mock, @@ -95,7 +96,8 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): @mock.patch.object(os.path, 'isdir', spec_set=True, autospec=True) def test__parse_config_option_non_existed_root( self, isdir_mock, check_share_fs_mounted_mock): - CONF.irmc.remote_image_share_root = '/non_existed_root' + CONF.set_override('remote_image_share_root', '/non_existed_root', + 'irmc') isdir_mock.return_value = False self.assertRaises(exception.InvalidParameterValue, @@ -248,7 +250,7 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): def test__parse_instance_info_with_boot_iso_file_name_ok( self, check_share_fs_mounted_mock): """With optional 'boot_iso' file name.""" - CONF.irmc.remote_image_share_root = '/etc' + CONF.set_override('remote_image_share_root', '/etc', 'irmc') self.node.instance_info['boot_iso'] = 'hosts' instance_info_expected = {'boot_iso': 'hosts'} instance_info_actual = irmc_boot._parse_instance_info(self.node) @@ -258,7 +260,7 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): def test__parse_instance_info_with_boot_iso_deprecated( self, check_share_fs_mounted_mock): """With optional 'irmc_boot_iso' file name.""" - CONF.irmc.remote_image_share_root = '/etc' + CONF.set_override('remote_image_share_root', '/etc', 'irmc') self.node.instance_info['irmc_boot_iso'] = 'hosts' instance_info_expected = {'boot_iso': 'hosts'} instance_info_actual = irmc_boot._parse_instance_info(self.node) @@ -268,7 +270,7 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): def test__parse_instance_info_without_boot_iso_ok( self, check_share_fs_mounted_mock): """With optional no 'boot_iso' file name.""" - CONF.irmc.remote_image_share_root = '/etc' + CONF.set_override('remote_image_share_root', '/etc', 'irmc') self.node.instance_info['boot_iso'] = None instance_info_expected = {} @@ -335,7 +337,7 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): @mock.patch.object(os.path, 'isfile', spec_set=True, autospec=True) def test__parse_instance_info_with_boot_iso_invalid( self, isfile_mock, check_share_fs_mounted_mock): - CONF.irmc.remote_image_share_root = '/etc' + CONF.set_override('remote_image_share_root', '/etc', 'irmc') isfile_mock.return_value = False with task_manager.acquire(self.context, self.node.uuid) as task: @@ -357,7 +359,7 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): def test_parse_deploy_info_ok(self, mock_isfile, get_image_instance_info_mock, check_share_fs_mounted_mock): - CONF.irmc.remote_image_share_root = '/etc' + CONF.set_override('remote_image_share_root', '/etc', 'irmc') get_image_instance_info_mock.return_value = {'a': 'b'} driver_info_expected = { 'a': 'b', @@ -443,7 +445,7 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): setup_vmedia_mock, set_boot_device_mock, check_share_fs_mounted_mock): - CONF.irmc.remote_image_share_root = '/' + CONF.set_override('remote_image_share_root', '/', 'irmc') with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: @@ -476,7 +478,7 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): setup_vmedia_mock, set_boot_device_mock, check_share_fs_mounted_mock): - CONF.irmc.remote_image_share_root = '/' + CONF.set_override('remote_image_share_root', '/', 'irmc') with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: @@ -550,7 +552,7 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): boot_mode_mock, create_boot_iso_mock, check_share_fs_mounted_mock): - CONF.irmc.remote_image_share_root = '/' + CONF.set_override('remote_image_share_root', '/', 'irmc') image = '733d1c44-a2ea-414b-aca7-69decf20d810' is_image_href_ordinary_file_name_mock.return_value = False deploy_info_mock.return_value = {'boot_iso': image} @@ -828,7 +830,7 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): autospec=True) def test__remove_share_file(self, unlink_without_raise_mock, check_share_fs_mounted_mock): - CONF.irmc.remote_image_share_root = '/share' + CONF.set_override('remote_image_share_root', '/share', 'irmc') irmc_boot._remove_share_file("boot.iso") @@ -844,12 +846,12 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): cd_set_params = (irmc_boot.scci .get_virtual_cd_set_params_cmd.return_value) - CONF.irmc.remote_image_server = '10.20.30.40' - CONF.irmc.remote_image_user_domain = 'local' - CONF.irmc.remote_image_share_type = 'NFS' - CONF.irmc.remote_image_share_name = 'share' - CONF.irmc.remote_image_user_name = 'admin' - CONF.irmc.remote_image_user_password = 'admin0' + CONF.set_override('remote_image_server', '10.20.30.40', 'irmc') + CONF.set_override('remote_image_share_type', 'NFS', 'irmc') + CONF.set_override('remote_image_share_name', 'share', 'irmc') + CONF.set_override('remote_image_user_name', 'admin', 'irmc') + CONF.set_override('remote_image_user_password', 'admin0', 'irmc') + CONF.set_override('remote_image_user_domain', 'local', 'irmc') irmc_boot.scci.get_share_type.return_value = 0 @@ -926,12 +928,12 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): fd_set_params = (irmc_boot.scci .get_virtual_fd_set_params_cmd.return_value) - CONF.irmc.remote_image_server = '10.20.30.40' - CONF.irmc.remote_image_user_domain = 'local' - CONF.irmc.remote_image_share_type = 'NFS' - CONF.irmc.remote_image_share_name = 'share' - CONF.irmc.remote_image_user_name = 'admin' - CONF.irmc.remote_image_user_password = 'admin0' + CONF.set_override('remote_image_server', '10.20.30.40', 'irmc') + CONF.set_override('remote_image_share_type', 'NFS', 'irmc') + CONF.set_override('remote_image_share_name', 'share', 'irmc') + CONF.set_override('remote_image_user_name', 'admin', 'irmc') + CONF.set_override('remote_image_user_password', 'admin0', 'irmc') + CONF.set_override('remote_image_user_domain', 'local', 'irmc') irmc_boot.scci.get_share_type.return_value = 0 @@ -1009,8 +1011,8 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): # irmc_boot.check_share_fs_mounted is mocked in # third_party_driver_mocks.py. # irmc_boot.check_share_fs_mounted_orig is the real function. - CONF.irmc.remote_image_share_root = '/' - CONF.irmc.remote_image_share_type = 'nfs' + CONF.set_override('remote_image_share_root', '/', 'irmc') + CONF.set_override('remote_image_share_type', 'nfs', 'irmc') result = irmc_boot.check_share_fs_mounted_orig() parse_conf_mock.assert_called_once_with() @@ -1026,8 +1028,8 @@ class IRMCDeployPrivateMethodsTestCase(test_common.BaseIRMCTest): # irmc_boot.check_share_fs_mounted is mocked in # third_party_driver_mocks.py. # irmc_boot.check_share_fs_mounted_orig is the real function. - CONF.irmc.remote_image_share_root = '/etc' - CONF.irmc.remote_image_share_type = 'cifs' + CONF.set_override('remote_image_share_root', '/etc', 'irmc') + CONF.set_override('remote_image_share_type', 'cifs', 'irmc') self.assertRaises(exception.IRMCSharedFileSystemNotMounted, irmc_boot.check_share_fs_mounted_orig) @@ -1144,8 +1146,9 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest): autospec=True) @mock.patch.object(irmc_boot, '_cleanup_vmedia_boot', spec_set=True, autospec=True) - def _test_prepare_instance_whole_disk_image( - self, _cleanup_vmedia_boot_mock, set_boot_device_mock): + def test_prepare_instance_whole_disk_image( + self, _cleanup_vmedia_boot_mock, set_boot_device_mock, + check_share_fs_mounted_mock): self.node.driver_internal_info = {'is_whole_disk_image': True} self.node.save() with task_manager.acquire(self.context, self.node.uuid, @@ -1157,26 +1160,13 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest): boot_devices.DISK, persistent=True) - def test_prepare_instance_whole_disk_image_local( - self, check_share_fs_mounted_mock): - self.node.instance_info = {'capabilities': '{"boot_option": "local"}'} - self.node.save() - self._test_prepare_instance_whole_disk_image() - - def test_prepare_instance_whole_disk_image(self, - check_share_fs_mounted_mock): - self._test_prepare_instance_whole_disk_image() - - @mock.patch.object(irmc_boot.IRMCVirtualMediaBoot, - '_configure_vmedia_boot', spec_set=True, + @mock.patch.object(manager_utils, 'node_set_boot_device', spec_set=True, autospec=True) @mock.patch.object(irmc_boot, '_cleanup_vmedia_boot', spec_set=True, autospec=True) def test_prepare_instance_partition_image( - self, _cleanup_vmedia_boot_mock, _configure_vmedia_mock, + self, _cleanup_vmedia_boot_mock, set_boot_device_mock, check_share_fs_mounted_mock): - self.node.instance_info = { - 'capabilities': {'boot_option': 'netboot'}} self.node.driver_internal_info = {'root_uuid_or_disk_id': "some_uuid"} self.node.save() with task_manager.acquire(self.context, self.node.uuid, @@ -1184,8 +1174,9 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest): task.driver.boot.prepare_instance(task) _cleanup_vmedia_boot_mock.assert_called_once_with(task) - _configure_vmedia_mock.assert_called_once_with(mock.ANY, task, - "some_uuid") + set_boot_device_mock.assert_called_once_with(task, + boot_devices.DISK, + persistent=True) @mock.patch.object(irmc_boot, '_cleanup_vmedia_boot', spec_set=True, autospec=True) @@ -1253,9 +1244,10 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest): self.node.driver_internal_info = {'root_uuid_or_disk_id': "12312642"} self.node.provision_state = states.DEPLOYING self.node.target_provision_state = states.ACTIVE + self.node.deploy_interface = 'ramdisk' self.node.instance_info = { 'capabilities': { - "secure_boot": "true", 'boot_option': 'netboot' + "secure_boot": "true" } } self.node.save() @@ -1281,9 +1273,10 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest): self.node.driver_internal_info = {'root_uuid_or_disk_id': "12312642"} self.node.provision_state = states.DEPLOYING self.node.target_provision_state = states.ACTIVE + self.node.deploy_interface = 'ramdisk' self.node.instance_info = { 'capabilities': { - "secure_boot": "false", 'boot_option': 'netboot' + "secure_boot": "false" } } self.node.save() @@ -1308,11 +1301,7 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest): self.node.driver_internal_info = {'root_uuid_or_disk_id': "12312642"} self.node.provision_state = states.DEPLOYING self.node.target_provision_state = states.ACTIVE - self.node.instance_info = { - 'capabilities': { - 'boot_option': 'netboot' - } - } + self.node.deploy_interface = 'ramdisk' self.node.save() with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: diff --git a/ironic/tests/unit/drivers/modules/network/test_neutron.py b/ironic/tests/unit/drivers/modules/network/test_neutron.py index 0b70446ce..665a674a6 100644 --- a/ironic/tests/unit/drivers/modules/network/test_neutron.py +++ b/ironic/tests/unit/drivers/modules/network/test_neutron.py @@ -19,7 +19,6 @@ from oslo_utils import uuidutils from ironic.common import exception from ironic.common import neutron as neutron_common -from ironic.common import states from ironic.conductor import task_manager from ironic.drivers import base as drivers_base from ironic.drivers.modules.network import neutron @@ -106,65 +105,6 @@ class NeutronInterfaceTestCase(db_base.DbTestCase): context=task.context)], validate_mock.call_args_list) - @mock.patch.object(neutron_common, 'validate_network', autospec=True) - def test_validate_boot_option_netboot(self, validate_mock): - driver_internal_info = self.node.driver_internal_info - driver_internal_info['is_whole_disk_image'] = True - self.node.driver_internal_info = driver_internal_info - boot_option = {'capabilities': '{"boot_option": "netboot"}'} - self.node.instance_info = boot_option - self.node.provision_state = states.DEPLOYING - self.node.save() - with task_manager.acquire(self.context, self.node.id) as task: - self.assertRaisesRegex( - exception.InvalidParameterValue, - 'cannot perform "local" boot for whole disk image', - self.interface.validate, task) - self.assertEqual([mock.call(CONF.neutron.cleaning_network, - 'cleaning network', - context=task.context), - mock.call(CONF.neutron.provisioning_network, - 'provisioning network', - context=task.context)], - validate_mock.call_args_list) - - @mock.patch.object(neutron_common, 'validate_network', autospec=True) - def test_validate_boot_option_netboot_no_exc(self, validate_mock): - CONF.set_override('default_boot_option', 'netboot', 'deploy') - driver_internal_info = self.node.driver_internal_info - driver_internal_info['is_whole_disk_image'] = True - self.node.driver_internal_info = driver_internal_info - self.node.provision_state = states.AVAILABLE - self.node.save() - with task_manager.acquire(self.context, self.node.id) as task: - self.interface.validate(task) - self.assertEqual([mock.call(CONF.neutron.cleaning_network, - 'cleaning network', - context=task.context), - mock.call(CONF.neutron.provisioning_network, - 'provisioning network', - context=task.context)], - validate_mock.call_args_list) - - @mock.patch.object(neutron_common, 'validate_network', autospec=True) - def test_validate_boot_option_local(self, validate_mock): - driver_internal_info = self.node.driver_internal_info - driver_internal_info['is_whole_disk_image'] = True - self.node.driver_internal_info = driver_internal_info - boot_option = {'capabilities': '{"boot_option": "local"}'} - self.node.instance_info = boot_option - self.node.provision_state = states.DEPLOYING - self.node.save() - with task_manager.acquire(self.context, self.node.id) as task: - self.interface.validate(task) - self.assertEqual([mock.call(CONF.neutron.cleaning_network, - 'cleaning network', - context=task.context), - mock.call(CONF.neutron.provisioning_network, - 'provisioning network', - context=task.context)], - validate_mock.call_args_list) - @mock.patch.object(neutron_common, 'validate_network', side_effect=lambda n, t, context=None: n, autospec=True) @mock.patch.object(neutron_common, 'rollback_ports', autospec=True) diff --git a/ironic/tests/unit/drivers/modules/redfish/test_firmware_utils.py b/ironic/tests/unit/drivers/modules/redfish/test_firmware_utils.py index e2c6e75b2..61bc23e48 100644 --- a/ironic/tests/unit/drivers/modules/redfish/test_firmware_utils.py +++ b/ironic/tests/unit/drivers/modules/redfish/test_firmware_utils.py @@ -262,9 +262,9 @@ class FirmwareUtilsTestCase(base.TestCase): @mock.patch.object(os, 'chmod', autospec=True) def test_stage_http(self, mock_chmod, mock_link, mock_copyfile, mock_makedirs): - CONF.deploy.http_url = 'http://10.0.0.2' - CONF.deploy.external_http_url = None - CONF.deploy.http_root = '/httproot' + CONF.set_override('http_url', 'http://10.0.0.2', 'deploy') + CONF.set_override('external_http_url', None, 'deploy') + CONF.set_override('http_root', '/httproot', 'deploy') node = mock.Mock(uuid='55cdaba0-1123-4622-8b37-bb52dd6285d3') staged_url, need_cleanup = firmware_utils.stage( @@ -291,9 +291,9 @@ class FirmwareUtilsTestCase(base.TestCase): @mock.patch.object(os, 'chmod', autospec=True) def test_stage_http_copyfile(self, mock_chmod, mock_link, mock_copyfile, mock_makedirs): - CONF.deploy.http_url = 'http://10.0.0.2' - CONF.deploy.external_http_url = None - CONF.deploy.http_root = '/httproot' + CONF.set_override('http_url', 'http://10.0.0.2', 'deploy') + CONF.set_override('external_http_url', None, 'deploy') + CONF.set_override('http_root', '/httproot', 'deploy') node = mock.Mock(uuid='55cdaba0-1123-4622-8b37-bb52dd6285d3') mock_link.side_effect = OSError @@ -323,9 +323,9 @@ class FirmwareUtilsTestCase(base.TestCase): @mock.patch.object(os, 'chmod', autospec=True) def test_stage_http_copyfile_fails(self, mock_chmod, mock_link, mock_copyfile, mock_makedirs): - CONF.deploy.http_url = 'http://10.0.0.2' - CONF.deploy.external_http_url = None - CONF.deploy.http_root = '/httproot' + CONF.set_override('http_url', 'http://10.0.0.2', 'deploy') + CONF.set_override('external_http_url', None, 'deploy') + CONF.set_override('http_root', '/httproot', 'deploy') node = mock.Mock(uuid='55cdaba0-1123-4622-8b37-bb52dd6285d3') mock_link.side_effect = OSError mock_copyfile.side_effect = IOError @@ -352,9 +352,9 @@ class FirmwareUtilsTestCase(base.TestCase): @mock.patch.object(os, 'chmod', autospec=True) def test_stage_local_external(self, mock_chmod, mock_link, mock_rmtree, mock_copyfile, mock_makedirs): - CONF.deploy.http_url = 'http://10.0.0.2' - CONF.deploy.external_http_url = 'http://90.0.0.9' - CONF.deploy.http_root = '/httproot' + CONF.set_override('http_url', 'http://10.0.0.2', 'deploy') + CONF.set_override('external_http_url', 'http://90.0.0.9', 'deploy') + CONF.set_override('http_root', '/httproot', 'deploy') node = mock.Mock(uuid='55cdaba0-1123-4622-8b37-bb52dd6285d3') staged_url, need_cleanup = firmware_utils.stage( @@ -402,7 +402,7 @@ class FirmwareUtilsTestCase(base.TestCase): @mock.patch.object(swift, 'SwiftAPI', autospec=True) def test_cleanup(self, mock_swift_api, mock_gettempdir, mock_rmtree): mock_gettempdir.return_value = '/tmp' - CONF.deploy.http_root = '/httproot' + CONF.set_override('http_root', '/httproot', 'deploy') node = mock.Mock( uuid='55cdaba0-1123-4622-8b37-bb52dd6285d3', driver_internal_info={'firmware_cleanup': ['http', 'swift']}) diff --git a/ironic/tests/unit/drivers/modules/redfish/test_management.py b/ironic/tests/unit/drivers/modules/redfish/test_management.py index 93aae5de8..f8c82949a 100644 --- a/ironic/tests/unit/drivers/modules/redfish/test_management.py +++ b/ironic/tests/unit/drivers/modules/redfish/test_management.py @@ -836,7 +836,7 @@ class RedfishManagementTestCase(db_base.DbTestCase): mock_update_service = mock.Mock() mock_update_service.simple_update.return_value = mock_task_monitor mock_get_update_service.return_value = mock_update_service - CONF.redfish.firmware_source = 'http' + CONF.set_override('firmware_source', 'http', 'redfish') with task_manager.acquire(self.context, self.node.uuid, shared=False) as task: task.node.save = mock.Mock() @@ -1346,7 +1346,7 @@ class RedfishManagementTestCase(db_base.DbTestCase): {'task_monitor': '/task/123', 'url': 'http://test1'}, {'url': 'http://test2'}]} self.node.driver_internal_info = driver_internal_info - CONF.redfish.firmware_source = 'http' + CONF.set_override('firmware_source', 'http', 'redfish') management = redfish_mgmt.RedfishManagement() with task_manager.acquire(self.context, self.node.uuid, @@ -1375,7 +1375,7 @@ class RedfishManagementTestCase(db_base.DbTestCase): @mock.patch.object(firmware_utils, 'stage', autospec=True) def test__stage_firmware_file_https(self, mock_stage, mock_verify_checksum, mock_download_to_temp): - CONF.redfish.firmware_source = 'local' + CONF.set_override('firmware_source', 'local', 'redfish') firmware_update = {'url': 'https://test1', 'checksum': 'abc'} node = mock.Mock() mock_download_to_temp.return_value = '/tmp/test1' @@ -1399,7 +1399,7 @@ class RedfishManagementTestCase(db_base.DbTestCase): def test__stage_firmware_file_swift( self, mock_get_swift_temp_url, mock_stage, mock_verify_checksum, mock_download_to_temp): - CONF.redfish.firmware_source = 'swift' + CONF.set_override('firmware_source', 'swift', 'redfish') firmware_update = {'url': 'swift://container/bios.exe'} node = mock.Mock() mock_get_swift_temp_url.return_value = 'http://temp' @@ -1423,7 +1423,7 @@ class RedfishManagementTestCase(db_base.DbTestCase): mock_download_to_temp, mock_cleanup): node = mock.Mock() firmware_update = {'url': 'https://test1'} - CONF.redfish.firmware_source = 'local' + CONF.set_override('firmware_source', 'local', 'redfish') firmware_update = {'url': 'https://test1'} node = mock.Mock() mock_download_to_temp.return_value = '/tmp/test1' diff --git a/ironic/tests/unit/drivers/modules/redfish/test_raid.py b/ironic/tests/unit/drivers/modules/redfish/test_raid.py index b2d3a0a0e..dfb3c1473 100644 --- a/ironic/tests/unit/drivers/modules/redfish/test_raid.py +++ b/ironic/tests/unit/drivers/modules/redfish/test_raid.py @@ -1483,3 +1483,22 @@ class RedfishRAIDTestCase(db_base.DbTestCase): mock_reboot.assert_not_called() # Not yet updated as in progress self.assertEqual({}, task.node.raid_config) + + @mock.patch.object(redfish_raid, 'LOG', autospec=True) + def test_update_raid_config_missing_raid_type( + self, mock_log, mock_get_system): + volumes = [ + _mock_volume( + '1', raid_type=None, + capacity_bytes=100 * units.Gi), + _mock_volume( + '2', raid_type=None, + capacity_bytes=500 * units.Gi)] + self.mock_storage.volumes.get_members.return_value = volumes + mock_get_system.return_value.storage.get_members.return_value = [ + self.mock_storage] + + redfish_raid.update_raid_config(self.node) + + self.assertEqual([], self.node.raid_config['logical_disks']) + mock_log.warning.assert_called_once() diff --git a/ironic/tests/unit/drivers/modules/test_agent.py b/ironic/tests/unit/drivers/modules/test_agent.py index 4b6d271d4..653359f33 100644 --- a/ironic/tests/unit/drivers/modules/test_agent.py +++ b/ironic/tests/unit/drivers/modules/test_agent.py @@ -18,7 +18,6 @@ from oslo_config import cfg from ironic.common import dhcp_factory from ironic.common import exception -from ironic.common import image_service from ironic.common import images from ironic.common import raid from ironic.common import states @@ -848,212 +847,6 @@ class TestAgentDeploy(CommonTestsMixin, db_base.DbTestCase): @mock.patch('ironic.drivers.modules.agent.check_image_size', autospec=True) - @mock.patch.object(noop_storage.NoopStorage, 'attach_volumes', - autospec=True) - @mock.patch.object(deploy_utils, 'populate_storage_driver_internal_info', - autospec=True) - @mock.patch.object(pxe.PXEBoot, 'prepare_ramdisk', autospec=True) - @mock.patch.object(deploy_utils, 'build_agent_options', autospec=True) - @mock.patch.object(image_service.HttpImageService, 'validate_href', - autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, - 'add_provisioning_network', - spec_set=True, autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, - 'unconfigure_tenant_networks', - spec_set=True, autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, 'validate', - spec_set=True, autospec=True) - def test_prepare_with_neutron_net_capabilities_as_string( - self, validate_net_mock, - unconfigure_tenant_net_mock, add_provisioning_net_mock, - validate_href_mock, build_options_mock, - pxe_prepare_ramdisk_mock, storage_driver_info_mock, - storage_attach_volumes_mock, check_image_size_mock): - node = self.node - node.network_interface = 'neutron' - instance_info = node.instance_info - instance_info['capabilities'] = '{"lion": "roar"}' - node.instance_info = instance_info - node.save() - validate_net_mock.side_effect = [ - exception.InvalidParameterValue('invalid'), None] - with task_manager.acquire( - self.context, self.node['uuid'], shared=False) as task: - task.node.provision_state = states.DEPLOYING - build_options_mock.return_value = {'a': 'b'} - self.driver.prepare(task) - storage_driver_info_mock.assert_called_once_with(task) - self.assertEqual(2, validate_net_mock.call_count) - add_provisioning_net_mock.assert_called_once_with(mock.ANY, task) - unconfigure_tenant_net_mock.assert_called_once_with(mock.ANY, task) - storage_attach_volumes_mock.assert_called_once_with( - task.driver.storage, task) - validate_href_mock.assert_called_once_with(mock.ANY, 'fake-image', - secret=False) - build_options_mock.assert_called_once_with(task.node) - pxe_prepare_ramdisk_mock.assert_called_once_with( - task.driver.boot, task, {'a': 'b'}) - check_image_size_mock.assert_called_once_with(task) - self.node.refresh() - capabilities = self.node.instance_info['capabilities'] - self.assertEqual('local', capabilities['boot_option']) - self.assertEqual('roar', capabilities['lion']) - - @mock.patch('ironic.drivers.modules.agent.check_image_size', - autospec=True) - @mock.patch.object(noop_storage.NoopStorage, 'attach_volumes', - autospec=True) - @mock.patch.object(deploy_utils, 'populate_storage_driver_internal_info', - autospec=True) - @mock.patch.object(pxe.PXEBoot, 'prepare_ramdisk', autospec=True) - @mock.patch.object(deploy_utils, 'build_agent_options', autospec=True) - @mock.patch.object(image_service.HttpImageService, 'validate_href', - autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, - 'add_provisioning_network', - spec_set=True, autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, - 'unconfigure_tenant_networks', - spec_set=True, autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, 'validate', - spec_set=True, autospec=True) - def test_prepare_with_neutron_net_exc_no_capabilities( - self, validate_net_mock, - unconfigure_tenant_net_mock, add_provisioning_net_mock, - validate_href_mock, build_options_mock, - pxe_prepare_ramdisk_mock, storage_driver_info_mock, - storage_attach_volumes_mock, check_image_size_mock): - node = self.node - node.network_interface = 'neutron' - node.save() - validate_net_mock.side_effect = [ - exception.InvalidParameterValue('invalid'), None] - with task_manager.acquire( - self.context, self.node['uuid'], shared=False) as task: - task.node.provision_state = states.DEPLOYING - build_options_mock.return_value = {'a': 'b'} - self.driver.prepare(task) - storage_driver_info_mock.assert_called_once_with(task) - self.assertEqual(2, validate_net_mock.call_count) - add_provisioning_net_mock.assert_called_once_with(mock.ANY, task) - unconfigure_tenant_net_mock.assert_called_once_with(mock.ANY, task) - storage_attach_volumes_mock.assert_called_once_with( - task.driver.storage, task) - validate_href_mock.assert_called_once_with(mock.ANY, 'fake-image', - secret=False) - build_options_mock.assert_called_once_with(task.node) - pxe_prepare_ramdisk_mock.assert_called_once_with( - task.driver.boot, task, {'a': 'b'}) - check_image_size_mock.assert_called_once_with(task) - self.node.refresh() - capabilities = self.node.instance_info['capabilities'] - self.assertEqual('local', capabilities['boot_option']) - - @mock.patch('ironic.drivers.modules.agent.check_image_size', - autospec=True) - @mock.patch.object(noop_storage.NoopStorage, 'attach_volumes', - autospec=True) - @mock.patch.object(deploy_utils, 'populate_storage_driver_internal_info', - autospec=True) - @mock.patch.object(pxe.PXEBoot, 'prepare_ramdisk', autospec=True) - @mock.patch.object(deploy_utils, 'build_agent_options', autospec=True) - @mock.patch.object(image_service.HttpImageService, 'validate_href', - autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, - 'add_provisioning_network', - spec_set=True, autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, - 'unconfigure_tenant_networks', - spec_set=True, autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, 'validate', - spec_set=True, autospec=True) - def test_prepare_with_neutron_net_exc_no_capabilities_overwrite( - self, validate_net_mock, - unconfigure_tenant_net_mock, add_provisioning_net_mock, - validate_href_mock, build_options_mock, - pxe_prepare_ramdisk_mock, storage_driver_info_mock, - storage_attach_volumes_mock, check_image_size_mock): - node = self.node - node.network_interface = 'neutron' - instance_info = node.instance_info - instance_info['capabilities'] = {"cat": "meow"} - node.instance_info = instance_info - node.save() - validate_net_mock.side_effect = [ - exception.InvalidParameterValue('invalid'), None] - with task_manager.acquire( - self.context, self.node['uuid'], shared=False) as task: - task.node.provision_state = states.DEPLOYING - build_options_mock.return_value = {'a': 'b'} - self.driver.prepare(task) - storage_driver_info_mock.assert_called_once_with(task) - self.assertEqual(2, validate_net_mock.call_count) - add_provisioning_net_mock.assert_called_once_with(mock.ANY, task) - unconfigure_tenant_net_mock.assert_called_once_with(mock.ANY, task) - storage_attach_volumes_mock.assert_called_once_with( - task.driver.storage, task) - validate_href_mock.assert_called_once_with(mock.ANY, 'fake-image', - secret=False) - build_options_mock.assert_called_once_with(task.node) - pxe_prepare_ramdisk_mock.assert_called_once_with( - task.driver.boot, task, {'a': 'b'}) - check_image_size_mock.assert_called_once_with(task) - self.node.refresh() - capabilities = self.node.instance_info['capabilities'] - self.assertEqual('local', capabilities['boot_option']) - self.assertEqual('meow', capabilities['cat']) - - @mock.patch.object(noop_storage.NoopStorage, 'attach_volumes', - autospec=True) - @mock.patch.object(deploy_utils, 'populate_storage_driver_internal_info', - autospec=True) - @mock.patch.object(pxe.PXEBoot, 'prepare_ramdisk', autospec=True) - @mock.patch.object(deploy_utils, 'build_agent_options', autospec=True) - @mock.patch.object(deploy_utils, 'build_instance_info_for_deploy', - autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, - 'add_provisioning_network', - spec_set=True, autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, - 'unconfigure_tenant_networks', - spec_set=True, autospec=True) - @mock.patch.object(neutron_network.NeutronNetwork, 'validate', - spec_set=True, autospec=True) - def test_prepare_with_neutron_net_exc_reraise( - self, validate_net_mock, - unconfigure_tenant_net_mock, add_provisioning_net_mock, - build_instance_info_mock, build_options_mock, - pxe_prepare_ramdisk_mock, storage_driver_info_mock, - storage_attach_volumes_mock): - node = self.node - node.network_interface = 'neutron' - instance_info = node.instance_info - instance_info['capabilities'] = {"boot_option": "netboot"} - node.instance_info = instance_info - node.save() - validate_net_mock.side_effect = ( - exception.InvalidParameterValue('invalid')) - with task_manager.acquire( - self.context, self.node['uuid'], shared=False) as task: - task.node.provision_state = states.DEPLOYING - self.assertRaises(exception.InvalidParameterValue, - task.driver.deploy.prepare, - task) - storage_driver_info_mock.assert_called_once_with(task) - validate_net_mock.assert_called_once_with(mock.ANY, task) - self.assertFalse(add_provisioning_net_mock.called) - self.assertFalse(unconfigure_tenant_net_mock.called) - self.assertFalse(storage_attach_volumes_mock.called) - self.assertFalse(build_instance_info_mock.called) - self.assertFalse(build_options_mock.called) - self.assertFalse(pxe_prepare_ramdisk_mock.called) - self.node.refresh() - capabilities = self.node.instance_info['capabilities'] - self.assertEqual('netboot', capabilities['boot_option']) - - @mock.patch('ironic.drivers.modules.agent.check_image_size', - autospec=True) @mock.patch.object(flat_network.FlatNetwork, 'add_provisioning_network', spec_set=True, autospec=True) @mock.patch.object(flat_network.FlatNetwork, 'validate', @@ -1643,8 +1436,6 @@ class TestAgentDeploy(CommonTestsMixin, db_base.DbTestCase): def test_prepare_instance_boot_partition_image(self, prepare_instance_mock, uuid_mock, boot_mode_mock, log_mock): - self.node.instance_info = { - 'capabilities': {'boot_option': 'netboot'}} uuid_mock.return_value = { 'command_result': {'root uuid': 'root_uuid'} } diff --git a/ironic/tests/unit/drivers/modules/test_agent_base.py b/ironic/tests/unit/drivers/modules/test_agent_base.py index 97daca79f..f8b23e9fb 100644 --- a/ironic/tests/unit/drivers/modules/test_agent_base.py +++ b/ironic/tests/unit/drivers/modules/test_agent_base.py @@ -1426,40 +1426,11 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest): @mock.patch.object(deploy_utils, 'set_failed_state', autospec=True) @mock.patch.object(pxe.PXEBoot, 'prepare_instance', autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_option', autospec=True) @mock.patch.object(agent_base.AgentDeployMixin, 'configure_local_boot', autospec=True) - def test_prepare_instance_to_boot_netboot(self, configure_mock, - boot_option_mock, - prepare_instance_mock, - failed_state_mock): - boot_option_mock.return_value = 'netboot' - prepare_instance_mock.return_value = None - self.node.provision_state = states.DEPLOYING - self.node.target_provision_state = states.ACTIVE - self.node.save() - root_uuid = 'root_uuid' - efi_system_part_uuid = 'efi_sys_uuid' - with task_manager.acquire(self.context, self.node['uuid'], - shared=False) as task: - self.deploy.prepare_instance_to_boot(task, root_uuid, - efi_system_part_uuid) - self.assertFalse(configure_mock.called) - boot_option_mock.assert_called_once_with(task.node) - prepare_instance_mock.assert_called_once_with(task.driver.boot, - task) - self.assertFalse(failed_state_mock.called) - - @mock.patch.object(deploy_utils, 'set_failed_state', autospec=True) - @mock.patch.object(pxe.PXEBoot, 'prepare_instance', autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_option', autospec=True) - @mock.patch.object(agent_base.AgentDeployMixin, - 'configure_local_boot', autospec=True) - def test_prepare_instance_to_boot_localboot(self, configure_mock, - boot_option_mock, - prepare_instance_mock, - failed_state_mock): - boot_option_mock.return_value = 'local' + def test_prepare_instance_to_boot(self, configure_mock, + prepare_instance_mock, + failed_state_mock): prepare_instance_mock.return_value = None self.node.provision_state = states.DEPLOYING self.node.target_provision_state = states.ACTIVE @@ -1475,20 +1446,16 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest): root_uuid=root_uuid, efi_system_part_uuid=efi_system_part_uuid, prep_boot_part_uuid=None) - boot_option_mock.assert_called_once_with(task.node) prepare_instance_mock.assert_called_once_with(task.driver.boot, task) self.assertFalse(failed_state_mock.called) @mock.patch.object(deploy_utils, 'set_failed_state', autospec=True) @mock.patch.object(pxe.PXEBoot, 'prepare_instance', autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_option', autospec=True) @mock.patch.object(agent_base.AgentDeployMixin, 'configure_local_boot', autospec=True) def test_prepare_instance_to_boot_localboot_prep_partition( - self, configure_mock, boot_option_mock, - prepare_instance_mock, failed_state_mock): - boot_option_mock.return_value = 'local' + self, configure_mock, prepare_instance_mock, failed_state_mock): prepare_instance_mock.return_value = None self.node.provision_state = states.DEPLOYING self.node.target_provision_state = states.ACTIVE @@ -1506,21 +1473,17 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest): root_uuid=root_uuid, efi_system_part_uuid=efi_system_part_uuid, prep_boot_part_uuid=prep_boot_part_uuid) - boot_option_mock.assert_called_once_with(task.node) prepare_instance_mock.assert_called_once_with(task.driver.boot, task) self.assertFalse(failed_state_mock.called) @mock.patch.object(deploy_utils, 'set_failed_state', autospec=True) @mock.patch.object(pxe.PXEBoot, 'prepare_instance', autospec=True) - @mock.patch.object(deploy_utils, 'get_boot_option', autospec=True) @mock.patch.object(agent_base.AgentDeployMixin, 'configure_local_boot', autospec=True) def test_prepare_instance_to_boot_configure_fails(self, configure_mock, - boot_option_mock, prepare_mock, failed_state_mock): - boot_option_mock.return_value = 'local' self.node.provision_state = states.DEPLOYING self.node.target_provision_state = states.ACTIVE self.node.save() @@ -1542,7 +1505,6 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest): root_uuid=root_uuid, efi_system_part_uuid=efi_system_part_uuid, prep_boot_part_uuid=None) - boot_option_mock.assert_called_once_with(task.node) self.assertFalse(prepare_mock.called) self.assertFalse(failed_state_mock.called) diff --git a/ironic/tests/unit/drivers/modules/test_deploy_utils.py b/ironic/tests/unit/drivers/modules/test_deploy_utils.py index 2bcdf1cb6..1177e9743 100644 --- a/ironic/tests/unit/drivers/modules/test_deploy_utils.py +++ b/ironic/tests/unit/drivers/modules/test_deploy_utils.py @@ -54,27 +54,6 @@ kernel deploy_kernel append initrd=deploy_ramdisk ipappend 3 -label boot_partition -kernel kernel -append initrd=ramdisk root={{ ROOT }} - -label boot_whole_disk -COM32 chain.c32 -append mbr:{{ DISK_IDENTIFIER }} -""" - -_PXECONF_BOOT_PARTITION = """ -default boot_partition - -label deploy -kernel deploy_kernel -append initrd=deploy_ramdisk -ipappend 3 - -label boot_partition -kernel kernel -append initrd=ramdisk root=UUID=12345678-1234-1234-1234-1234567890abcdef - label boot_whole_disk COM32 chain.c32 append mbr:{{ DISK_IDENTIFIER }} @@ -88,10 +67,6 @@ kernel deploy_kernel append initrd=deploy_ramdisk ipappend 3 -label boot_partition -kernel kernel -append initrd=ramdisk root={{ ROOT }} - label boot_whole_disk COM32 chain.c32 append mbr:0x12345678 @@ -109,34 +84,6 @@ kernel deploy_kernel initrd deploy_ramdisk boot -:boot_partition -kernel kernel -append initrd=ramdisk root={{ ROOT }} -boot - -:boot_whole_disk -kernel chain.c32 -append mbr:{{ DISK_IDENTIFIER }} -boot -""" - -_IPXECONF_BOOT_PARTITION = """ -#!ipxe - -dhcp - -goto boot_partition - -:deploy -kernel deploy_kernel -initrd deploy_ramdisk -boot - -:boot_partition -kernel kernel -append initrd=ramdisk root=UUID=12345678-1234-1234-1234-1234567890abcdef -boot - :boot_whole_disk kernel chain.c32 append mbr:{{ DISK_IDENTIFIER }} @@ -155,11 +102,6 @@ kernel deploy_kernel initrd deploy_ramdisk boot -:boot_partition -kernel kernel -append initrd=ramdisk root={{ ROOT }} -boot - :boot_whole_disk kernel chain.c32 append mbr:0x12345678 @@ -178,11 +120,6 @@ kernel deploy_kernel initrd deploy_ramdisk boot -:boot_partition -kernel kernel -append initrd=ramdisk root=UUID=0x12345678 -boot - :boot_whole_disk kernel chain.c32 append mbr:{{ DISK_IDENTIFIER }} @@ -197,29 +134,6 @@ image=deploy_kernel initrd=deploy_ramdisk append="ro text" -image=kernel - label=boot_partition - initrd=ramdisk - append="root={{ ROOT }}" - -image=chain.c32 - label=boot_whole_disk - append="mbr:{{ DISK_IDENTIFIER }}" -""" - -_UEFI_PXECONF_BOOT_PARTITION = """ -default=boot_partition - -image=deploy_kernel - label=deploy - initrd=deploy_ramdisk - append="ro text" - -image=kernel - label=boot_partition - initrd=ramdisk - append="root=UUID=12345678-1234-1234-1234-1234567890abcdef" - image=chain.c32 label=boot_whole_disk append="mbr:{{ DISK_IDENTIFIER }}" @@ -233,11 +147,6 @@ image=deploy_kernel initrd=deploy_ramdisk append="ro text" -image=kernel - label=boot_partition - initrd=ramdisk - append="root={{ ROOT }}" - image=chain.c32 label=boot_whole_disk append="mbr:0x12345678" @@ -253,31 +162,6 @@ menuentry "deploy" { initrdefi deploy_ramdisk } -menuentry "boot_partition" { - linuxefi kernel "root=(( ROOT ))" - initrdefi ramdisk -} - -menuentry "boot_whole_disk" { - linuxefi chain.c32 mbr:(( DISK_IDENTIFIER )) -} -""" - -_UEFI_PXECONF_BOOT_PARTITION_GRUB = """ -set default=boot_partition -set timeout=5 -set hidden_timeout_quiet=false - -menuentry "deploy" { - linuxefi deploy_kernel "ro text" - initrdefi deploy_ramdisk -} - -menuentry "boot_partition" { - linuxefi kernel "root=UUID=12345678-1234-1234-1234-1234567890abcdef" - initrdefi ramdisk -} - menuentry "boot_whole_disk" { linuxefi chain.c32 mbr:(( DISK_IDENTIFIER )) } @@ -293,11 +177,6 @@ menuentry "deploy" { initrdefi deploy_ramdisk } -menuentry "boot_partition" { - linuxefi kernel "root=(( ROOT ))" - initrdefi ramdisk -} - menuentry "boot_whole_disk" { linuxefi chain.c32 mbr:0x12345678 } @@ -322,17 +201,6 @@ class SwitchPxeConfigTestCase(tests_base.TestCase): self.addCleanup(os.unlink, fname) return fname - def test_switch_pxe_config_partition_image(self): - boot_mode = 'bios' - fname = self._create_config() - utils.switch_pxe_config(fname, - '12345678-1234-1234-1234-1234567890abcdef', - boot_mode, - False) - with open(fname, 'r') as f: - pxeconf = f.read() - self.assertEqual(_PXECONF_BOOT_PARTITION, pxeconf) - def test_switch_pxe_config_whole_disk_image(self): boot_mode = 'bios' fname = self._create_config() @@ -344,18 +212,6 @@ class SwitchPxeConfigTestCase(tests_base.TestCase): pxeconf = f.read() self.assertEqual(_PXECONF_BOOT_WHOLE_DISK, pxeconf) - def test_switch_ipxe_config_partition_image(self): - boot_mode = 'bios' - fname = self._create_config(ipxe=True) - utils.switch_pxe_config(fname, - '12345678-1234-1234-1234-1234567890abcdef', - boot_mode, - False, - ipxe_enabled=True) - with open(fname, 'r') as f: - pxeconf = f.read() - self.assertEqual(_IPXECONF_BOOT_PARTITION, pxeconf) - def test_switch_ipxe_config_whole_disk_image(self): boot_mode = 'bios' fname = self._create_config(ipxe=True) @@ -370,19 +226,6 @@ class SwitchPxeConfigTestCase(tests_base.TestCase): # NOTE(TheJulia): Remove elilo support after the deprecation period, # in the Queens release. - def test_switch_uefi_elilo_pxe_config_partition_image(self): - boot_mode = 'uefi' - fname = self._create_config(boot_mode=boot_mode) - utils.switch_pxe_config(fname, - '12345678-1234-1234-1234-1234567890abcdef', - boot_mode, - False) - with open(fname, 'r') as f: - pxeconf = f.read() - self.assertEqual(_UEFI_PXECONF_BOOT_PARTITION, pxeconf) - - # NOTE(TheJulia): Remove elilo support after the deprecation period, - # in the Queens release. def test_switch_uefi_elilo_config_whole_disk_image(self): boot_mode = 'uefi' fname = self._create_config(boot_mode=boot_mode) @@ -394,17 +237,6 @@ class SwitchPxeConfigTestCase(tests_base.TestCase): pxeconf = f.read() self.assertEqual(_UEFI_PXECONF_BOOT_WHOLE_DISK, pxeconf) - def test_switch_uefi_grub_pxe_config_partition_image(self): - boot_mode = 'uefi' - fname = self._create_config(boot_mode=boot_mode, boot_loader='grub') - utils.switch_pxe_config(fname, - '12345678-1234-1234-1234-1234567890abcdef', - boot_mode, - False) - with open(fname, 'r') as f: - pxeconf = f.read() - self.assertEqual(_UEFI_PXECONF_BOOT_PARTITION_GRUB, pxeconf) - def test_switch_uefi_grub_config_whole_disk_image(self): boot_mode = 'uefi' fname = self._create_config(boot_mode=boot_mode, boot_loader='grub') @@ -416,18 +248,6 @@ class SwitchPxeConfigTestCase(tests_base.TestCase): pxeconf = f.read() self.assertEqual(_UEFI_PXECONF_BOOT_WHOLE_DISK_GRUB, pxeconf) - def test_switch_uefi_ipxe_config_partition_image(self): - boot_mode = 'uefi' - fname = self._create_config(boot_mode=boot_mode, ipxe=True) - utils.switch_pxe_config(fname, - '12345678-1234-1234-1234-1234567890abcdef', - boot_mode, - False, - ipxe_enabled=True) - with open(fname, 'r') as f: - pxeconf = f.read() - self.assertEqual(_IPXECONF_BOOT_PARTITION, pxeconf) - def test_switch_uefi_ipxe_config_whole_disk_image(self): boot_mode = 'uefi' fname = self._create_config(boot_mode=boot_mode, ipxe=True) @@ -738,36 +558,11 @@ class OtherFunctionTestCase(db_base.DbTestCase): self._test_set_failed_state(collect_logs=False) self.assertFalse(mock_collect.called) - def test_get_boot_option(self): - self.node.instance_info = {'capabilities': '{"boot_option": "local"}'} - result = utils.get_boot_option(self.node) - self.assertEqual("local", result) - def test_get_boot_option_default_value(self): self.node.instance_info = {} result = utils.get_boot_option(self.node) self.assertEqual("local", result) - def test_get_boot_option_overridden_default_value(self): - cfg.CONF.set_override('default_boot_option', 'local', 'deploy') - self.node.instance_info = {} - result = utils.get_boot_option(self.node) - self.assertEqual("local", result) - - def test_get_boot_option_instance_info_priority(self): - cfg.CONF.set_override('default_boot_option', 'local', 'deploy') - self.node.instance_info = {'capabilities': - '{"boot_option": "netboot"}'} - result = utils.get_boot_option(self.node) - self.assertEqual("netboot", result) - - @mock.patch.object(utils, 'is_software_raid', autospec=True) - def test_get_boot_option_software_raid(self, mock_is_software_raid): - mock_is_software_raid.return_value = True - cfg.CONF.set_override('default_boot_option', 'netboot', 'deploy') - result = utils.get_boot_option(self.node) - self.assertEqual("local", result) - @mock.patch.object(utils, 'is_anaconda_deploy', autospec=True) def test_get_boot_option_anaconda_deploy(self, mock_is_anaconda_deploy): mock_is_anaconda_deploy.return_value = True @@ -972,8 +767,6 @@ class ParseInstanceInfoCapabilitiesTestCase(tests_base.TestCase): utils.validate_capabilities, self.node) def test_all_supported_capabilities(self): - self.assertEqual(('local', 'netboot', 'ramdisk', 'kickstart'), - utils.SUPPORTED_CAPABILITIES['boot_option']) self.assertEqual(('bios', 'uefi'), utils.SUPPORTED_CAPABILITIES['boot_mode']) self.assertEqual(('true', 'false'), @@ -1302,38 +1095,6 @@ class ValidateImagePropertiesTestCase(db_base.DbTestCase): utils.validate_image_properties(self.task, inst_info) @mock.patch.object(utils, 'get_boot_option', autospec=True, - return_value='netboot') - @mock.patch.object(image_service, 'get_image_service', autospec=True) - def test_validate_image_properties_glance_image(self, image_service_mock, - boot_options_mock): - inst_info = utils.get_image_instance_info(self.node) - image_service_mock.return_value.show.return_value = { - 'properties': {'kernel_id': '1111', 'ramdisk_id': '2222'}, - } - - utils.validate_image_properties(self.task, inst_info) - image_service_mock.assert_called_once_with( - self.node.instance_info['image_source'], context=self.context - ) - - @mock.patch.object(utils, 'get_boot_option', autospec=True, - return_value='netboot') - @mock.patch.object(image_service, 'get_image_service', autospec=True) - def test_validate_image_properties_glance_image_missing_prop( - self, image_service_mock, boot_options_mock): - inst_info = utils.get_image_instance_info(self.node) - image_service_mock.return_value.show.return_value = { - 'properties': {'kernel_id': '1111'}, - } - - self.assertRaises(exception.MissingParameterValue, - utils.validate_image_properties, - self.task, inst_info) - image_service_mock.assert_called_once_with( - self.node.instance_info['image_source'], context=self.context - ) - - @mock.patch.object(utils, 'get_boot_option', autospec=True, return_value='kickstart') @mock.patch.object(image_service, 'get_image_service', autospec=True) def test_validate_image_properties_glance_image_missing_stage2_id( @@ -1351,7 +1112,7 @@ class ValidateImagePropertiesTestCase(db_base.DbTestCase): ) @mock.patch.object(utils, 'get_boot_option', autospec=True, - return_value='netboot') + return_value='kickstart') @mock.patch.object(image_service, 'get_image_service', autospec=True) def test_validate_image_properties_glance_image_not_authorized( self, image_service_mock, boot_options_mock): @@ -1363,7 +1124,7 @@ class ValidateImagePropertiesTestCase(db_base.DbTestCase): inst_info) @mock.patch.object(utils, 'get_boot_option', autospec=True, - return_value='netboot') + return_value='kickstart') @mock.patch.object(image_service, 'get_image_service', autospec=True) def test_validate_image_properties_glance_image_not_found( self, image_service_mock, boot_options_mock): @@ -1381,7 +1142,7 @@ class ValidateImagePropertiesTestCase(db_base.DbTestCase): inst_info) @mock.patch.object(utils, 'get_boot_option', autospec=True, - return_value='netboot') + return_value='kickstart') def test_validate_image_properties_nonglance_image( self, boot_options_mock): instance_info = { @@ -1473,8 +1234,8 @@ class ValidateParametersTestCase(db_base.DbTestCase): self.assertNotIn('ramdisk', info) @mock.patch.object(utils, 'get_boot_option', autospec=True, - return_value='netboot') - def test__get_img_instance_info_good_non_glance_image_netboot( + return_value='kickstart') + def test__get_img_instance_info_good_non_glance_image_anaconda( self, mock_boot_opt): instance_info = INST_INFO_DICT.copy() instance_info['image_source'] = 'http://image' @@ -1488,7 +1249,7 @@ class ValidateParametersTestCase(db_base.DbTestCase): self.assertIsNotNone(info['kernel']) @mock.patch.object(utils, 'get_boot_option', autospec=True, - return_value='netboot') + return_value='kickstart') def test__get_img_instance_info_non_glance_image_missing_kernel( self, mock_boot_opt): instance_info = INST_INFO_DICT.copy() @@ -1501,7 +1262,7 @@ class ValidateParametersTestCase(db_base.DbTestCase): instance_info=instance_info) @mock.patch.object(utils, 'get_boot_option', autospec=True, - return_value='netboot') + return_value='kickstart') def test__get_img_instance_info_non_glance_image_missing_ramdisk( self, mock_boot_opt): instance_info = INST_INFO_DICT.copy() @@ -1768,23 +1529,26 @@ class InstanceInfoTestCase(db_base.DbTestCase): ) utils.parse_instance_info(node) - def test_parse_instance_info_nonglance_image_netboot(self): + @mock.patch.object(utils, 'get_boot_option', autospec=True, + return_value='kickstart') + def test_parse_instance_info_nonglance_image_anaconda(self, mock_boot_opt): info = INST_INFO_DICT.copy() info['image_source'] = 'file:///image.qcow2' info['kernel'] = 'file:///image.vmlinuz' info['ramdisk'] = 'file:///image.initrd' - info['capabilities'] = {'boot_option': 'netboot'} node = obj_utils.create_test_node( self.context, instance_info=info, driver_internal_info=DRV_INTERNAL_INFO_DICT, ) utils.parse_instance_info(node) - def test_parse_instance_info_nonglance_image_no_kernel(self): + @mock.patch.object(utils, 'get_boot_option', autospec=True, + return_value='kickstart') + def test_parse_instance_info_nonglance_image_no_kernel(self, + mock_boot_opt): info = INST_INFO_DICT.copy() info['image_source'] = 'file:///image.qcow2' info['ramdisk'] = 'file:///image.initrd' - info['capabilities'] = {'boot_option': 'netboot'} node = obj_utils.create_test_node( self.context, instance_info=info, driver_internal_info=DRV_INTERNAL_INFO_DICT, @@ -1947,12 +1711,15 @@ class TestBuildInstanceInfoForDeploy(db_base.DbTestCase): self.assertEqual(expected_i_info, info) parse_instance_info_mock.assert_called_once_with(task.node) + @mock.patch.object(utils, 'get_boot_option', autospec=True, + return_value='kickstart') @mock.patch.object(image_service.HttpImageService, 'validate_href', autospec=True) @mock.patch.object(utils, 'parse_instance_info', autospec=True) @mock.patch.object(image_service, 'GlanceImageService', autospec=True) - def test_build_instance_info_for_deploy_glance_partition_image_netboot( - self, glance_mock, parse_instance_info_mock, validate_mock): + def test_build_instance_info_for_deploy_glance_partition_image_anaconda( + self, glance_mock, parse_instance_info_mock, validate_mock, + boot_opt_mock): i_info = {} i_info['image_source'] = '733d1c44-a2ea-414b-aca7-69decf20d810' i_info['kernel'] = '13ce5a56-1de3-4916-b8b2-be778645d003' @@ -1962,7 +1729,6 @@ class TestBuildInstanceInfoForDeploy(db_base.DbTestCase): i_info['ephemeral_gb'] = 0 i_info['ephemeral_format'] = None i_info['configdrive'] = 'configdrive' - i_info['capabilities'] = {'boot_option': 'netboot'} driver_internal_info = self.node.driver_internal_info driver_internal_info['is_whole_disk_image'] = False self.node.driver_internal_info = driver_internal_info @@ -1980,8 +1746,7 @@ class TestBuildInstanceInfoForDeploy(db_base.DbTestCase): glance_obj_mock.swift_temp_url.return_value = 'http://temp-url' parse_instance_info_mock.return_value = {'swap_mb': 4} image_source = '733d1c44-a2ea-414b-aca7-69decf20d810' - expected_i_info = {'capabilities': {'boot_option': 'netboot'}, - 'root_gb': 5, + expected_i_info = {'root_gb': 5, 'swap_mb': 4, 'ephemeral_gb': 0, 'ephemeral_format': None, diff --git a/ironic/tests/unit/drivers/modules/test_ipxe.py b/ironic/tests/unit/drivers/modules/test_ipxe.py index d9dd126b3..ef37e3fc4 100644 --- a/ironic/tests/unit/drivers/modules/test_ipxe.py +++ b/ironic/tests/unit/drivers/modules/test_ipxe.py @@ -169,16 +169,6 @@ class iPXEBootTestCase(db_base.DbTestCase): task.driver.boot.validate(task) mock_boot_option.assert_called_with(task.node) - @mock.patch('ironic.drivers.modules.deploy_utils.get_boot_option', - return_value='netboot', autospec=True) - def test_validate_fail_missing_image_source(self, mock_boot_option): - with task_manager.acquire(self.context, self.node.uuid, - shared=True) as task: - del task.node['instance_info']['image_source'] - self.assertRaises(exception.MissingParameterValue, - task.driver.boot.validate, task) - mock_boot_option.assert_called_with(task.node) - def test_validate_fail_no_port(self): new_node = obj_utils.create_test_node( self.context, @@ -190,48 +180,6 @@ class iPXEBootTestCase(db_base.DbTestCase): self.assertRaises(exception.MissingParameterValue, task.driver.boot.validate, task) - @mock.patch.object(image_service.GlanceImageService, 'show', - autospec=True) - def test_validate_fail_no_image_kernel_ramdisk_props(self, mock_glance): - instance_info = {"boot_option": "netboot"} - mock_glance.return_value = {'properties': {}} - with task_manager.acquire(self.context, self.node.uuid, - shared=True) as task: - task.node.instance_info['capabilities'] = instance_info - self.assertRaises(exception.MissingParameterValue, - task.driver.boot.validate, - task) - - @mock.patch('ironic.drivers.modules.deploy_utils.get_boot_option', - return_value='netboot', autospec=True) - @mock.patch.object(image_service.GlanceImageService, 'show', - autospec=True) - def test_validate_fail_glance_image_doesnt_exists(self, mock_glance, - mock_boot_option): - mock_glance.side_effect = exception.ImageNotFound('not found') - with task_manager.acquire(self.context, self.node.uuid, - shared=True) as task: - self.assertRaises(exception.InvalidParameterValue, - task.driver.boot.validate, task) - mock_boot_option.assert_called_with(task.node) - - @mock.patch('ironic.drivers.modules.deploy_utils.get_boot_option', - return_value='netboot', autospec=True) - @mock.patch.object(image_service.GlanceImageService, 'show', - autospec=True) - def test_validate_fail_glance_conn_problem(self, mock_glance, - mock_boot_option): - exceptions = (exception.GlanceConnectionFailed('connection fail'), - exception.ImageNotAuthorized('not authorized'), - exception.Invalid('invalid')) - mock_glance.side_effect = exceptions - for exc in exceptions: - with task_manager.acquire(self.context, self.node.uuid, - shared=True) as task: - self.assertRaises(exception.InvalidParameterValue, - task.driver.boot.validate, task) - mock_boot_option.assert_called_with(task.node) - def test_validate_inspection(self): with task_manager.acquire(self.context, self.node.uuid) as task: task.driver.boot.validate_inspection(task) @@ -563,94 +511,6 @@ class iPXEBootTestCase(db_base.DbTestCase): self.node.save() self._test_clean_up_ramdisk(mode='rescue') - @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) - @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) - @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) - @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) - @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_netboot( - self, get_image_info_mock, cache_mock, - dhcp_factory_mock, switch_pxe_config_mock, - set_boot_device_mock): - provider_mock = mock.MagicMock() - dhcp_factory_mock.return_value = provider_mock - image_info = {'kernel': ('', '/path/to/kernel'), - 'ramdisk': ('', '/path/to/ramdisk')} - instance_info = {"boot_option": "netboot"} - get_image_info_mock.return_value = image_info - with task_manager.acquire(self.context, self.node.uuid) as task: - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True, ip_version=6) - pxe_config_path = pxe_utils.get_pxe_config_file_path( - task.node.uuid, ipxe_enabled=True) - task.node.properties['capabilities'] = 'boot_mode:uefi' - task.node.instance_info['capabilities'] = instance_info - task.node.driver_internal_info['root_uuid_or_disk_id'] = ( - "30212642-09d3-467f-8e09-21685826ab50") - task.node.driver_internal_info['is_whole_disk_image'] = False - - task.driver.boot.prepare_instance(task) - - get_image_info_mock.assert_called_once_with( - task, ipxe_enabled=True) - cache_mock.assert_called_once_with(task, image_info, - ipxe_enabled=True) - provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) - switch_pxe_config_mock.assert_called_once_with( - pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50", - 'uefi', False, iscsi_boot=False, ramdisk_boot=False, - ipxe_enabled=True, anaconda_boot=False) - set_boot_device_mock.assert_called_once_with(task, - boot_devices.PXE, - persistent=True) - - @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) - @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) - @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) - @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) - @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_netboot_bios( - self, get_image_info_mock, cache_mock, - dhcp_factory_mock, switch_pxe_config_mock, - set_boot_device_mock): - provider_mock = mock.MagicMock() - dhcp_factory_mock.return_value = provider_mock - image_info = {'kernel': ('', '/path/to/kernel'), - 'ramdisk': ('', '/path/to/ramdisk')} - instance_info = {"boot_option": "netboot", - "boot_mode": "bios"} - get_image_info_mock.return_value = image_info - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.properties['capabilities'] = 'boot_mode:bios' - task.node.instance_info['capabilities'] = instance_info - task.node.driver_internal_info['root_uuid_or_disk_id'] = ( - "30212642-09d3-467f-8e09-21685826ab50") - task.node.driver_internal_info['is_whole_disk_image'] = False - - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True, ip_version=6) - pxe_config_path = pxe_utils.get_pxe_config_file_path( - task.node.uuid, ipxe_enabled=True) - - task.driver.boot.prepare_instance(task) - - get_image_info_mock.assert_called_once_with( - task, ipxe_enabled=True) - cache_mock.assert_called_once_with(task, image_info, - ipxe_enabled=True) - provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) - switch_pxe_config_mock.assert_called_once_with( - pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50", - 'bios', False, iscsi_boot=False, ramdisk_boot=False, - ipxe_enabled=True, anaconda_boot=False) - set_boot_device_mock.assert_called_once_with(task, - boot_devices.PXE, - persistent=True) - @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) @@ -665,8 +525,7 @@ class iPXEBootTestCase(db_base.DbTestCase): dhcp_factory_mock.return_value = provider_mock image_info = {'kernel': ('', '/path/to/kernel'), 'ramdisk': ('', '/path/to/ramdisk')} - i_info_caps = {"boot_option": "ramdisk", - "boot_mode": "bios"} + i_info_caps = {"boot_mode": "bios"} kernel_arg = "meow" get_image_info_mock.return_value = image_info @@ -676,6 +535,7 @@ class iPXEBootTestCase(db_base.DbTestCase): i_info['capabilities'] = i_info_caps i_info['kernel_append_params'] = kernel_arg task.node.instance_info = i_info + task.node.deploy_interface = 'ramdisk' task.node.save() dhcp_opts = pxe_utils.dhcp_options_for_instance( task, ipxe_enabled=True) @@ -721,15 +581,14 @@ class iPXEBootTestCase(db_base.DbTestCase): dhcp_factory_mock.return_value = provider_mock image_info = {'kernel': ('', '/path/to/kernel'), 'ramdisk': ('', '/path/to/ramdisk')} - i_info_caps = {"boot_option": "ramdisk"} kernel_arg = "meow" get_image_info_mock.return_value = image_info with task_manager.acquire(self.context, self.node.uuid) as task: i_info = task.node.instance_info - i_info['capabilities'] = i_info_caps i_info['kernel_append_params'] = kernel_arg task.node.instance_info = i_info + task.node.deploy_interface = 'ramdisk' task.node.save() dhcp_opts = pxe_utils.dhcp_options_for_instance( task, ipxe_enabled=True) @@ -761,160 +620,6 @@ class iPXEBootTestCase(db_base.DbTestCase): mock_create_pxe_config.assert_called_once_with( task, expected_params, mock.ANY, ipxe_enabled=True) - @mock.patch('os.path.isfile', return_value=False, autospec=True) - @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True) - @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) - @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) - @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) - @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) - @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_netboot_active( - self, get_image_info_mock, cache_mock, - dhcp_factory_mock, switch_pxe_config_mock, - set_boot_device_mock, create_pxe_config_mock, isfile_mock): - provider_mock = mock.MagicMock() - dhcp_factory_mock.return_value = provider_mock - image_info = {'kernel': ('', '/path/to/kernel'), - 'ramdisk': ('', '/path/to/ramdisk')} - instance_info = {"boot_option": "netboot"} - get_image_info_mock.return_value = image_info - self.node.provision_state = states.ACTIVE - self.node.save() - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.properties['capabilities'] = 'boot_mode:bios' - task.node.instance_info['capabilities'] = instance_info - task.node.driver_internal_info['root_uuid_or_disk_id'] = ( - "30212642-09d3-467f-8e09-21685826ab50") - task.node.driver_internal_info['is_whole_disk_image'] = False - - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True, ip_version=6) - pxe_config_path = pxe_utils.get_pxe_config_file_path( - task.node.uuid, ipxe_enabled=True) - - task.driver.boot.prepare_instance(task) - - get_image_info_mock.assert_called_once_with( - task, ipxe_enabled=True) - cache_mock.assert_called_once_with(task, image_info, - ipxe_enabled=True) - provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) - create_pxe_config_mock.assert_called_once_with( - task, mock.ANY, CONF.pxe.ipxe_config_template, - ipxe_enabled=True) - switch_pxe_config_mock.assert_called_once_with( - pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50", - 'bios', False, iscsi_boot=False, ramdisk_boot=False, - ipxe_enabled=True, anaconda_boot=False) - self.assertFalse(set_boot_device_mock.called) - - @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) - @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) - @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) - @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) - @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_netboot_missing_root_uuid( - self, get_image_info_mock, cache_mock, - dhcp_factory_mock, switch_pxe_config_mock, - set_boot_device_mock): - provider_mock = mock.MagicMock() - dhcp_factory_mock.return_value = provider_mock - image_info = {'kernel': ('', '/path/to/kernel'), - 'ramdisk': ('', '/path/to/ramdisk')} - get_image_info_mock.return_value = image_info - instance_info = {"boot_option": "netboot"} - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.properties['capabilities'] = 'boot_mode:bios' - task.node.instance_info['capabilities'] = instance_info - task.node.driver_internal_info['is_whole_disk_image'] = False - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True, ip_version=4) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True, ip_version=6) - - task.driver.boot.prepare_instance(task) - - get_image_info_mock.assert_called_once_with( - task, ipxe_enabled=True) - cache_mock.assert_called_once_with(task, image_info, - ipxe_enabled=True) - provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) - self.assertFalse(switch_pxe_config_mock.called) - self.assertFalse(set_boot_device_mock.called) - - @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) - @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) - @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) - @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) - @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_netboot_missing_root_uuid_default( - self, get_image_info_mock, cache_mock, - dhcp_factory_mock, switch_pxe_config_mock, - set_boot_device_mock): - provider_mock = mock.MagicMock() - dhcp_factory_mock.return_value = provider_mock - image_info = {'kernel': ('', '/path/to/kernel'), - 'ramdisk': ('', '/path/to/ramdisk')} - get_image_info_mock.return_value = image_info - instance_info = self.node.instance_info - instance_info['capabilities'] = {"boot_option": "netboot"} - self.node.instance_info = instance_info - self.node.save() - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_internal_info['is_whole_disk_image'] = False - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True, ip_version=4) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True, ip_version=6) - - task.driver.boot.prepare_instance(task) - - get_image_info_mock.assert_called_once_with( - task, ipxe_enabled=True) - cache_mock.assert_called_once_with(task, image_info, - ipxe_enabled=True) - provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) - self.assertFalse(switch_pxe_config_mock.called) - self.assertFalse(set_boot_device_mock.called) - - # NOTE(TheJulia): The log mock below is attached to the iPXE interface - # which directly logs the warning that is being checked for. - @mock.patch.object(pxe_base.LOG, 'warning', autospec=True) - @mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True) - @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) - @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) - @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) - @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_whole_disk_image_missing_root_uuid( - self, get_image_info_mock, cache_mock, - dhcp_factory_mock, set_boot_device_mock, - clean_up_pxe_mock, log_mock): - provider_mock = mock.MagicMock() - dhcp_factory_mock.return_value = provider_mock - get_image_info_mock.return_value = {} - instance_info = {"boot_option": "netboot", - "boot_mode": "bios"} - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.properties['capabilities'] = 'boot_mode:bios' - task.node.instance_info['capabilities'] = instance_info - task.node.driver_internal_info['is_whole_disk_image'] = True - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=True, ip_version=6) - - task.driver.boot.prepare_instance(task) - get_image_info_mock.assert_called_once_with( - task, ipxe_enabled=True) - cache_mock.assert_called_once_with(task, {}, ipxe_enabled=True) - provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) - self.assertTrue(log_mock.called) - clean_up_pxe_mock.assert_called_once_with(task, ipxe_enabled=True) - set_boot_device_mock.assert_called_once_with( - task, boot_devices.DISK, persistent=True) - @mock.patch('os.path.isfile', lambda filename: False) @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True) @mock.patch.object(deploy_utils, 'is_iscsi_boot', lambda task: True) @@ -1037,8 +742,8 @@ class iPXEBootTestCase(db_base.DbTestCase): self.config(http_url=http_url, group='deploy') provider_mock = mock.MagicMock() dhcp_factory_mock.return_value = provider_mock - self.node.instance_info = {'boot_iso': 'http://1.2.3.4:1234/boot.iso', - 'capabilities': {'boot_option': 'ramdisk'}} + self.node.deploy_interface = 'ramdisk' + self.node.instance_info = {'boot_iso': 'http://1.2.3.4:1234/boot.iso'} image_info = {'kernel': ('', '/path/to/kernel'), 'deploy_kernel': ('', '/path/to/kernel'), 'ramdisk': ('', '/path/to/ramdisk'), @@ -1075,7 +780,7 @@ class iPXEBootTestCase(db_base.DbTestCase): @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_netboot_ramdisk_with_kernel_arg( + def test_prepare_instance_ramdisk_with_kernel_arg( self, get_image_info_mock, cache_mock, dhcp_factory_mock, switch_pxe_config_mock, set_boot_device_mock, create_pxe_config_mock): @@ -1130,14 +835,9 @@ class iPXEBootTestCase(db_base.DbTestCase): autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) @mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True) - def test_prepare_instance_localboot(self, clean_up_pxe_config_mock, - set_boot_device_mock, - secure_boot_mock): + def test_prepare_instance(self, clean_up_pxe_config_mock, + set_boot_device_mock, secure_boot_mock): with task_manager.acquire(self.context, self.node.uuid) as task: - instance_info = task.node.instance_info - instance_info['capabilities'] = {'boot_option': 'local'} - task.node.instance_info = instance_info - task.node.save() task.driver.boot.prepare_instance(task) clean_up_pxe_config_mock.assert_called_once_with( task, ipxe_enabled=True) @@ -1148,15 +848,11 @@ class iPXEBootTestCase(db_base.DbTestCase): @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) @mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True) - def test_prepare_instance_localboot_active(self, clean_up_pxe_config_mock, - set_boot_device_mock): + def test_prepare_instance_active(self, clean_up_pxe_config_mock, + set_boot_device_mock): self.node.provision_state = states.ACTIVE self.node.save() with task_manager.acquire(self.context, self.node.uuid) as task: - instance_info = task.node.instance_info - instance_info['capabilities'] = {'boot_option': 'local'} - task.node.instance_info = instance_info - task.node.save() task.driver.boot.prepare_instance(task) clean_up_pxe_config_mock.assert_called_once_with( task, ipxe_enabled=True) @@ -1168,14 +864,12 @@ class iPXEBootTestCase(db_base.DbTestCase): @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_localboot_with_fallback( + def test_prepare_instance_with_fallback( self, get_image_info_mock, cache_mock, dhcp_factory_mock, switch_pxe_config_mock, clean_up_pxe_config_mock, set_boot_device_mock): self.config(enable_netboot_fallback=True, group='pxe') with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.instance_info = task.node.instance_info - task.node.instance_info['capabilities'] = {'boot_option': 'local'} task.node.driver_internal_info['root_uuid_or_disk_id'] = ( "30212642-09d3-467f-8e09-21685826ab50") task.node.driver_internal_info['is_whole_disk_image'] = False diff --git a/ironic/tests/unit/drivers/modules/test_pxe.py b/ironic/tests/unit/drivers/modules/test_pxe.py index 779606229..e7d444104 100644 --- a/ironic/tests/unit/drivers/modules/test_pxe.py +++ b/ironic/tests/unit/drivers/modules/test_pxe.py @@ -77,7 +77,8 @@ class PXEBootTestCase(db_base.DbTestCase): self.config(enabled_boot_interfaces=[self.boot_interface, 'ipxe', 'fake']) - self.config(enabled_deploy_interfaces=['fake', 'direct', 'anaconda']) + self.config(enabled_deploy_interfaces=['fake', 'direct', 'anaconda', + 'ramdisk']) self.node = obj_utils.create_test_node( self.context, driver=self.driver, @@ -144,15 +145,6 @@ class PXEBootTestCase(db_base.DbTestCase): del task.node['instance_info']['image_source'] task.driver.boot.validate(task) - def test_validate_fail_missing_image_source(self): - with task_manager.acquire(self.context, self.node.uuid, - shared=True) as task: - task.node['instance_info']['capabilities'] = { - 'boot_option': 'netboot'} - del task.node['instance_info']['image_source'] - self.assertRaises(exception.MissingParameterValue, - task.driver.boot.validate, task) - def test_validate_fail_no_port(self): new_node = obj_utils.create_test_node( self.context, @@ -164,40 +156,18 @@ class PXEBootTestCase(db_base.DbTestCase): self.assertRaises(exception.MissingParameterValue, task.driver.boot.validate, task) - @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) - def test_validate_fail_no_image_kernel_ramdisk_props(self, mock_glance): - instance_info = {"boot_option": "netboot"} - mock_glance.return_value = {'properties': {}} - with task_manager.acquire(self.context, self.node.uuid, - shared=True) as task: - task.node.instance_info['capabilities'] = instance_info - self.assertRaises(exception.MissingParameterValue, - task.driver.boot.validate, - task) - - @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) - def test_validate_fail_glance_image_doesnt_exists(self, mock_glance): - mock_glance.side_effect = exception.ImageNotFound('not found') + @mock.patch.object(deploy_utils, 'get_boot_option', + return_value='ramdisk', autospec=True) + @mock.patch.object(deploy_utils, 'validate_image_properties', + autospec=True) + @mock.patch.object(deploy_utils, 'get_image_instance_info', autospec=True) + def test_validate_non_local(self, mock_get_iinfo, mock_validate, + mock_boot_opt): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: - task.node.instance_info['capabilities'] = { - 'boot_option': 'netboot'} - self.assertRaises(exception.InvalidParameterValue, - task.driver.boot.validate, task) - - @mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) - def test_validate_fail_glance_conn_problem(self, mock_glance): - exceptions = (exception.GlanceConnectionFailed('connection fail'), - exception.ImageNotAuthorized('not authorized'), - exception.Invalid('invalid')) - mock_glance.side_effect = exceptions - for exc in exceptions: - with task_manager.acquire(self.context, self.node.uuid, - shared=True) as task: - task.node.instance_info['capabilities'] = { - 'boot_option': 'netboot'} - self.assertRaises(exception.InvalidParameterValue, - task.driver.boot.validate, task) + task.driver.boot.validate(task) + mock_validate.assert_called_once_with( + task, mock_get_iinfo.return_value) def test_validate_inspection(self): with task_manager.acquire(self.context, self.node.uuid) as task: @@ -486,217 +456,13 @@ class PXEBootTestCase(db_base.DbTestCase): self.node.save() self._test_clean_up_ramdisk(mode='rescue') - @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) - @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) - @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) - @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) - @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_netboot_bios( - self, get_image_info_mock, cache_mock, - dhcp_factory_mock, switch_pxe_config_mock, - set_boot_device_mock): - provider_mock = mock.MagicMock() - dhcp_factory_mock.return_value = provider_mock - image_info = {'kernel': ('', '/path/to/kernel'), - 'ramdisk': ('', '/path/to/ramdisk')} - get_image_info_mock.return_value = image_info - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.properties['capabilities'] = 'boot_mode:bios' - task.node.driver_internal_info['root_uuid_or_disk_id'] = ( - "30212642-09d3-467f-8e09-21685826ab50") - task.node.driver_internal_info['is_whole_disk_image'] = False - task.node.instance_info = { - 'capabilities': {'boot_option': 'netboot', - 'boot_mode': 'bios'}} - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=False, ip_version=4) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=False, ip_version=6) - pxe_config_path = pxe_utils.get_pxe_config_file_path( - task.node.uuid) - task.driver.boot.prepare_instance(task) - - get_image_info_mock.assert_called_once_with( - task, ipxe_enabled=False) - cache_mock.assert_called_once_with( - task, image_info, ipxe_enabled=False) - provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) - switch_pxe_config_mock.assert_called_once_with( - pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50", - 'bios', False, iscsi_boot=False, ramdisk_boot=False, - ipxe_enabled=False, anaconda_boot=False) - set_boot_device_mock.assert_called_once_with(task, - boot_devices.PXE, - persistent=True) - - @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) - @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) - @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) - @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) - @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_netboot_uefi( - self, get_image_info_mock, cache_mock, - dhcp_factory_mock, switch_pxe_config_mock, - set_boot_device_mock): - provider_mock = mock.MagicMock() - dhcp_factory_mock.return_value = provider_mock - image_info = {'kernel': ('', '/path/to/kernel'), - 'ramdisk': ('', '/path/to/ramdisk')} - get_image_info_mock.return_value = image_info - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_internal_info['root_uuid_or_disk_id'] = ( - "30212642-09d3-467f-8e09-21685826ab50") - task.node.driver_internal_info['is_whole_disk_image'] = False - task.node.instance_info = { - 'capabilities': {'boot_option': 'netboot'}} - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=False, ip_version=4) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=False, ip_version=6) - pxe_config_path = pxe_utils.get_pxe_config_file_path( - task.node.uuid) - task.driver.boot.prepare_instance(task) - - get_image_info_mock.assert_called_once_with( - task, ipxe_enabled=False) - cache_mock.assert_called_once_with( - task, image_info, ipxe_enabled=False) - provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) - switch_pxe_config_mock.assert_called_once_with( - pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50", - 'uefi', False, iscsi_boot=False, ramdisk_boot=False, - ipxe_enabled=False, anaconda_boot=False) - set_boot_device_mock.assert_called_once_with(task, - boot_devices.PXE, - persistent=True) - - @mock.patch('os.path.isfile', return_value=False, autospec=True) - @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True) - @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) - @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) - @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) - @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) - @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_netboot_active( - self, get_image_info_mock, cache_mock, - dhcp_factory_mock, switch_pxe_config_mock, - set_boot_device_mock, create_pxe_config_mock, isfile_mock): - provider_mock = mock.MagicMock() - dhcp_factory_mock.return_value = provider_mock - image_info = {'kernel': ('', '/path/to/kernel'), - 'ramdisk': ('', '/path/to/ramdisk')} - instance_info = {"boot_option": "netboot"} - get_image_info_mock.return_value = image_info - self.node.provision_state = states.ACTIVE - self.node.save() - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.properties['capabilities'] = 'boot_mode:bios' - task.node.driver_internal_info['root_uuid_or_disk_id'] = ( - "30212642-09d3-467f-8e09-21685826ab50") - task.node.driver_internal_info['is_whole_disk_image'] = False - task.node.instance_info['capabilities'] = instance_info - task.driver.boot.prepare_instance(task) - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=False) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=False, ip_version=6) - pxe_config_path = pxe_utils.get_pxe_config_file_path( - task.node.uuid) - - get_image_info_mock.assert_called_once_with( - task, ipxe_enabled=False) - cache_mock.assert_called_once_with( - task, image_info, ipxe_enabled=False) - provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) - create_pxe_config_mock.assert_called_once_with( - task, mock.ANY, CONF.pxe.pxe_config_template, - ipxe_enabled=False) - switch_pxe_config_mock.assert_called_once_with( - pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50", - 'bios', False, iscsi_boot=False, ramdisk_boot=False, - ipxe_enabled=False, anaconda_boot=False) - self.assertFalse(set_boot_device_mock.called) - - @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) - @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) - @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) - @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) - @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_netboot_missing_root_uuid( - self, get_image_info_mock, cache_mock, - dhcp_factory_mock, switch_pxe_config_mock, - set_boot_device_mock): - provider_mock = mock.MagicMock() - dhcp_factory_mock.return_value = provider_mock - image_info = {'kernel': ('', '/path/to/kernel'), - 'ramdisk': ('', '/path/to/ramdisk')} - instance_info = {"boot_option": "netboot"} - get_image_info_mock.return_value = image_info - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.properties['capabilities'] = 'boot_mode:bios' - task.node.instance_info['capabilities'] = instance_info - task.node.driver_internal_info['is_whole_disk_image'] = False - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=False) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=False, ip_version=6) - - task.driver.boot.prepare_instance(task) - - get_image_info_mock.assert_called_once_with(task, - ipxe_enabled=False) - cache_mock.assert_called_once_with( - task, image_info, ipxe_enabled=False) - provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) - self.assertFalse(switch_pxe_config_mock.called) - self.assertFalse(set_boot_device_mock.called) - - @mock.patch.object(pxe_base.LOG, 'warning', autospec=True) - @mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True) - @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) - @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) - @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) - @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) - def test_prepare_instance_whole_disk_image_missing_root_uuid( - self, get_image_info_mock, cache_mock, - dhcp_factory_mock, set_boot_device_mock, - clean_up_pxe_mock, log_mock): - provider_mock = mock.MagicMock() - dhcp_factory_mock.return_value = provider_mock - get_image_info_mock.return_value = {} - instance_info = {"boot_option": "netboot"} - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.properties['capabilities'] = 'boot_mode:bios' - task.node.instance_info['capabilities'] = instance_info - task.node.driver_internal_info['is_whole_disk_image'] = True - dhcp_opts = pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=False) - dhcp_opts += pxe_utils.dhcp_options_for_instance( - task, ipxe_enabled=False, ip_version=6) - task.driver.boot.prepare_instance(task) - get_image_info_mock.assert_called_once_with(task, - ipxe_enabled=False) - cache_mock.assert_called_once_with( - task, {}, ipxe_enabled=False) - provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) - self.assertTrue(log_mock.called) - clean_up_pxe_mock.assert_called_once_with( - task, ipxe_enabled=False) - set_boot_device_mock.assert_called_once_with( - task, boot_devices.DISK, persistent=True) - @mock.patch.object(boot_mode_utils, 'configure_secure_boot_if_needed', autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) @mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True) - def test_prepare_instance_localboot(self, clean_up_pxe_config_mock, - set_boot_device_mock, - secure_boot_mock): + def test_prepare_instance(self, clean_up_pxe_config_mock, + set_boot_device_mock, secure_boot_mock): with task_manager.acquire(self.context, self.node.uuid) as task: - instance_info = task.node.instance_info - instance_info['capabilities'] = {'boot_option': 'local'} - task.node.instance_info = instance_info - task.node.save() task.driver.boot.prepare_instance(task) clean_up_pxe_config_mock.assert_called_once_with( task, ipxe_enabled=False) @@ -707,15 +473,11 @@ class PXEBootTestCase(db_base.DbTestCase): @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) @mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True) - def test_prepare_instance_localboot_active(self, clean_up_pxe_config_mock, - set_boot_device_mock): + def test_prepare_instance_active(self, clean_up_pxe_config_mock, + set_boot_device_mock): self.node.provision_state = states.ACTIVE self.node.save() with task_manager.acquire(self.context, self.node.uuid) as task: - instance_info = task.node.instance_info - instance_info['capabilities'] = {'boot_option': 'local'} - task.node.instance_info = instance_info - task.node.save() task.driver.boot.prepare_instance(task) clean_up_pxe_config_mock.assert_called_once_with( task, ipxe_enabled=False) @@ -741,9 +503,7 @@ class PXEBootTestCase(db_base.DbTestCase): self.node.provision_state = states.DEPLOYING get_image_info_mock.return_value = image_info with task_manager.acquire(self.context, self.node.uuid) as task: - instance_info = task.node.instance_info - instance_info['capabilities'] = {'boot_option': 'ramdisk'} - task.node.instance_info = instance_info + task.node.deploy_interface = 'ramdisk' task.node.save() dhcp_opts = pxe_utils.dhcp_options_for_instance( task, ipxe_enabled=False) diff --git a/ironic/tests/unit/drivers/modules/test_ramdisk.py b/ironic/tests/unit/drivers/modules/test_ramdisk.py index 4deedbfc2..66d11aa18 100644 --- a/ironic/tests/unit/drivers/modules/test_ramdisk.py +++ b/ironic/tests/unit/drivers/modules/test_ramdisk.py @@ -47,8 +47,6 @@ class RamdiskDeployTestCase(db_base.DbTestCase): self.config(tftp_root=self.temp_dir, group='pxe') self.temp_dir = tempfile.mkdtemp() self.config(images_path=self.temp_dir, group='pxe') - self.config(enabled_deploy_interfaces=['ramdisk']) - self.config(enabled_boot_interfaces=['pxe']) for iface in drivers_base.ALL_INTERFACES: impl = 'fake' if iface == 'network': @@ -94,7 +92,6 @@ class RamdiskDeployTestCase(db_base.DbTestCase): task, ipxe_enabled=False, ip_version=6) pxe_config_path = pxe_utils.get_pxe_config_file_path( task.node.uuid) - task.node.properties['capabilities'] = 'boot_option:netboot' task.node.driver_internal_info['is_whole_disk_image'] = False task.driver.deploy.prepare(task) task.driver.deploy.deploy(task) @@ -122,20 +119,26 @@ class RamdiskDeployTestCase(db_base.DbTestCase): image_info = {'kernel': ('', '/path/to/kernel'), 'ramdisk': ('', '/path/to/ramdisk')} mock_image_info.return_value = image_info - i_info = self.node.instance_info - i_info.update({'capabilities': {'boot_option': 'ramdisk'}}) - self.node.instance_info = i_info - self.node.save() with task_manager.acquire(self.context, self.node.uuid) as task: self.assertIsNone(task.driver.deploy.deploy(task)) mock_image_info.assert_called_once_with(task, ipxe_enabled=False) mock_cache.assert_called_once_with( task, image_info, ipxe_enabled=False) self.assertFalse(mock_warning.called) - i_info['configdrive'] = 'meow' - self.node.instance_info = i_info + + @mock.patch.object(ramdisk.LOG, 'warning', autospec=True) + @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) + @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) + @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True) + @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True) + def test_deploy_with_configdrive(self, mock_image_info, mock_cache, + mock_dhcp_factory, mock_switch_config, + mock_warning): + image_info = {'kernel': ('', '/path/to/kernel'), + 'ramdisk': ('', '/path/to/ramdisk')} + mock_image_info.return_value = image_info + self.node.set_instance_info('configdrive', 'meow') self.node.save() - mock_warning.reset_mock() with task_manager.acquire(self.context, self.node.uuid) as task: self.assertIsNone(task.driver.deploy.deploy(task)) self.assertTrue(mock_warning.called) diff --git a/ironic/tests/unit/drivers/modules/test_snmp.py b/ironic/tests/unit/drivers/modules/test_snmp.py index 36a59a396..6bdd2da5a 100644 --- a/ironic/tests/unit/drivers/modules/test_snmp.py +++ b/ironic/tests/unit/drivers/modules/test_snmp.py @@ -875,7 +875,7 @@ class SNMPDeviceDriverTestCase(db_base.DbTestCase): def test_power_off_timeout(self, mock_sleep, mock_get_client): # Ensure that a power off consistency poll timeout causes an error mock_client = mock_get_client.return_value - CONF.snmp.power_timeout = 5 + CONF.set_override('power_timeout', 5, 'snmp') driver = snmp._get_driver(self.node) mock_client.get.return_value = driver.value_power_on pstate = driver.power_off() diff --git a/ironic/tests/unit/drivers/pxe_config.template b/ironic/tests/unit/drivers/pxe_config.template index 7cf91e369..238dde4ce 100644 --- a/ironic/tests/unit/drivers/pxe_config.template +++ b/ironic/tests/unit/drivers/pxe_config.template @@ -5,12 +5,6 @@ kernel /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/deploy_kernel append initrd=/tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/deploy_ramdisk selinux=0 troubleshoot=0 text test_param ipappend 2 - -label boot_partition -kernel /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/kernel -append initrd=/tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/ramdisk root={{ ROOT }} ro text test_param - - label boot_whole_disk COM32 chain.c32 append mbr:{{ DISK_IDENTIFIER }} diff --git a/ironic/tests/unit/drivers/pxe_grub_config.template b/ironic/tests/unit/drivers/pxe_grub_config.template index 568018671..c4410b489 100644 --- a/ironic/tests/unit/drivers/pxe_grub_config.template +++ b/ironic/tests/unit/drivers/pxe_grub_config.template @@ -7,11 +7,6 @@ menuentry "deploy" { initrdefi /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/deploy_ramdisk } -menuentry "boot_partition" { - linuxefi /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/kernel root=(( ROOT )) ro text test_param boot_server=192.0.2.1 - initrdefi /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/ramdisk -} - menuentry "boot_ramdisk" { linuxefi /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/kernel root=/dev/ram0 text test_param ramdisk_param initrdefi /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/ramdisk |