at 25.11-pre 5.9 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8{ 9 10 imports = [ ./etc.nix ]; 11 12 config = lib.mkMerge [ 13 14 { 15 system.activationScripts.etc = lib.stringAfter [ 16 "users" 17 "groups" 18 "specialfs" 19 ] config.system.build.etcActivationCommands; 20 } 21 22 (lib.mkIf config.system.etc.overlay.enable { 23 24 assertions = [ 25 { 26 assertion = config.boot.initrd.systemd.enable; 27 message = "`system.etc.overlay.enable` requires `boot.initrd.systemd.enable`"; 28 } 29 { 30 assertion = 31 (!config.system.etc.overlay.mutable) 32 -> (config.systemd.sysusers.enable || config.services.userborn.enable); 33 message = "`!system.etc.overlay.mutable` requires `systemd.sysusers.enable` or `services.userborn.enable`"; 34 } 35 { 36 assertion = 37 (config.system.switch.enable) 38 -> (lib.versionAtLeast config.boot.kernelPackages.kernel.version "6.6"); 39 message = "switchable systems with `system.etc.overlay.enable` require a newer kernel, at least version 6.6"; 40 } 41 ]; 42 43 boot.initrd.availableKernelModules = [ 44 "loop" 45 "erofs" 46 "overlay" 47 ]; 48 49 boot.initrd.systemd = { 50 mounts = [ 51 { 52 where = "/run/nixos-etc-metadata"; 53 what = "/etc-metadata-image"; 54 type = "erofs"; 55 options = "loop,ro"; 56 unitConfig = { 57 # Since this unit depends on the nix store being mounted, it cannot 58 # be a dependency of local-fs.target, because if it did, we'd have 59 # local-fs.target ordered after the nix store mount which would cause 60 # things like network.target to only become active after the nix store 61 # has been mounted. 62 # This breaks for instance setups where sshd needs to be up before 63 # any encrypted disks can be mounted. 64 DefaultDependencies = false; 65 RequiresMountsFor = [ 66 "/sysroot/nix/store" 67 ]; 68 }; 69 requires = [ 70 config.boot.initrd.systemd.services.initrd-find-etc.name 71 ]; 72 after = [ 73 config.boot.initrd.systemd.services.initrd-find-etc.name 74 ]; 75 requiredBy = [ "initrd-fs.target" ]; 76 before = [ "initrd-fs.target" ]; 77 } 78 { 79 where = "/sysroot/etc"; 80 what = "overlay"; 81 type = "overlay"; 82 options = lib.concatStringsSep "," ( 83 [ 84 "relatime" 85 "redirect_dir=on" 86 "metacopy=on" 87 "lowerdir=/run/nixos-etc-metadata::/etc-basedir" 88 ] 89 ++ lib.optionals config.system.etc.overlay.mutable [ 90 "rw" 91 "upperdir=/sysroot/.rw-etc/upper" 92 "workdir=/sysroot/.rw-etc/work" 93 ] 94 ++ lib.optionals (!config.system.etc.overlay.mutable) [ 95 "ro" 96 ] 97 ); 98 requiredBy = [ "initrd-fs.target" ]; 99 before = [ "initrd-fs.target" ]; 100 requires = 101 [ 102 config.boot.initrd.systemd.services.initrd-find-etc.name 103 ] 104 ++ lib.optionals config.system.etc.overlay.mutable [ 105 config.boot.initrd.systemd.services."rw-etc".name 106 ]; 107 after = 108 [ 109 config.boot.initrd.systemd.services.initrd-find-etc.name 110 ] 111 ++ lib.optionals config.system.etc.overlay.mutable [ 112 config.boot.initrd.systemd.services."rw-etc".name 113 ]; 114 unitConfig = { 115 RequiresMountsFor = [ 116 "/sysroot/nix/store" 117 "/run/nixos-etc-metadata" 118 ]; 119 DefaultDependencies = false; 120 }; 121 } 122 ]; 123 services = lib.mkMerge [ 124 (lib.mkIf config.system.etc.overlay.mutable { 125 rw-etc = { 126 requiredBy = [ "initrd-fs.target" ]; 127 before = [ "initrd-fs.target" ]; 128 unitConfig = { 129 DefaultDependencies = false; 130 RequiresMountsFor = "/sysroot"; 131 }; 132 serviceConfig = { 133 Type = "oneshot"; 134 ExecStart = '' 135 /bin/mkdir -p -m 0755 /sysroot/.rw-etc/upper /sysroot/.rw-etc/work 136 ''; 137 }; 138 }; 139 }) 140 { 141 initrd-find-etc = { 142 description = "Find the path to the etc metadata image and based dir"; 143 requires = [ 144 config.boot.initrd.systemd.services.initrd-find-nixos-closure.name 145 ]; 146 after = [ 147 config.boot.initrd.systemd.services.initrd-find-nixos-closure.name 148 ]; 149 before = [ "shutdown.target" ]; 150 conflicts = [ "shutdown.target" ]; 151 requiredBy = [ "initrd.target" ]; 152 unitConfig = { 153 DefaultDependencies = false; 154 RequiresMountsFor = "/sysroot/nix/store"; 155 }; 156 serviceConfig = { 157 Type = "oneshot"; 158 RemainAfterExit = true; 159 }; 160 161 script = # bash 162 '' 163 set -uo pipefail 164 165 closure="$(realpath /nixos-closure)" 166 167 metadata_image="$(${pkgs.chroot-realpath}/bin/chroot-realpath /sysroot "$closure/etc-metadata-image")" 168 ln -s "/sysroot$metadata_image" /etc-metadata-image 169 170 basedir="$(${pkgs.chroot-realpath}/bin/chroot-realpath /sysroot "$closure/etc-basedir")" 171 ln -s "/sysroot$basedir" /etc-basedir 172 ''; 173 }; 174 } 175 ]; 176 }; 177 178 }) 179 180 ]; 181}