From f7921f97219ee7a67c5859ebafa6f98f23f11ddf Mon Sep 17 00:00:00 2001 From: Georges Discry Date: Wed, 24 Jan 2018 00:52:41 +0100 Subject: [PATCH] arch: better package selection The package selection for Arch Linux is not optimal, especially when the image is not bootable. The main issue is that a kernel is still installed when the image is not bootable. Optional packages from the `base` group that are required under specific configurations are first deleted from the package selection and explicitly re-added when required. For example, the `cryptsetup` and `device-mapper` packages are included only if the image is bootable and encrypted. Similarly, a kernel is included only if the image is bootable or if the user selected one explicitly. Sets are now better used in the package selection. The appropriate operators and methods are directly used instead of relying on intermediary sets. The installation of the packages is split into two operations. The first only installs the packages from the `base` group and the second installs the packages selected by the user. This is necessary because some packages (e.g. `git`) have an install script that depends on the `base` group without listing those in their dependencies. If they are installed before their implicit dependency, their install script will most likely fail. --- mkosi | 75 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/mkosi b/mkosi index 9a01832a7..99567c546 100755 --- a/mkosi +++ b/mkosi @@ -1394,53 +1394,60 @@ SigLevel = Required DatabaseOptional run_pacman(["-Sy"]) # determine base packages list from base group - c = run_pacman(["-Sg", "base"], stdout=PIPE, universal_newlines=True) + c = run_pacman(["-Sqg", "base"], stdout=PIPE, universal_newlines=True) packages = set(c.stdout.split()) - packages.remove("base") + packages -= { + "cryptsetup", + "device-mapper", + "dhcpcd", + "e2fsprogs", + "jfsutils", + "linux", + "lvm2", + "man-db", + "man-pages", + "mdadm", + "netctl", + "pcmciautils", + "reiserfsprogs", + "xfsprogs", + } - official_kernel_packages = [ + official_kernel_packages = { "linux", "linux-lts", "linux-hardened", - "linux-zen" - ] - - kernel_packages = {"linux"} - if args.packages: - kernel_packages = set.intersection(set(args.packages), set(official_kernel_packages)) - # prefer user-specified packages over implicit base kernel - if kernel_packages and "linux" not in kernel_packages: - packages.remove("linux") - if len(kernel_packages) > 1: - warn('More than one kernel will be installed: {}', ' '.join(kernel_packages)) - - packages -= {"device-mapper", - "dhcpcd", - "e2fsprogs", - "jfsutils", - "lvm2", - "man-db", - "man-pages", - "mdadm", - "netctl", - "pcmciautils", - "reiserfsprogs", - "xfsprogs"} + "linux-zen", + } + kernel_packages = official_kernel_packages.intersection(args.packages) + packages |= kernel_packages + if len(kernel_packages) > 1: + warn('More than one kernel will be installed: {}', ' '.join(kernel_packages)) if args.bootable: if args.output_format == OutputFormat.raw_gpt: packages.add("e2fsprogs") elif args.output_format == OutputFormat.raw_btrfs: packages.add("btrfs-progs") - else: - packages -= kernel_packages - - packages |= set(args.packages) + if args.encrypt: + packages.add("cryptsetup") + packages.add("device-mapper") + if not kernel_packages: + # No user-specified kernel + packages.add("linux") + + # Set up system with packages from the base group + run_pacstrap(packages) + # Install the user-specified packages + packages = set(args.packages) if run_build_script: - packages |= set(args.build_packages) - - run_pacstrap(packages) + packages.update(args.build_packages) + # Remove already installed packages + c = run_pacman(['-Qq'], stdout=PIPE, universal_newlines=True) + packages.difference_update(c.stdout.split()) + if packages: + run_pacstrap(packages) # Kill the gpg-agent used by pacman and pacman-key run(['gpg-connect-agent', '--homedir', os.path.join(root, 'etc/pacman.d/gnupg'), 'KILLAGENT', '/bye']) -- 2.47.2