def test_link_bootloader_copies_from_system(self): method = UEFIAMD64BootMethod() bootloader_dir = ('/var/lib/maas/boot-resources/%s' % factory.make_name('snapshot')) # Since the fall back looks for paths on the filesystem we need to # intercept the calls and make sure they were called with the right # arguments otherwise the test environment will interfere. allowed_src_files = [ '/usr/lib/shim/shim.efi.signed', '/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed', ] def fake_exists(path): if path in allowed_src_files: return True else: return False self.patch(uefi_amd64_module.os.path, 'exists').side_effect = (fake_exists) mock_atomic_symlink = self.patch(uefi_amd64_module, 'atomic_symlink') method._find_and_copy_bootloaders(bootloader_dir) self.assertThat( mock_atomic_symlink, MockAnyCall('/usr/lib/shim/shim.efi.signed', os.path.join(bootloader_dir, 'bootx64.efi'))) self.assertThat( mock_atomic_symlink, MockAnyCall( '/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed', os.path.join(bootloader_dir, 'grubx64.efi')))
def test_get_reader(self): # Given the right configuration options, the UEFI configuration is # correctly rendered. method = UEFIAMD64BootMethod() params = make_kernel_parameters(purpose="xinstall") output = method.get_reader(backend=None, kernel_params=params) # The output is a BytesReader. self.assertThat(output, IsInstance(BytesReader)) output = output.read(10000).decode("utf-8") # The template has rendered without error. UEFI configurations # typically start with a DEFAULT line. self.assertThat(output, StartsWith("set default=\"0\"")) # The UEFI parameters are all set according to the options. image_dir = compose_image_path(osystem=params.osystem, arch=params.arch, subarch=params.subarch, release=params.release, label=params.label) self.assertThat( output, MatchesAll( MatchesRegex( r".*\s+lin.*cc:\\{\'datasource_list\':" r" \[\'MAAS\'\]\\}end_cc.*", re.MULTILINE | re.DOTALL), MatchesRegex( r'.*^\s+linux %s/%s .+?$' % (re.escape(image_dir), params.kernel), re.MULTILINE | re.DOTALL), MatchesRegex( r'.*^\s+initrd %s/%s$' % (re.escape(image_dir), params.initrd), re.MULTILINE | re.DOTALL)))
def test_link_bootloader_logs_missing_bootloader_files(self): method = UEFIAMD64BootMethod() self.patch(uefi_amd64_module.os.path, 'exists').return_value = False mock_maaslog = self.patch(uefi_amd64_module.maaslog, 'error') bootloader_dir = ('/var/lib/maas/boot-resources/%s' % factory.make_name('snapshot')) method._find_and_copy_bootloaders(bootloader_dir) self.assertThat(mock_maaslog, MockCalledOnce())
def test_get_reader_with_local_purpose(self): # If purpose is "local", the config.localboot.template should be # used. method = UEFIAMD64BootMethod() options = { "backend": None, "kernel_params": make_kernel_parameters(purpose="local", arch="amd64"), } output = method.get_reader(**options).read(10000).decode("utf-8") self.assertIn("chainloader /efi/ubuntu/grubx64.efi", output)
def test_link_bootloader_copies_previous_downloaded_files(self): method = UEFIAMD64BootMethod() with tempdir() as tmp: new_dir = os.path.join(tmp, 'new') current_dir = os.path.join(tmp, 'current') os.makedirs(new_dir) os.makedirs(current_dir) for bootloader_file in method.bootloader_files: factory.make_file(current_dir, bootloader_file) method.link_bootloader(new_dir) for bootloader_file in method.bootloader_files: bootloader_file_path = os.path.join(new_dir, bootloader_file) self.assertTrue(os.path.isfile(bootloader_file_path))
def test_get_reader_with_commissioning_purpose(self): # If purpose is "commissioning", the config.commissioning.template # should be used. method = UEFIAMD64BootMethod() params = make_kernel_parameters(purpose="commissioning", arch="amd64") options = {"backend": None, "kernel_params": params} output = method.get_reader(**options).read(10000).decode("utf-8") self.assertThat( output, ContainsAll([ "menuentry 'Commission'", "%s/%s/%s" % (params.osystem, params.arch, params.subarch), params.kernel, ]), )
def test_get_reader_with_extra_arguments_does_not_affect_output(self): # get_reader() allows any keyword arguments as a safety valve. method = UEFIAMD64BootMethod() options = { "backend": None, "kernel_params": make_kernel_parameters(purpose="install"), } # Capture the output before sprinking in some random options. output_before = method.get_reader(**options).read(10000) # Sprinkle some magic in. options.update((factory.make_name("name"), factory.make_name("value")) for _ in range(10)) # Capture the output after sprinking in some random options. output_after = method.get_reader(**options).read(10000) # The generated template is the same. self.assertEqual(output_before, output_after)
def test_link_bootloader_creates_grub_cfg(self): method = UEFIAMD64BootMethod() with tempdir() as tmp: stream_path = os.path.join(tmp, 'bootloader', method.bios_boot_method, method.bootloader_arches[0]) os.makedirs(stream_path) for bootloader_file in method.bootloader_files: factory.make_file(stream_path, bootloader_file) method.link_bootloader(tmp) for bootloader_file in method.bootloader_files: bootloader_file_path = os.path.join(tmp, bootloader_file) self.assertTrue(os.path.islink(bootloader_file_path)) grub_file_path = os.path.join(tmp, 'grub', 'grub.cfg') self.assertTrue(grub_file_path, FileContains(CONFIG_FILE))
PowerNVBootMethod, ) from provisioningserver.boot.pxe import PXEBootMethod # noqa:E402 isort:skip from provisioningserver.boot.s390x import ( # noqa:E402 isort:skip S390XBootMethod, ) from provisioningserver.boot.uefi_amd64 import ( # noqa:E402 isort:skip UEFIAMD64BootMethod, UEFIAMD64HTTPBootMethod, ) from provisioningserver.boot.uefi_arm64 import ( # noqa:E402 isort:skip UEFIARM64BootMethod, ) from provisioningserver.boot.windows import ( # noqa:E402 isort:skip WindowsPXEBootMethod, ) builtin_boot_methods = [ IPXEBootMethod(), PXEBootMethod(), UEFIAMD64BootMethod(), UEFIAMD64HTTPBootMethod(), UEFIARM64BootMethod(), OpenFirmwarePPC64ELBootMethod(), PowerNVBootMethod(), WindowsPXEBootMethod(), S390XBootMethod(), ] for method in builtin_boot_methods: BootMethodRegistry.register_item(method.name, method)