Exemple #1
0
    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)
Exemple #2
0
    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)))
Exemple #3
0
    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),
        )
Exemple #4
0
 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)))
Exemple #5
0
 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)
Exemple #6
0
 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)))
Exemple #7
0
    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)
Exemple #8
0
    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"])
Exemple #9
0
    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),
            ),
        )
Exemple #10
0
 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)))
Exemple #11
0
    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))
Exemple #12
0
    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),
        )
Exemple #13
0
 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)
Exemple #14
0
    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)
Exemple #15
0
 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)
Exemple #16
0
 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)
Exemple #17
0
 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),
         ),
     )
Exemple #18
0
 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)
Exemple #19
0
    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))
Exemple #20
0
 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)
Exemple #21
0
 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'])
Exemple #22
0
 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)
Exemple #23
0
    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))
Exemple #24
0
 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)
Exemple #25
0
    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))
Exemple #26
0
    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"])
Exemple #27
0
 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)
Exemple #28
0
 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)
Exemple #29
0
 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)
Exemple #30
0
 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"])
Exemple #31
0
 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)
Exemple #32
0
    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,
                ),
            ),
        )
Exemple #33
0
    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)
Exemple #34
0
 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)
Exemple #35
0
    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)
Exemple #36
0
 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)