at 23.11-beta 5.0 kB view raw
1{ config, lib, pkgs, utils, ... }: 2 3let 4 cfg = config.systemd.repart; 5 initrdCfg = config.boot.initrd.systemd.repart; 6 7 format = pkgs.formats.ini { }; 8 9 definitionsDirectory = utils.systemdUtils.lib.definitions 10 "repart.d" 11 format 12 (lib.mapAttrs (_n: v: { Partition = v; }) cfg.partitions); 13in 14{ 15 options = { 16 boot.initrd.systemd.repart = { 17 enable = lib.mkEnableOption (lib.mdDoc "systemd-repart") // { 18 description = lib.mdDoc '' 19 Grow and add partitions to a partition table at boot time in the initrd. 20 systemd-repart only works with GPT partition tables. 21 22 To run systemd-repart after the initrd, see 23 `options.systemd.repart.enable`. 24 ''; 25 }; 26 27 device = lib.mkOption { 28 type = with lib.types; nullOr str; 29 description = lib.mdDoc '' 30 The device to operate on. 31 32 If `device == null`, systemd-repart will operate on the device 33 backing the root partition. So in order to dynamically *create* the 34 root partition in the initrd you need to set a device. 35 ''; 36 default = null; 37 example = "/dev/vda"; 38 }; 39 }; 40 41 systemd.repart = { 42 enable = lib.mkEnableOption (lib.mdDoc "systemd-repart") // { 43 description = lib.mdDoc '' 44 Grow and add partitions to a partition table. 45 systemd-repart only works with GPT partition tables. 46 47 To run systemd-repart while in the initrd, see 48 `options.boot.initrd.systemd.repart.enable`. 49 ''; 50 }; 51 52 partitions = lib.mkOption { 53 type = with lib.types; attrsOf (attrsOf (oneOf [ str int bool ])); 54 default = { }; 55 example = { 56 "10-root" = { 57 Type = "root"; 58 }; 59 "20-home" = { 60 Type = "home"; 61 SizeMinBytes = "512M"; 62 SizeMaxBytes = "2G"; 63 }; 64 }; 65 description = lib.mdDoc '' 66 Specify partitions as a set of the names of the definition files as the 67 key and the partition configuration as its value. The partition 68 configuration can use all upstream options. See <link 69 xlink:href="https://www.freedesktop.org/software/systemd/man/repart.d.html"/> 70 for all available options. 71 ''; 72 }; 73 }; 74 }; 75 76 config = lib.mkIf (cfg.enable || initrdCfg.enable) { 77 assertions = [ 78 { 79 assertion = initrdCfg.enable -> config.boot.initrd.systemd.enable; 80 message = '' 81 'boot.initrd.systemd.repart.enable' requires 'boot.initrd.systemd.enable' to be enabled. 82 ''; 83 } 84 ]; 85 86 boot.initrd.systemd = lib.mkIf initrdCfg.enable { 87 additionalUpstreamUnits = [ 88 "systemd-repart.service" 89 ]; 90 91 storePaths = [ 92 "${config.boot.initrd.systemd.package}/bin/systemd-repart" 93 ]; 94 95 contents."/etc/repart.d".source = definitionsDirectory; 96 97 # Override defaults in upstream unit. 98 services.systemd-repart = 99 let 100 deviceUnit = "${utils.escapeSystemdPath initrdCfg.device}.device"; 101 in 102 { 103 # systemd-repart tries to create directories in /var/tmp by default to 104 # store large temporary files that benefit from persistence on disk. In 105 # the initrd, however, /var/tmp does not provide more persistence than 106 # /tmp, so we re-use it here. 107 environment."TMPDIR" = "/tmp"; 108 serviceConfig = { 109 ExecStart = [ 110 " " # required to unset the previous value. 111 # When running in the initrd, systemd-repart by default searches 112 # for definition files in /sysroot or /sysusr. We tell it to look 113 # in the initrd itself. 114 ''${config.boot.initrd.systemd.package}/bin/systemd-repart \ 115 --definitions=/etc/repart.d \ 116 --dry-run=no ${lib.optionalString (initrdCfg.device != null) initrdCfg.device} 117 '' 118 ]; 119 }; 120 # systemd-repart needs to run after /sysroot (or /sysuser, but we 121 # don't have it) has been mounted because otherwise it cannot 122 # determine the device (i.e disk) to operate on. If you want to run 123 # systemd-repart without /sysroot (i.e. to create the root 124 # partition), you have to explicitly tell it which device to operate 125 # on. The service then needs to be ordered to run after this device 126 # is available. 127 requires = lib.mkIf (initrdCfg.device != null) [ deviceUnit ]; 128 after = 129 if initrdCfg.device == null then 130 [ "sysroot.mount" ] 131 else 132 [ deviceUnit ]; 133 }; 134 }; 135 136 environment.etc = lib.mkIf cfg.enable { 137 "repart.d".source = definitionsDirectory; 138 }; 139 140 systemd = lib.mkIf cfg.enable { 141 additionalUpstreamSystemUnits = [ 142 "systemd-repart.service" 143 ]; 144 }; 145 }; 146 147 meta.maintainers = with lib.maintainers; [ nikstur ]; 148}