예제 #1
0
    def __call__(
        self,
        location: Location,
        system_context: SystemContext,
        *args: typing.Any,
        **kwargs: typing.Any,
    ) -> None:
        """Execute command."""
        if not os.path.exists(
                system_context.file_name(
                    "/usr/lib/systemd/system/fontconfig-trigger.service")
        ) or not os.path.isfile(system_context.file_name("/usr/bin/fc-cache")):
            return

        run(
            "/usr/bin/fc-cache",
            chroot_helper=self._binary(Binaries.SYSTEMD_NSPAWN),
            chroot=system_context.fs_directory,
        )

        self._execute(
            location,
            system_context,
            "persist_on_usr",
            "fontconfig-trigger",
            "/var/cache/fontconfig",
        )

        os.remove(
            system_context.file_name(
                "/usr/lib/systemd/system/fontconfig-trigger.service"))
        os.remove(
            system_context.file_name(
                "/usr/lib/systemd/system/update-triggers.target.wants/fontconfig-trigger.service"
            ))
def _install_debug_support(
    system_context: SystemContext,
    tmp: str,
):
    _install_shadow_file(tmp, system_context),

    for cmd in [
            "/usr/bin/journalctl",
            "/usr/lib/systemd/systemd-sulogin-shell"
            "/usr/lib/systemd/system/rescue.target",
            "/usr/lib/systemd/system/rescue.service",
    ]:
        assert cmd[0] == "/"

        if os.path.isfile(system_context.file_name(cmd)):
            os.makedirs(os.path.join(tmp, os.path.dirname(cmd)), exist_ok=True)

            dest = os.path.join(tmp, cmd[1:])
            if os.path.exists(dest):
                os.remove(dest)

            shutil.copy2(
                system_context.file_name(cmd),
                dest,
                follow_symlinks=False,
            )
예제 #3
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""
        assert firewall_type(system_context) == "iptables"
        location.set_description("Enable firewall")
        to_enable: typing.List[str] = []
        if os.path.exists(
                system_context.file_name(
                    "/usr/lib/systemd/system/iptables.service")):
            to_enable.append("iptables.service")
        if os.path.exists(
                system_context.file_name(
                    "/usr/lib/systemd/system/ip6tables.service")):
            to_enable.append("ip6tables.service")
        if os.path.exists(
                system_context.file_name(
                    "/usr/lib/systemd/system/iptables-restore.service")):
            to_enable.append("iptables-restore.service")

        self._execute(
            location,
            system_context,
            "systemd_enable",
            *to_enable,
        )
예제 #4
0
    def __call__(
        self,
        location: Location,
        system_context: SystemContext,
        *args: typing.Any,
        **kwargs: typing.Any,
    ) -> None:
        """Execute command."""
        name = args[0]
        assert name
        directory = args[1]
        assert directory[0] == "/"

        full_directory = system_context.file_name(directory)
        usr_dir = f"/usr/lib/persistent{directory}"
        full_usr_dir = system_context.file_name(usr_dir)
        if not os.path.isdir(full_directory):
            return

        os.makedirs(dirname(full_usr_dir), exist_ok=True)

        if os.path.isdir(full_directory):
            shutil.move(full_directory, full_usr_dir)
        else:
            os.makedirs(full_usr_dir)
        os.symlink(usr_dir, full_directory)

        self._execute(
            location,
            system_context,
            "create",
            f"/usr/lib/tmpfiles.d/{name}.conf",
            f"L {directory} - - - - {usr_dir}\n",
            mode=0o644,
        )
예제 #5
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""

        # enable kms:
        system_context.set_or_append_substitution("INITRD_EXTRA_MODULES",
                                                  "intel_agp i915")
예제 #6
0
    def __call__(
        self,
        location: Location,
        system_context: SystemContext,
        *args: typing.Any,
        **kwargs: typing.Any,
    ) -> None:
        """Execute command."""
        static_hostname = args[0]
        pretty_hostname = kwargs.get("pretty", static_hostname)

        if system_context.substitution("HOSTNAME", ""):
            raise GenerateError("Hostname was already set.", location=location)

        system_context.set_substitution("HOSTNAME", static_hostname)
        system_context.set_substitution("PRETTY_HOSTNAME", pretty_hostname)

        self._execute(location, system_context, "create", "/etc/hostname",
                      static_hostname)
        self._execute(
            location.next_line(),
            system_context,
            "sed",
            f'/^PRETTY_HOSTNAME=/ cPRETTY_HOSTNAME="{pretty_hostname}"',
            "/etc/machine.info",
        )
예제 #7
0
    def create_export_directory(self, system_context: SystemContext) -> str:
        """Return the root directory."""
        export_volume = os.path.join(system_context.scratch_directory,
                                     'export')
        btrfs_helper = self._service('btrfs_helper')
        if btrfs_helper.is_subvolume(export_volume):
            btrfs_helper.delete_subvolume_recursive(export_volume)
        btrfs_helper.create_subvolume(export_volume)

        os_name = system_context.substitution('DISTRO_ID', 'clrm')
        timestamp = system_context.substitution('TIMESTAMP', 'unknown')

        image_filename \
            = os.path.join(export_volume,
                           '{}_{}{}'.format(os_name, timestamp,
                                            '.' + self._image_format
                                            if self._image_format != 'raw'
                                            else ''))
        create_image(image_filename,
                     self._image_format,
                     self._extra_partitions,
                     self._efi_size,
                     self._swap_size,
                     kernel_file=self._kernel_file,
                     root_partition=self._root_partition,
                     verity_partition=self._verity_partition,
                     root_hash=self._root_hash,
                     flock_command=self._binary(Binaries.FLOCK),
                     sfdisk_command=self._binary(Binaries.SFDISK))

        return export_volume
예제 #8
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""
        old_base = system_context.file_name("/etc/systemd/system") + "/"
        new_base = system_context.file_name("/usr/lib/systemd/system") + "/"

        trace("walking:", old_base)

        for root, _dirs, files in os.walk(old_base):
            for f in files:
                full_path = os.path.join(root, f)
                trace("Checking", full_path)
                if os.path.islink(full_path):
                    trace("Moving link", full_path)
                    _move_symlink(location, system_context, old_base, new_base,
                                  full_path)
                else:
                    trace("Moving file", full_path)
                    _move_file(location, old_base, new_base, full_path)

        self._execute(
            location.next_line(),
            system_context,
            "remove",
            "/etc/systemd/system/*",
            recursive=True,
            force=True,
        )
예제 #9
0
파일: tar.py 프로젝트: phunni/cleanroom
    def __call__(
        self,
        location: Location,
        system_context: SystemContext,
        *args: typing.Any,
        **kwargs: typing.Any
    ) -> None:
        """Execute command."""
        work_directory = kwargs.get("work_directory", "/")
        source = system_context.file_name(os.path.join(work_directory, args[0]))

        to_outside = kwargs.get("to_outside", False)

        target = (
            args[1]
            if to_outside
            else system_context.file_name(os.path.join(work_directory, args[1]))
        )
        assert os.path.isabs(target)

        arguments = ["-cz"] if kwargs.get("compress", False) else ["-c"]
        run(
            self._binary(Binaries.TAR),
            *arguments,
            "-f",
            target,
            source,
            work_directory=work_directory
        )
예제 #10
0
 def _setup_hooks(
     self,
     location: Location,
     system_context: SystemContext,
     locales: typing.Sequence[str],
 ) -> None:
     if not system_context.substitution("CLRM_LOCALES", ""):
         location.set_description("run locale-gen")
         self._add_hook(
             location,
             system_context,
             "export",
             "run",
             "/usr/bin/locale-gen",
             inside=True,
         )
         location.set_description("Remove locale related data.")
         self._add_hook(
             location,
             system_context,
             "export",
             "remove",
             "/usr/share/locale/*",
             "/etc/locale.gen",
             "/usr/bin/locale-gen",
             "/usr/bin/localedef",
             force=True,
             recursive=True,
         )
         system_context.set_substitution("CLRM_LOCALES", ",".join(locales))
예제 #11
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""
        verity_file = args[0]
        base_image = kwargs.get("base_image", "")
        assert base_image

        result = run(self._binary(Binaries.VERITYSETUP), "format", base_image,
                     verity_file)

        size_extend(verity_file)

        root_hash: typing.Optional[str] = None
        uuid: typing.Optional[str] = None
        for line in result.stdout.split("\n"):
            if line.startswith("Root hash:"):
                root_hash = line[10:].strip()
            if line.startswith("UUID:"):
                uuid = line[10:].strip()

        assert root_hash is not None
        assert uuid is not None

        system_context.set_substitution("LAST_DMVERITY_UUID", uuid)
        system_context.set_substitution("LAST_DMVERITY_ROOTHASH", root_hash)
예제 #12
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""
        target = args[0]
        systemd_directory = "/usr/lib/systemd/system/"
        target_path = systemd_directory + args[0]

        if not isfile(system_context, target_path):
            raise GenerateError(
                'Target "{}" does not exist or is no file. '
                "Can not use as default target.".format(target))

        default = "default.target"
        default_path = systemd_directory + "default.target"

        self._execute(location,
                      system_context,
                      "remove",
                      default_path,
                      force=True)
        self._execute(
            location.next_line(),
            system_context,
            "symlink",
            target,
            default,
            work_directory=systemd_directory,
        )

        system_context.set_substitution("DEFAULT_BOOT_TARGET", target)
예제 #13
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""

        # Set some kernel parameters for:
        system_context.set_or_append_substitution(
            "KERNEL_CMDLINE", "nvidia-drm.modeset=1 nouveau.blacklist=1")

        self._execute(
            location,
            system_context,
            "pacman",
            "nvidia",
            "nvidia-settings",
            "nvidia-utils",
            "opencl-nvidia",
            "libvdpau",
            "lib32-libvdpau",
            "lib32-nvidia-utils",
            "lib32-opencl-nvidia",
            "vdpauinfo",
            "mesa",
            "mesa-demos",
        )

        self._execute(
            location.next_line(),
            system_context,
            "create",
            "/etc/modprobe.d/nouveau-blacklist.conf",
            "blacklist nouveau",
        )
예제 #14
0
    def __call__(
        self,
        location: Location,
        system_context: SystemContext,
        *args: typing.Any,
        **kwargs: typing.Any,
    ) -> None:
        """Execute command."""
        old_machine_id = system_context.substitution("MACHINE_ID", "")
        if old_machine_id:
            raise GenerateError(
                f'Machine-id was already set to "{old_machine_id}".',
                location=location,
            )

        machine_id = args[0]
        system_context.set_substitution("MACHINE_ID", machine_id)
        machine_id += "\n"
        self._execute(
            location.next_line(),
            system_context,
            "create",
            "/etc/machine-id",
            machine_id,
        )
예제 #15
0
def _install_volatile_support(
        staging_area: str, system_context: SystemContext) -> typing.List[str]:
    shutil.copyfile(
        system_context.file_name(
            "/usr/lib/systemd/system/systemd-volatile-root.service"),
        os.path.join(staging_area,
                     "usr/lib/systemd/system/systemd-volatile-root.service"),
    )
    trace("Installed systemd-volatile-root.service")
    symlink(
        os.path.join(
            staging_area,
            "usr/lib/systemd/system/initrd.target.wants/systemd-volatile-root.service",
        ),
        "../systemd-volatile-root.service",
    )
    # Installing binaries is not a good idea in general, as dependencies are not handled!
    # These binaries are probably safe: systemd binaries tend to have few dependencies and those
    # that are included are most likely already in the image due to other systemd binaries!
    shutil.copyfile(
        system_context.file_name("/usr/lib/systemd/systemd-volatile-root"),
        os.path.join(staging_area, "usr/lib/systemd/systemd-volatile-root"),
    )
    os.chmod(
        os.path.join(staging_area, "usr/lib/systemd/systemd-volatile-root"),
        0o755)
    trace("Installed systemd-volatile-root binary.")

    return []
예제 #16
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""
        self._setup(*args, **kwargs)

        h2('Exporting system "{}".'.format(system_context.system_name))
        debug('Running Hooks.')
        self._run_all_exportcommand_hooks(system_context)

        verbose('Preparing system for export.')
        self.prepare_for_export(location, system_context)

        info('Validating installation for export.')
        if not self._skip_validation:
            _validate_installation(location.next_line(), system_context)

        export_directory \
            = self.create_export_directory(system_context)
        assert export_directory

        system_context.set_substitution('EXPORT_DIRECTORY', export_directory)

        verbose('Exporting all data in {}.'.format(export_directory))
        self._execute(location.next_line(),
                      system_context,
                      '_export_directory',
                      export_directory,
                      compression=self._repository_compression,
                      compression_level=self._repository_compression_level,
                      repository=self._repository)

        info('Cleaning up export location.')
        self.delete_export_directory(export_directory)
예제 #17
0
    def __call__(
        self,
        location: Location,
        system_context: SystemContext,
        *args: typing.Any,
        **kwargs: typing.Any,
    ) -> None:
        """Execute command."""
        modules = system_context.file_name("/usr/lib/modules")
        if not os.path.isdir(modules):
            return  # No kernel installed, nothing to do.

        kernel_version = system_context.substitution_expanded(
            "KERNEL_VERSION", "")
        assert kernel_version

        location.set_description(
            f"Run depmod for kernel version {kernel_version}...")
        self._execute(
            location,
            system_context,
            "run",
            self._binary(Binaries.DEPMOD),
            "-a",
            "-b",
            system_context.fs_directory,
            kernel_version,
        )
예제 #18
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""

        # Enable KMS:
        self._execute(location, system_context, 'pkg_intel_kms')

        self._execute(location, system_context, 'pkg_xorg')

        # Set some kernel parameters:
        cmdline = system_context.substitution('KERNEL_CMDLINE', '')
        if cmdline:
            cmdline += ' '
        cmdline += 'intel_iommu=igfx_off i915.fastboot=1'
        system_context.set_substitution('KERNEL_CMDLINE', cmdline)

        self._execute(location, system_context, 'pacman', 'libva-intel-driver',
                      'mesa', 'vulkan-intel', 'xf86-video-intel',
                      'intel-media-driver')

        self._execute(location.next_line(), system_context, 'create',
                      '/etc/modprobe.d/i915-guc.conf',
                      'options i915 enable_guc=3')

        self._execute(location.next_line(),
                      system_context,
                      'remove',
                      '/usr/lib/firmware/amdgpu/*',
                      '/usr/lib/firmware/nvidia/*',
                      '/usr/lib/firmware/radeon/*',
                      force=True,
                      recursive=True)
예제 #19
0
    def _setup_hooks(self, location: Location,
                     system_context: SystemContext) -> None:
        i_gpg_dir = "/usr/lib/pacman/gpg"
        i_packages = "/var/cache/pacman/pkg/*"

        location.set_description("cleanup pacman-key files (internal)")
        self._add_hook(
            location,
            system_context,
            "_teardown",
            "remove",
            i_gpg_dir + "/S.*",
            i_gpg_dir + "/pubring.gpg~",
            i_gpg_dir + "/secring.gpg*",
            "/var/log/pacman.log",
            i_packages,
            recursive=True,
            force=True,
        )

        location.set_description("Cleanup pacman-key files (external)")
        o_gpg_dir = os.path.join(system_context.meta_directory, "pacman/gpg")

        self._add_hook(
            location,
            system_context,
            "_teardown",
            "remove",
            o_gpg_dir + "/S.*",
            o_gpg_dir + "/pubring.gpg~",
            o_gpg_dir + "/secring.gpg*",
            recursive=True,
            force=True,
            outside=True,
        )

        location.set_description("Move systemd files into /usr")
        self._add_hook(location, system_context, "_teardown",
                       "systemd_cleanup")

        location.set_description("Moving /opt into /usr")
        self._add_hook(location.next_line(), system_context, "export", "move",
                       "/opt", "/usr")
        self._add_hook(
            location,
            system_context,
            "export",
            "symlink",
            "usr/opt",
            "opt",
            work_directory="/",
        )

        location.set_description("Writing package information to FS.")
        self._add_hook(location.next_line(), system_context, "export",
                       "_pacman_write_package_data")

        system_context.set_substitution("DISTRO_ID_LIKE", "archlinux")
예제 #20
0
파일: set.py 프로젝트: phunni/cleanroom
 def __call__(
     self,
     location: Location,
     system_context: SystemContext,
     *args: typing.Any,
     **kwargs: typing.Any
 ) -> None:
     """Execute command."""
     system_context.set_substitution(args[0], args[1])
    def __call__(
        self,
        location: Location,
        system_context: SystemContext,
        *args: typing.Any,
        **kwargs: typing.Any,
    ) -> None:
        """Execute command."""
        if not os.path.isfile(
                system_context.file_name(
                    "/usr/lib/systemd/system/locale-archive-trigger.service"
                )) or not os.path.isfile(
                    system_context.file_name("/usr/bin/localedef")):
            return

        run(
            "/usr/bin/localedef",
            "-i",
            "en_US",
            "-c",
            "-f",
            "UTF-8",
            "en_US.UTF-8",
            chroot_helper=self._binary(Binaries.SYSTEMD_NSPAWN),
            chroot=system_context.fs_directory,
        )

        if os.path.isfile(
                system_context.file_name("/usr/lib/tmpfiles.d/var.conf")):
            self._execute(
                location,
                system_context,
                "sed",
                "/\\/var\\/cache\\/locale/ d",
                "/usr/lib/tmpfiles.d/var.conf",
            )

        self._execute(
            location,
            system_context,
            "sed",
            "/\\/var\\/cache\\/locale/ d",
            "/usr/lib/tmpfiles.d/filesystem.conf",
        )

        self._execute(
            location,
            system_context,
            "persist_on_usr",
            "locale-archive-trigger",
            "/var/cache/locale",
        )

        os.remove(
            system_context.file_name(
                "/usr/lib/systemd/system/locale-archive-trigger.service"))
예제 #22
0
파일: export.py 프로젝트: phunni/cleanroom
def _root_part_label(system_context: SystemContext) -> str:
    label = system_context.substitution("ROOTFS_PARTLABEL", "")
    return (
        label
        if label
        else "{}_{}".format(
            system_context.substitution("DISTRO_ID", "clrm"),
            system_context.substitution("DISTRO_VERSION_ID", system_context.timestamp),
        )
    )
예제 #23
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""

        if system_context.substitution("ROOT_DEVICE") is None:
            GenerateError("ROOT_DEVICE must be set when creating EFI kernel.",
                          location=location)

        output = args[0]
        kernel = kwargs.get("kernel", "")
        initrd_directory = kwargs.get(
            "initrd",
            os.path.join(system_context.boot_directory, "initrd-parts"))
        initrd_files = _get_initrd_parts(location, initrd_directory)
        cmdline_input = kwargs.get("commandline", "")
        osrelease_file = system_context.file_name("/usr/lib/os-release")
        efistub = system_context.file_name("/usr/lib/systemd/boot/efi/"
                                           "linuxx64.efi.stub")

        debug("{}: Kernel   : {}.".format(self.name, kernel))
        debug("{}: Initrd   : {}.".format(self.name, ", ".join(initrd_files)))
        debug("{}: cmdline  : {}.".format(self.name, cmdline_input))
        debug("{}: osrelease: {}.".format(self.name, osrelease_file))
        debug("{}: efistub  : {}.".format(self.name, efistub))

        self._validate_files(kernel, *initrd_files, osrelease_file, efistub)
        with tempfile.TemporaryDirectory() as tmp:
            initrd = _create_initrd(tmp, *initrd_files)
            cmdline = _create_cmdline_file(tmp, cmdline_input)

            run(
                self._binary(Binaries.OBJCOPY),
                "--add-section",
                ".osrel={}".format(osrelease_file),
                "--change-section-vma",
                ".osrel=0x20000",
                "--add-section",
                ".cmdline={}".format(cmdline),
                "--change-section-vma",
                ".cmdline=0x30000",
                "--add-section",
                ".linux={}".format(kernel),
                "--change-section-vma",
                ".linux=0x40000",
                "--add-section",
                ".initrd={}".format(initrd),
                "--change-section-vma",
                ".initrd=0x3000000",
                efistub,
                output,
            )

            os.remove(initrd)
            os.remove(cmdline)
예제 #24
0
파일: export.py 프로젝트: phunni/cleanroom
def _validate_installation(location: Location, system_context: SystemContext) -> None:
    hostname = system_context.substitution("HOSTNAME")
    if hostname is None:
        raise GenerateError(
            "Trying to export a system without a hostname.", location=location
        )

    machine_id = system_context.substitution("MACHINE_ID")
    if machine_id is None:
        raise GenerateError(
            "Trying to export a system without " "a machine_id.", location=location
        )
예제 #25
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""
        if system_context.has_substitution('MACHINE_ID'):
            raise GenerateError('Machine-id was already set.',
                                location=location)

        machine_id = args[0]
        system_context.set_substitution('MACHINE_ID', machine_id)
        machine_id += '\n'
        self._execute(location.next_line(), system_context, 'create',
                      '/etc/machine-id', machine_id)
예제 #26
0
    def __call__(
        self,
        location: Location,
        system_context: SystemContext,
        *args: typing.Any,
        **kwargs: typing.Any,
    ) -> None:
        """Execute command."""
        output = args[0]
        kernel = kwargs.get("kernel", "")
        initrd_directory = kwargs.get(
            "initrd", os.path.join(system_context.boot_directory, "initrd-parts")
        )
        initrd_files = _get_initrd_parts(location, initrd_directory)
        cmdline_input = kwargs.get("commandline", "")
        osrelease_file = system_context.file_name("/usr/lib/os-release")
        efistub = system_context.file_name(
            "/usr/lib/systemd/boot/efi/" "linuxx64.efi.stub"
        )

        debug(f"{self.name}: Kernel   : {kernel}.")
        debug(f"{self.name}: Initrd   : {initrd_files}.")
        debug(f"{self.name}: cmdline  : {cmdline_input}.")
        debug(f"{self.name}: osrelease: {osrelease_file}.")
        debug(f"{self.name}: efistub  : {efistub}.")

        self._validate_files(location, kernel, *initrd_files, osrelease_file, efistub)

        initrd = _create_initrd(system_context.boot_directory, *initrd_files)
        cmdline = _create_cmdline_file(system_context.boot_directory, cmdline_input)

        run(
            self._binary(Binaries.OBJCOPY),
            "--add-section",
            f".osrel={osrelease_file}",
            "--change-section-vma",
            ".osrel=0x20000",
            "--add-section",
            f".cmdline={cmdline}",
            "--change-section-vma",
            ".cmdline=0x30000",
            "--add-section",
            f".linux={kernel}",
            "--change-section-vma",
            ".linux=0x40000",
            "--add-section",
            f".initrd={initrd}",
            "--change-section-vma",
            ".initrd=0x3000000",
            efistub,
            output,
        )
예제 #27
0
 def _setup_hooks(self, location: Location, system_context: SystemContext,
                  locales: typing.Sequence[str]) -> None:
     if not system_context.has_substitution('CLRM_LOCALES'):
         location.set_description('run locale-gen')
         self._add_hook(location, system_context, 'export',
                        'run', '/usr/bin/locale-gen', inside=True)
         location.set_description('Remove locale related data.')
         self._add_hook(location, system_context, 'export',
                        'remove', '/usr/share/locale/*',
                        '/etc/locale.gen', '/usr/bin/locale-gen',
                        '/usr/bin/localedef',
                        force=True, recursive=True)
         system_context.set_substitution('CLRM_LOCALES', ','.join(locales))
예제 #28
0
    def create_image(
        self,
        location: Location,
        system_context: SystemContext,
        export_volume: str,
        *,
        efi_partition: str,
        root_partition: str,
        verity_partition: str,
        root_hash: str,
    ):
        image_name = system_context.substitution_expanded(
            "CLRM_IMAGE_FILENAME", "")
        assert image_name

        image_filename = os.path.join(
            export_volume,
            image_name,
        )

        assert efi_partition
        assert root_partition
        assert verity_partition

        total_size = ((2 * 1024 * 1024) + file_size(None, efi_partition) +
                      file_size(None, root_partition) +
                      file_size(None, verity_partition))

        root_uuid = _uuid_ify(root_hash[:32]) if root_hash else ""
        verity_uuid = _uuid_ify(root_hash[32:]) if root_hash else ""

        with open(image_filename, "wb") as fd:
            fd.seek(total_size - 1)
            fd.write(b"\b")

        self._execute(
            location,
            system_context,
            "_create_export_image",
            image_filename,
            efi_fsimage=efi_partition,
            efi_label="ESP",
            root_fsimage=root_partition,
            root_label=system_context.substitution_expanded(
                "ROOTFS_PARTLABEL", ""),
            root_uuid=root_uuid,
            verity_fsimage=verity_partition,
            verity_label=system_context.substitution_expanded(
                "VRTYFS_PARTLABEL", ""),
            verity_uuid=verity_uuid,
        )
예제 #29
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""
        self._run_hooks(system_context, '_teardown')
        self._run_hooks(system_context, 'testing')

        system_context.pickle()

        self._execute(location, system_context, '_store')

        debug('Cleaning up everything in "{}".'.format(
            system_context.scratch_directory))
        self._service('btrfs_helper').delete_subvolume_recursive(
            system_context.scratch_directory)
예제 #30
0
    def __call__(self, location: Location, system_context: SystemContext,
                 *args: typing.Any, **kwargs: typing.Any) -> None:
        """Execute command."""
        os_release = 'NAME="{}"\n'\
            .format(system_context.substitution('DISTRO_NAME',
                                                'Arch Linux'))
        os_release += 'PRETTY_NAME=\"{}\"\n'\
            .format(system_context.substitution('DISTRO_PRETTY_NAME',
                                                'Arch Linux'))
        os_release += 'ID=\"{}\"\n'\
            .format(system_context.substitution('DISTRO_ID', 'arch'))
        os_release += 'ID_LIKE=\"arch\"\n'
        os_release += 'ANSI_COLOR=\"0;36\"\n'
        os_release += 'HOME_URL=\"{}\"\n'\
            .format(system_context.substitution('DISTRO_HOME_URL',
                                                'https://www.archlinux.org/'))
        os_release += 'SUPPORT_URL=\"{}\"\n'\
            .format(system_context.substitution('DISTRO_SUPPORT_URL',
                                                'https://bbs.archlinux.org/'))
        os_release += 'BUG_REPORT_URL=\"{}\"\n'\
            .format(system_context.substitution('DISTRO_BUG_URL',
                                                'https://bugs.archlinux.org/'))
        os_release += 'VERSION=\"{}\"\n'\
            .format(system_context.substitution('DISTRO_VERSION',
                                                'unknown'))
        os_release += 'VERSION_ID=\"{}\"\n'\
            .format(system_context.substitution('DISTRO_VERSION_ID',
                                                'unknown'))

        self._execute(location, system_context,
                      'create', '/usr/lib/os-release',
                      os_release, force=True, mode=0o644)