def test_get_config_reader_returns_rendered_params(self): # get_config_reader() takes a dict() of parameters and returns an # `IReader` of a PXE configuration, rendered by `render_pxe_config`. backend = TFTPBackend(self.make_dir(), b"http://example.com/") # Fake configuration parameters, as discovered from the file path. fake_params = {"mac": factory.getRandomMACAddress("-")} # Fake kernel configuration parameters, as returned from the API call. fake_kernel_params = make_kernel_parameters() # Stub get_page to return the fake API configuration parameters. fake_get_page_result = json.dumps(fake_kernel_params._asdict()) get_page_patch = self.patch(backend, "get_page") get_page_patch.return_value = succeed(fake_get_page_result) # Stub render_pxe_config to return the render parameters. fake_render_result = factory.make_name("render") render_patch = self.patch(backend, "render_pxe_config") render_patch.return_value = fake_render_result # Get the rendered configuration, which will actually be a JSON dump # of the render-time parameters. reader = yield backend.get_config_reader(fake_params) self.addCleanup(reader.finish) self.assertIsInstance(reader, BytesReader) output = reader.read(10000) # The kernel parameters were fetched using `backend.get_page`. backend.get_page.assert_called_once() # The result has been rendered by `backend.render_pxe_config`. self.assertEqual(fake_render_result.encode("utf-8"), output) backend.render_pxe_config.assert_called_once_with( kernel_params=fake_kernel_params, **fake_params)
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_compose_template_namespace_returns_dtb_file_when_arm(self): kernel_params = make_kernel_parameters(subarch="xgene-uboot-mustang") method = FakeBootMethod() image_dir = compose_image_path( kernel_params.osystem, kernel_params.arch, kernel_params.subarch, kernel_params.release, kernel_params.label, ) template_namespace = method.compose_template_namespace(kernel_params) self.assertEqual( "%s/%s" % (image_dir, kernel_params.initrd), template_namespace["initrd_path"](kernel_params), ) self.assertEqual( compose_kernel_command_line(kernel_params), template_namespace["kernel_command"](kernel_params), ) self.assertEqual(kernel_params, template_namespace["kernel_params"]) self.assertEqual( "%s/%s" % (image_dir, kernel_params.kernel), template_namespace["kernel_path"](kernel_params), ) self.assertEqual( "%s/%s" % (image_dir, kernel_params.boot_dtb), template_namespace["dtb_path"](kernel_params), )
def test_get_reader_install(self): # Given the right configuration options, the PXE configuration is # correctly rendered. method = PXEBootMethod() params = make_kernel_parameters(self, purpose="xinstall") fs_host = 'http://%s:5248/images' % (convert_host_to_uri_str( params.fs_host)) 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. PXELINUX configurations # typically start with a DEFAULT line. self.assertThat(output, StartsWith("DEFAULT ")) # The PXE 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+KERNEL %s/%s/%s$' % (re.escape(fs_host), re.escape(image_dir), params.kernel), re.MULTILINE | re.DOTALL), MatchesRegex( r'.*^\s+INITRD %s/%s/%s$' % (re.escape(fs_host), re.escape(image_dir), params.initrd), re.MULTILINE | re.DOTALL), MatchesRegex(r'.*^\s+APPEND .+?$', re.MULTILINE | re.DOTALL)))
def test_render_pxe_config_scenarios(self): # The commissioning config uses an extra PXELINUX module to auto # select between i386 and amd64. get_ephemeral_name = self.patch(kernel_opts, "get_ephemeral_name") get_ephemeral_name.return_value = factory.make_name("ephemeral") options = { "kernel_params": make_kernel_parameters(purpose=self.purpose), } output = render_pxe_config(**options) config = parse_pxe_config(output) # The default section is defined. default_section_label = config.header["DEFAULT"] self.assertThat(config, Contains(default_section_label)) default_section = config[default_section_label] # The default section uses the ifcpu64 module, branching to the "i386" # or "amd64" labels accordingly. self.assertEqual("ifcpu64.c32", default_section["KERNEL"]) self.assertEqual( ["amd64", "--", "i386"], default_section["APPEND"].split()) # Both "i386" and "amd64" sections exist. self.assertThat(config, ContainsAll(("i386", "amd64"))) # Each section defines KERNEL, INITRD, and APPEND settings. The # KERNEL and INITRD ones contain paths referring to their # architectures. for section_label in ("i386", "amd64"): section = config[section_label] self.assertThat( section, ContainsAll(("KERNEL", "INITRD", "APPEND"))) contains_arch_path = StartsWith("%s/" % section_label) self.assertThat(section["KERNEL"], contains_arch_path) self.assertThat(section["INITRD"], contains_arch_path) self.assertIn("APPEND", section)
def test_render(self): # Given the right configuration options, the PXE configuration is # correctly rendered. params = make_kernel_parameters(purpose="install") output = render_pxe_config(kernel_params=params) # The output is always a Unicode string. self.assertThat(output, IsInstance(unicode)) # The template has rendered without error. PXELINUX configurations # typically start with a DEFAULT line. self.assertThat(output, StartsWith("DEFAULT ")) # The PXE parameters are all set according to the options. image_dir = compose_image_path( arch=params.arch, subarch=params.subarch, release=params.release, purpose=params.purpose) self.assertThat( output, MatchesAll( MatchesRegex( r'.*^\s+KERNEL %s/linux$' % re.escape(image_dir), re.MULTILINE | re.DOTALL), MatchesRegex( r'.*^\s+INITRD %s/initrd[.]gz$' % re.escape(image_dir), re.MULTILINE | re.DOTALL), MatchesRegex( r'.*^\s+APPEND .+?$', re.MULTILINE | re.DOTALL)))
def test_get_config_reader_returns_rendered_params(self): # get_config_reader() takes a dict() of parameters and returns an # `IReader` of a PXE configuration, rendered by `render_pxe_config`. backend = TFTPBackend(self.make_dir(), b"http://example.com/") # Fake configuration parameters, as discovered from the file path. fake_params = {"mac": factory.getRandomMACAddress(b"-")} # Fake kernel configuration parameters, as returned from the API call. fake_kernel_params = make_kernel_parameters() # Stub get_page to return the fake API configuration parameters. fake_get_page_result = json.dumps(fake_kernel_params._asdict()) get_page_patch = self.patch(backend, "get_page") get_page_patch.return_value = succeed(fake_get_page_result) # Stub render_pxe_config to return the render parameters. fake_render_result = factory.make_name("render") render_patch = self.patch(backend, "render_pxe_config") render_patch.return_value = fake_render_result # Get the rendered configuration, which will actually be a JSON dump # of the render-time parameters. reader = yield backend.get_config_reader(fake_params) self.addCleanup(reader.finish) self.assertIsInstance(reader, BytesReader) output = reader.read(10000) # The kernel parameters were fetched using `backend.get_page`. backend.get_page.assert_called_once() # The result has been rendered by `backend.render_pxe_config`. self.assertEqual(fake_render_result.encode("utf-8"), output) backend.render_pxe_config.assert_called_once_with( kernel_params=fake_kernel_params, **fake_params)
def test_get_reader_scenarios(self): method = PXEBootMethod() get_ephemeral_name = self.patch(kernel_opts, "get_ephemeral_name") get_ephemeral_name.return_value = factory.make_name("ephemeral") osystem = factory.make_name('osystem') arch = factory.make_name('arch') subarch = factory.make_name('subarch') options = { "backend": None, "kernel_params": make_kernel_parameters(testcase=self, osystem=osystem, subarch=subarch, arch=arch, purpose=self.purpose), } fs_host = 'http://%s:5248/images' % (convert_host_to_uri_str( options['kernel_params'].fs_host)) output = method.get_reader(**options).read(10000).decode("utf-8") config = parse_pxe_config(output) # The default section is defined. default_section_label = config.header["DEFAULT"] self.assertThat(config, Contains(default_section_label)) default_section = dict(config[default_section_label]) contains_arch_path = StartsWith("%s/%s/%s/%s" % (fs_host, osystem, arch, subarch)) self.assertThat(default_section["KERNEL"], contains_arch_path) self.assertThat(default_section["INITRD"], contains_arch_path) self.assertEqual("2", default_section["IPAPPEND"])
def test_get_reader_ephemeral_no_mac(self): s390x_partition = S390XPartitionBootMethod() params = make_kernel_parameters( self, arch="s390x", purpose=random.choice( ["commissioning", "enlist", "install", "xinstall"]), ) output = s390x_partition.get_reader(None, params) output = output.read(output.size).decode() 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+kernel=%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, ), MatchesRegex(r".*^\s+append=.*$", re.MULTILINE | re.DOTALL), ), )
def test_render(self): # Given the right configuration options, the PXE configuration is # correctly rendered. params = make_kernel_parameters(purpose="install") output = render_pxe_config(kernel_params=params) # The output is always a Unicode string. self.assertThat(output, IsInstance(unicode)) # The template has rendered without error. PXELINUX configurations # typically start with a DEFAULT line. self.assertThat(output, StartsWith("DEFAULT ")) # The PXE parameters are all set according to the options. image_dir = compose_image_path( arch=params.arch, subarch=params.subarch, release=params.release, purpose=params.purpose) self.assertThat( output, MatchesAll( MatchesRegex( r'.*^\s+KERNEL %s/linux$' % re.escape(image_dir), re.MULTILINE | re.DOTALL), MatchesRegex( r'.*^\s+INITRD %s/initrd[.]gz$' % re.escape(image_dir), re.MULTILINE | re.DOTALL), MatchesRegex( r'.*^\s+APPEND .+?$', re.MULTILINE | re.DOTALL)))
def test_compose_template_namespace(self): kernel_params = make_kernel_parameters() method = FakeBootMethod() image_dir = compose_image_path( kernel_params.osystem, kernel_params.arch, kernel_params.subarch, kernel_params.release, kernel_params.label, ) template_namespace = method.compose_template_namespace(kernel_params) self.assertEqual( "%s/%s" % (image_dir, kernel_params.initrd), template_namespace["initrd_path"](kernel_params), ) self.assertEqual( compose_kernel_command_line(kernel_params), template_namespace["kernel_command"](kernel_params), ) self.assertEqual(kernel_params, template_namespace["kernel_params"]) self.assertEqual( "%s/%s" % (image_dir, kernel_params.kernel), template_namespace["kernel_path"](kernel_params), ) self.assertIsNone(template_namespace["dtb_path"](kernel_params))
def test_compose_template_namespace_returns_filetype_when_missing(self): kernel_params = make_kernel_parameters( subarch="xgene-uboot-mustang", kernel=None, initrd=None, boot_dtb=None, ) method = FakeBootMethod() image_dir = compose_image_path( kernel_params.osystem, kernel_params.arch, kernel_params.subarch, kernel_params.release, kernel_params.label, ) template_namespace = method.compose_template_namespace(kernel_params) self.assertEqual( "%s/boot-initrd" % image_dir, template_namespace["initrd_path"](kernel_params), ) self.assertEqual( compose_kernel_command_line(kernel_params), template_namespace["kernel_command"](kernel_params), ) self.assertEqual(kernel_params, template_namespace["kernel_params"]) self.assertEqual( "%s/boot-kernel" % image_dir, template_namespace["kernel_path"](kernel_params), ) self.assertEqual( "%s/boot-dtb" % image_dir, template_namespace["dtb_path"](kernel_params), )
def test_render_pxe_config_for_commissioning(self): # The commissioning config uses an extra PXELINUX module to auto # select between i386 and amd64. get_ephemeral_name = self.patch(kernel_opts, "get_ephemeral_name") get_ephemeral_name.return_value = factory.make_name("ephemeral") options = { "kernel_params": make_kernel_parameters(purpose="commissioning"), } output = render_pxe_config(**options) config = parse_pxe_config(output) # The default section is defined. default_section_label = config.header["DEFAULT"] self.assertThat(config, Contains(default_section_label)) default_section = config[default_section_label] # The default section uses the ifcpu64 module, branching to the "i386" # or "amd64" labels accordingly. self.assertEqual("ifcpu64.c32", default_section["KERNEL"]) self.assertEqual( ["amd64", "--", "i386"], default_section["APPEND"].split()) # Both "i386" and "amd64" sections exist. self.assertThat(config, ContainsAll(("i386", "amd64"))) # Each section defines KERNEL, INITRD, and APPEND settings. The # KERNEL and INITRD ones contain paths referring to their # architectures. for section_label in ("i386", "amd64"): section = config[section_label] self.assertThat( section, ContainsAll(("KERNEL", "INITRD", "APPEND"))) contains_arch_path = StartsWith("%s/" % section_label) self.assertThat(section["KERNEL"], contains_arch_path) self.assertThat(section["INITRD"], contains_arch_path) self.assertIn("APPEND", section)
def test_compose_bcd_missing_template(self): method = WindowsPXEBootMethod() self.patch(method, "get_resource_path").return_value = "" local_host = factory.make_ipv4_address() kernel_params = make_kernel_parameters() self.assertRaises(BootMethodError, method.compose_bcd, kernel_params, local_host)
def test_render_pxe_config_with_local_purpose(self): # If purpose is "local", the config.localboot.template should be # used. options = { "kernel_params": make_kernel_parameters(purpose="local"), } output = render_pxe_config(**options) self.assertIn("LOCALBOOT 0", output)
def test_render_pxe_config_with_local_purpose(self): # If purpose is "local", the config.localboot.template should be # used. options = { "kernel_params": make_kernel_parameters(purpose="local"), } output = render_pxe_config(**options) self.assertIn("LOCALBOOT 0", output)
def test_get_reader_ephemeral(self): # Given the right configuration options, the iPXE configuration is # correctly rendered. method = IPXEBootMethod() xtra = ("custom_xtra_cfg=http://{{ kernel_params.fs_host }}/" "my_extra_config?mac={{ kernel_params.mac }}") params = make_kernel_parameters( self, arch="amd64", subarch="generic", purpose="ephemeral", extra_opts=xtra, ) fs_host = "http://%s:5248/images" % (convert_host_to_uri_str( params.fs_host)) 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. iPXE configurations # start with #ipxe. self.assertThat(output, StartsWith("#!ipxe")) # The iPXE 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*kernel %s/%s/%s$" % ( re.escape(fs_host), re.escape(image_dir), params.kernel, ), re.MULTILINE | re.DOTALL, ), MatchesRegex( r".*^\s*initrd %s/%s/%s\s+" % ( re.escape(fs_host), re.escape(image_dir), params.initrd, ), re.MULTILINE | re.DOTALL, ), MatchesRegex( r".*\s+custom_xtra_cfg=http://%s/my_extra_config.*?\s+" % (params.fs_host), re.MULTILINE | re.DOTALL, ), MatchesRegex(r".*\s+maas_url=.+?$", re.MULTILINE | re.DOTALL), ), )
def test_get_reader_with_local_purpose(self): # If purpose is "local", output should be empty string. method = PowerNVBootMethod() options = { "backend": None, "kernel_params": make_kernel_parameters(purpose="local"), } output = method.get_reader(**options).read(10000).decode("utf-8") self.assertIn("", output)
def test_get_reader_static_file(self): method = WindowsPXEBootMethod() mock_path = factory.make_name("path") mock_output_static = self.patch(method, "output_static") kernel_params = make_kernel_parameters(osystem="windows") method.get_reader(None, kernel_params, path=mock_path) self.assertThat(mock_output_static, MockCalledOnceWith(kernel_params, mock_path))
def test_render_pxe_config_with_local_purpose_amd64_arch(self): # Intel amd64 is a special case and needs to use the chain.c32 # loader as the LOCALBOOT PXE directive is unreliable. options = { "kernel_params": make_kernel_parameters( arch="amd64", purpose="local"), } output = render_pxe_config(**options) self.assertIn("chain.c32", output) self.assertNotIn("LOCALBOOT", output)
def test_get_reader_appends_bootif(self): method = S390XBootMethod() fake_mac = factory.make_mac_address("-") params = make_kernel_parameters(self, arch="amd64", purpose="install") output = method.get_reader( backend=None, kernel_params=params, arch='s390x', mac=fake_mac) output = output.read(10000).decode("utf-8") config = parse_pxe_config(output) expected = 'BOOTIF=%s' % format_bootif(fake_mac) self.assertIn(expected, config['execute']['APPEND'])
def test_render_pxe_config_with_local_purpose_amd64_arch(self): # Intel amd64 is a special case and needs to use the chain.c32 # loader as the LOCALBOOT PXE directive is unreliable. options = { "kernel_params": make_kernel_parameters(arch="amd64", purpose="local"), } output = render_pxe_config(**options) self.assertIn("chain.c32", output) self.assertNotIn("LOCALBOOT", output)
def test_get_reader_bcd(self): method = WindowsPXEBootMethod() mock_compose_bcd = self.patch(method, 'compose_bcd') local_host = factory.make_ipv4_address() kernel_params = make_kernel_parameters(osystem='windows') method.get_reader( None, kernel_params, path='bcd', local_host=local_host) self.assertThat( mock_compose_bcd, MockCalledOnceWith(kernel_params, local_host))
def test_get_reader_with_local_purpose(self): # If purpose is "local", the config.localboot.template should be # used. method = PXEBootMethod() options = { "backend": None, "kernel_params": make_kernel_parameters(purpose="local"), } output = method.get_reader(**options).read(10000) self.assertIn(b"LOCALBOOT 0", output)
def test_get_boot_method_reader_returns_rendered_params(self): # Fake configuration parameters, as discovered from the file path. fake_params = {"mac": factory.make_mac_address("-")} # Fake kernel configuration parameters, as returned from the RPC call. fake_kernel_params = make_kernel_parameters() fake_params = fake_kernel_params._asdict() # Stub the output of list_boot_images so the label is set in the # kernel parameters. boot_image = { "osystem": fake_params["osystem"], "release": fake_params["release"], "architecture": fake_params["arch"], "subarchitecture": fake_params["subarch"], "purpose": fake_params["purpose"], "supported_subarches": "", "label": fake_params["label"], } self.patch(tftp_module, "list_boot_images").return_value = [boot_image] del fake_params["label"] # Stub RPC call to return the fake configuration parameters. client = Mock() client.localIdent = factory.make_name("system_id") client.return_value = succeed(fake_params) client_service = Mock() client_service.getClientNow.return_value = succeed(client) # get_boot_method_reader() takes a dict() of parameters and returns an # `IReader` of a PXE configuration, rendered by # `PXEBootMethod.get_reader`. backend = TFTPBackend(self.make_dir(), client_service) # Stub get_reader to return the render parameters. method = PXEBootMethod() fake_render_result = factory.make_name("render").encode("utf-8") render_patch = self.patch(method, "get_reader") render_patch.return_value = BytesReader(fake_render_result) # Get the rendered configuration, which will actually be a JSON dump # of the render-time parameters. params_with_ip = dict(fake_params) params_with_ip['remote_ip'] = factory.make_ipv4_address() reader = yield backend.get_boot_method_reader(method, params_with_ip) self.addCleanup(reader.finish) self.assertIsInstance(reader, BytesReader) output = reader.read(10000) # The result has been rendered by `method.get_reader`. self.assertEqual(fake_render_result, output) self.assertThat( method.get_reader, MockCalledOnceWith(backend, kernel_params=fake_kernel_params, **params_with_ip))
def test_compose_template_namespace_include_debug(self): debug = factory.pick_bool() boot.debug_enabled.cache_clear() self.addClassCleanup(boot.debug_enabled.cache_clear) self.useFixture(ClusterConfigurationFixture(debug=debug)) kernel_params = make_kernel_parameters() method = FakeBootMethod() template_namespace = method.compose_template_namespace(kernel_params) self.assertEqual(debug, template_namespace["debug"])
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_get_reader_with_local_purpose_amd64_arch(self): # Intel amd64 is a special case and needs to use the chain.c32 # loader as the LOCALBOOT PXE directive is unreliable. method = PXEBootMethod() options = { "backend": None, "kernel_params": make_kernel_parameters(arch="amd64", purpose="local"), } output = method.get_reader(**options).read(10000) self.assertIn(b"chain.c32", output) self.assertNotIn(b"LOCALBOOT", output)
def test_get_resouce_path(self): fake_tftproot = self.make_dir() self.useFixture(ClusterConfigurationFixture(tftp_root=fake_tftproot)) method = WindowsPXEBootMethod() fake_path = factory.make_name('path') fake_kernelparams = make_kernel_parameters() result = method.get_resource_path(fake_kernelparams, fake_path) expected = os.path.join( fake_tftproot, 'windows', fake_kernelparams.arch, fake_kernelparams.subarch, fake_kernelparams.release, fake_kernelparams.label, fake_path) self.assertEqual(expected, result)
def test_get_reader_appends_bootif(self): method = PowerNVBootMethod() fake_mac = factory.make_mac_address("-") params = make_kernel_parameters(self, purpose="install") output = method.get_reader(backend=None, kernel_params=params, arch="ppc64el", mac=fake_mac) output = output.read(10000).decode("utf-8") config = parse_pxe_config(output) expected = "BOOTIF=%s" % format_bootif(fake_mac) self.assertIn(expected, config["execute"]["APPEND"])
def test_highbank_scenarios(self): # get_ephemeral_name depends on ephemeral images being present but # doesn't affect the test outcome, so patch it out. self.patch( kernel_opts, "get_ephemeral_name").return_value = "ephemeral_name" options = { "kernel_params": make_kernel_parameters( arch=self.arch, purpose=self.purpose, subarch="highbank", release=self.release), } output = render_pxe_config(**options) self.assertIn(self.expect_in_output, output)
def test_get_reader_tftp(self): # Given the right configuration options, the UEFI configuration is # correctly rendered. method = UEFIAMD64BootMethod() params = make_kernel_parameters(arch="amd64", purpose="xinstall") fs_host = "(http,%s:5248)/images" % (convert_host_to_uri_str( params.fs_host)) output = method.get_reader(backend=None, kernel_params=params, protocol="tftp") # 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/%s .+?$" % ( re.escape(fs_host), re.escape(image_dir), params.kernel, ), re.MULTILINE | re.DOTALL, ), MatchesRegex( r".*^\s+initrd %s/%s/%s$" % ( re.escape(fs_host), re.escape(image_dir), params.initrd, ), re.MULTILINE | re.DOTALL, ), ), )
def test_get_reader_poweroff_no_mac(self): s390x_partition = S390XPartitionBootMethod() params = make_kernel_parameters(self, arch="s390x", purpose=random.choice( ["local", "poweroff"])) output = s390x_partition.get_reader(None, params) output = [ line for line in output.read(output.size).decode().splitlines() if line.split("#", 1)[0].strip() ] self.assertEqual([], output)
def test_render_with_extra_arguments_does_not_affect_output(self): # render_pxe_config() allows any keyword arguments as a safety valve. options = {"kernel_params": make_kernel_parameters(purpose="install")} # Capture the output before sprinking in some random options. output_before = render_pxe_config(**options) # 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 = render_pxe_config(**options) # The generated template is the same. self.assertEqual(output_before, output_after)
def test_get_boot_method_reader_rendered_parms_for_depoyed_ephemeral(self): # Fake kernel configuration parameters, as returned from the RPC call. fake_kernel_params = make_kernel_parameters( purpose="local", label="local", osystem="caringo" ) fake_params = fake_kernel_params._asdict() # Stub the output of list_boot_images so the label is set in the # kernel parameters. boot_image = { "osystem": fake_params["osystem"], "release": fake_params["release"], "architecture": fake_params["arch"], "subarchitecture": fake_params["subarch"], "purpose": "ephemeral", "supported_subarches": "", "label": fake_params["label"], } self.patch(tftp_module, "list_boot_images").return_value = [boot_image] del fake_params["label"] # Stub RPC call to return the fake configuration parameters. client = Mock() client.localIdent = factory.make_name("system_id") client.return_value = succeed(fake_params) client_service = Mock() client_service.getClient.return_value = client # get_boot_method_reader() takes a dict() of parameters and returns an # `IReader` of a PXE configuration, rendered by # `PXEBootMethod.get_reader`. backend = TFTPBackend(self.make_dir(), client_service) # Stub get_reader to return the render parameters. method = PXEBootMethod() fake_render_result = factory.make_name("render").encode("utf-8") render_patch = self.patch(method, "get_reader") render_patch.return_value = BytesReader(fake_render_result) # Get the rendered configuration, which will actually be a JSON dump # of the render-time parameters. reader = yield backend.get_boot_method_reader(method, fake_params) self.addCleanup(reader.finish) self.assertIsInstance(reader, BytesReader) output = reader.read(10000) # The result has been rendered by `method.get_reader`. self.assertEqual(fake_render_result, output)
def test_render_with_extra_arguments_does_not_affect_output(self): # render_pxe_config() allows any keyword arguments as a safety valve. options = { "kernel_params": make_kernel_parameters(purpose="install"), } # Capture the output before sprinking in some random options. output_before = render_pxe_config(**options) # 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 = render_pxe_config(**options) # The generated template is the same. self.assertEqual(output_before, output_after)