From: Joerg Behrmann Date: Tue, 4 Oct 2022 15:38:03 +0000 (+0200) Subject: Move Arch install functions to distributions.arch X-Git-Tag: v15~384^2~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a3e33af5cfc4bc7624bba3ae26f4fd2a2766dd11;p=thirdparty%2Fmkosi.git Move Arch install functions to distributions.arch --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 20c4a82ca..14d5a4a79 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -1541,8 +1541,6 @@ def mount_cache(state: MkosiState) -> Iterator[None]: cache_paths = ["var/cache/yum", "var/cache/dnf"] elif state.config.distribution in (Distribution.debian, Distribution.ubuntu): cache_paths = ["var/cache/apt/archives"] - elif state.config.distribution == Distribution.arch: - cache_paths = ["var/cache/pacman/pkg"] elif state.config.distribution == Distribution.gentoo: cache_paths = ["var/cache/binpkgs"] elif state.config.distribution == Distribution.opensuse: @@ -2567,163 +2565,6 @@ def install_ubuntu(state: MkosiState) -> None: install_debian_or_ubuntu(state) -@complete_step("Installing Arch Linux…") -def install_arch(state: MkosiState) -> None: - if state.config.release is not None: - MkosiPrinter.info("Distribution release specification is not supported for Arch Linux, ignoring.") - - assert state.config.mirror - - if state.config.local_mirror: - server = f"Server = {state.config.local_mirror}" - else: - if state.config.architecture == "aarch64": - server = f"Server = {state.config.mirror}/$arch/$repo" - else: - server = f"Server = {state.config.mirror}/$repo/os/$arch" - - # Create base layout for pacman and pacman-key - os.makedirs(state.root / "var/lib/pacman", 0o755, exist_ok=True) - os.makedirs(state.root / "etc/pacman.d/gnupg", 0o755, exist_ok=True) - - # Permissions on these directories are all 0o777 because of 'mount --bind' - # limitations but pacman expects them to be 0o755 so we fix them before - # calling pacman (except /var/tmp which is 0o1777). - fix_permissions_dirs = { - "boot": 0o755, - "etc": 0o755, - "etc/pacman.d": 0o755, - "var": 0o755, - "var/lib": 0o755, - "var/cache": 0o755, - "var/cache/pacman": 0o755, - "var/tmp": 0o1777, - "run": 0o755, - } - - for dir, permissions in fix_permissions_dirs.items(): - path = state.root / dir - if path.exists(): - path.chmod(permissions) - - pacman_conf = state.workspace / "pacman.conf" - if state.config.repository_key_check: - sig_level = "Required DatabaseOptional" - else: - # If we are using a single local mirror built on the fly there - # will be no signatures - sig_level = "Never" - with pacman_conf.open("w") as f: - f.write( - dedent( - f"""\ - [options] - RootDir = {state.root} - LogFile = /dev/null - CacheDir = {state.root}/var/cache/pacman/pkg/ - GPGDir = /etc/pacman.d/gnupg/ - HookDir = {state.root}/etc/pacman.d/hooks/ - HoldPkg = pacman glibc - Architecture = {state.config.architecture} - Color - CheckSpace - SigLevel = {sig_level} - ParallelDownloads = 5 - - [core] - {server} - """ - ) - ) - - if not state.config.local_mirror: - f.write( - dedent( - f"""\ - - [extra] - {server} - - [community] - {server} - """ - ) - ) - - f.write( - dedent( - f"""\ - - {f"Include = {state.config.repos_dir}/*" if state.config.repos_dir else ""} - """ - ) - ) - - if state.config.repositories: - for repository in state.config.repositories: - # repositories must be passed in the form :: - repository_name, repository_server = repository.split("::", 1) - - # note: for additional repositories, signature checking options are set to pacman's default values - f.write( - dedent( - f"""\ - - [{repository_name}] - SigLevel = Optional TrustedOnly - Server = {repository_server} - """ - ) - ) - - keyring = "archlinux" - if platform.machine() == "aarch64": - keyring += "arm" - - packages: Set[str] = set() - add_packages(state.config, packages, "base") - - if not state.do_run_build_script and state.config.bootable: - if state.config.output_format == OutputFormat.gpt_btrfs: - add_packages(state.config, packages, "btrfs-progs") - elif state.config.output_format == OutputFormat.gpt_xfs: - add_packages(state.config, packages, "xfsprogs") - if state.config.encrypt: - add_packages(state.config, packages, "cryptsetup", "device-mapper") - - add_packages(state.config, packages, "dracut") - - packages.update(state.config.packages) - - official_kernel_packages = { - "linux", - "linux-lts", - "linux-hardened", - "linux-zen", - } - - has_kernel_package = official_kernel_packages.intersection(state.config.packages) - if not state.do_run_build_script and state.config.bootable and not has_kernel_package: - # No user-specified kernel - add_packages(state.config, packages, "linux") - - if state.do_run_build_script: - packages.update(state.config.build_packages) - - if not state.do_run_build_script and state.config.ssh: - add_packages(state.config, packages, "openssh") - - with mount_api_vfs(state.root): - run(["pacman", "--config", pacman_conf, "--noconfirm", "-Sy", *sort_packages(packages)], - env={"KERNEL_INSTALL_BYPASS": state.environment.get("KERNEL_INSTALL_BYPASS", "1")}) - - state.root.joinpath("etc/pacman.d/mirrorlist").write_text(f"Server = {state.config.mirror}/$repo/os/$arch\n") - - # Arch still uses pam_securetty which prevents root login into - # systemd-nspawn containers. See https://bugs.archlinux.org/task/45903. - disable_pam_securetty(state.root) - - @complete_step("Installing openSUSE…") def install_opensuse(state: MkosiState) -> None: release = state.config.release.strip('"') @@ -2869,7 +2710,6 @@ def install_distribution(state: MkosiState, cached: bool) -> None: Distribution.mageia: install_mageia, Distribution.debian: install_debian, Distribution.ubuntu: install_ubuntu, - Distribution.arch: install_arch, Distribution.opensuse: install_opensuse, Distribution.openmandriva: install_openmandriva, Distribution.gentoo: install_gentoo, diff --git a/mkosi/distributions/arch.py b/mkosi/distributions/arch.py new file mode 100644 index 000000000..12119081a --- /dev/null +++ b/mkosi/distributions/arch.py @@ -0,0 +1,185 @@ +# SPDX-License-Identifier: LGPL-2.1+ + +import os +from textwrap import dedent +from typing import List, Set + +from ..backend import ( + MkosiPrinter, + MkosiState, + OutputFormat, + add_packages, + complete_step, + disable_pam_securetty, + run, + sort_packages, +) +from ..mounts import mount_api_vfs +from . import DistributionInstaller + + +class ArchInstaller(DistributionInstaller): + @classmethod + def cache_path(cls) -> List[str]: + return ["var/cache/pacman/pkg"] + + @classmethod + def install(cls, state: "MkosiState") -> None: + return install_arch(state) + + +@complete_step("Installing Arch Linux…") +def install_arch(state: MkosiState) -> None: + if state.config.release is not None: + MkosiPrinter.info("Distribution release specification is not supported for Arch Linux, ignoring.") + + assert state.config.mirror + + if state.config.local_mirror: + server = f"Server = {state.config.local_mirror}" + else: + if state.config.architecture == "aarch64": + server = f"Server = {state.config.mirror}/$arch/$repo" + else: + server = f"Server = {state.config.mirror}/$repo/os/$arch" + + # Create base layout for pacman and pacman-key + os.makedirs(state.root / "var/lib/pacman", 0o755, exist_ok=True) + os.makedirs(state.root / "etc/pacman.d/gnupg", 0o755, exist_ok=True) + + # Permissions on these directories are all 0o777 because of 'mount --bind' + # limitations but pacman expects them to be 0o755 so we fix them before + # calling pacman (except /var/tmp which is 0o1777). + fix_permissions_dirs = { + "boot": 0o755, + "etc": 0o755, + "etc/pacman.d": 0o755, + "var": 0o755, + "var/lib": 0o755, + "var/cache": 0o755, + "var/cache/pacman": 0o755, + "var/tmp": 0o1777, + "run": 0o755, + } + + for dir, permissions in fix_permissions_dirs.items(): + path = state.root / dir + if path.exists(): + path.chmod(permissions) + + pacman_conf = state.workspace / "pacman.conf" + if state.config.repository_key_check: + sig_level = "Required DatabaseOptional" + else: + # If we are using a single local mirror built on the fly there + # will be no signatures + sig_level = "Never" + with pacman_conf.open("w") as f: + f.write( + dedent( + f"""\ + [options] + RootDir = {state.root} + LogFile = /dev/null + CacheDir = {state.root}/var/cache/pacman/pkg/ + GPGDir = /etc/pacman.d/gnupg/ + HookDir = {state.root}/etc/pacman.d/hooks/ + HoldPkg = pacman glibc + Architecture = {state.config.architecture} + Color + CheckSpace + SigLevel = {sig_level} + ParallelDownloads = 5 + + [core] + {server} + """ + ) + ) + + if not state.config.local_mirror: + f.write( + dedent( + f"""\ + + [extra] + {server} + + [community] + {server} + """ + ) + ) + + f.write( + dedent( + f"""\ + + {f"Include = {state.config.repos_dir}/*" if state.config.repos_dir else ""} + """ + ) + ) + + if state.config.repositories: + for repository in state.config.repositories: + # repositories must be passed in the form :: + repository_name, repository_server = repository.split("::", 1) + + # note: for additional repositories, signature checking options are set to pacman's default values + f.write( + dedent( + f"""\ + + [{repository_name}] + SigLevel = Optional TrustedOnly + Server = {repository_server} + """ + ) + ) + + keyring = "archlinux" + if platform.machine() == "aarch64": + keyring += "arm" + + packages: Set[str] = set() + add_packages(state.config, packages, "base") + + if not state.do_run_build_script and state.config.bootable: + if state.config.output_format == OutputFormat.gpt_btrfs: + add_packages(state.config, packages, "btrfs-progs") + elif state.config.output_format == OutputFormat.gpt_xfs: + add_packages(state.config, packages, "xfsprogs") + if state.config.encrypt: + add_packages(state.config, packages, "cryptsetup", "device-mapper") + + add_packages(state.config, packages, "dracut") + + packages.update(state.config.packages) + + official_kernel_packages = { + "linux", + "linux-lts", + "linux-hardened", + "linux-zen", + } + + has_kernel_package = official_kernel_packages.intersection(state.config.packages) + if not state.do_run_build_script and state.config.bootable and not has_kernel_package: + # No user-specified kernel + add_packages(state.config, packages, "linux") + + if state.do_run_build_script: + packages.update(state.config.build_packages) + + if not state.do_run_build_script and state.config.ssh: + add_packages(state.config, packages, "openssh") + + with mount_api_vfs(state.root): + run(["pacman", "--config", pacman_conf, "--noconfirm", "-Sy", *sort_packages(packages)], + env={"KERNEL_INSTALL_BYPASS": state.environment.get("KERNEL_INSTALL_BYPASS", "1")}) + + state.root.joinpath("etc/pacman.d/mirrorlist").write_text(f"Server = {state.config.mirror}/$repo/os/$arch\n") + + # Arch still uses pam_securetty which prevents root login into + # systemd-nspawn containers. See https://bugs.archlinux.org/task/45903. + disable_pam_securetty(state.root)