diff options
author | Arian van Putten <arian.vanputten@gmail.com> | 2023-02-10 20:03:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-10 20:03:09 +0100 |
commit | 5b23d0e51c440e717bec8cdf5fe695b03a12fe43 (patch) | |
tree | cf9e7a5eaf6afabca6a7233df0e6cfdc76f777ac /nixos/modules/system | |
parent | c34c235192bb2827d979aaf728db7451a5baf57e (diff) | |
parent | 4700198654affcca0a76915e083b857e7e605cf5 (diff) |
Merge pull request #214396 from nikstur/systemd-repart
systemd-repart
Diffstat (limited to 'nixos/modules/system')
-rw-r--r-- | nixos/modules/system/boot/systemd/repart.nix | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/nixos/modules/system/boot/systemd/repart.nix b/nixos/modules/system/boot/systemd/repart.nix new file mode 100644 index 0000000000000..33f1b247c5ede --- /dev/null +++ b/nixos/modules/system/boot/systemd/repart.nix @@ -0,0 +1,101 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.boot.initrd.systemd.repart; + + writeDefinition = name: partitionConfig: pkgs.writeText + "${name}.conf" + (lib.generators.toINI { } { Partition = partitionConfig; }); + + listOfDefinitions = lib.mapAttrsToList + writeDefinition + (lib.filterAttrs (k: _: !(lib.hasPrefix "_" k)) cfg.partitions); + + # Create a directory in the store that contains a copy of all definition + # files. This is then passed to systemd-repart in the initrd so it can access + # the definition files after the sysroot has been mounted but before + # activation. This needs a hard copy of the files and not just symlinks + # because otherwise the files do not show up in the sysroot. + definitionsDirectory = pkgs.runCommand "systemd-repart-definitions" { } '' + mkdir -p $out + ${(lib.concatStringsSep "\n" + (map (pkg: "cp ${pkg} $out/${pkg.name}") listOfDefinitions) + )} + ''; +in +{ + options.boot.initrd.systemd.repart = { + enable = lib.mkEnableOption (lib.mdDoc "systemd-repart") // { + description = lib.mdDoc '' + Grow and add partitions to a partition table a boot time in the initrd. + systemd-repart only works with GPT partition tables. + ''; + }; + + partitions = lib.mkOption { + type = with lib.types; attrsOf (attrsOf (oneOf [ str int bool ])); + default = { }; + example = { + "10-root" = { + Type = "root"; + }; + "20-home" = { + Type = "home"; + SizeMinBytes = "512M"; + SizeMaxBytes = "2G"; + }; + }; + description = lib.mdDoc '' + Specify partitions as a set of the names of the definition files as the + key and the partition configuration as its value. The partition + configuration can use all upstream options. See <link + xlink:href="https://www.freedesktop.org/software/systemd/man/repart.d.html"/> + for all available options. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + # Link the definitions into /etc so that they are included in the + # /nix/store of the sysroot. This also allows the user to run the + # systemd-repart binary after activation manually while automatically + # picking up the definition files. + environment.etc."repart.d".source = definitionsDirectory; + + boot.initrd.systemd = { + additionalUpstreamUnits = [ + "systemd-repart.service" + ]; + + storePaths = [ + "${config.boot.initrd.systemd.package}/bin/systemd-repart" + ]; + + # Override defaults in upstream unit. + services.systemd-repart = { + # Unset the coniditions as they cannot be met before activation because + # the definition files are not stored in the expected locations. + unitConfig.ConditionDirectoryNotEmpty = [ + " " # required to unset the previous value. + ]; + serviceConfig = { + # systemd-repart runs before the activation script. Thus we cannot + # rely on them being linked in /etc already. Instead we have to + # explicitly pass their location in the sysroot to the binary. + ExecStart = [ + " " # required to unset the previous value. + ''${config.boot.initrd.systemd.package}/bin/systemd-repart \ + --definitions=/sysroot${definitionsDirectory} \ + --dry-run=no + '' + ]; + }; + # Because the initrd does not have the `initrd-usr-fs.target` the + # upestream unit runs too early in the boot process, before the sysroot + # is available. However, systemd-repart needs access to the sysroot to + # find the definition files. + after = [ "sysroot.mount" ]; + }; + }; + }; +} |