Finally remove support for netboot and the boot_option capability

Instance network boot (not to be confused with ramdisk, iSCSI or
anaconda deploy methods) is insecure, underused and difficult to
maintain. This change removes a lot of related code from Ironic.

The so called "netboot fallback" is still supported for legacy boot when
boot device management is not available or is unreliable.

Change-Id: Ia8510e4acac6dec0a1e4f5cb0e07008548a00c52
This commit is contained in:
Dmitry Tantsur 2022-07-14 17:33:55 +02:00
parent 41484988ef
commit f0a1778766
39 changed files with 168 additions and 1577 deletions

View File

@ -681,12 +681,6 @@ if [[ "$IRONIC_BOOT_MODE" == "uefi" ]]; then
fi fi
fi fi
# TODO(dtantsur): change this when we change the default value.
IRONIC_DEFAULT_BOOT_OPTION=${IRONIC_DEFAULT_BOOT_OPTION:-local}
if [ $IRONIC_DEFAULT_BOOT_OPTION != "netboot" ] && [ $IRONIC_DEFAULT_BOOT_OPTION != "local" ]; then
die $LINENO "Supported values for IRONIC_DEFAULT_BOOT_OPTION are 'netboot' and 'local' only."
fi
# TODO(pas-ha) find a way to (cross-)sign the custom CA bundle used by tls-proxy # TODO(pas-ha) find a way to (cross-)sign the custom CA bundle used by tls-proxy
# with default iPXE cert - for reference see http://ipxe.org/crypto # with default iPXE cert - for reference see http://ipxe.org/crypto
if is_service_enabled tls-proxy && [[ "$IRONIC_IPXE_USE_SWIFT" == "True" ]]; then if is_service_enabled tls-proxy && [[ "$IRONIC_IPXE_USE_SWIFT" == "True" ]]; then
@ -1855,8 +1849,6 @@ function configure_ironic_conductor {
iniset $IRONIC_CONF_FILE dhcp dhcp_provider $IRONIC_DHCP_PROVIDER iniset $IRONIC_CONF_FILE dhcp dhcp_provider $IRONIC_DHCP_PROVIDER
iniset $IRONIC_CONF_FILE deploy default_boot_option $IRONIC_DEFAULT_BOOT_OPTION
isolinux=$(find -L /usr -type f -name "isolinux.bin" | head -1) isolinux=$(find -L /usr -type f -name "isolinux.bin" | head -1)
if [[ -n "$isolinux" ]]; then if [[ -n "$isolinux" ]]; then
iniset $IRONIC_CONF_FILE DEFAULT isolinux_bin "$isolinux" iniset $IRONIC_CONF_FILE DEFAULT isolinux_bin "$isolinux"
@ -2903,8 +2895,7 @@ function upload_image_if_needed {
# Change the default image only if the provided settings prevent the # Change the default image only if the provided settings prevent the
# default cirros image from working. # default cirros image from working.
if [[ "$IRONIC_TEMPEST_WHOLE_DISK_IMAGE" != True \ if [[ "$IRONIC_TEMPEST_WHOLE_DISK_IMAGE" != True ]]; then
&& "$IRONIC_DEFAULT_BOOT_OPTION" == local ]]; then
IRONIC_IMAGE_NAME=$IRONIC_PARTITIONED_IMAGE_NAME IRONIC_IMAGE_NAME=$IRONIC_PARTITIONED_IMAGE_NAME
DEFAULT_IMAGE_NAME=$IRONIC_IMAGE_NAME DEFAULT_IMAGE_NAME=$IRONIC_IMAGE_NAME
fi fi
@ -3242,7 +3233,9 @@ function ironic_configure_tempest {
# Driver for API tests # Driver for API tests
iniset $TEMPEST_CONFIG baremetal driver fake-hardware iniset $TEMPEST_CONFIG baremetal driver fake-hardware
iniset $TEMPEST_CONFIG baremetal default_boot_option $IRONIC_DEFAULT_BOOT_OPTION # NOTE(dtantsur): remove this when the tempest plugin no longer supports
# netboot (i.e. when Zed is the oldest supported branch).
iniset $TEMPEST_CONFIG baremetal default_boot_option local
local adjusted_root_disk_size_gb local adjusted_root_disk_size_gb
if [[ "$IRONIC_IS_HARDWARE" == "False" ]]; then if [[ "$IRONIC_IS_HARDWARE" == "False" ]]; then

View File

@ -120,18 +120,6 @@ opts = [
mutable=True, mutable=True,
help=_('Whether to power off a node after deploy failure. ' help=_('Whether to power off a node after deploy failure. '
'Defaults to True.')), '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', cfg.StrOpt('default_boot_mode',
choices=[(boot_modes.UEFI, _('UEFI boot mode')), choices=[(boot_modes.UEFI, _('UEFI boot mode')),
(boot_modes.LEGACY_BIOS, _('Legacy BIOS boot mode'))], (boot_modes.LEGACY_BIOS, _('Legacy BIOS boot mode'))],

View File

@ -16,7 +16,6 @@ from urllib import parse as urlparse
from ironic_lib import metrics_utils from ironic_lib import metrics_utils
from oslo_log import log from oslo_log import log
from oslo_utils import excutils
from oslo_utils import units from oslo_utils import units
from ironic.common import exception from ironic.common import exception
@ -325,33 +324,7 @@ class CustomAgentDeploy(agent_base.AgentBaseMixin, agent_base.AgentDeployMixin,
if node.provision_state == states.DEPLOYING: if node.provision_state == states.DEPLOYING:
# Validate network interface to ensure that it supports boot # Validate network interface to ensure that it supports boot
# options configured on the node. # options configured on the node.
try: task.driver.network.validate(task)
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
# Determine if this is a fast track sequence # Determine if this is a fast track sequence
fast_track_deploy = manager_utils.is_fast_track(task) fast_track_deploy = manager_utils.is_fast_track(task)
if fast_track_deploy: if fast_track_deploy:
@ -597,13 +570,6 @@ class AgentDeploy(CustomAgentDeploy):
iwdi = task.node.driver_internal_info.get('is_whole_disk_image') iwdi = task.node.driver_internal_info.get('is_whole_disk_image')
cpu_arch = task.node.properties.get('cpu_arch') 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 # In case of local boot using partition image, we need both
# 'root_uuid_or_disk_id' and 'efi_system_partition_uuid' to configure # 'root_uuid_or_disk_id' and 'efi_system_partition_uuid' to configure
# bootloader for local boot. # bootloader for local boot.

View File

@ -1217,12 +1217,12 @@ class AgentDeployMixin(HeartbeatMixin, AgentOobStepsMixin):
""" """
node = task.node node = task.node
if deploy_utils.get_boot_option(node) == "local": # Install the boot loader
# Install the boot loader self.configure_local_boot(
self.configure_local_boot( task, root_uuid=root_uuid,
task, root_uuid=root_uuid, efi_system_part_uuid=efi_sys_uuid,
efi_system_part_uuid=efi_sys_uuid, prep_boot_part_uuid=prep_boot_part_uuid)
prep_boot_part_uuid=prep_boot_part_uuid)
try: try:
task.driver.boot.prepare_instance(task) task.driver.boot.prepare_instance(task)
except Exception as e: except Exception as e:

View File

@ -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 }}

View File

@ -396,12 +396,6 @@ class AnsibleDeploy(agent_base.HeartbeatMixin,
task.driver.boot.validate(task) task.driver.boot.validate(task)
node = task.node 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 = {} params = {}
image_source = node.instance_info.get('image_source') image_source = node.instance_info.get('image_source')

View File

@ -55,7 +55,6 @@ LOG = logging.getLogger(__name__)
METRICS = metrics_utils.get_metrics_logger(__name__) METRICS = metrics_utils.get_metrics_logger(__name__)
SUPPORTED_CAPABILITIES = { SUPPORTED_CAPABILITIES = {
'boot_option': ('local', 'netboot', 'ramdisk', 'kickstart'),
'boot_mode': ('bios', 'uefi'), 'boot_mode': ('bios', 'uefi'),
'secure_boot': ('true', 'false'), 'secure_boot': ('true', 'false'),
'disk_label': ('msdos', 'gpt'), '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. # 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, def switch_pxe_config(path, root_uuid_or_disk_id, boot_mode,
is_whole_disk_image, iscsi_boot=False, is_whole_disk_image, iscsi_boot=False,
ramdisk_boot=False, ipxe_enabled=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 :returns: A string representing the boot option type. Defaults to
configuration setting [deploy]default_boot_mode. 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): if is_anaconda_deploy(node):
return 'kickstart' return 'kickstart'
if is_ramdisk_deploy(node): if is_ramdisk_deploy(node):
return 'ramdisk' return 'ramdisk'
capabilities = utils.parse_instance_info_capabilities(node) return 'local'
return capabilities.get('boot_option',
CONF.deploy.default_boot_option).lower()
# FIXME(dtantsur): relying on deploy interface name is an anti-pattern. # FIXME(dtantsur): relying on deploy interface name is an anti-pattern.

View File

@ -320,7 +320,7 @@ class IloVirtualMediaBoot(base.BootInterface):
except exception.ImageRefValidationFailed: except exception.ImageRefValidationFailed:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
LOG.error("Virtual media deploy with 'ramdisk' " LOG.error("Virtual media deploy with 'ramdisk' "
"boot_option accepts only Glance images or " "deploy accepts only Glance images or "
"HTTP(S) URLs as " "HTTP(S) URLs as "
"instance_info['boot_iso']. Either %s " "instance_info['boot_iso']. Either %s "
"is not a valid HTTP(S) URL or is not " "is not a valid HTTP(S) URL or is not "
@ -460,21 +460,8 @@ class IloVirtualMediaBoot(base.BootInterface):
boot_devices.CDROM, boot_devices.CDROM,
persistent=True) persistent=True)
else: else:
# Boot from disk every time if the image deployed is manager_utils.node_set_boot_device(task, boot_devices.DISK,
# a whole disk image. persistent=True)
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)
# Set boot mode # Set boot mode
ilo_common.update_boot_mode(task) ilo_common.update_boot_mode(task)
# Need to enable secure boot, if being requested # Need to enable secure boot, if being requested
@ -590,8 +577,7 @@ class IloPXEBoot(pxe.PXEBoot):
"""Prepares the boot of instance. """Prepares the boot of instance.
This method prepares the boot of the instance after reading This method prepares the boot of the instance after reading
relevant information from the node's instance_info. In case of netboot, relevant information from the node's instance_info. In case of
it updates the dhcp entries and switches the PXE config. In case of
localboot, it cleans up the PXE config. localboot, it cleans up the PXE config.
In case of 'boot from volume', it updates the iSCSI info onto iLO and In case of 'boot from volume', it updates the iSCSI info onto iLO and
sets the node to boot from 'UefiTarget' boot device. sets the node to boot from 'UefiTarget' boot device.
@ -683,8 +669,7 @@ class IloiPXEBoot(ipxe.iPXEBoot):
"""Prepares the boot of instance. """Prepares the boot of instance.
This method prepares the boot of the instance after reading This method prepares the boot of the instance after reading
relevant information from the node's instance_info. In case of netboot, relevant information from the node's instance_info. In case of
it updates the dhcp entries and switches the PXE config. In case of
localboot, it cleans up the PXE config. localboot, it cleans up the PXE config.
In case of 'boot from volume', it updates the iSCSI info onto iLO and In case of 'boot from volume', it updates the iSCSI info onto iLO and
sets the node to boot from 'UefiTarget' boot device. sets the node to boot from 'UefiTarget' boot device.
@ -904,7 +889,7 @@ class IloUefiHttpsBoot(base.BootInterface):
except exception.ImageRefValidationFailed: except exception.ImageRefValidationFailed:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
LOG.error("UEFI-HTTPS boot with 'ramdisk' " LOG.error("UEFI-HTTPS boot with 'ramdisk' "
"boot_option accepts only Glance images or " "deploy accepts only Glance images or "
"HTTPS URLs as " "HTTPS URLs as "
"instance_info['boot_iso']. Either %s " "instance_info['boot_iso']. Either %s "
"is not a valid HTTPS URL or is not " "is not a valid HTTPS URL or is not "

View File

@ -44,9 +44,8 @@ def _attach_boot_iso_if_needed(task):
This method checks the instance info of the baremetal node for a 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', boot iso. If the instance info has a value of key 'boot_iso',
it indicates that 'boot_option' is 'netboot'. Therefore it attaches it indicates ramdisk deploy. Therefore it attaches the boot ISO on the
the boot ISO on the baremetal node and then sets the node to boot from baremetal node and then sets the node to boot from virtual media cdrom.
virtual media cdrom.
:param task: a TaskManager instance containing the node to act on. :param task: a TaskManager instance containing the node to act on.
""" """

View File

@ -25,12 +25,6 @@ echo Powering off in 30 seconds.
sleep 30 sleep 30
poweroff 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 :boot_anaconda
imgfree 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 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

View File

@ -376,9 +376,8 @@ def attach_boot_iso_if_needed(task):
This method checks the instance info of the bare metal node for a 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', boot ISO. If the instance info has a value of key 'boot_iso',
it indicates that 'boot_option' is 'netboot'. Threfore it attaches it indicates ramdisk deploy. Therefore it attaches the boot ISO on the bare
the boot ISO on the bare metal node and then sets the node to boot from metal node and then sets the node to boot from virtual media cdrom.
virtual media cdrom.
:param task: a TaskManager instance containing the node to act on. :param task: a TaskManager instance containing the node to act on.
:raises: IRMCOperationError if attaching virtual media failed. :raises: IRMCOperationError if attaching virtual media failed.

View File

@ -20,9 +20,7 @@ from oslo_log import log
from ironic.common import exception from ironic.common import exception
from ironic.common.i18n import _ from ironic.common.i18n import _
from ironic.common import neutron from ironic.common import neutron
from ironic.common import states
from ironic.drivers import base from ironic.drivers import base
from ironic.drivers.modules import deploy_utils
from ironic.drivers.modules.network import common from ironic.drivers.modules.network import common
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
@ -61,15 +59,6 @@ class NeutronNetwork(common.NeutronVIFPortIDMixin,
""" """
self.get_cleaning_network_uuid(task) self.get_cleaning_network_uuid(task)
self.get_provisioning_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): def _add_network(self, task, network, security_groups, process):
# If we have left over ports from a previous process, remove them # If we have left over ports from a previous process, remove them

View File

@ -261,50 +261,6 @@ class PXEBaseMixin(object):
anaconda_boot=(boot_option == "kickstart")) anaconda_boot=(boot_option == "kickstart"))
boot_device = boot_devices.PXE 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: else:
# NOTE(dtantsur): create a PXE configuration as a safety net for # NOTE(dtantsur): create a PXE configuration as a safety net for
# hardware uncapable of persistent boot. If on a reboot it will try # hardware uncapable of persistent boot. If on a reboot it will try

View File

@ -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) }} append initrd={{ pxe_options.deployment_ari_path }} selinux=0 troubleshoot=0 text {{ pxe_options.pxe_append_params|default("", true) }}
ipappend 2 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 label boot_whole_disk
COM32 chain.c32 COM32 chain.c32
append mbr:{{ DISK_IDENTIFIER }} append mbr:{{ DISK_IDENTIFIER }}

View File

@ -7,11 +7,6 @@ menuentry "deploy" {
initrdefi {{ pxe_options.deployment_ari_path }} 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" { 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) }} 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 }} initrdefi {{ pxe_options.ari_path }}

View File

@ -1295,25 +1295,6 @@ class PXEInterfacesTestCase(db_base.DbTestCase):
self.assertEqual('instance_ramdisk_uuid', self.assertEqual('instance_ramdisk_uuid',
task.node.instance_info['ramdisk']) 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', @mock.patch('ironic.drivers.modules.deploy_utils.get_boot_option',
return_value='local', autospec=True) return_value='local', autospec=True)
def test_get_instance_image_info_localboot(self, boot_opt_mock): def test_get_instance_image_info_localboot(self, boot_opt_mock):

View File

@ -7319,7 +7319,6 @@ class DoNodeAdoptionTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
mock_take_over.assert_called_once_with(task.driver.deploy, task) mock_take_over.assert_called_once_with(task.driver.deploy, task)
self.assertFalse(mock_start_console.called) self.assertFalse(mock_start_console.called)
mock_boot_validate.assert_not_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', @mock.patch('ironic.common.image_service.HttpImageService.validate_href',
autospec=True) 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.FakeBoot.validate', autospec=True)
@mock.patch('ironic.drivers.modules.fake.FakeConsole.start_console', @mock.patch('ironic.drivers.modules.fake.FakeConsole.start_console',
autospec=True) autospec=True)
@mock.patch('ironic.drivers.modules.fake.FakeDeploy.take_over', @mock.patch('ironic.drivers.modules.ramdisk.RamdiskDeploy.take_over',
autospec=True) autospec=True)
@mock.patch('ironic.drivers.modules.fake.FakeDeploy.prepare', @mock.patch('ironic.drivers.modules.ramdisk.RamdiskDeploy.prepare',
autospec=True) autospec=True)
def test__do_adoption_with_netboot(self, def test__do_adoption_ramdisk_deploy(self,
mock_prepare, mock_prepare,
mock_take_over, mock_take_over,
mock_start_console, mock_start_console,
mock_boot_validate, mock_boot_validate,
mock_power_validate, mock_power_validate,
mock_validate_href): mock_validate_href):
"""Test a successful node adoption""" """Test a successful node adoption"""
self._start_service() self._start_service()
node = obj_utils.create_test_node( node = obj_utils.create_test_node(
self.context, driver='fake-hardware', self.context, driver='fake-hardware',
provision_state=states.ADOPTING, deploy_interface='ramdisk',
instance_info={ provision_state=states.ADOPTING)
'capabilities': {'boot_option': 'netboot'},
'image_source': 'http://127.0.0.1/image',
})
task = task_manager.TaskManager(self.context, node.uuid) task = task_manager.TaskManager(self.context, node.uuid)
self.service._do_adoption(task) 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) mock_take_over.assert_called_once_with(task.driver.deploy, task)
self.assertFalse(mock_start_console.called) self.assertFalse(mock_start_console.called)
mock_boot_validate.assert_called_once_with(task.driver.boot, task) 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.FakeBoot.validate', autospec=True)
@mock.patch('ironic.drivers.modules.fake.FakeConsole.start_console', @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.FakeBoot.validate', autospec=True)
@mock.patch('ironic.drivers.modules.fake.FakeConsole.start_console', @mock.patch('ironic.drivers.modules.fake.FakeConsole.start_console',
autospec=True) autospec=True)
@mock.patch('ironic.drivers.modules.fake.FakeDeploy.take_over', @mock.patch('ironic.drivers.modules.ramdisk.RamdiskDeploy.take_over',
autospec=True) autospec=True)
@mock.patch('ironic.drivers.modules.fake.FakeDeploy.prepare', @mock.patch('ironic.drivers.modules.ramdisk.RamdiskDeploy.prepare',
autospec=True) autospec=True)
def test__do_adoption_boot_validate_failure(self, def test__do_adoption_boot_validate_failure(self,
mock_prepare, mock_prepare,
@ -7428,10 +7420,8 @@ class DoNodeAdoptionTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
self._start_service() self._start_service()
node = obj_utils.create_test_node( node = obj_utils.create_test_node(
self.context, driver='fake-hardware', self.context, driver='fake-hardware',
provision_state=states.ADOPTING, deploy_interface='ramdisk',
instance_info={ provision_state=states.ADOPTING)
'capabilities': {'boot_option': 'netboot'},
})
task = task_manager.TaskManager(self.context, node.uuid) task = task_manager.TaskManager(self.context, node.uuid)
self.service._do_adoption(task) self.service._do_adoption(task)

View File

@ -25,12 +25,6 @@ echo Powering off in 30 seconds.
sleep 30 sleep 30
poweroff 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 :boot_anaconda
imgfree 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 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

View File

@ -25,12 +25,6 @@ echo Powering off in 30 seconds.
sleep 30 sleep 30
poweroff 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 :boot_anaconda
imgfree 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 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

View File

@ -25,12 +25,6 @@ echo Powering off in 30 seconds.
sleep 30 sleep 30
poweroff 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 :boot_anaconda
imgfree 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 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

View File

@ -25,12 +25,6 @@ echo Powering off in 30 seconds.
sleep 30 sleep 30
poweroff 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 :boot_anaconda
imgfree 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 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

View File

@ -25,12 +25,6 @@ echo Powering off in 30 seconds.
sleep 30 sleep 30
poweroff 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 :boot_anaconda
imgfree 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 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

View File

@ -25,12 +25,6 @@ echo Powering off in 30 seconds.
sleep 30 sleep 30
poweroff 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 :boot_anaconda
imgfree 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 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

View File

@ -25,12 +25,6 @@ echo Powering off in 30 seconds.
sleep 30 sleep 30
poweroff 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 :boot_anaconda
imgfree 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 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

View File

@ -25,12 +25,6 @@ echo Powering off in 30 seconds.
sleep 30 sleep 30
poweroff 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 :boot_anaconda
imgfree 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 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

View File

@ -623,24 +623,6 @@ class TestAnsibleDeploy(AnsibleDeployTestCaseBase):
{'instance_info.image_source': INSTANCE_INFO['image_source']}, {'instance_info.image_source': INSTANCE_INFO['image_source']},
mock.ANY) 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, @mock.patch.object(ansible_deploy, '_calculate_memory_req', autospec=True,
return_value=2000) return_value=2000)
@mock.patch.object(utils, 'node_power_action', autospec=True) @mock.patch.object(utils, 'node_power_action', autospec=True)

View File

@ -452,14 +452,14 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest):
spec_set=True, autospec=True) spec_set=True, autospec=True)
@mock.patch.object(service_utils, 'is_glance_image', spec_set=True, @mock.patch.object(service_utils, 'is_glance_image', spec_set=True,
autospec=True) autospec=True)
def test_validate_ramdisk_boot_option_glance(self, is_glance_image_mock, def test_validate_ramdisk_deploy_glance(self, is_glance_image_mock,
validate_href_mock, validate_href_mock,
val_driver_info_mock): val_driver_info_mock):
instance_info = self.node.instance_info instance_info = self.node.instance_info
boot_iso = '6b2f0c0c-79e8-4db6-842e-43c9764204af' boot_iso = '6b2f0c0c-79e8-4db6-842e-43c9764204af'
instance_info['boot_iso'] = boot_iso instance_info['boot_iso'] = boot_iso
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
self.node.instance_info = instance_info self.node.instance_info = instance_info
self.node.deploy_interface = 'ramdisk'
self.node.save() self.node.save()
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task: shared=False) as task:
@ -475,14 +475,14 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest):
spec_set=True, autospec=True) spec_set=True, autospec=True)
@mock.patch.object(service_utils, 'is_glance_image', spec_set=True, @mock.patch.object(service_utils, 'is_glance_image', spec_set=True,
autospec=True) autospec=True)
def test_validate_ramdisk_boot_option_webserver(self, is_glance_image_mock, def test_validate_ramdisk_deploy_webserver(self, is_glance_image_mock,
validate_href_mock, validate_href_mock,
val_driver_info_mock): val_driver_info_mock):
instance_info = self.node.instance_info instance_info = self.node.instance_info
boot_iso = 'http://myserver/boot.iso' boot_iso = 'http://myserver/boot.iso'
instance_info['boot_iso'] = boot_iso instance_info['boot_iso'] = boot_iso
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
self.node.instance_info = instance_info self.node.instance_info = instance_info
self.node.deploy_interface = 'ramdisk'
self.node.save() self.node.save()
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task: shared=False) as task:
@ -499,18 +499,18 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest):
spec_set=True, autospec=True) spec_set=True, autospec=True)
@mock.patch.object(service_utils, 'is_glance_image', spec_set=True, @mock.patch.object(service_utils, 'is_glance_image', spec_set=True,
autospec=True) autospec=True)
def test_validate_ramdisk_boot_option_webserver_exc(self, def test_validate_ramdisk_deploy_webserver_exc(self,
is_glance_image_mock, is_glance_image_mock,
validate_href_mock, validate_href_mock,
val_driver_info_mock, val_driver_info_mock,
log_mock): log_mock):
instance_info = self.node.instance_info instance_info = self.node.instance_info
validate_href_mock.side_effect = exception.ImageRefValidationFailed( validate_href_mock.side_effect = exception.ImageRefValidationFailed(
image_href='http://myserver/boot.iso', reason='fail') image_href='http://myserver/boot.iso', reason='fail')
boot_iso = 'http://myserver/boot.iso' boot_iso = 'http://myserver/boot.iso'
instance_info['boot_iso'] = boot_iso instance_info['boot_iso'] = boot_iso
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
self.node.instance_info = instance_info self.node.instance_info = instance_info
self.node.deploy_interface = 'ramdisk'
self.node.save() self.node.save()
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task: shared=False) as task:
@ -523,7 +523,7 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest):
is_glance_image_mock.assert_called_once_with(boot_iso) is_glance_image_mock.assert_called_once_with(boot_iso)
validate_href_mock.assert_called_once_with(mock.ANY, boot_iso) validate_href_mock.assert_called_once_with(mock.ANY, boot_iso)
self.assertFalse(val_driver_info_mock.called) 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 " "accepts only Glance images or HTTP(S) URLs as "
"instance_info['boot_iso'].", "instance_info['boot_iso'].",
log_mock.call_args[0][0]) log_mock.call_args[0][0])
@ -857,7 +857,7 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest):
autospec=True) autospec=True)
@mock.patch.object(ilo_common, 'cleanup_vmedia_boot', spec_set=True, @mock.patch.object(ilo_common, 'cleanup_vmedia_boot', spec_set=True,
autospec=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, self, cleanup_vmedia_boot_mock, set_boot_device_mock,
update_boot_mode_mock, update_secure_boot_mode_mock, update_boot_mode_mock, update_secure_boot_mode_mock,
is_iscsi_boot_mock): is_iscsi_boot_mock):
@ -877,41 +877,31 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest):
self.assertIsNone(task.node.driver_internal_info.get( self.assertIsNone(task.node.driver_internal_info.get(
'ilo_uefi_iscsi_boot')) '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', @mock.patch.object(deploy_utils, 'is_iscsi_boot',
spec_set=True, autospec=True) spec_set=True, autospec=True)
@mock.patch.object(boot_mode_utils, 'configure_secure_boot_if_needed', @mock.patch.object(boot_mode_utils, 'configure_secure_boot_if_needed',
spec_set=True, autospec=True) spec_set=True, autospec=True)
@mock.patch.object(ilo_common, 'update_boot_mode', spec_set=True, @mock.patch.object(ilo_common, 'update_boot_mode', spec_set=True,
autospec=True) autospec=True)
@mock.patch.object(ilo_boot.IloVirtualMediaBoot, @mock.patch.object(manager_utils, 'node_set_boot_device', spec_set=True,
'_configure_vmedia_boot', spec_set=True,
autospec=True) autospec=True)
@mock.patch.object(ilo_common, 'cleanup_vmedia_boot', spec_set=True, @mock.patch.object(ilo_common, 'cleanup_vmedia_boot', spec_set=True,
autospec=True) autospec=True)
def test_prepare_instance_partition_image( 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, update_boot_mode_mock, update_secure_boot_mode_mock,
is_iscsi_boot_mock): is_iscsi_boot_mock):
self.node.driver_internal_info = {'root_uuid_or_disk_id': ( self.node.driver_internal_info = {'root_uuid_or_disk_id': (
"12312642-09d3-467f-8e09-12385826a123")} "12312642-09d3-467f-8e09-12385826a123")}
self.node.instance_info = {
'capabilities': {'boot_option': 'netboot'}}
self.node.save() self.node.save()
is_iscsi_boot_mock.return_value = False is_iscsi_boot_mock.return_value = False
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task: shared=False) as task:
task.driver.boot.prepare_instance(task) task.driver.boot.prepare_instance(task)
cleanup_vmedia_boot_mock.assert_called_once_with(task) cleanup_vmedia_boot_mock.assert_called_once_with(task)
configure_vmedia_mock.assert_called_once_with( set_boot_device_mock.assert_called_once_with(task,
mock.ANY, task, "12312642-09d3-467f-8e09-12385826a123") boot_devices.DISK,
persistent=True)
update_boot_mode_mock.assert_called_once_with(task) update_boot_mode_mock.assert_called_once_with(task)
update_secure_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( self.assertIsNone(task.node.driver_internal_info.get(
@ -998,9 +988,7 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest):
cleanup_vmedia_boot_mock): cleanup_vmedia_boot_mock):
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task: shared=False) as task:
instance_info = task.node.instance_info task.node.deploy_interface = 'ramdisk'
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
task.node.instance_info = instance_info
task.node.save() task.node.save()
is_iscsi_boot_mock.return_value = False is_iscsi_boot_mock.return_value = False
url = 'http://myserver/boot.iso' url = 'http://myserver/boot.iso'
@ -1377,7 +1365,7 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
self.config(enabled_hardware_types=['ilo5'], self.config(enabled_hardware_types=['ilo5'],
enabled_boot_interfaces=['ilo-uefi-https'], enabled_boot_interfaces=['ilo-uefi-https'],
enabled_console_interfaces=['ilo'], enabled_console_interfaces=['ilo'],
enabled_deploy_interfaces=['direct'], enabled_deploy_interfaces=['direct', 'ramdisk'],
enabled_inspect_interfaces=['ilo'], enabled_inspect_interfaces=['ilo'],
enabled_management_interfaces=['ilo5'], enabled_management_interfaces=['ilo5'],
enabled_power_interfaces=['ilo'], enabled_power_interfaces=['ilo'],
@ -1653,16 +1641,16 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
spec_set=True, autospec=True) spec_set=True, autospec=True)
@mock.patch.object(service_utils, 'is_glance_image', spec_set=True, @mock.patch.object(service_utils, 'is_glance_image', spec_set=True,
autospec=True) autospec=True)
def test_validate_ramdisk_boot_option_glance(self, is_glance_image_mock, def test_validate_ramdisk_deploy_glance(self, is_glance_image_mock,
validate_href_mock, validate_href_mock,
val_driver_info_mock, val_driver_info_mock,
get_boot_mock): get_boot_mock):
get_boot_mock.return_value = 'UEFI' get_boot_mock.return_value = 'UEFI'
instance_info = self.node.instance_info instance_info = self.node.instance_info
boot_iso = '6b2f0c0c-79e8-4db6-842e-43c9764204af' boot_iso = '6b2f0c0c-79e8-4db6-842e-43c9764204af'
instance_info['boot_iso'] = boot_iso instance_info['boot_iso'] = boot_iso
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
self.node.instance_info = instance_info self.node.instance_info = instance_info
self.node.deploy_interface = 'ramdisk'
self.node.save() self.node.save()
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task: shared=False) as task:
@ -1680,16 +1668,16 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
spec_set=True, autospec=True) spec_set=True, autospec=True)
@mock.patch.object(service_utils, 'is_glance_image', spec_set=True, @mock.patch.object(service_utils, 'is_glance_image', spec_set=True,
autospec=True) autospec=True)
def test_validate_ramdisk_boot_option_webserver(self, is_glance_image_mock, def test_validate_ramdisk_deploy_webserver(self, is_glance_image_mock,
validate_href_mock, validate_href_mock,
val_driver_info_mock, val_driver_info_mock,
get_boot_mock): get_boot_mock):
get_boot_mock.return_value = 'UEFI' get_boot_mock.return_value = 'UEFI'
instance_info = self.node.instance_info instance_info = self.node.instance_info
boot_iso = 'http://myserver/boot.iso' boot_iso = 'http://myserver/boot.iso'
instance_info['boot_iso'] = boot_iso instance_info['boot_iso'] = boot_iso
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
self.node.instance_info = instance_info self.node.instance_info = instance_info
self.node.deploy_interface = 'ramdisk'
self.node.save() self.node.save()
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task: shared=False) as task:
@ -1708,7 +1696,7 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
spec_set=True, autospec=True) spec_set=True, autospec=True)
@mock.patch.object(service_utils, 'is_glance_image', spec_set=True, @mock.patch.object(service_utils, 'is_glance_image', spec_set=True,
autospec=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, self, is_glance_image_mock, validate_href_mock,
val_driver_info_mock, log_mock, get_boot_mock): val_driver_info_mock, log_mock, get_boot_mock):
@ -1718,8 +1706,8 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
image_href='http://myserver/boot.iso', reason='fail') image_href='http://myserver/boot.iso', reason='fail')
boot_iso = 'http://myserver/boot.iso' boot_iso = 'http://myserver/boot.iso'
instance_info['boot_iso'] = boot_iso instance_info['boot_iso'] = boot_iso
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
self.node.instance_info = instance_info self.node.instance_info = instance_info
self.node.deploy_interface = 'ramdisk'
self.node.save() self.node.save()
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task: shared=False) as task:
@ -1732,7 +1720,7 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
is_glance_image_mock.assert_called_once_with(boot_iso) is_glance_image_mock.assert_called_once_with(boot_iso)
validate_href_mock.assert_called_once_with(mock.ANY, boot_iso) validate_href_mock.assert_called_once_with(mock.ANY, boot_iso)
self.assertFalse(val_driver_info_mock.called) 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 " "accepts only Glance images or HTTPS URLs as "
"instance_info['boot_iso'].", "instance_info['boot_iso'].",
log_mock.call_args[0][0]) log_mock.call_args[0][0])
@ -1902,7 +1890,7 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
spec_set=True, autospec=True) spec_set=True, autospec=True)
@mock.patch.object(manager_utils, 'node_set_boot_device', spec_set=True, @mock.patch.object(manager_utils, 'node_set_boot_device', spec_set=True,
autospec=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, self, set_boot_device_mock,
parse_deploy_mock, prepare_iso_mock, setup_uefi_https_mock, parse_deploy_mock, prepare_iso_mock, setup_uefi_https_mock,
cleanup_iso_mock, update_secureboot_mock): cleanup_iso_mock, update_secureboot_mock):
@ -1919,16 +1907,6 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
prepare_iso_mock.assert_not_called() prepare_iso_mock.assert_not_called()
setup_uefi_https_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', @mock.patch.object(boot_mode_utils, 'configure_secure_boot_if_needed',
spec_set=True, autospec=True) spec_set=True, autospec=True)
@mock.patch.object(image_utils, 'cleanup_iso_image', spec_set=True, @mock.patch.object(image_utils, 'cleanup_iso_image', spec_set=True,
@ -1937,41 +1915,30 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
spec_set=True, autospec=True) spec_set=True, autospec=True)
@mock.patch.object(image_utils, 'prepare_boot_iso', @mock.patch.object(image_utils, 'prepare_boot_iso',
spec_set=True, autospec=True) 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, @mock.patch.object(manager_utils, 'node_set_boot_device', spec_set=True,
autospec=True) autospec=True)
def test_prepare_instance_partition_image( def test_prepare_instance_partition_image(
self, set_boot_device_mock, 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): cleanup_iso_mock, update_secureboot_mock):
self.node.instance_info = {
'capabilities': '{"boot_option": "netboot"}'
}
self.node.driver_internal_info = { self.node.driver_internal_info = {
'root_uuid_or_disk_id': ( 'root_uuid_or_disk_id': (
"12312642-09d3-467f-8e09-12385826a123") "12312642-09d3-467f-8e09-12385826a123")
} }
self.node.driver_internal_info.update({'is_whole_disk_image': False}) self.node.driver_internal_info.update({'is_whole_disk_image': False})
self.node.save() 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, with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task: shared=False) as task:
task.driver.boot.prepare_instance(task) task.driver.boot.prepare_instance(task)
cleanup_iso_mock.assert_called_once_with(task) cleanup_iso_mock.assert_called_once_with(task)
set_boot_device_mock.assert_not_called() set_boot_device_mock.assert_called_once_with(task,
parse_deploy_mock.assert_called_once_with(mock.ANY, task.node) boot_devices.DISK,
prepare_iso_mock.assert_called_once_with( persistent=True)
task, d_info, root_uuid='12312642-09d3-467f-8e09-12385826a123') prepare_iso_mock.assert_not_called()
update_secureboot_mock.assert_called_once_with(task) update_secureboot_mock.assert_called_once_with(task)
setup_uefi_https_mock.assert_called_once_with( setup_uefi_https_mock.assert_not_called()
task, "recreated-iso", True)
self.assertEqual(task.node.instance_info['boot_iso'],
"recreated-iso")
@mock.patch.object(boot_mode_utils, 'configure_secure_boot_if_needed', @mock.patch.object(boot_mode_utils, 'configure_secure_boot_if_needed',
spec_set=True, autospec=True) spec_set=True, autospec=True)
@ -1998,9 +1965,7 @@ class IloUefiHttpsBootTestCase(db_base.DbTestCase):
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task: shared=False) as task:
instance_info = task.node.instance_info task.node.deploy_interface = 'ramdisk'
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
task.node.instance_info = instance_info
task.node.save() task.node.save()
task.driver.boot.prepare_instance(task) task.driver.boot.prepare_instance(task)

View File

@ -1144,8 +1144,9 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest):
autospec=True) autospec=True)
@mock.patch.object(irmc_boot, '_cleanup_vmedia_boot', spec_set=True, @mock.patch.object(irmc_boot, '_cleanup_vmedia_boot', spec_set=True,
autospec=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): 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.driver_internal_info = {'is_whole_disk_image': True}
self.node.save() self.node.save()
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
@ -1157,26 +1158,13 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest):
boot_devices.DISK, boot_devices.DISK,
persistent=True) persistent=True)
def test_prepare_instance_whole_disk_image_local( @mock.patch.object(manager_utils, 'node_set_boot_device', spec_set=True,
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,
autospec=True) autospec=True)
@mock.patch.object(irmc_boot, '_cleanup_vmedia_boot', spec_set=True, @mock.patch.object(irmc_boot, '_cleanup_vmedia_boot', spec_set=True,
autospec=True) autospec=True)
def test_prepare_instance_partition_image( 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): 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.driver_internal_info = {'root_uuid_or_disk_id': "some_uuid"}
self.node.save() self.node.save()
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
@ -1184,8 +1172,9 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest):
task.driver.boot.prepare_instance(task) task.driver.boot.prepare_instance(task)
_cleanup_vmedia_boot_mock.assert_called_once_with(task) _cleanup_vmedia_boot_mock.assert_called_once_with(task)
_configure_vmedia_mock.assert_called_once_with(mock.ANY, task, set_boot_device_mock.assert_called_once_with(task,
"some_uuid") boot_devices.DISK,
persistent=True)
@mock.patch.object(irmc_boot, '_cleanup_vmedia_boot', spec_set=True, @mock.patch.object(irmc_boot, '_cleanup_vmedia_boot', spec_set=True,
autospec=True) autospec=True)
@ -1253,9 +1242,10 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest):
self.node.driver_internal_info = {'root_uuid_or_disk_id': "12312642"} self.node.driver_internal_info = {'root_uuid_or_disk_id': "12312642"}
self.node.provision_state = states.DEPLOYING self.node.provision_state = states.DEPLOYING
self.node.target_provision_state = states.ACTIVE self.node.target_provision_state = states.ACTIVE
self.node.deploy_interface = 'ramdisk'
self.node.instance_info = { self.node.instance_info = {
'capabilities': { 'capabilities': {
"secure_boot": "true", 'boot_option': 'netboot' "secure_boot": "true"
} }
} }
self.node.save() self.node.save()
@ -1281,9 +1271,10 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest):
self.node.driver_internal_info = {'root_uuid_or_disk_id': "12312642"} self.node.driver_internal_info = {'root_uuid_or_disk_id': "12312642"}
self.node.provision_state = states.DEPLOYING self.node.provision_state = states.DEPLOYING
self.node.target_provision_state = states.ACTIVE self.node.target_provision_state = states.ACTIVE
self.node.deploy_interface = 'ramdisk'
self.node.instance_info = { self.node.instance_info = {
'capabilities': { 'capabilities': {
"secure_boot": "false", 'boot_option': 'netboot' "secure_boot": "false"
} }
} }
self.node.save() self.node.save()
@ -1308,11 +1299,7 @@ class IRMCVirtualMediaBootTestCase(test_common.BaseIRMCTest):
self.node.driver_internal_info = {'root_uuid_or_disk_id': "12312642"} self.node.driver_internal_info = {'root_uuid_or_disk_id': "12312642"}
self.node.provision_state = states.DEPLOYING self.node.provision_state = states.DEPLOYING
self.node.target_provision_state = states.ACTIVE self.node.target_provision_state = states.ACTIVE
self.node.instance_info = { self.node.deploy_interface = 'ramdisk'
'capabilities': {
'boot_option': 'netboot'
}
}
self.node.save() self.node.save()
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task: shared=False) as task:

View File

@ -19,7 +19,6 @@ from oslo_utils import uuidutils
from ironic.common import exception from ironic.common import exception
from ironic.common import neutron as neutron_common from ironic.common import neutron as neutron_common
from ironic.common import states
from ironic.conductor import task_manager from ironic.conductor import task_manager
from ironic.drivers import base as drivers_base from ironic.drivers import base as drivers_base
from ironic.drivers.modules.network import neutron from ironic.drivers.modules.network import neutron
@ -106,65 +105,6 @@ class NeutronInterfaceTestCase(db_base.DbTestCase):
context=task.context)], context=task.context)],
validate_mock.call_args_list) 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', @mock.patch.object(neutron_common, 'validate_network',
side_effect=lambda n, t, context=None: n, autospec=True) side_effect=lambda n, t, context=None: n, autospec=True)
@mock.patch.object(neutron_common, 'rollback_ports', autospec=True) @mock.patch.object(neutron_common, 'rollback_ports', autospec=True)

View File

@ -18,7 +18,6 @@ from oslo_config import cfg
from ironic.common import dhcp_factory from ironic.common import dhcp_factory
from ironic.common import exception from ironic.common import exception
from ironic.common import image_service
from ironic.common import images from ironic.common import images
from ironic.common import raid from ironic.common import raid
from ironic.common import states from ironic.common import states
@ -846,212 +845,6 @@ class TestAgentDeploy(CommonTestsMixin, db_base.DbTestCase):
self.node.refresh() self.node.refresh()
self.assertEqual('bar', self.node.instance_info['foo']) self.assertEqual('bar', self.node.instance_info['foo'])
@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', @mock.patch('ironic.drivers.modules.agent.check_image_size',
autospec=True) autospec=True)
@mock.patch.object(flat_network.FlatNetwork, 'add_provisioning_network', @mock.patch.object(flat_network.FlatNetwork, 'add_provisioning_network',
@ -1643,8 +1436,6 @@ class TestAgentDeploy(CommonTestsMixin, db_base.DbTestCase):
def test_prepare_instance_boot_partition_image(self, prepare_instance_mock, def test_prepare_instance_boot_partition_image(self, prepare_instance_mock,
uuid_mock, boot_mode_mock, uuid_mock, boot_mode_mock,
log_mock): log_mock):
self.node.instance_info = {
'capabilities': {'boot_option': 'netboot'}}
uuid_mock.return_value = { uuid_mock.return_value = {
'command_result': {'root uuid': 'root_uuid'} 'command_result': {'root uuid': 'root_uuid'}
} }

View File

@ -1426,40 +1426,11 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
@mock.patch.object(deploy_utils, 'set_failed_state', autospec=True) @mock.patch.object(deploy_utils, 'set_failed_state', autospec=True)
@mock.patch.object(pxe.PXEBoot, 'prepare_instance', 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, @mock.patch.object(agent_base.AgentDeployMixin,
'configure_local_boot', autospec=True) 'configure_local_boot', autospec=True)
def test_prepare_instance_to_boot_netboot(self, configure_mock, def test_prepare_instance_to_boot(self, configure_mock,
boot_option_mock, prepare_instance_mock,
prepare_instance_mock, failed_state_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'
prepare_instance_mock.return_value = None prepare_instance_mock.return_value = None
self.node.provision_state = states.DEPLOYING self.node.provision_state = states.DEPLOYING
self.node.target_provision_state = states.ACTIVE self.node.target_provision_state = states.ACTIVE
@ -1475,20 +1446,16 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
root_uuid=root_uuid, root_uuid=root_uuid,
efi_system_part_uuid=efi_system_part_uuid, efi_system_part_uuid=efi_system_part_uuid,
prep_boot_part_uuid=None) prep_boot_part_uuid=None)
boot_option_mock.assert_called_once_with(task.node)
prepare_instance_mock.assert_called_once_with(task.driver.boot, prepare_instance_mock.assert_called_once_with(task.driver.boot,
task) task)
self.assertFalse(failed_state_mock.called) self.assertFalse(failed_state_mock.called)
@mock.patch.object(deploy_utils, 'set_failed_state', autospec=True) @mock.patch.object(deploy_utils, 'set_failed_state', autospec=True)
@mock.patch.object(pxe.PXEBoot, 'prepare_instance', 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, @mock.patch.object(agent_base.AgentDeployMixin,
'configure_local_boot', autospec=True) 'configure_local_boot', autospec=True)
def test_prepare_instance_to_boot_localboot_prep_partition( def test_prepare_instance_to_boot_localboot_prep_partition(
self, configure_mock, boot_option_mock, self, configure_mock, prepare_instance_mock, failed_state_mock):
prepare_instance_mock, failed_state_mock):
boot_option_mock.return_value = 'local'
prepare_instance_mock.return_value = None prepare_instance_mock.return_value = None
self.node.provision_state = states.DEPLOYING self.node.provision_state = states.DEPLOYING
self.node.target_provision_state = states.ACTIVE self.node.target_provision_state = states.ACTIVE
@ -1506,21 +1473,17 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
root_uuid=root_uuid, root_uuid=root_uuid,
efi_system_part_uuid=efi_system_part_uuid, efi_system_part_uuid=efi_system_part_uuid,
prep_boot_part_uuid=prep_boot_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, prepare_instance_mock.assert_called_once_with(task.driver.boot,
task) task)
self.assertFalse(failed_state_mock.called) self.assertFalse(failed_state_mock.called)
@mock.patch.object(deploy_utils, 'set_failed_state', autospec=True) @mock.patch.object(deploy_utils, 'set_failed_state', autospec=True)
@mock.patch.object(pxe.PXEBoot, 'prepare_instance', 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, @mock.patch.object(agent_base.AgentDeployMixin,
'configure_local_boot', autospec=True) 'configure_local_boot', autospec=True)
def test_prepare_instance_to_boot_configure_fails(self, configure_mock, def test_prepare_instance_to_boot_configure_fails(self, configure_mock,
boot_option_mock,
prepare_mock, prepare_mock,
failed_state_mock): failed_state_mock):
boot_option_mock.return_value = 'local'
self.node.provision_state = states.DEPLOYING self.node.provision_state = states.DEPLOYING
self.node.target_provision_state = states.ACTIVE self.node.target_provision_state = states.ACTIVE
self.node.save() self.node.save()
@ -1542,7 +1505,6 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
root_uuid=root_uuid, root_uuid=root_uuid,
efi_system_part_uuid=efi_system_part_uuid, efi_system_part_uuid=efi_system_part_uuid,
prep_boot_part_uuid=None) prep_boot_part_uuid=None)
boot_option_mock.assert_called_once_with(task.node)
self.assertFalse(prepare_mock.called) self.assertFalse(prepare_mock.called)
self.assertFalse(failed_state_mock.called) self.assertFalse(failed_state_mock.called)

View File

@ -54,27 +54,6 @@ kernel deploy_kernel
append initrd=deploy_ramdisk append initrd=deploy_ramdisk
ipappend 3 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 label boot_whole_disk
COM32 chain.c32 COM32 chain.c32
append mbr:{{ DISK_IDENTIFIER }} append mbr:{{ DISK_IDENTIFIER }}
@ -88,10 +67,6 @@ kernel deploy_kernel
append initrd=deploy_ramdisk append initrd=deploy_ramdisk
ipappend 3 ipappend 3
label boot_partition
kernel kernel
append initrd=ramdisk root={{ ROOT }}
label boot_whole_disk label boot_whole_disk
COM32 chain.c32 COM32 chain.c32
append mbr:0x12345678 append mbr:0x12345678
@ -109,34 +84,6 @@ kernel deploy_kernel
initrd deploy_ramdisk initrd deploy_ramdisk
boot 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 :boot_whole_disk
kernel chain.c32 kernel chain.c32
append mbr:{{ DISK_IDENTIFIER }} append mbr:{{ DISK_IDENTIFIER }}
@ -155,11 +102,6 @@ kernel deploy_kernel
initrd deploy_ramdisk initrd deploy_ramdisk
boot boot
:boot_partition
kernel kernel
append initrd=ramdisk root={{ ROOT }}
boot
:boot_whole_disk :boot_whole_disk
kernel chain.c32 kernel chain.c32
append mbr:0x12345678 append mbr:0x12345678
@ -178,11 +120,6 @@ kernel deploy_kernel
initrd deploy_ramdisk initrd deploy_ramdisk
boot boot
:boot_partition
kernel kernel
append initrd=ramdisk root=UUID=0x12345678
boot
:boot_whole_disk :boot_whole_disk
kernel chain.c32 kernel chain.c32
append mbr:{{ DISK_IDENTIFIER }} append mbr:{{ DISK_IDENTIFIER }}
@ -197,29 +134,6 @@ image=deploy_kernel
initrd=deploy_ramdisk initrd=deploy_ramdisk
append="ro text" 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 image=chain.c32
label=boot_whole_disk label=boot_whole_disk
append="mbr:{{ DISK_IDENTIFIER }}" append="mbr:{{ DISK_IDENTIFIER }}"
@ -233,11 +147,6 @@ image=deploy_kernel
initrd=deploy_ramdisk initrd=deploy_ramdisk
append="ro text" append="ro text"
image=kernel
label=boot_partition
initrd=ramdisk
append="root={{ ROOT }}"
image=chain.c32 image=chain.c32
label=boot_whole_disk label=boot_whole_disk
append="mbr:0x12345678" append="mbr:0x12345678"
@ -253,31 +162,6 @@ menuentry "deploy" {
initrdefi deploy_ramdisk 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" { menuentry "boot_whole_disk" {
linuxefi chain.c32 mbr:(( DISK_IDENTIFIER )) linuxefi chain.c32 mbr:(( DISK_IDENTIFIER ))
} }
@ -293,11 +177,6 @@ menuentry "deploy" {
initrdefi deploy_ramdisk initrdefi deploy_ramdisk
} }
menuentry "boot_partition" {
linuxefi kernel "root=(( ROOT ))"
initrdefi ramdisk
}
menuentry "boot_whole_disk" { menuentry "boot_whole_disk" {
linuxefi chain.c32 mbr:0x12345678 linuxefi chain.c32 mbr:0x12345678
} }
@ -322,17 +201,6 @@ class SwitchPxeConfigTestCase(tests_base.TestCase):
self.addCleanup(os.unlink, fname) self.addCleanup(os.unlink, fname)
return 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): def test_switch_pxe_config_whole_disk_image(self):
boot_mode = 'bios' boot_mode = 'bios'
fname = self._create_config() fname = self._create_config()
@ -344,18 +212,6 @@ class SwitchPxeConfigTestCase(tests_base.TestCase):
pxeconf = f.read() pxeconf = f.read()
self.assertEqual(_PXECONF_BOOT_WHOLE_DISK, pxeconf) 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): def test_switch_ipxe_config_whole_disk_image(self):
boot_mode = 'bios' boot_mode = 'bios'
fname = self._create_config(ipxe=True) fname = self._create_config(ipxe=True)
@ -368,19 +224,6 @@ class SwitchPxeConfigTestCase(tests_base.TestCase):
pxeconf = f.read() pxeconf = f.read()
self.assertEqual(_IPXECONF_BOOT_WHOLE_DISK, pxeconf) self.assertEqual(_IPXECONF_BOOT_WHOLE_DISK, pxeconf)
# 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, # NOTE(TheJulia): Remove elilo support after the deprecation period,
# in the Queens release. # in the Queens release.
def test_switch_uefi_elilo_config_whole_disk_image(self): def test_switch_uefi_elilo_config_whole_disk_image(self):
@ -394,17 +237,6 @@ class SwitchPxeConfigTestCase(tests_base.TestCase):
pxeconf = f.read() pxeconf = f.read()
self.assertEqual(_UEFI_PXECONF_BOOT_WHOLE_DISK, pxeconf) 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): def test_switch_uefi_grub_config_whole_disk_image(self):
boot_mode = 'uefi' boot_mode = 'uefi'
fname = self._create_config(boot_mode=boot_mode, boot_loader='grub') fname = self._create_config(boot_mode=boot_mode, boot_loader='grub')
@ -416,18 +248,6 @@ class SwitchPxeConfigTestCase(tests_base.TestCase):
pxeconf = f.read() pxeconf = f.read()
self.assertEqual(_UEFI_PXECONF_BOOT_WHOLE_DISK_GRUB, pxeconf) 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): def test_switch_uefi_ipxe_config_whole_disk_image(self):
boot_mode = 'uefi' boot_mode = 'uefi'
fname = self._create_config(boot_mode=boot_mode, ipxe=True) 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._test_set_failed_state(collect_logs=False)
self.assertFalse(mock_collect.called) 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): def test_get_boot_option_default_value(self):
self.node.instance_info = {} self.node.instance_info = {}
result = utils.get_boot_option(self.node) result = utils.get_boot_option(self.node)
self.assertEqual("local", result) 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) @mock.patch.object(utils, 'is_anaconda_deploy', autospec=True)
def test_get_boot_option_anaconda_deploy(self, mock_is_anaconda_deploy): def test_get_boot_option_anaconda_deploy(self, mock_is_anaconda_deploy):
mock_is_anaconda_deploy.return_value = True mock_is_anaconda_deploy.return_value = True
@ -972,8 +767,6 @@ class ParseInstanceInfoCapabilitiesTestCase(tests_base.TestCase):
utils.validate_capabilities, self.node) utils.validate_capabilities, self.node)
def test_all_supported_capabilities(self): def test_all_supported_capabilities(self):
self.assertEqual(('local', 'netboot', 'ramdisk', 'kickstart'),
utils.SUPPORTED_CAPABILITIES['boot_option'])
self.assertEqual(('bios', 'uefi'), self.assertEqual(('bios', 'uefi'),
utils.SUPPORTED_CAPABILITIES['boot_mode']) utils.SUPPORTED_CAPABILITIES['boot_mode'])
self.assertEqual(('true', 'false'), self.assertEqual(('true', 'false'),
@ -1301,38 +1094,6 @@ class ValidateImagePropertiesTestCase(db_base.DbTestCase):
inst_info = utils.get_image_instance_info(self.node) inst_info = utils.get_image_instance_info(self.node)
utils.validate_image_properties(self.task, inst_info) 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, @mock.patch.object(utils, 'get_boot_option', autospec=True,
return_value='kickstart') return_value='kickstart')
@mock.patch.object(image_service, 'get_image_service', autospec=True) @mock.patch.object(image_service, 'get_image_service', autospec=True)
@ -1351,7 +1112,7 @@ class ValidateImagePropertiesTestCase(db_base.DbTestCase):
) )
@mock.patch.object(utils, 'get_boot_option', autospec=True, @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) @mock.patch.object(image_service, 'get_image_service', autospec=True)
def test_validate_image_properties_glance_image_not_authorized( def test_validate_image_properties_glance_image_not_authorized(
self, image_service_mock, boot_options_mock): self, image_service_mock, boot_options_mock):
@ -1363,7 +1124,7 @@ class ValidateImagePropertiesTestCase(db_base.DbTestCase):
inst_info) inst_info)
@mock.patch.object(utils, 'get_boot_option', autospec=True, @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) @mock.patch.object(image_service, 'get_image_service', autospec=True)
def test_validate_image_properties_glance_image_not_found( def test_validate_image_properties_glance_image_not_found(
self, image_service_mock, boot_options_mock): self, image_service_mock, boot_options_mock):
@ -1381,7 +1142,7 @@ class ValidateImagePropertiesTestCase(db_base.DbTestCase):
inst_info) inst_info)
@mock.patch.object(utils, 'get_boot_option', autospec=True, @mock.patch.object(utils, 'get_boot_option', autospec=True,
return_value='netboot') return_value='kickstart')
def test_validate_image_properties_nonglance_image( def test_validate_image_properties_nonglance_image(
self, boot_options_mock): self, boot_options_mock):
instance_info = { instance_info = {
@ -1473,8 +1234,8 @@ class ValidateParametersTestCase(db_base.DbTestCase):
self.assertNotIn('ramdisk', info) self.assertNotIn('ramdisk', info)
@mock.patch.object(utils, 'get_boot_option', autospec=True, @mock.patch.object(utils, 'get_boot_option', autospec=True,
return_value='netboot') return_value='kickstart')
def test__get_img_instance_info_good_non_glance_image_netboot( def test__get_img_instance_info_good_non_glance_image_anaconda(
self, mock_boot_opt): self, mock_boot_opt):
instance_info = INST_INFO_DICT.copy() instance_info = INST_INFO_DICT.copy()
instance_info['image_source'] = 'http://image' instance_info['image_source'] = 'http://image'
@ -1488,7 +1249,7 @@ class ValidateParametersTestCase(db_base.DbTestCase):
self.assertIsNotNone(info['kernel']) self.assertIsNotNone(info['kernel'])
@mock.patch.object(utils, 'get_boot_option', autospec=True, @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( def test__get_img_instance_info_non_glance_image_missing_kernel(
self, mock_boot_opt): self, mock_boot_opt):
instance_info = INST_INFO_DICT.copy() instance_info = INST_INFO_DICT.copy()
@ -1501,7 +1262,7 @@ class ValidateParametersTestCase(db_base.DbTestCase):
instance_info=instance_info) instance_info=instance_info)
@mock.patch.object(utils, 'get_boot_option', autospec=True, @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( def test__get_img_instance_info_non_glance_image_missing_ramdisk(
self, mock_boot_opt): self, mock_boot_opt):
instance_info = INST_INFO_DICT.copy() instance_info = INST_INFO_DICT.copy()
@ -1768,23 +1529,26 @@ class InstanceInfoTestCase(db_base.DbTestCase):
) )
utils.parse_instance_info(node) 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 = INST_INFO_DICT.copy()
info['image_source'] = 'file:///image.qcow2' info['image_source'] = 'file:///image.qcow2'
info['kernel'] = 'file:///image.vmlinuz' info['kernel'] = 'file:///image.vmlinuz'
info['ramdisk'] = 'file:///image.initrd' info['ramdisk'] = 'file:///image.initrd'
info['capabilities'] = {'boot_option': 'netboot'}
node = obj_utils.create_test_node( node = obj_utils.create_test_node(
self.context, instance_info=info, self.context, instance_info=info,
driver_internal_info=DRV_INTERNAL_INFO_DICT, driver_internal_info=DRV_INTERNAL_INFO_DICT,
) )
utils.parse_instance_info(node) 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 = INST_INFO_DICT.copy()
info['image_source'] = 'file:///image.qcow2' info['image_source'] = 'file:///image.qcow2'
info['ramdisk'] = 'file:///image.initrd' info['ramdisk'] = 'file:///image.initrd'
info['capabilities'] = {'boot_option': 'netboot'}
node = obj_utils.create_test_node( node = obj_utils.create_test_node(
self.context, instance_info=info, self.context, instance_info=info,
driver_internal_info=DRV_INTERNAL_INFO_DICT, driver_internal_info=DRV_INTERNAL_INFO_DICT,
@ -1947,12 +1711,15 @@ class TestBuildInstanceInfoForDeploy(db_base.DbTestCase):
self.assertEqual(expected_i_info, info) self.assertEqual(expected_i_info, info)
parse_instance_info_mock.assert_called_once_with(task.node) 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', @mock.patch.object(image_service.HttpImageService, 'validate_href',
autospec=True) autospec=True)
@mock.patch.object(utils, 'parse_instance_info', autospec=True) @mock.patch.object(utils, 'parse_instance_info', autospec=True)
@mock.patch.object(image_service, 'GlanceImageService', autospec=True) @mock.patch.object(image_service, 'GlanceImageService', autospec=True)
def test_build_instance_info_for_deploy_glance_partition_image_netboot( def test_build_instance_info_for_deploy_glance_partition_image_anaconda(
self, glance_mock, parse_instance_info_mock, validate_mock): self, glance_mock, parse_instance_info_mock, validate_mock,
boot_opt_mock):
i_info = {} i_info = {}
i_info['image_source'] = '733d1c44-a2ea-414b-aca7-69decf20d810' i_info['image_source'] = '733d1c44-a2ea-414b-aca7-69decf20d810'
i_info['kernel'] = '13ce5a56-1de3-4916-b8b2-be778645d003' 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_gb'] = 0
i_info['ephemeral_format'] = None i_info['ephemeral_format'] = None
i_info['configdrive'] = 'configdrive' i_info['configdrive'] = 'configdrive'
i_info['capabilities'] = {'boot_option': 'netboot'}
driver_internal_info = self.node.driver_internal_info driver_internal_info = self.node.driver_internal_info
driver_internal_info['is_whole_disk_image'] = False driver_internal_info['is_whole_disk_image'] = False
self.node.driver_internal_info = driver_internal_info 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' glance_obj_mock.swift_temp_url.return_value = 'http://temp-url'
parse_instance_info_mock.return_value = {'swap_mb': 4} parse_instance_info_mock.return_value = {'swap_mb': 4}
image_source = '733d1c44-a2ea-414b-aca7-69decf20d810' image_source = '733d1c44-a2ea-414b-aca7-69decf20d810'
expected_i_info = {'capabilities': {'boot_option': 'netboot'}, expected_i_info = {'root_gb': 5,
'root_gb': 5,
'swap_mb': 4, 'swap_mb': 4,
'ephemeral_gb': 0, 'ephemeral_gb': 0,
'ephemeral_format': None, 'ephemeral_format': None,

View File

@ -169,16 +169,6 @@ class iPXEBootTestCase(db_base.DbTestCase):
task.driver.boot.validate(task) task.driver.boot.validate(task)
mock_boot_option.assert_called_with(task.node) 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): def test_validate_fail_no_port(self):
new_node = obj_utils.create_test_node( new_node = obj_utils.create_test_node(
self.context, self.context,
@ -190,48 +180,6 @@ class iPXEBootTestCase(db_base.DbTestCase):
self.assertRaises(exception.MissingParameterValue, self.assertRaises(exception.MissingParameterValue,
task.driver.boot.validate, task) 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): def test_validate_inspection(self):
with task_manager.acquire(self.context, self.node.uuid) as task: with task_manager.acquire(self.context, self.node.uuid) as task:
task.driver.boot.validate_inspection(task) task.driver.boot.validate_inspection(task)
@ -563,94 +511,6 @@ class iPXEBootTestCase(db_base.DbTestCase):
self.node.save() self.node.save()
self._test_clean_up_ramdisk(mode='rescue') 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(pxe_utils, 'create_pxe_config', autospec=True)
@mock.patch.object(manager_utils, 'node_set_boot_device', 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(deploy_utils, 'switch_pxe_config', autospec=True)
@ -665,8 +525,7 @@ class iPXEBootTestCase(db_base.DbTestCase):
dhcp_factory_mock.return_value = provider_mock dhcp_factory_mock.return_value = provider_mock
image_info = {'kernel': ('', '/path/to/kernel'), image_info = {'kernel': ('', '/path/to/kernel'),
'ramdisk': ('', '/path/to/ramdisk')} 'ramdisk': ('', '/path/to/ramdisk')}
i_info_caps = {"boot_option": "ramdisk", i_info_caps = {"boot_mode": "bios"}
"boot_mode": "bios"}
kernel_arg = "meow" kernel_arg = "meow"
get_image_info_mock.return_value = image_info 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['capabilities'] = i_info_caps
i_info['kernel_append_params'] = kernel_arg i_info['kernel_append_params'] = kernel_arg
task.node.instance_info = i_info task.node.instance_info = i_info
task.node.deploy_interface = 'ramdisk'
task.node.save() task.node.save()
dhcp_opts = pxe_utils.dhcp_options_for_instance( dhcp_opts = pxe_utils.dhcp_options_for_instance(
task, ipxe_enabled=True) task, ipxe_enabled=True)
@ -721,15 +581,14 @@ class iPXEBootTestCase(db_base.DbTestCase):
dhcp_factory_mock.return_value = provider_mock dhcp_factory_mock.return_value = provider_mock
image_info = {'kernel': ('', '/path/to/kernel'), image_info = {'kernel': ('', '/path/to/kernel'),
'ramdisk': ('', '/path/to/ramdisk')} 'ramdisk': ('', '/path/to/ramdisk')}
i_info_caps = {"boot_option": "ramdisk"}
kernel_arg = "meow" kernel_arg = "meow"
get_image_info_mock.return_value = image_info get_image_info_mock.return_value = image_info
with task_manager.acquire(self.context, self.node.uuid) as task: with task_manager.acquire(self.context, self.node.uuid) as task:
i_info = task.node.instance_info i_info = task.node.instance_info
i_info['capabilities'] = i_info_caps
i_info['kernel_append_params'] = kernel_arg i_info['kernel_append_params'] = kernel_arg
task.node.instance_info = i_info task.node.instance_info = i_info
task.node.deploy_interface = 'ramdisk'
task.node.save() task.node.save()
dhcp_opts = pxe_utils.dhcp_options_for_instance( dhcp_opts = pxe_utils.dhcp_options_for_instance(
task, ipxe_enabled=True) task, ipxe_enabled=True)
@ -761,160 +620,6 @@ class iPXEBootTestCase(db_base.DbTestCase):
mock_create_pxe_config.assert_called_once_with( mock_create_pxe_config.assert_called_once_with(
task, expected_params, mock.ANY, ipxe_enabled=True) 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('os.path.isfile', lambda filename: False)
@mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True) @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True)
@mock.patch.object(deploy_utils, 'is_iscsi_boot', lambda task: 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') self.config(http_url=http_url, group='deploy')
provider_mock = mock.MagicMock() provider_mock = mock.MagicMock()
dhcp_factory_mock.return_value = provider_mock dhcp_factory_mock.return_value = provider_mock
self.node.instance_info = {'boot_iso': 'http://1.2.3.4:1234/boot.iso', self.node.deploy_interface = 'ramdisk'
'capabilities': {'boot_option': 'ramdisk'}} self.node.instance_info = {'boot_iso': 'http://1.2.3.4:1234/boot.iso'}
image_info = {'kernel': ('', '/path/to/kernel'), image_info = {'kernel': ('', '/path/to/kernel'),
'deploy_kernel': ('', '/path/to/kernel'), 'deploy_kernel': ('', '/path/to/kernel'),
'ramdisk': ('', '/path/to/ramdisk'), 'ramdisk': ('', '/path/to/ramdisk'),
@ -1075,7 +780,7 @@ class iPXEBootTestCase(db_base.DbTestCase):
@mock.patch.object(dhcp_factory, 'DHCPFactory', 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, 'cache_ramdisk_kernel', autospec=True)
@mock.patch.object(pxe_utils, 'get_instance_image_info', 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, self, get_image_info_mock, cache_mock,
dhcp_factory_mock, switch_pxe_config_mock, dhcp_factory_mock, switch_pxe_config_mock,
set_boot_device_mock, create_pxe_config_mock): set_boot_device_mock, create_pxe_config_mock):
@ -1130,14 +835,9 @@ class iPXEBootTestCase(db_base.DbTestCase):
autospec=True) autospec=True)
@mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
@mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True) @mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True)
def test_prepare_instance_localboot(self, clean_up_pxe_config_mock, def test_prepare_instance(self, clean_up_pxe_config_mock,
set_boot_device_mock, set_boot_device_mock, secure_boot_mock):
secure_boot_mock):
with task_manager.acquire(self.context, self.node.uuid) as task: 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) task.driver.boot.prepare_instance(task)
clean_up_pxe_config_mock.assert_called_once_with( clean_up_pxe_config_mock.assert_called_once_with(
task, ipxe_enabled=True) 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(manager_utils, 'node_set_boot_device', autospec=True)
@mock.patch.object(pxe_utils, 'clean_up_pxe_config', 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, def test_prepare_instance_active(self, clean_up_pxe_config_mock,
set_boot_device_mock): set_boot_device_mock):
self.node.provision_state = states.ACTIVE self.node.provision_state = states.ACTIVE
self.node.save() self.node.save()
with task_manager.acquire(self.context, self.node.uuid) as task: 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) task.driver.boot.prepare_instance(task)
clean_up_pxe_config_mock.assert_called_once_with( clean_up_pxe_config_mock.assert_called_once_with(
task, ipxe_enabled=True) task, ipxe_enabled=True)
@ -1168,14 +864,12 @@ class iPXEBootTestCase(db_base.DbTestCase):
@mock.patch.object(dhcp_factory, 'DHCPFactory', 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, 'cache_ramdisk_kernel', autospec=True)
@mock.patch.object(pxe_utils, 'get_instance_image_info', 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, self, get_image_info_mock, cache_mock,
dhcp_factory_mock, switch_pxe_config_mock, dhcp_factory_mock, switch_pxe_config_mock,
clean_up_pxe_config_mock, set_boot_device_mock): clean_up_pxe_config_mock, set_boot_device_mock):
self.config(enable_netboot_fallback=True, group='pxe') self.config(enable_netboot_fallback=True, group='pxe')
with task_manager.acquire(self.context, self.node.uuid) as task: 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'] = ( task.node.driver_internal_info['root_uuid_or_disk_id'] = (
"30212642-09d3-467f-8e09-21685826ab50") "30212642-09d3-467f-8e09-21685826ab50")
task.node.driver_internal_info['is_whole_disk_image'] = False task.node.driver_internal_info['is_whole_disk_image'] = False

View File

@ -77,7 +77,8 @@ class PXEBootTestCase(db_base.DbTestCase):
self.config(enabled_boot_interfaces=[self.boot_interface, self.config(enabled_boot_interfaces=[self.boot_interface,
'ipxe', 'fake']) '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.node = obj_utils.create_test_node(
self.context, self.context,
driver=self.driver, driver=self.driver,
@ -144,15 +145,6 @@ class PXEBootTestCase(db_base.DbTestCase):
del task.node['instance_info']['image_source'] del task.node['instance_info']['image_source']
task.driver.boot.validate(task) 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): def test_validate_fail_no_port(self):
new_node = obj_utils.create_test_node( new_node = obj_utils.create_test_node(
self.context, self.context,
@ -164,40 +156,18 @@ class PXEBootTestCase(db_base.DbTestCase):
self.assertRaises(exception.MissingParameterValue, self.assertRaises(exception.MissingParameterValue,
task.driver.boot.validate, task) task.driver.boot.validate, task)
@mock.patch.object(image_service.GlanceImageService, 'show', autospec=True) @mock.patch.object(deploy_utils, 'get_boot_option',
def test_validate_fail_no_image_kernel_ramdisk_props(self, mock_glance): return_value='ramdisk', autospec=True)
instance_info = {"boot_option": "netboot"} @mock.patch.object(deploy_utils, 'validate_image_properties',
mock_glance.return_value = {'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, with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task: shared=True) as task:
task.node.instance_info['capabilities'] = instance_info task.driver.boot.validate(task)
self.assertRaises(exception.MissingParameterValue, mock_validate.assert_called_once_with(
task.driver.boot.validate, task, mock_get_iinfo.return_value)
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')
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)
def test_validate_inspection(self): def test_validate_inspection(self):
with task_manager.acquire(self.context, self.node.uuid) as task: with task_manager.acquire(self.context, self.node.uuid) as task:
@ -486,217 +456,13 @@ class PXEBootTestCase(db_base.DbTestCase):
self.node.save() self.node.save()
self._test_clean_up_ramdisk(mode='rescue') 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', @mock.patch.object(boot_mode_utils, 'configure_secure_boot_if_needed',
autospec=True) autospec=True)
@mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
@mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True) @mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True)
def test_prepare_instance_localboot(self, clean_up_pxe_config_mock, def test_prepare_instance(self, clean_up_pxe_config_mock,
set_boot_device_mock, set_boot_device_mock, secure_boot_mock):
secure_boot_mock):
with task_manager.acquire(self.context, self.node.uuid) as task: 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) task.driver.boot.prepare_instance(task)
clean_up_pxe_config_mock.assert_called_once_with( clean_up_pxe_config_mock.assert_called_once_with(
task, ipxe_enabled=False) 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(manager_utils, 'node_set_boot_device', autospec=True)
@mock.patch.object(pxe_utils, 'clean_up_pxe_config', 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, def test_prepare_instance_active(self, clean_up_pxe_config_mock,
set_boot_device_mock): set_boot_device_mock):
self.node.provision_state = states.ACTIVE self.node.provision_state = states.ACTIVE
self.node.save() self.node.save()
with task_manager.acquire(self.context, self.node.uuid) as task: 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) task.driver.boot.prepare_instance(task)
clean_up_pxe_config_mock.assert_called_once_with( clean_up_pxe_config_mock.assert_called_once_with(
task, ipxe_enabled=False) task, ipxe_enabled=False)
@ -741,9 +503,7 @@ class PXEBootTestCase(db_base.DbTestCase):
self.node.provision_state = states.DEPLOYING self.node.provision_state = states.DEPLOYING
get_image_info_mock.return_value = image_info get_image_info_mock.return_value = image_info
with task_manager.acquire(self.context, self.node.uuid) as task: with task_manager.acquire(self.context, self.node.uuid) as task:
instance_info = task.node.instance_info task.node.deploy_interface = 'ramdisk'
instance_info['capabilities'] = {'boot_option': 'ramdisk'}
task.node.instance_info = instance_info
task.node.save() task.node.save()
dhcp_opts = pxe_utils.dhcp_options_for_instance( dhcp_opts = pxe_utils.dhcp_options_for_instance(
task, ipxe_enabled=False) task, ipxe_enabled=False)

View File

@ -92,7 +92,6 @@ class RamdiskDeployTestCase(db_base.DbTestCase):
task, ipxe_enabled=False, ip_version=6) task, ipxe_enabled=False, ip_version=6)
pxe_config_path = pxe_utils.get_pxe_config_file_path( pxe_config_path = pxe_utils.get_pxe_config_file_path(
task.node.uuid) task.node.uuid)
task.node.properties['capabilities'] = 'boot_option:netboot'
task.node.driver_internal_info['is_whole_disk_image'] = False task.node.driver_internal_info['is_whole_disk_image'] = False
task.driver.deploy.prepare(task) task.driver.deploy.prepare(task)
task.driver.deploy.deploy(task) task.driver.deploy.deploy(task)
@ -120,20 +119,26 @@ class RamdiskDeployTestCase(db_base.DbTestCase):
image_info = {'kernel': ('', '/path/to/kernel'), image_info = {'kernel': ('', '/path/to/kernel'),
'ramdisk': ('', '/path/to/ramdisk')} 'ramdisk': ('', '/path/to/ramdisk')}
mock_image_info.return_value = image_info 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: with task_manager.acquire(self.context, self.node.uuid) as task:
self.assertIsNone(task.driver.deploy.deploy(task)) self.assertIsNone(task.driver.deploy.deploy(task))
mock_image_info.assert_called_once_with(task, ipxe_enabled=False) mock_image_info.assert_called_once_with(task, ipxe_enabled=False)
mock_cache.assert_called_once_with( mock_cache.assert_called_once_with(
task, image_info, ipxe_enabled=False) task, image_info, ipxe_enabled=False)
self.assertFalse(mock_warning.called) 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() self.node.save()
mock_warning.reset_mock()
with task_manager.acquire(self.context, self.node.uuid) as task: with task_manager.acquire(self.context, self.node.uuid) as task:
self.assertIsNone(task.driver.deploy.deploy(task)) self.assertIsNone(task.driver.deploy.deploy(task))
self.assertTrue(mock_warning.called) self.assertTrue(mock_warning.called)

View File

@ -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 append initrd=/tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/deploy_ramdisk selinux=0 troubleshoot=0 text test_param
ipappend 2 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 label boot_whole_disk
COM32 chain.c32 COM32 chain.c32
append mbr:{{ DISK_IDENTIFIER }} append mbr:{{ DISK_IDENTIFIER }}

View File

@ -7,11 +7,6 @@ menuentry "deploy" {
initrdefi /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/deploy_ramdisk 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" { menuentry "boot_ramdisk" {
linuxefi /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/kernel root=/dev/ram0 text test_param ramdisk_param linuxefi /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/kernel root=/dev/ram0 text test_param ramdisk_param
initrdefi /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/ramdisk initrdefi /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/ramdisk

View File

@ -0,0 +1,6 @@
---
upgrade:
- |
The deprecated support for instance network booting (not to be confused
with the ``ramdisk`` deploy, iSCSI boot or Anaconda deploy) has been
removed. The ``boot_option`` capability is no longer supported.

View File

@ -240,17 +240,6 @@
s-object: False s-object: False
s-proxy: False s-proxy: False
# TODO(dtantsur): remove when sushy-tools no longer uses it.
- job:
name: ironic-tempest-bios-redfish-netboot
description: "Deploy ironic node over PXE using BIOS boot mode"
parent: ironic-tempest-bios-redfish-pxe
vars:
devstack_localrc:
IRONIC_DEFAULT_BOOT_OPTION: netboot
IRONIC_TEMPEST_WHOLE_DISK_IMAGE: False
IRONIC_VM_EPHEMERAL_DISK: 1
- job: - job:
name: ironic-tempest-uefi-redfish-vmedia name: ironic-tempest-uefi-redfish-vmedia
description: "Deploy ironic node over Redfish virtual media using UEFI boot mode" description: "Deploy ironic node over Redfish virtual media using UEFI boot mode"
@ -519,7 +508,6 @@
IRONIC_BAREMETAL_BASIC_OPS: True IRONIC_BAREMETAL_BASIC_OPS: True
IRONIC_BUILD_DEPLOY_RAMDISK: False IRONIC_BUILD_DEPLOY_RAMDISK: False
IRONIC_CALLBACK_TIMEOUT: 600 IRONIC_CALLBACK_TIMEOUT: 600
IRONIC_DEFAULT_BOOT_OPTION: local
IRONIC_DEPLOY_DRIVER: ipmi IRONIC_DEPLOY_DRIVER: ipmi
IRONIC_ENABLED_NETWORK_INTERFACES: flat,neutron IRONIC_ENABLED_NETWORK_INTERFACES: flat,neutron
IRONIC_INSPECTOR_BUILD_RAMDISK: False IRONIC_INSPECTOR_BUILD_RAMDISK: False
@ -609,7 +597,6 @@
IRONIC_AUTOMATED_CLEAN_ENABLED: False IRONIC_AUTOMATED_CLEAN_ENABLED: False
IRONIC_BAREMETAL_BASIC_OPS: True IRONIC_BAREMETAL_BASIC_OPS: True
IRONIC_DEPLOY_DRIVER: ipmi IRONIC_DEPLOY_DRIVER: ipmi
IRONIC_DEFAULT_BOOT_OPTION: local
IRONIC_ENABLED_NETWORK_INTERFACES: flat,neutron IRONIC_ENABLED_NETWORK_INTERFACES: flat,neutron
IRONIC_NETWORK_INTERFACE: neutron IRONIC_NETWORK_INTERFACE: neutron
IRONIC_PROVISION_NETWORK_NAME: ironic-provision IRONIC_PROVISION_NETWORK_NAME: ironic-provision