Codebase list ironic / af90309
Merge "Yoga: Change default boot mode to uefi" Zuul authored 2 years ago Gerrit Code Review committed 2 years ago
19 changed file(s) with 834 addition(s) and 125 deletion(s). Raw diff Collapse all Expand all
44 fi
55
66 # Whether configure the nodes to boot in Legacy BIOS or UEFI mode. Accepted
7 # values are: "bios" or "uefi", defaults to "bios".
8 IRONIC_BOOT_MODE=${IRONIC_BOOT_MODE:-bios}
7 # values are: "bios" or "uefi", defaults to "uefi".
8 IRONIC_BOOT_MODE=${IRONIC_BOOT_MODE:-uefi}
99
1010 CIRROS_VERSION_DEVSTACK=$(set +o xtrace &&
1111 source $TOP_DIR/stackrc &&
23692369 local node_capabilities=""
23702370 if [[ "$IRONIC_BOOT_MODE" == "uefi" ]]; then
23712371 node_capabilities+=" --property capabilities=boot_mode:uefi"
2372 fi
2373 if [[ "$IRONIC_BOOT_MODE" == "bios" ]]; then
2374 node_capabilities+=" --property capabilities=boot_mode:bios"
23722375 fi
23732376 if [[ "$IRONIC_SECURE_BOOT" == "True" ]]; then
23742377 if [[ -n "$node_capabilities" ]]; then
25802583 if [[ "$IRONIC_BOOT_MODE" == "uefi" ]]; then
25812584 openstack --os-cloud $OS_CLOUD flavor set baremetal --property "capabilities:boot_mode"="uefi"
25822585 fi
2583
2586 if [[ "$IRONIC_BOOT_MODE" == "bios" ]]; then
2587 openstack --os-cloud $OS_CLOUD flavor set baremetal --property "capabilities:boot_mode"="bios"
2588 fi
25842589 for trait in $IRONIC_DEFAULT_TRAITS; do
25852590 openstack --os-cloud $OS_CLOUD flavor set baremetal --property "trait:$trait"="required"
25862591 done
6262
6363 openstack baremetal node set <node-uuid> --property capabilities='boot_mode:uefi'
6464
65 Conversely, to configure a node in ``bios`` mode, then set the
66 ``capabilities`` as below::
67
68 openstack baremetal node set <node-uuid> --property capabilities='boot_mode:bios'
69
70 .. note::
71
72 The Ironic project changed the default boot mode setting for nodes from
73 ``bios`` to ``uefi`` during the Yoga development cycle.
74
6575 Nodes having ``boot_mode`` set to ``uefi`` may be requested by adding an
6676 ``extra_spec`` to the Compute service flavor::
6777
131131 cfg.StrOpt('default_boot_mode',
132132 choices=[(boot_modes.UEFI, _('UEFI boot mode')),
133133 (boot_modes.LEGACY_BIOS, _('Legacy BIOS boot mode'))],
134 default=boot_modes.LEGACY_BIOS,
134 default=boot_modes.UEFI,
135135 mutable=True,
136136 help=_('Default boot mode to use when no boot mode is '
137137 'requested in node\'s driver_info, capabilities or '
138138 'in the `instance_info` configuration. Currently the '
139 'default boot mode is "%(bios)s", but it will be '
140 'changed to "%(uefi)s in the future. It is recommended '
141 'to set an explicit value for this option. This option '
139 'default boot mode is "%(uefi)s", but it was '
140 '"%(bios)s" previously in Ironic. It is recommended '
141 'to set an explicit value for this option, and if the '
142 'setting or default differs from nodes, to ensure that '
143 'nodes are configured specifically for their desired '
144 'boot mode. This option '
142145 'only has effect when management interface supports '
143146 'boot mode management') % {
144147 'bios': boot_modes.LEGACY_BIOS,
1515 from oslo_log import log as logging
1616 from oslo_utils import excutils
1717
18 from ironic.common import boot_modes
1918 from ironic.common import exception
2019 from ironic.common.i18n import _
2120 from ironic.common import utils as common_utils
292291 boot_mode = get_boot_mode_for_deploy(node)
293292 if boot_mode:
294293 return boot_mode
295 # TODO(hshiina): The default boot mode will be changed to UEFI.
296 global warn_about_default_boot_mode
297 if (not warn_about_default_boot_mode
298 and CONF.deploy.default_boot_mode == boot_modes.LEGACY_BIOS):
299 warn_about_default_boot_mode = True
300 LOG.warning('Boot mode is not configured for node %(node_uuid)s '
301 'explicitly. The default boot mode is "%(bios)s", but, '
302 'the default will be changed to "%(uefi)s" in the future. '
303 'It is recommended to set the boot option into '
304 'properties/capabilities/boot_mode for all nodes.',
305 {'node_uuid': node.uuid,
306 'bios': boot_modes.LEGACY_BIOS,
307 'uefi': boot_modes.UEFI})
308294 return CONF.deploy.default_boot_mode
309295
310296
607607 :raises: InvalidParameterValue if the capabilities string is not a
608608 dict or is malformed.
609609 :returns: A string representing the boot option type. Defaults to
610 'netboot'.
610 configuration setting [deploy]default_boot_mode.
611611 """
612612
613613 # NOTE(TheJulia): Software raid always implies local deployment
437437 unlink_mock.assert_called_once_with('/tftpboot/10.10.0.1.conf')
438438 create_link_mock.assert_has_calls(create_link_calls)
439439
440 @mock.patch.object(pxe_utils, '_link_ip_address_pxe_configs',
441 autospec=True)
440442 @mock.patch.object(os, 'chmod', autospec=True)
441443 @mock.patch('ironic.common.utils.write_to_file', autospec=True)
442444 @mock.patch('ironic.common.utils.render_template', autospec=True)
443445 @mock.patch('oslo_utils.fileutils.ensure_tree', autospec=True)
444446 def test_create_pxe_config(self, ensure_tree_mock, render_mock,
445 write_mock, chmod_mock):
447 write_mock, chmod_mock, mock_link_ip_addr):
446448 self.config(tftp_root=tempfile.mkdtemp(), group='pxe')
447449 with task_manager.acquire(self.context, self.node.uuid) as task:
448450 pxe_utils.create_pxe_config(task, self.pxe_options,
450452 render_mock.assert_called_with(
451453 CONF.pxe.pxe_config_template,
452454 {'pxe_options': self.pxe_options,
453 'ROOT': '{{ ROOT }}',
454 'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'}
455 'ROOT': '(( ROOT ))',
456 'DISK_IDENTIFIER': '(( DISK_IDENTIFIER ))'}
455457 )
456458 node_dir = os.path.join(CONF.pxe.tftp_root, self.node.uuid)
457459 pxe_dir = os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg')
464466 pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
465467 write_mock.assert_called_with(pxe_cfg_file_path,
466468 render_mock.return_value)
467
469 self.assertTrue(mock_link_ip_addr.called)
470
471 @mock.patch.object(pxe_utils, '_link_ip_address_pxe_configs',
472 autospec=True)
468473 @mock.patch.object(os, 'chmod', autospec=True)
469474 @mock.patch('ironic.common.utils.write_to_file', autospec=True)
470475 @mock.patch('ironic.common.utils.render_template', autospec=True)
471476 @mock.patch('oslo_utils.fileutils.ensure_tree', autospec=True)
472477 def test_create_pxe_config_set_dir_permission(self, ensure_tree_mock,
473478 render_mock,
474 write_mock, chmod_mock):
479 write_mock, chmod_mock,
480 mock_link_ip_addr):
475481 self.config(tftp_root=tempfile.mkdtemp(), group='pxe')
476482 self.config(dir_permission=0o755, group='pxe')
477483 with task_manager.acquire(self.context, self.node.uuid) as task:
480486 render_mock.assert_called_with(
481487 CONF.pxe.pxe_config_template,
482488 {'pxe_options': self.pxe_options,
483 'ROOT': '{{ ROOT }}',
484 'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'}
489 'ROOT': '(( ROOT ))',
490 'DISK_IDENTIFIER': '(( DISK_IDENTIFIER ))'}
485491 )
486492 node_dir = os.path.join(CONF.pxe.tftp_root, self.node.uuid)
487493 pxe_dir = os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg')
495501 pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
496502 write_mock.assert_called_with(pxe_cfg_file_path,
497503 render_mock.return_value)
498
504 self.assertTrue(mock_link_ip_addr.called)
505
506 @mock.patch.object(pxe_utils, '_link_ip_address_pxe_configs',
507 autospec=True)
499508 @mock.patch.object(os.path, 'isdir', autospec=True)
500509 @mock.patch.object(os, 'chmod', autospec=True)
501510 @mock.patch('ironic.common.utils.write_to_file', autospec=True)
502511 @mock.patch('ironic.common.utils.render_template', autospec=True)
503512 @mock.patch('oslo_utils.fileutils.ensure_tree', autospec=True)
504 def test_create_pxe_config_existing_dirs(self, ensure_tree_mock,
505 render_mock,
506 write_mock, chmod_mock,
507 isdir_mock):
513 def test_create_pxe_config_existing_dirs_uefi(
514 self, ensure_tree_mock,
515 render_mock,
516 write_mock, chmod_mock,
517 isdir_mock, mock_link_ip_address):
508518 self.config(dir_permission=0o755, group='pxe')
519 with task_manager.acquire(self.context, self.node.uuid) as task:
520 isdir_mock.return_value = True
521 pxe_utils.create_pxe_config(task, self.pxe_options,
522 CONF.pxe.pxe_config_template)
523 render_mock.assert_called_with(
524 CONF.pxe.pxe_config_template,
525 {'pxe_options': self.pxe_options,
526 'ROOT': '(( ROOT ))',
527 'DISK_IDENTIFIER': '(( DISK_IDENTIFIER ))'}
528 )
529 ensure_tree_mock.assert_has_calls([])
530 chmod_mock.assert_not_called()
531 isdir_mock.assert_has_calls([])
532 pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
533 write_mock.assert_called_with(pxe_cfg_file_path,
534 render_mock.return_value)
535 self.assertTrue(mock_link_ip_address.called)
536
537 @mock.patch.object(os.path, 'isdir', autospec=True)
538 @mock.patch.object(os, 'chmod', autospec=True)
539 @mock.patch('ironic.common.utils.write_to_file', autospec=True)
540 @mock.patch('ironic.common.utils.render_template', autospec=True)
541 @mock.patch('oslo_utils.fileutils.ensure_tree', autospec=True)
542 def test_create_pxe_config_existing_dirs_bios(
543 self, ensure_tree_mock,
544 render_mock,
545 write_mock, chmod_mock,
546 isdir_mock):
547 self.config(dir_permission=0o755, group='pxe')
548 self.config(default_boot_mode='bios', group='deploy')
509549 with task_manager.acquire(self.context, self.node.uuid) as task:
510550 isdir_mock.return_value = True
511551 pxe_utils.create_pxe_config(task, self.pxe_options,
633673 write_mock.assert_called_with(pxe_cfg_file_path,
634674 render_mock.return_value)
635675
676 @mock.patch('ironic.dhcp.neutron.NeutronDHCPApi.get_ip_addresses',
677 autospec=True)
636678 @mock.patch('ironic.common.utils.rmtree_without_raise', autospec=True)
637679 @mock.patch('ironic_lib.utils.unlink_without_raise', autospec=True)
638 def test_clean_up_pxe_config(self, unlink_mock, rmtree_mock):
680 def test_clean_up_pxe_config(self, unlink_mock, rmtree_mock,
681 mock_get_ip_addr):
639682 address = "aa:aa:aa:aa:aa:aa"
640683 object_utils.create_test_port(self.context, node_id=self.node.id,
641684 address=address)
653696 unlink_mock.assert_has_calls(ensure_calls)
654697 rmtree_mock.assert_called_once_with(
655698 os.path.join(CONF.pxe.tftp_root, self.node.uuid))
699 self.assertTrue(mock_get_ip_addr.called)
656700
657701 @mock.patch.object(os.path, 'isfile', lambda path: False)
658702 @mock.patch('ironic.common.utils.file_has_content', autospec=True)
736780 self.config(tftp_server='192.0.2.1', group='pxe')
737781 elif ip_version == 6:
738782 self.config(tftp_server='ff80::1', group='pxe')
739 self.config(pxe_bootfile_name='fake-bootfile', group='pxe')
783 if CONF.deploy.default_boot_mode == 'uefi':
784 if ipxe:
785 self.config(uefi_ipxe_bootfile_name='fake-bootfile-ipxe',
786 group='pxe')
787 else:
788 self.config(uefi_pxe_bootfile_name='fake-bootfile',
789 group='pxe')
790 else:
791 if ipxe:
792 self.config(ipxe_bootfile_name='fake-bootfile-ipxe',
793 group='pxe')
794 else:
795 self.config(pxe_bootfile_name='fake-bootfile', group='pxe')
740796 self.config(tftp_root='/tftp-path/', group='pxe')
741797 if ipxe:
742798 bootfile = 'fake-bootfile-ipxe'
773829 pxe_utils.dhcp_options_for_instance(task))
774830
775831 def test_dhcp_options_for_instance(self):
832 self.config(default_boot_mode='uefi', group='deploy')
833 self._dhcp_options_for_instance(ip_version=4)
834
835 def test_dhcp_options_for_instance_bios(self):
836 self.config(default_boot_mode='bios', group='deploy')
776837 self._dhcp_options_for_instance(ip_version=4)
777838
778839 def test_dhcp_options_for_instance_ipv6(self):
779840 self.config(tftp_server='ff80::1', group='pxe')
841 self._dhcp_options_for_instance(ip_version=6)
842
843 def test_dhcp_options_for_instance_ipv6_bios(self):
844 self.config(tftp_server='ff80::1', group='pxe')
845 self.config(default_boot_mode='bios', group='deploy')
780846 self._dhcp_options_for_instance(ip_version=6)
781847
782848 def _test_get_kernel_ramdisk_info(self, expected_dir, mode='deploy',
17041770 def test_dhcp_options_for_instance_ipxe_bios(self):
17051771 self.config(ip_version=4, group='pxe')
17061772 boot_file = 'fake-bootfile-bios-ipxe'
1773 self.config(default_boot_mode='bios', group='deploy')
17071774 self.config(ipxe_bootfile_name=boot_file, group='pxe')
17081775 with task_manager.acquire(self.context, self.node.uuid) as task:
17091776 self._dhcp_options_for_instance_ipxe(task, boot_file)
17201787 self.config(ip_version=6, group='pxe')
17211788 boot_file = 'fake-bootfile-ipxe'
17221789 self.config(ipxe_bootfile_name=boot_file, group='pxe')
1790 self.config(default_boot_mode='bios', group='deploy')
1791 with task_manager.acquire(self.context, self.node.uuid) as task:
1792 self._dhcp_options_for_instance_ipxe(task, boot_file, ip_version=6)
1793
1794 def test_dhcp_options_for_ipxe_ipv6_uefi(self):
1795 self.config(ip_version=6, group='pxe')
1796 boot_file = 'fake-bootfile-ipxe'
1797 self.config(uefi_ipxe_bootfile_name=boot_file, group='pxe')
1798 self.config(default_boot_mode='uefi', group='deploy')
17231799 with task_manager.acquire(self.context, self.node.uuid) as task:
17241800 self._dhcp_options_for_instance_ipxe(task, boot_file, ip_version=6)
17251801
241241 '--private-key=/path/to/key')
242242
243243 def test__parse_partitioning_info_root_msdos(self):
244 self.config(default_boot_mode='bios', group='deploy')
244245 expected_info = {
245246 'partition_info': {
246247 'label': 'msdos',
289289 fake_system.set_system_boot_options.assert_has_calls(
290290 [mock.call(sushy.BOOT_SOURCE_TARGET_PXE,
291291 enabled=expected),
292 mock.call(mode=sushy.BOOT_SOURCE_MODE_BIOS)])
292 mock.call(mode=sushy.BOOT_SOURCE_MODE_UEFI)])
293293 else:
294294 fake_system.set_system_boot_options.assert_has_calls(
295295 [mock.call(sushy.BOOT_SOURCE_TARGET_PXE,
984984 with task_manager.acquire(self.context, self.node['uuid'],
985985 shared=False) as task:
986986 self.deploy.configure_local_boot(task)
987 # NOTE(TheJulia): We explicitly call install_bootloader when
988 # we have a whole disk image *and* are in UEFI mode as setting
989 # the internal NVRAM helps negate need to know a root device
990 # hint if the boot order is weird.
991 self.assertTrue(install_bootloader_mock.called)
992 try_set_boot_device_mock.assert_called_once_with(
993 task, boot_devices.DISK, persistent=True)
994
995 @mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True)
996 @mock.patch.object(agent_client.AgentClient, 'install_bootloader',
997 autospec=True)
998 def test_configure_local_boot_whole_disk_image_bios(
999 self, install_bootloader_mock, try_set_boot_device_mock):
1000 self.config(default_boot_mode='bios', group='deploy')
1001
1002 with task_manager.acquire(self.context, self.node['uuid'],
1003 shared=False) as task:
1004 self.deploy.configure_local_boot(task)
9871005 self.assertFalse(install_bootloader_mock.called)
9881006 try_set_boot_device_mock.assert_called_once_with(
9891007 task, boot_devices.DISK, persistent=True)
10291047 def test_configure_local_boot_on_software_raid(
10301048 self, install_bootloader_mock, try_set_boot_device_mock,
10311049 GlanceImageService_mock):
1050 image = GlanceImageService_mock.return_value.show.return_value
1051 image.get.return_value = {'rootfs_uuid': 'rootfs'}
1052 with task_manager.acquire(self.context, self.node['uuid'],
1053 shared=False) as task:
1054 task.node.driver_internal_info['is_whole_disk_image'] = True
1055 task.node.target_raid_config = {
1056 "logical_disks": [
1057 {
1058 "size_gb": 100,
1059 "raid_level": "1",
1060 "controller": "software",
1061 },
1062 {
1063 "size_gb": 'MAX',
1064 "raid_level": "0",
1065 "controller": "software",
1066 }
1067 ]
1068 }
1069 self.deploy.configure_local_boot(task)
1070 self.assertTrue(GlanceImageService_mock.called)
1071 install_bootloader_mock.assert_called_once_with(
1072 mock.ANY, task.node,
1073 root_uuid='rootfs',
1074 efi_system_part_uuid=None,
1075 prep_boot_part_uuid=None,
1076 target_boot_mode='uefi',
1077 software_raid=True)
1078 try_set_boot_device_mock.assert_called_once_with(
1079 task, boot_devices.DISK, persistent=True)
1080
1081 @mock.patch.object(image_service, 'GlanceImageService', autospec=True)
1082 @mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True)
1083 @mock.patch.object(agent_client.AgentClient, 'install_bootloader',
1084 autospec=True)
1085 def test_configure_local_boot_on_software_raid_bios(
1086 self, install_bootloader_mock, try_set_boot_device_mock,
1087 GlanceImageService_mock):
1088 self.config(default_boot_mode='bios', group='deploy')
10321089 image = GlanceImageService_mock.return_value.show.return_value
10331090 image.get.return_value = {'rootfs_uuid': 'rootfs'}
10341091 with task_manager.acquire(self.context, self.node['uuid'],
10671124 def test_configure_local_boot_on_software_raid_explicit_uuid(
10681125 self, install_bootloader_mock, try_set_boot_device_mock,
10691126 GlanceImageService_mock):
1127 with task_manager.acquire(self.context, self.node['uuid'],
1128 shared=False) as task:
1129 task.node.driver_internal_info['is_whole_disk_image'] = True
1130 task.node.instance_info['image_rootfs_uuid'] = 'rootfs'
1131 task.node.target_raid_config = {
1132 "logical_disks": [
1133 {
1134 "size_gb": 100,
1135 "raid_level": "1",
1136 "controller": "software",
1137 },
1138 {
1139 "size_gb": 'MAX',
1140 "raid_level": "0",
1141 "controller": "software",
1142 }
1143 ]
1144 }
1145 self.deploy.configure_local_boot(task)
1146 self.assertFalse(GlanceImageService_mock.called)
1147 install_bootloader_mock.assert_called_once_with(
1148 mock.ANY, task.node,
1149 root_uuid='rootfs',
1150 efi_system_part_uuid=None,
1151 prep_boot_part_uuid=None,
1152 target_boot_mode='uefi',
1153 software_raid=True)
1154 try_set_boot_device_mock.assert_called_once_with(
1155 task, boot_devices.DISK, persistent=True)
1156
1157 @mock.patch.object(image_service, 'GlanceImageService', autospec=True)
1158 @mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True)
1159 @mock.patch.object(agent_client.AgentClient, 'install_bootloader',
1160 autospec=True)
1161 def test_configure_local_boot_on_software_raid_explicit_uuid_bios(
1162 self, install_bootloader_mock, try_set_boot_device_mock,
1163 GlanceImageService_mock):
1164 self.config(default_boot_mode='bios', group='deploy')
10701165 with task_manager.acquire(self.context, self.node['uuid'],
10711166 shared=False) as task:
10721167 task.node.driver_internal_info['is_whole_disk_image'] = True
11011196 @mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True)
11021197 @mock.patch.object(agent_client.AgentClient, 'install_bootloader',
11031198 autospec=True)
1104 def test_configure_local_boot_on_software_raid_exception(
1199 def test_configure_local_boot_on_software_raid_exception_uefi(
11051200 self, install_bootloader_mock, try_set_boot_device_mock,
11061201 GlanceImageService_mock):
1202 GlanceImageService_mock.side_effect = Exception('Glance not found')
1203 with task_manager.acquire(self.context, self.node['uuid'],
1204 shared=False) as task:
1205 task.node.driver_internal_info['is_whole_disk_image'] = True
1206 root_uuid = "1efecf88-2b58-4d4e-8fbd-7bef1a40a1b0"
1207 task.node.driver_internal_info['root_uuid_or_disk_id'] = root_uuid
1208 task.node.target_raid_config = {
1209 "logical_disks": [
1210 {
1211 "size_gb": 100,
1212 "raid_level": "1",
1213 "controller": "software",
1214 },
1215 {
1216 "size_gb": 'MAX',
1217 "raid_level": "0",
1218 "controller": "software",
1219 }
1220 ]
1221 }
1222 self.deploy.configure_local_boot(task)
1223 self.assertTrue(GlanceImageService_mock.called)
1224 # check if the root_uuid comes from the driver_internal_info
1225 install_bootloader_mock.assert_called_once_with(
1226 mock.ANY, task.node, root_uuid=root_uuid,
1227 efi_system_part_uuid=None, prep_boot_part_uuid=None,
1228 target_boot_mode='uefi', software_raid=True)
1229 try_set_boot_device_mock.assert_called_once_with(
1230 task, boot_devices.DISK, persistent=True)
1231
1232 @mock.patch.object(image_service, 'GlanceImageService', autospec=True)
1233 @mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True)
1234 @mock.patch.object(agent_client.AgentClient, 'install_bootloader',
1235 autospec=True)
1236 def test_configure_local_boot_on_software_raid_exception_bios(
1237 self, install_bootloader_mock, try_set_boot_device_mock,
1238 GlanceImageService_mock):
1239 self.config(default_boot_mode='bios', group='deploy')
11071240 GlanceImageService_mock.side_effect = Exception('Glance not found')
11081241 with task_manager.acquire(self.context, self.node['uuid'],
11091242 shared=False) as task:
5252 boot_mode_utils.warn_about_default_boot_mode = False
5353 mock_for_deploy.return_value = None
5454 boot_mode = boot_mode_utils.get_boot_mode(self.node)
55 self.assertEqual(boot_modes.UEFI, boot_mode)
56 boot_mode = boot_mode_utils.get_boot_mode(self.node)
57 self.assertEqual(boot_modes.UEFI, boot_mode)
58 self.assertEqual(0, mock_log.warning.call_count)
59
60 @mock.patch.object(boot_mode_utils, 'LOG', autospec=True)
61 @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy',
62 autospec=True)
63 def test_get_boot_mode_bios_default(self, mock_for_deploy, mock_log):
64 self.config(default_boot_mode='bios', group='deploy')
65 boot_mode_utils.warn_about_default_boot_mode = False
66 mock_for_deploy.return_value = None
67 boot_mode = boot_mode_utils.get_boot_mode(self.node)
5568 self.assertEqual(boot_modes.LEGACY_BIOS, boot_mode)
5669 boot_mode = boot_mode_utils.get_boot_mode(self.node)
5770 self.assertEqual(boot_modes.LEGACY_BIOS, boot_mode)
58 self.assertEqual(1, mock_log.warning.call_count)
71 self.assertEqual(0, mock_log.warning.call_count)
5972
6073 @mock.patch.object(boot_mode_utils, 'LOG', autospec=True)
6174 @mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy',
578578 self.config(pxe_bootfile_name_by_arch=self.bootfile_by_arch,
579579 group='pxe')
580580 result = utils.get_pxe_boot_file(self.node)
581 self.assertEqual('uefi-bootfile', result)
582
583 def test_get_pxe_boot_file_emtpy_property_bios_default(self):
584 self.config(default_boot_mode='bios', group='deploy')
585 self.node.properties = {}
586 self.config(pxe_bootfile_name_by_arch=self.bootfile_by_arch,
587 group='pxe')
588 result = utils.get_pxe_boot_file(self.node)
581589 self.assertEqual('bios-bootfile', result)
582590
583 def test_get_ipxe_boot_file(self):
591 def test_get_ipxe_boot_uefi(self):
592 self.config(uefi_ipxe_bootfile_name='meow', group='pxe')
593 result = utils.get_ipxe_boot_file(self.node)
594 self.assertEqual('meow', result)
595
596 def test_get_ipxe_boot_bios(self):
597 self.config(default_boot_mode='bios', group='deploy')
584598 self.config(ipxe_bootfile_name='meow', group='pxe')
585599 result = utils.get_ipxe_boot_file(self.node)
586600 self.assertEqual('meow', result)
604618 def test_get_ipxe_boot_file_fallback(self):
605619 self.config(ipxe_bootfile_name=None, group='pxe')
606620 self.config(uefi_ipxe_bootfile_name=None, group='pxe')
621 self.config(pxe_bootfile_name=None, group='pxe')
622 self.config(uefi_pxe_bootfile_name='lolcat', group='pxe')
623 result = utils.get_ipxe_boot_file(self.node)
624 self.assertEqual('lolcat', result)
625
626 def test_get_ipxe_boot_file_fallback_bios(self):
627 self.config(default_boot_mode='bios', group='deploy')
628 self.config(ipxe_bootfile_name=None, group='pxe')
629 self.config(uefi_ipxe_bootfile_name=None, group='pxe')
607630 self.config(pxe_bootfile_name='lolcat', group='pxe')
608631 result = utils.get_ipxe_boot_file(self.node)
609632 self.assertEqual('lolcat', result)
610633
611634 def test_get_pxe_config_template_emtpy_property(self):
635 self.node.properties = {}
636 self.config(pxe_config_template_by_arch=self.template_by_arch,
637 group='pxe')
638 result = utils.get_pxe_config_template(self.node)
639 self.assertEqual('uefi-template', result)
640
641 def test_get_pxe_config_template_emtpy_property_bios(self):
642 self.config(default_boot_mode='bios', group='deploy')
612643 self.node.properties = {}
613644 self.config(pxe_config_template_by_arch=self.template_by_arch,
614645 group='pxe')
630661 utils.get_ipxe_config_template(node))
631662
632663 def test_get_ipxe_config_template_none(self):
664 self.config(ipxe_config_template=None, group='pxe')
665 self.config(uefi_pxe_config_template='magical_bootloader',
666 group='pxe')
667 node = obj_utils.create_test_node(
668 self.context, driver='fake-hardware')
669 self.assertEqual('magical_bootloader',
670 utils.get_ipxe_config_template(node))
671
672 def test_get_ipxe_config_template_none_bios(self):
673 self.config(default_boot_mode='bios', group='deploy')
633674 self.config(ipxe_config_template=None, group='pxe')
634675 self.config(pxe_config_template='magical_bootloader',
635676 group='pxe')
10121053 inst_info = {'capabilities': {'cat': 'meows'}}
10131054 self.node.instance_info = inst_info
10141055 result = utils.get_disk_label(self.node)
1056 self.assertEqual('gpt', result)
1057
1058 def test_get_disk_label_nothing_set_bios_mode(self):
1059 self.config(default_boot_mode='bios', group='deploy')
1060 inst_info = {'capabilities': {'cat': 'meows'}}
1061 self.node.instance_info = inst_info
1062 result = utils.get_disk_label(self.node)
10151063 self.assertIsNone(result)
10161064
10171065 def test_get_disk_label_uefi_mode(self):
10571105 @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
10581106 def test_try_set_boot_device_ipmifailure_bios(
10591107 self, node_set_boot_device_mock):
1108 self.config(default_boot_mode='bios', group='deploy')
10601109 node_set_boot_device_mock.side_effect = exception.IPMIFailure(cmd='a')
10611110 with task_manager.acquire(self.context, self.node.uuid,
10621111 shared=False) as task:
508508 @mock.patch.object(images, 'create_boot_iso', autospec=True)
509509 def test__prepare_iso_image_bios(
510510 self, mock_create_boot_iso, mock_publish_image):
511 self.config(default_boot_mode='bios', group='deploy')
511512 with task_manager.acquire(self.context, self.node.uuid,
512513 shared=True) as task:
513514
550551
551552 mock_create_boot_iso.assert_called_once_with(
552553 mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
553 boot_mode='bios', esp_image_href=None,
554 boot_mode='uefi', esp_image_href=None,
554555 kernel_params=kernel_params,
555556 root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
556557 inject_files=None)
560561 @mock.patch.object(images, 'create_boot_iso', autospec=True)
561562 def test__prepare_iso_image_kernel_params_driver_info(
562563 self, mock_create_boot_iso, mock_publish_image):
564 with task_manager.acquire(self.context, self.node.uuid,
565 shared=True) as task:
566 kernel_params = 'network-config=base64-cloudinit-blob'
567
568 task.node.driver_info['kernel_append_params'] = kernel_params
569
570 image_utils._prepare_iso_image(
571 task, 'http://kernel/img', 'http://ramdisk/img',
572 bootloader_href=None, root_uuid=task.node.uuid)
573
574 mock_create_boot_iso.assert_called_once_with(
575 mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
576 boot_mode='uefi', esp_image_href=None,
577 kernel_params=kernel_params,
578 root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
579 inject_files=None)
580
581 @mock.patch.object(image_utils.ImageHandler, 'publish_image',
582 autospec=True)
583 @mock.patch.object(images, 'create_boot_iso', autospec=True)
584 def test__prepare_iso_image_kernel_params_driver_info_bios(
585 self, mock_create_boot_iso, mock_publish_image):
586 self.config(default_boot_mode='bios', group='deploy')
563587 with task_manager.acquire(self.context, self.node.uuid,
564588 shared=True) as task:
565589 kernel_params = 'network-config=base64-cloudinit-blob'
581605 @mock.patch.object(image_utils.ImageHandler, 'publish_image',
582606 autospec=True)
583607 @mock.patch.object(images, 'create_boot_iso', autospec=True)
584 def test__prepare_iso_image_kernel_params_for_ramdisk(
608 def test__prepare_iso_image_kernel_params_for_ramdisk_uefi(
585609 self, mock_create_boot_iso, mock_publish_image):
610 with task_manager.acquire(self.context, self.node.uuid,
611 shared=True) as task:
612 kernel_params = 'network-config=base64-cloudinit-blob'
613
614 task.node.instance_info['ramdisk_kernel_arguments'] = kernel_params
615
616 image_utils._prepare_iso_image(
617 task, 'http://kernel/img', 'http://ramdisk/img',
618 bootloader_href=None, root_uuid=task.node.uuid)
619
620 mock_create_boot_iso.assert_called_once_with(
621 mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
622 boot_mode='uefi', esp_image_href=None,
623 kernel_params="root=/dev/ram0 text " + kernel_params,
624 root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
625 inject_files=None)
626
627 @mock.patch.object(deploy_utils, 'get_boot_option', lambda node: 'ramdisk')
628 @mock.patch.object(image_utils.ImageHandler, 'publish_image',
629 autospec=True)
630 @mock.patch.object(images, 'create_boot_iso', autospec=True)
631 def test__prepare_iso_image_kernel_params_for_ramdisk_bios(
632 self, mock_create_boot_iso, mock_publish_image):
633 self.config(default_boot_mode='bios', group='deploy')
586634 with task_manager.acquire(self.context, self.node.uuid,
587635 shared=True) as task:
588636 kernel_params = 'network-config=base64-cloudinit-blob'
619667
620668 mock_create_boot_iso.assert_called_once_with(
621669 mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
622 boot_mode='bios', esp_image_href=None,
670 boot_mode='uefi', esp_image_href=None,
623671 kernel_params=kernel_params,
624672 root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
625673 inject_files=None)
642690
643691 mock_create_boot_iso.assert_called_once_with(
644692 mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
645 boot_mode='bios', esp_image_href=None,
693 boot_mode='uefi', esp_image_href=None,
646694 kernel_params=kernel_params + ' foo=bar banana',
647695 root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
648696 inject_files=None)
24452445 self.assertEqual({}, driver_routes)
24462446
24472447 @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
2448 def test_management_interface_set_boot_device_ok(self, mock_exec):
2448 def test_management_interface_set_boot_device_ok_bios(self, mock_exec):
24492449 mock_exec.return_value = [None, None]
2450
2450 self.config(default_boot_mode='bios', group='deploy')
24512451 with task_manager.acquire(self.context, self.node.uuid) as task:
24522452 self.management.set_boot_device(task, boot_devices.PXE)
24532453
24572457
24582458 @mock.patch.object(driver_utils, 'force_persistent_boot', autospec=True)
24592459 @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
2460 def test_management_interface_no_force_set_boot_device(self,
2461 mock_exec,
2462 mock_force_boot):
2460 def test_management_interface_no_force_set_boot_device_bios(
2461 self, mock_exec, mock_force_boot):
24632462 mock_exec.return_value = [None, None]
2463 self.config(default_boot_mode='bios', group='deploy')
24642464
24652465 with task_manager.acquire(self.context, self.node.uuid) as task:
24662466 driver_info = task.node.driver_info
24752475 self.assertFalse(mock_force_boot.called)
24762476
24772477 @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
2478 def test_management_interface_force_set_boot_device_ok(self, mock_exec):
2478 def test_management_interface_force_set_boot_device_ok_bios(self,
2479 mock_exec):
24792480 mock_exec.return_value = [None, None]
2481 self.config(default_boot_mode='bios', group='deploy')
24802482
24812483 with task_manager.acquire(self.context, self.node.uuid) as task:
24822484 driver_info = task.node.driver_info
24952497 mock_exec.assert_has_calls(mock_calls)
24962498
24972499 @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
2498 def test_management_interface_set_boot_device_persistent(self, mock_exec):
2500 def test_management_interface_set_boot_device_persistent_bios(self,
2501 mock_exec):
24992502 mock_exec.return_value = [None, None]
2503 self.config(default_boot_mode='bios', group='deploy')
25002504
25012505 with task_manager.acquire(self.context, self.node.uuid) as task:
25022506 driver_info = task.node.driver_info
25192523 task, 'fake-device')
25202524
25212525 @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
2522 def test_management_interface_set_boot_device_without_timeout_1(self,
2523 mock_exec):
2526 def test_management_interface_set_boot_device_without_timeout_1_uefi(
2527 self, mock_exec):
25242528 mock_exec.return_value = [None, None]
2525
25262529 with task_manager.acquire(self.context, self.node.uuid) as task:
25272530 driver_info = task.node.driver_info
25282531 driver_info['ipmi_disable_boot_timeout'] = 'False'
25292532 task.node.driver_info = driver_info
25302533 self.management.set_boot_device(task, boot_devices.PXE)
25312534
2535 mock_calls = [mock.call(self.info, "raw 0x00 0x08 0x05 0xa0 0x04 "
2536 "0x00 0x00 0x00")]
2537 mock_exec.assert_has_calls(mock_calls)
2538
2539 @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
2540 def test_management_interface_set_boot_device_without_timeout_1_bios(
2541 self, mock_exec):
2542 mock_exec.return_value = [None, None]
2543 self.config(default_boot_mode='bios', group='deploy')
2544 with task_manager.acquire(self.context, self.node.uuid) as task:
2545 driver_info = task.node.driver_info
2546 driver_info['ipmi_disable_boot_timeout'] = 'False'
2547 task.node.driver_info = driver_info
2548 self.management.set_boot_device(task, boot_devices.PXE)
2549
25322550 mock_calls = [mock.call(self.info, "chassis bootdev pxe")]
25332551 mock_exec.assert_has_calls(mock_calls)
25342552
25352553 @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
2536 def test_management_interface_set_boot_device_without_timeout_2(self,
2537 mock_exec):
2554 def test_management_interface_set_boot_device_without_timeout_2_uefi(
2555 self, mock_exec):
25382556 CONF.set_override('disable_boot_timeout', False, 'ipmi')
2557 mock_exec.return_value = [None, None]
2558
2559 with task_manager.acquire(self.context, self.node.uuid) as task:
2560 self.management.set_boot_device(task, boot_devices.PXE)
2561
2562 mock_calls = [mock.call(self.info, "raw 0x00 0x08 0x05 0xa0 0x04 "
2563 "0x00 0x00 0x00")]
2564 mock_exec.assert_has_calls(mock_calls)
2565
2566 @mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
2567 def test_management_interface_set_boot_device_without_timeout_2_bios(
2568 self, mock_exec):
2569 CONF.set_override('disable_boot_timeout', False, 'ipmi')
2570 self.config(default_boot_mode='bios', group='deploy')
25392571 mock_exec.return_value = [None, None]
25402572
25412573 with task_manager.acquire(self.context, self.node.uuid) as task:
605605 task, ipxe_enabled=True, ip_version=6)
606606 pxe_config_path = pxe_utils.get_pxe_config_file_path(
607607 task.node.uuid, ipxe_enabled=True)
608 task.node.properties['capabilities'] = 'boot_mode:uefi'
609 task.node.instance_info['capabilities'] = instance_info
610 task.node.driver_internal_info['root_uuid_or_disk_id'] = (
611 "30212642-09d3-467f-8e09-21685826ab50")
612 task.node.driver_internal_info['is_whole_disk_image'] = False
613
614 task.driver.boot.prepare_instance(task)
615
616 get_image_info_mock.assert_called_once_with(
617 task, ipxe_enabled=True)
618 cache_mock.assert_called_once_with(task, image_info,
619 ipxe_enabled=True)
620 provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts)
621 switch_pxe_config_mock.assert_called_once_with(
622 pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50",
623 'uefi', False, False, False, False, ipxe_enabled=True,
624 anaconda_boot=False)
625 set_boot_device_mock.assert_called_once_with(task,
626 boot_devices.PXE,
627 persistent=True)
628
629 @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
630 @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True)
631 @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True)
632 @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True)
633 @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True)
634 def test_prepare_instance_netboot_bios(
635 self, get_image_info_mock, cache_mock,
636 dhcp_factory_mock, switch_pxe_config_mock,
637 set_boot_device_mock):
638 provider_mock = mock.MagicMock()
639 dhcp_factory_mock.return_value = provider_mock
640 image_info = {'kernel': ('', '/path/to/kernel'),
641 'ramdisk': ('', '/path/to/ramdisk')}
642 instance_info = {"boot_option": "netboot",
643 "boot_mode": "bios"}
644 get_image_info_mock.return_value = image_info
645 with task_manager.acquire(self.context, self.node.uuid) as task:
608646 task.node.properties['capabilities'] = 'boot_mode:bios'
609647 task.node.instance_info['capabilities'] = instance_info
610648 task.node.driver_internal_info['root_uuid_or_disk_id'] = (
611649 "30212642-09d3-467f-8e09-21685826ab50")
612650 task.node.driver_internal_info['is_whole_disk_image'] = False
651
652 dhcp_opts = pxe_utils.dhcp_options_for_instance(
653 task, ipxe_enabled=True)
654 dhcp_opts += pxe_utils.dhcp_options_for_instance(
655 task, ipxe_enabled=True, ip_version=6)
656 pxe_config_path = pxe_utils.get_pxe_config_file_path(
657 task.node.uuid, ipxe_enabled=True)
613658
614659 task.driver.boot.prepare_instance(task)
615660
640685 dhcp_factory_mock.return_value = provider_mock
641686 image_info = {'kernel': ('', '/path/to/kernel'),
642687 'ramdisk': ('', '/path/to/ramdisk')}
643 i_info_caps = {"boot_option": "ramdisk"}
688 i_info_caps = {"boot_option": "ramdisk",
689 "boot_mode": "bios"}
644690 kernel_arg = "meow"
645691 get_image_info_mock.return_value = image_info
646692
647693 with task_manager.acquire(self.context, self.node.uuid) as task:
648 dhcp_opts = pxe_utils.dhcp_options_for_instance(
649 task, ipxe_enabled=True)
650 dhcp_opts += pxe_utils.dhcp_options_for_instance(
651 task, ipxe_enabled=True, ip_version=6)
652 pxe_config_path = pxe_utils.get_pxe_config_file_path(
653 task.node.uuid, ipxe_enabled=True)
654694 task.node.properties['capabilities'] = 'boot_mode:bios'
655695 i_info = task.node.instance_info
656696 i_info['capabilities'] = i_info_caps
657697 i_info['kernel_append_params'] = kernel_arg
658698 task.node.instance_info = i_info
659699 task.node.save()
700 dhcp_opts = pxe_utils.dhcp_options_for_instance(
701 task, ipxe_enabled=True)
702 dhcp_opts += pxe_utils.dhcp_options_for_instance(
703 task, ipxe_enabled=True, ip_version=6)
704 pxe_config_path = pxe_utils.get_pxe_config_file_path(
705 task.node.uuid, ipxe_enabled=True)
706
660707 task.driver.boot.prepare_instance(task)
661708 get_image_info_mock.assert_called_once_with(
662709 task, ipxe_enabled=True)
680727 mock_create_pxe_config.assert_called_once_with(
681728 task, expected_params, mock.ANY, ipxe_enabled=True)
682729
730 @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True)
731 @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
732 @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True)
733 @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True)
734 @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True)
735 @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True)
736 def test_prepare_instance_ramdisk_bios(
737 self, get_image_info_mock, cache_mock,
738 dhcp_factory_mock, switch_pxe_config_mock,
739 set_boot_device_mock, mock_create_pxe_config):
740 provider_mock = mock.MagicMock()
741 dhcp_factory_mock.return_value = provider_mock
742 image_info = {'kernel': ('', '/path/to/kernel'),
743 'ramdisk': ('', '/path/to/ramdisk')}
744 i_info_caps = {"boot_option": "ramdisk"}
745 kernel_arg = "meow"
746 get_image_info_mock.return_value = image_info
747
748 with task_manager.acquire(self.context, self.node.uuid) as task:
749 i_info = task.node.instance_info
750 i_info['capabilities'] = i_info_caps
751 i_info['kernel_append_params'] = kernel_arg
752 task.node.instance_info = i_info
753 task.node.save()
754 dhcp_opts = pxe_utils.dhcp_options_for_instance(
755 task, ipxe_enabled=True)
756 dhcp_opts += pxe_utils.dhcp_options_for_instance(
757 task, ipxe_enabled=True, ip_version=6)
758 pxe_config_path = pxe_utils.get_pxe_config_file_path(
759 task.node.uuid, ipxe_enabled=True)
760
761 task.driver.boot.prepare_instance(task)
762 get_image_info_mock.assert_called_once_with(
763 task, ipxe_enabled=True)
764 cache_mock.assert_called_once_with(task, image_info,
765 ipxe_enabled=True)
766 provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts)
767 switch_pxe_config_mock.assert_called_once_with(
768 pxe_config_path, None,
769 'uefi', False, iscsi_boot=False, ramdisk_boot=True,
770 ipxe_enabled=True, anaconda_boot=False)
771 set_boot_device_mock.assert_called_once_with(task,
772 boot_devices.PXE,
773 persistent=True)
774 expected_params = {
775 'aki_path': 'http://myserver/' + task.node.uuid + '/kernel',
776 'ari_path': 'http://myserver/' + task.node.uuid + '/ramdisk',
777 'pxe_append_params': 'meow ipa-debug=1 ipa-global-request-id'
778 '=' + task.context.request_id,
779 'tftp_server': mock.ANY,
780 'ipxe_timeout': 0}
781 mock_create_pxe_config.assert_called_once_with(
782 task, expected_params, mock.ANY, ipxe_enabled=True)
783
683784 @mock.patch('os.path.isfile', return_value=False, autospec=True)
684785 @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True)
685786 @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
700801 self.node.provision_state = states.ACTIVE
701802 self.node.save()
702803 with task_manager.acquire(self.context, self.node.uuid) as task:
703 dhcp_opts = pxe_utils.dhcp_options_for_instance(
704 task, ipxe_enabled=True)
705 dhcp_opts += pxe_utils.dhcp_options_for_instance(
706 task, ipxe_enabled=True, ip_version=6)
707 pxe_config_path = pxe_utils.get_pxe_config_file_path(
708 task.node.uuid, ipxe_enabled=True)
709804 task.node.properties['capabilities'] = 'boot_mode:bios'
710805 task.node.instance_info['capabilities'] = instance_info
711806 task.node.driver_internal_info['root_uuid_or_disk_id'] = (
712807 "30212642-09d3-467f-8e09-21685826ab50")
713808 task.node.driver_internal_info['is_whole_disk_image'] = False
809
810 dhcp_opts = pxe_utils.dhcp_options_for_instance(
811 task, ipxe_enabled=True)
812 dhcp_opts += pxe_utils.dhcp_options_for_instance(
813 task, ipxe_enabled=True, ip_version=6)
814 pxe_config_path = pxe_utils.get_pxe_config_file_path(
815 task.node.uuid, ipxe_enabled=True)
714816
715817 task.driver.boot.prepare_instance(task)
716818
744846 get_image_info_mock.return_value = image_info
745847 instance_info = {"boot_option": "netboot"}
746848 with task_manager.acquire(self.context, self.node.uuid) as task:
849 task.node.properties['capabilities'] = 'boot_mode:bios'
850 task.node.instance_info['capabilities'] = instance_info
851 task.node.driver_internal_info['is_whole_disk_image'] = False
747852 dhcp_opts = pxe_utils.dhcp_options_for_instance(
748853 task, ipxe_enabled=True, ip_version=4)
749854 dhcp_opts += pxe_utils.dhcp_options_for_instance(
750855 task, ipxe_enabled=True, ip_version=6)
751 task.node.properties['capabilities'] = 'boot_mode:bios'
752 task.node.instance_info['capabilities'] = instance_info
856
857 task.driver.boot.prepare_instance(task)
858
859 get_image_info_mock.assert_called_once_with(
860 task, ipxe_enabled=True)
861 cache_mock.assert_called_once_with(task, image_info,
862 ipxe_enabled=True)
863 provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts)
864 self.assertFalse(switch_pxe_config_mock.called)
865 self.assertFalse(set_boot_device_mock.called)
866
867 @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
868 @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True)
869 @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True)
870 @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True)
871 @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True)
872 def test_prepare_instance_netboot_missing_root_uuid_default(
873 self, get_image_info_mock, cache_mock,
874 dhcp_factory_mock, switch_pxe_config_mock,
875 set_boot_device_mock):
876 provider_mock = mock.MagicMock()
877 dhcp_factory_mock.return_value = provider_mock
878 image_info = {'kernel': ('', '/path/to/kernel'),
879 'ramdisk': ('', '/path/to/ramdisk')}
880 get_image_info_mock.return_value = image_info
881 instance_info = self.node.instance_info
882 instance_info['capabilities'] = {"boot_option": "netboot"}
883 self.node.instance_info = instance_info
884 self.node.save()
885 with task_manager.acquire(self.context, self.node.uuid) as task:
753886 task.node.driver_internal_info['is_whole_disk_image'] = False
887 dhcp_opts = pxe_utils.dhcp_options_for_instance(
888 task, ipxe_enabled=True, ip_version=4)
889 dhcp_opts += pxe_utils.dhcp_options_for_instance(
890 task, ipxe_enabled=True, ip_version=6)
754891
755892 task.driver.boot.prepare_instance(task)
756893
777914 provider_mock = mock.MagicMock()
778915 dhcp_factory_mock.return_value = provider_mock
779916 get_image_info_mock.return_value = {}
780 instance_info = {"boot_option": "netboot"}
781 with task_manager.acquire(self.context, self.node.uuid) as task:
782 dhcp_opts = pxe_utils.dhcp_options_for_instance(
783 task, ipxe_enabled=True)
784 dhcp_opts += pxe_utils.dhcp_options_for_instance(
785 task, ipxe_enabled=True, ip_version=6)
917 instance_info = {"boot_option": "netboot",
918 "boot_mode": "bios"}
919 with task_manager.acquire(self.context, self.node.uuid) as task:
786920 task.node.properties['capabilities'] = 'boot_mode:bios'
787921 task.node.instance_info['capabilities'] = instance_info
788922 task.node.driver_internal_info['is_whole_disk_image'] = True
923 dhcp_opts = pxe_utils.dhcp_options_for_instance(
924 task, ipxe_enabled=True)
925 dhcp_opts += pxe_utils.dhcp_options_for_instance(
926 task, ipxe_enabled=True, ip_version=6)
927
789928 task.driver.boot.prepare_instance(task)
790929 get_image_info_mock.assert_called_once_with(
791930 task, ipxe_enabled=True)
795934 clean_up_pxe_mock.assert_called_once_with(task, ipxe_enabled=True)
796935 set_boot_device_mock.assert_called_once_with(
797936 task, boot_devices.DISK, persistent=True)
937
938 @mock.patch('os.path.isfile', lambda filename: False)
939 @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True)
940 @mock.patch.object(deploy_utils, 'is_iscsi_boot', lambda task: True)
941 @mock.patch.object(noop_storage.NoopStorage, 'should_write_image',
942 lambda task: False)
943 @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
944 @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True)
945 @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True)
946 @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True)
947 @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True)
948 def test_prepare_instance_netboot_iscsi_bios(
949 self, get_image_info_mock, cache_mock,
950 dhcp_factory_mock, switch_pxe_config_mock,
951 set_boot_device_mock, create_pxe_config_mock):
952 http_url = 'http://192.1.2.3:1234'
953 self.config(http_url=http_url, group='deploy')
954 provider_mock = mock.MagicMock()
955 dhcp_factory_mock.return_value = provider_mock
956 vol_id = uuidutils.generate_uuid()
957 obj_utils.create_test_volume_target(
958 self.context, node_id=self.node.id, volume_type='iscsi',
959 boot_index=0, volume_id='1234', uuid=vol_id,
960 properties={'target_lun': 0,
961 'target_portal': 'fake_host:3260',
962 'target_iqn': 'fake_iqn',
963 'auth_username': 'fake_username',
964 'auth_password': 'fake_password'})
965 with task_manager.acquire(self.context, self.node.uuid) as task:
966 task.node.driver_internal_info = {
967 'boot_from_volume': vol_id}
968 task.node.properties['capabilities'] = 'boot_mode:bios'
969 task.node.instance_info['capabilities'] = {'boot_mode': 'bios'}
970 dhcp_opts = pxe_utils.dhcp_options_for_instance(task,
971 ipxe_enabled=True)
972 dhcp_opts += pxe_utils.dhcp_options_for_instance(
973 task, ipxe_enabled=True, ip_version=6)
974 pxe_config_path = pxe_utils.get_pxe_config_file_path(
975 task.node.uuid, ipxe_enabled=True)
976
977 task.driver.boot.prepare_instance(task)
978 self.assertFalse(get_image_info_mock.called)
979 self.assertFalse(cache_mock.called)
980 provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts)
981 create_pxe_config_mock.assert_called_once_with(
982 task, mock.ANY, CONF.pxe.ipxe_config_template,
983 ipxe_enabled=True)
984 switch_pxe_config_mock.assert_called_once_with(
985 pxe_config_path, None, boot_modes.LEGACY_BIOS, False,
986 ipxe_enabled=True, iscsi_boot=True, ramdisk_boot=False,
987 anaconda_boot=False)
988 set_boot_device_mock.assert_called_once_with(task,
989 boot_devices.PXE,
990 persistent=True)
798991
799992 @mock.patch('os.path.isfile', lambda filename: False)
800993 @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True)
8231016 'target_iqn': 'fake_iqn',
8241017 'auth_username': 'fake_username',
8251018 'auth_password': 'fake_password'})
1019
8261020 with task_manager.acquire(self.context, self.node.uuid) as task:
8271021 task.node.driver_internal_info = {
8281022 'boot_from_volume': vol_id}
8321026 task, ipxe_enabled=True, ip_version=6)
8331027 pxe_config_path = pxe_utils.get_pxe_config_file_path(
8341028 task.node.uuid, ipxe_enabled=True)
835 task.node.properties['capabilities'] = 'boot_mode:bios'
1029
8361030 task.driver.boot.prepare_instance(task)
8371031 self.assertFalse(get_image_info_mock.called)
8381032 self.assertFalse(cache_mock.called)
8411035 task, mock.ANY, CONF.pxe.ipxe_config_template,
8421036 ipxe_enabled=True)
8431037 switch_pxe_config_mock.assert_called_once_with(
844 pxe_config_path, None, boot_modes.LEGACY_BIOS, False,
1038 pxe_config_path, None, boot_modes.UEFI, False,
8451039 ipxe_enabled=True, iscsi_boot=True, ramdisk_boot=False,
8461040 anaconda_boot=False)
8471041 set_boot_device_mock.assert_called_once_with(task,
8731067 self.node.provision_state = states.DEPLOYING
8741068 self.node.save()
8751069 with task_manager.acquire(self.context, self.node.uuid) as task:
876 print(task.node)
8771070 dhcp_opts = pxe_utils.dhcp_options_for_instance(task,
8781071 ipxe_enabled=True)
8791072 dhcp_opts += pxe_utils.dhcp_options_for_instance(
8881081 task, mock.ANY, CONF.pxe.ipxe_config_template,
8891082 ipxe_enabled=True)
8901083 switch_pxe_config_mock.assert_called_once_with(
891 pxe_config_path, None, boot_modes.LEGACY_BIOS, False,
1084 pxe_config_path, None, boot_modes.UEFI, False,
8921085 ipxe_enabled=True, iscsi_boot=False, ramdisk_boot=True,
8931086 anaconda_boot=False)
8941087 set_boot_device_mock.assert_called_once_with(task,
9581151 persistent=True)
9591152 switch_pxe_config_mock.assert_called_once_with(
9601153 pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50",
961 'bios', True, False, False, False, ipxe_enabled=True,
1154 'uefi', True, False, False, False, ipxe_enabled=True,
9621155 anaconda_boot=False)
9631156 # No clean up
9641157 self.assertFalse(clean_up_pxe_config_mock.called)
270270 dhcp_factory_mock,
271271 set_boot_device_mock,
272272 get_boot_mode_mock,
273 uefi=False,
273 uefi=True,
274274 cleaning=False,
275275 ipxe_use_swift=False,
276276 whole_disk_image=False,
294294 driver_internal_info = self.node.driver_internal_info
295295 driver_internal_info['is_whole_disk_image'] = whole_disk_image
296296 self.node.driver_internal_info = driver_internal_info
297
297298 if mode == 'rescue':
298299 mock_deploy_img_info.return_value = {
299300 'rescue_kernel': 'a',
355356 self.node.save()
356357 self._test_prepare_ramdisk()
357358
359 def test_prepare_ramdisk_bios(self):
360 self.node.provision_state = states.DEPLOYING
361 self.node.save()
362 self._test_prepare_ramdisk(uefi=True)
363
358364 def test_prepare_ramdisk_rescue(self):
359365 self.node.provision_state = states.RESCUING
360366 self.node.save()
361367 self._test_prepare_ramdisk(mode='rescue')
368
369 def test_prepare_ramdisk_rescue_bios(self):
370 self.node.provision_state = states.RESCUING
371 self.node.save()
372 self._test_prepare_ramdisk(mode='rescue', uefi=True)
362373
363374 def test_prepare_ramdisk_uefi(self):
364375 self.node.provision_state = states.DEPLOYING
390401 self, set_boot_mode_mock):
391402 self.node.provision_state = states.DEPLOYING
392403 self.node.save()
393 self._test_prepare_ramdisk(node_boot_mode=boot_modes.LEGACY_BIOS)
404 self._test_prepare_ramdisk(node_boot_mode=boot_modes.LEGACY_BIOS,
405 uefi=False)
394406
395407 with task_manager.acquire(self.context, self.node.uuid) as task:
396408 driver_internal_info = task.node.driver_internal_info
407419
408420 self.config(default_boot_mode=boot_modes.LEGACY_BIOS, group='deploy')
409421
410 self._test_prepare_ramdisk()
411
422 self._test_prepare_ramdisk(uefi=False)
412423 with task_manager.acquire(self.context, self.node.uuid) as task:
413424 driver_internal_info = task.node.driver_internal_info
414425 self.assertIn('deploy_boot_mode', driver_internal_info)
469480 properties['capabilities'] = 'boot_mode:uefi'
470481 self.node.properties = properties
471482 self.node.save()
472 self._test_prepare_ramdisk(uefi=True, node_boot_mode=boot_modes.UEFI)
483 self._test_prepare_ramdisk(node_boot_mode=boot_modes.UEFI)
473484 self.assertEqual(set_boot_mode_mock.call_count, 0)
474485
475486 @mock.patch.object(pxe_utils, 'clean_up_pxe_env', autospec=True)
503514 @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True)
504515 @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True)
505516 @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True)
506 def test_prepare_instance_netboot(
517 def test_prepare_instance_netboot_bios(
507518 self, get_image_info_mock, cache_mock,
508519 dhcp_factory_mock, switch_pxe_config_mock,
509520 set_boot_device_mock):
513524 'ramdisk': ('', '/path/to/ramdisk')}
514525 get_image_info_mock.return_value = image_info
515526 with task_manager.acquire(self.context, self.node.uuid) as task:
527 task.node.properties['capabilities'] = 'boot_mode:bios'
528 task.node.driver_internal_info['root_uuid_or_disk_id'] = (
529 "30212642-09d3-467f-8e09-21685826ab50")
530 task.node.driver_internal_info['is_whole_disk_image'] = False
531 task.node.instance_info = {
532 'capabilities': {'boot_option': 'netboot',
533 'boot_mode': 'bios'}}
516534 dhcp_opts = pxe_utils.dhcp_options_for_instance(
517535 task, ipxe_enabled=False, ip_version=4)
518536 dhcp_opts += pxe_utils.dhcp_options_for_instance(
519537 task, ipxe_enabled=False, ip_version=6)
520538 pxe_config_path = pxe_utils.get_pxe_config_file_path(
521539 task.node.uuid)
522 task.node.properties['capabilities'] = 'boot_mode:bios'
523 task.node.driver_internal_info['root_uuid_or_disk_id'] = (
524 "30212642-09d3-467f-8e09-21685826ab50")
525 task.node.driver_internal_info['is_whole_disk_image'] = False
526 task.node.instance_info = {
527 'capabilities': {'boot_option': 'netboot'}}
528540 task.driver.boot.prepare_instance(task)
529541
530542 get_image_info_mock.assert_called_once_with(
535547 switch_pxe_config_mock.assert_called_once_with(
536548 pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50",
537549 'bios', False, False, False, False, ipxe_enabled=False,
550 anaconda_boot=False)
551 set_boot_device_mock.assert_called_once_with(task,
552 boot_devices.PXE,
553 persistent=True)
554
555 @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
556 @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True)
557 @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True)
558 @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True)
559 @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True)
560 def test_prepare_instance_netboot_uefi(
561 self, get_image_info_mock, cache_mock,
562 dhcp_factory_mock, switch_pxe_config_mock,
563 set_boot_device_mock):
564 provider_mock = mock.MagicMock()
565 dhcp_factory_mock.return_value = provider_mock
566 image_info = {'kernel': ('', '/path/to/kernel'),
567 'ramdisk': ('', '/path/to/ramdisk')}
568 get_image_info_mock.return_value = image_info
569 with task_manager.acquire(self.context, self.node.uuid) as task:
570 task.node.driver_internal_info['root_uuid_or_disk_id'] = (
571 "30212642-09d3-467f-8e09-21685826ab50")
572 task.node.driver_internal_info['is_whole_disk_image'] = False
573 task.node.instance_info = {
574 'capabilities': {'boot_option': 'netboot'}}
575 dhcp_opts = pxe_utils.dhcp_options_for_instance(
576 task, ipxe_enabled=False, ip_version=4)
577 dhcp_opts += pxe_utils.dhcp_options_for_instance(
578 task, ipxe_enabled=False, ip_version=6)
579 pxe_config_path = pxe_utils.get_pxe_config_file_path(
580 task.node.uuid)
581 task.driver.boot.prepare_instance(task)
582
583 get_image_info_mock.assert_called_once_with(
584 task, ipxe_enabled=False)
585 cache_mock.assert_called_once_with(
586 task, image_info, ipxe_enabled=False)
587 provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts)
588 switch_pxe_config_mock.assert_called_once_with(
589 pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50",
590 'uefi', False, False, False, False, ipxe_enabled=False,
538591 anaconda_boot=False)
539592 set_boot_device_mock.assert_called_once_with(task,
540593 boot_devices.PXE,
560613 self.node.provision_state = states.ACTIVE
561614 self.node.save()
562615 with task_manager.acquire(self.context, self.node.uuid) as task:
616 task.node.properties['capabilities'] = 'boot_mode:bios'
617 task.node.driver_internal_info['root_uuid_or_disk_id'] = (
618 "30212642-09d3-467f-8e09-21685826ab50")
619 task.node.driver_internal_info['is_whole_disk_image'] = False
620 task.node.instance_info['capabilities'] = instance_info
621 task.driver.boot.prepare_instance(task)
563622 dhcp_opts = pxe_utils.dhcp_options_for_instance(
564623 task, ipxe_enabled=False)
565624 dhcp_opts += pxe_utils.dhcp_options_for_instance(
566625 task, ipxe_enabled=False, ip_version=6)
567626 pxe_config_path = pxe_utils.get_pxe_config_file_path(
568627 task.node.uuid)
569 task.node.properties['capabilities'] = 'boot_mode:bios'
570 task.node.driver_internal_info['root_uuid_or_disk_id'] = (
571 "30212642-09d3-467f-8e09-21685826ab50")
572 task.node.driver_internal_info['is_whole_disk_image'] = False
573 task.node.instance_info['capabilities'] = instance_info
574 task.driver.boot.prepare_instance(task)
575628
576629 get_image_info_mock.assert_called_once_with(
577630 task, ipxe_enabled=False)
603656 instance_info = {"boot_option": "netboot"}
604657 get_image_info_mock.return_value = image_info
605658 with task_manager.acquire(self.context, self.node.uuid) as task:
659 task.node.properties['capabilities'] = 'boot_mode:bios'
660 task.node.instance_info['capabilities'] = instance_info
661 task.node.driver_internal_info['is_whole_disk_image'] = False
606662 dhcp_opts = pxe_utils.dhcp_options_for_instance(
607663 task, ipxe_enabled=False)
608664 dhcp_opts += pxe_utils.dhcp_options_for_instance(
609665 task, ipxe_enabled=False, ip_version=6)
610 task.node.properties['capabilities'] = 'boot_mode:bios'
611 task.node.instance_info['capabilities'] = instance_info
612 task.node.driver_internal_info['is_whole_disk_image'] = False
613666
614667 task.driver.boot.prepare_instance(task)
615668
636689 get_image_info_mock.return_value = {}
637690 instance_info = {"boot_option": "netboot"}
638691 with task_manager.acquire(self.context, self.node.uuid) as task:
692 task.node.properties['capabilities'] = 'boot_mode:bios'
693 task.node.instance_info['capabilities'] = instance_info
694 task.node.driver_internal_info['is_whole_disk_image'] = True
639695 dhcp_opts = pxe_utils.dhcp_options_for_instance(
640696 task, ipxe_enabled=False)
641697 dhcp_opts += pxe_utils.dhcp_options_for_instance(
642698 task, ipxe_enabled=False, ip_version=6)
643 task.node.properties['capabilities'] = 'boot_mode:bios'
644 task.node.instance_info['capabilities'] = instance_info
645 task.node.driver_internal_info['is_whole_disk_image'] = True
646699 task.driver.boot.prepare_instance(task)
647700 get_image_info_mock.assert_called_once_with(task,
648701 ipxe_enabled=False)
701754 self, get_image_info_mock, cache_mock,
702755 dhcp_factory_mock, create_pxe_config_mock,
703756 switch_pxe_config_mock,
704 set_boot_device_mock, config_file_exits=False):
757 set_boot_device_mock, config_file_exits=False,
758 uefi=True):
705759 image_info = {'kernel': ['', '/path/to/kernel'],
706760 'ramdisk': ['', '/path/to/ramdisk']}
707761 get_image_info_mock.return_value = image_info
730784 if config_file_exits:
731785 self.assertFalse(create_pxe_config_mock.called)
732786 else:
733 create_pxe_config_mock.assert_called_once_with(
734 task, mock.ANY, CONF.pxe.pxe_config_template,
735 ipxe_enabled=False)
787 if not uefi:
788 create_pxe_config_mock.assert_called_once_with(
789 task, mock.ANY, CONF.pxe.pxe_config_template,
790 ipxe_enabled=False)
791 else:
792 create_pxe_config_mock.assert_called_once_with(
793 task, mock.ANY, CONF.pxe.uefi_pxe_config_template,
794 ipxe_enabled=False)
795 if uefi:
796 boot_mode = 'uefi'
797 else:
798 boot_mode = 'bios'
799
736800 switch_pxe_config_mock.assert_called_once_with(
737801 pxe_config_path, None,
738 'bios', False, ipxe_enabled=False, iscsi_boot=False,
802 boot_mode, False, ipxe_enabled=False, iscsi_boot=False,
739803 ramdisk_boot=True, anaconda_boot=False)
740804 set_boot_device_mock.assert_called_once_with(task,
741805 boot_devices.PXE,
777841 dhcp_factory_mock.return_value = provider_mock
778842 self.node.provision_state = states.DEPLOYING
779843 self.config(http_url='http://fake_url', group='deploy')
844 with task_manager.acquire(self.context, self.node.uuid) as task:
845 dhcp_opts = pxe_utils.dhcp_options_for_instance(
846 task, ipxe_enabled=False)
847 dhcp_opts += pxe_utils.dhcp_options_for_instance(
848 task, ipxe_enabled=False, ip_version=6)
849 pxe_config_path = pxe_utils.get_pxe_config_file_path(
850 task.node.uuid)
851
852 task.driver.boot.prepare_instance(task)
853
854 get_image_info_mock.assert_called_once_with(task,
855 ipxe_enabled=False)
856 cache_mock.assert_called_once_with(
857 task, image_info, False)
858 if os.path.isfile('/usr/bin/ksvalidator'):
859 exec_mock.assert_called_once_with(
860 'ksvalidator', mock.ANY, check_on_exit=[0], attempts=1
861 )
862 provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts)
863 render_mock.assert_called()
864 write_file_mock.assert_called_with(
865 '/path/to/ks.cfg', render_mock.return_value
866 )
867 create_pxe_config_mock.assert_called_once_with(
868 task, mock.ANY, CONF.pxe.uefi_pxe_config_template,
869 ipxe_enabled=False)
870 switch_pxe_config_mock.assert_called_once_with(
871 pxe_config_path, None,
872 'uefi', False, ipxe_enabled=False, iscsi_boot=False,
873 ramdisk_boot=False, anaconda_boot=True)
874 set_boot_device_mock.assert_called_once_with(task,
875 boot_devices.PXE,
876 persistent=True)
877
878 @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
879 @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True)
880 @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True)
881 @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True)
882 @mock.patch.object(pxe_utils, 'cache_ramdisk_kernel', autospec=True)
883 @mock.patch.object(pxe_utils, 'get_instance_image_info', autospec=True)
884 @mock.patch('ironic.drivers.modules.deploy_utils.get_boot_option',
885 return_value='kickstart', autospec=True)
886 @mock.patch('ironic.drivers.modules.deploy_utils.get_ironic_api_url',
887 return_value='http://fakeserver/api', autospec=True)
888 @mock.patch('ironic.common.utils.render_template', autospec=True)
889 @mock.patch('ironic.common.utils.write_to_file', autospec=True)
890 @mock.patch('ironic.common.utils.execute', autospec=True)
891 def test_prepare_instance_kickstart_bios(
892 self, exec_mock, write_file_mock, render_mock, api_url_mock,
893 boot_opt_mock, get_image_info_mock, cache_mock, dhcp_factory_mock,
894 create_pxe_config_mock, switch_pxe_config_mock,
895 set_boot_device_mock):
896 image_info = {'kernel': ['ins_kernel_id', '/path/to/kernel'],
897 'ramdisk': ['ins_ramdisk_id', '/path/to/ramdisk'],
898 'stage2': ['ins_stage2_id', '/path/to/stage2'],
899 'ks_cfg': ['', '/path/to/ks.cfg'],
900 'ks_template': ['template_id', '/path/to/ks_template']}
901 get_image_info_mock.return_value = image_info
902 provider_mock = mock.MagicMock()
903 dhcp_factory_mock.return_value = provider_mock
904 self.node.provision_state = states.DEPLOYING
905 self.config(http_url='http://fake_url', group='deploy')
906 self.config(default_boot_mode='bios', group='deploy')
907
780908 with task_manager.acquire(self.context, self.node.uuid) as task:
781909 dhcp_opts = pxe_utils.dhcp_options_for_instance(
782910 task, ipxe_enabled=False)
105105 provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts)
106106 switch_pxe_config_mock.assert_called_once_with(
107107 pxe_config_path, None,
108 'bios', False, ipxe_enabled=False, iscsi_boot=False,
109 ramdisk_boot=True, anaconda_boot=False)
108 CONF.deploy.default_boot_mode, False, ipxe_enabled=False,
109 iscsi_boot=False, ramdisk_boot=True, anaconda_boot=False)
110110 set_boot_device_mock.assert_called_once_with(task,
111111 boot_devices.PXE,
112112 persistent=True)
0 ---
1 features:
2 - |
3 The default deployment boot mode is *now* UEFI. Legacy BIOS is still
4 supported, however operators who require BIOS nodes will need to
5 set their nodes, or deployment, appropriately.
6 upgrade:
7 - |
8 The default boot mode has been changed and now UEFI. Operators who
9 were explicitly relying upon BIOS based deployments in the past,
10 may wish to consider setting an explicit node level override for
11 the node to only utilize BIOS mode. This can be configured at a
12 conductor level with the ``[deploy]default_boot_mode``. Options
13 to set this at a node level can be found in the
14 `Ironic Installation guide - Advanced features <https://docs.openstack.org/ironic/latest/install/advanced.html#boot-mode-support>`_
15 documentation.
212212 - job:
213213 name: ironic-tempest-partition-bios-redfish-pxe
214214 description: "Deploy ironic node over PXE using BIOS boot mode"
215 parent: ironic-base
215 parent: ironic-tempest-partition-uefi-redfish-vmedia
216216 required-projects:
217217 - opendev.org/openstack/sushy-tools
218 vars:
219 devstack_localrc:
220 IRONIC_ENABLED_BOOT_INTERFACES: ipxe
221 SWIFT_ENABLE_TEMPURLS: False
222 SWIFT_TEMPURL_KEY: ''
223 # Parent job has a longer timeout due to vmedia usage,
224 # Reset the callback to a normal-ish value.
225 IRONIC_CALLBACK_TIMEOUT: 600
226 IRONIC_DEFAULT_BOOT_OPTION: netboot
227 IRONIC_BOOT_MODE: bios
228 devstack_services:
229 # Parent job uses swift, this one does not, thus we can turn it off.
230 s-account: False
231 s-container: False
232 s-object: False
233 s-proxy: False
234
235 - job:
236 name: ironic-tempest-partition-uefi-redfish-vmedia
237 description: "Deploy ironic node over Redfish virtual media using UEFI boot mode"
238 parent: ironic-base
218239 vars:
219240 devstack_localrc:
220241 IRONIC_DEPLOY_DRIVER: redfish
222243 IRONIC_ENABLED_POWER_INTERFACES: redfish
223244 IRONIC_ENABLED_MANAGEMENT_INTERFACES: redfish
224245 IRONIC_AUTOMATED_CLEAN_ENABLED: False
246 # TODO(TheJulia): We need to excise netboot from
247 # jobs at some point.
225248 IRONIC_DEFAULT_BOOT_OPTION: netboot
226
227 - job:
228 name: ironic-tempest-partition-uefi-redfish-vmedia
229 description: "Deploy ironic node over Redfish virtual media using UEFI boot mode"
230 parent: ironic-tempest-partition-bios-redfish-pxe
231 vars:
232 devstack_localrc:
233 IRONIC_BOOT_MODE: uefi
234249 IRONIC_ENABLED_BOOT_INTERFACES: redfish-virtual-media
235250 SWIFT_ENABLE_TEMPURLS: True
236251 SWIFT_TEMPURL_KEY: secretkey
237 IRONIC_AUTOMATED_CLEAN_ENABLED: False
238252 # Ironic has to master a new image, and this CAN take longer as a
239253 # result and makes this job VERY sensitive to heavy disk IO of the
240254 # underlying hypervisor/cloud.
296310 IRONIC_VM_SPECS_RAM: 3096
297311 SWIFT_ENABLE_TEMPURLS: True
298312 SWIFT_TEMPURL_KEY: secretkey
313 IRONIC_BOOT_MODE: bios
299314 devstack_services:
300315 s-account: True
301316 s-container: True
314329 IRONIC_VM_EPHEMERAL_DISK: 0
315330 IRONIC_AUTOMATED_CLEAN_ENABLED: False
316331 IRONIC_ENFORCE_SCOPE: True
332 IRONIC_BOOT_MODE: bios
317333
318334 - job:
319335 name: ironic-tempest-ipa-partition-uefi-pxe_ipmitool
321337 parent: ironic-base
322338 vars:
323339 devstack_localrc:
324 IRONIC_BOOT_MODE: uefi
325340 IRONIC_VM_SPECS_RAM: 4096
326341 IRONIC_AUTOMATED_CLEAN_ENABLED: False
327342 IRONIC_DEFAULT_BOOT_OPTION: netboot
654669 IRONIC_ENABLED_HARDWARE_TYPES: ipmi
655670 IRONIC_ENABLED_BOOT_INTERFACES: pxe
656671 IRONIC_IPXE_ENABLED: False
657 IRONIC_BOOT_MODE: uefi
658672 IRONIC_RAMDISK_TYPE: tinyipa
659673 IRONIC_AUTOMATED_CLEAN_ENABLED: False
660674 IRONIC_DEFAULT_BOOT_OPTION: netboot
699713 IRONIC_AUTOMATED_CLEAN_ENABLED: False
700714 SWIFT_ENABLE_TEMPURLS: True
701715 SWIFT_TEMPURL_KEY: secretkey
716 IRONIC_BOOT_MODE: bios
702717
703718 - job:
704719 name: ironic-tempest-ipxe-ipv6
776791 IRONIC_VM_EPHEMERAL_DISK: 0
777792 SWIFT_ENABLE_TEMPURLS: True
778793 SWIFT_TEMPURL_KEY: secretkey
794 IRONIC_BOOT_MODE: bios
779795 devstack_services:
780796 s-account: True
781797 s-container: True