about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/system/boot
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2024-06-23 00:32:22 +0200
committerAlyssa Ross <hi@alyssa.is>2024-06-23 00:32:22 +0200
commit6402b188ddd100b3cd6afe7b8a3e553365203f43 (patch)
tree676b85e4a6ffee092e413e723f7dce8ba01bb48f /nixpkgs/nixos/modules/system/boot
parent5a1826585861b32ce2509c0643e793196d81893e (diff)
parentd603719ec6e294f034936c0d0dc06f689d91b6c3 (diff)
downloadnixlib-master.tar
nixlib-master.tar.gz
nixlib-master.tar.bz2
nixlib-master.tar.lz
nixlib-master.tar.xz
nixlib-master.tar.zst
nixlib-master.zip
Merge remote-tracking branch 'nixpkgs/nixos-unstable' HEAD master
Diffstat (limited to 'nixpkgs/nixos/modules/system/boot')
-rw-r--r--nixpkgs/nixos/modules/system/boot/initrd-ssh.nix2
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py3
-rw-r--r--nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix6
-rw-r--r--nixpkgs/nixos/modules/system/boot/networkd.nix265
-rw-r--r--nixpkgs/nixos/modules/system/boot/resolved.nix143
-rw-r--r--nixpkgs/nixos/modules/system/boot/stage-1-init.sh1
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd.nix11
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd/coredump.nix2
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd/sysusers.nix21
-rw-r--r--nixpkgs/nixos/modules/system/boot/systemd/user.nix12
10 files changed, 205 insertions, 261 deletions
diff --git a/nixpkgs/nixos/modules/system/boot/initrd-ssh.nix b/nixpkgs/nixos/modules/system/boot/initrd-ssh.nix
index 9ce5a85b4f07..d1cd601c2d9b 100644
--- a/nixpkgs/nixos/modules/system/boot/initrd-ssh.nix
+++ b/nixpkgs/nixos/modules/system/boot/initrd-ssh.nix
@@ -82,7 +82,7 @@ in
       type = types.bool;
       default = false;
       description = ''
-        Allow leaving {option}`config.boot.initrd.network.ssh` empty,
+        Allow leaving {option}`config.boot.initrd.network.ssh.hostKeys` empty,
         to deploy ssh host keys out of band.
       '';
     };
diff --git a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
index 03bff1dee5b9..694d34d1c059 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
+++ b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
@@ -196,8 +196,7 @@ def get_generations(profile: str | None = None) -> list[SystemIdentifier]:
         f"{NIX}/bin/nix-env",
         "--list-generations",
         "-p",
-        "/nix/var/nix/profiles/%s" % ("system-profiles/" + profile if profile else "system"),
-        "--option", "build-users-group", ""],
+        "/nix/var/nix/profiles/%s" % ("system-profiles/" + profile if profile else "system")],
         universal_newlines=True)
     gen_lines = gen_list.split('\n')
     gen_lines.pop()
diff --git a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
index cee8663f0040..e73048dc2ecb 100644
--- a/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
+++ b/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
@@ -323,15 +323,15 @@ in {
     assertions = [
       {
         assertion = (hasPrefix "/" efi.efiSysMountPoint);
-        message = "The ESP mount point '${efi.efiSysMountPoint}' must be an absolute path";
+        message = "The ESP mount point '${toString efi.efiSysMountPoint}' must be an absolute path";
       }
       {
         assertion = cfg.xbootldrMountPoint == null || (hasPrefix "/" cfg.xbootldrMountPoint);
-        message = "The XBOOTLDR mount point '${cfg.xbootldrMountPoint}' must be an absolute path";
+        message = "The XBOOTLDR mount point '${toString cfg.xbootldrMountPoint}' must be an absolute path";
       }
       {
         assertion = cfg.xbootldrMountPoint != efi.efiSysMountPoint;
-        message = "The XBOOTLDR mount point '${cfg.xbootldrMountPoint}' cannot be the same as the ESP mount point '${efi.efiSysMountPoint}'";
+        message = "The XBOOTLDR mount point '${toString cfg.xbootldrMountPoint}' cannot be the same as the ESP mount point '${toString efi.efiSysMountPoint}'";
       }
       {
         assertion = (config.boot.kernelPackages.kernel.features or { efiBootStub = true; }) ? efiBootStub;
diff --git a/nixpkgs/nixos/modules/system/boot/networkd.nix b/nixpkgs/nixos/modules/system/boot/networkd.nix
index 7f53efbf83f5..761bbe6e03d4 100644
--- a/nixpkgs/nixos/modules/system/boot/networkd.nix
+++ b/nixpkgs/nixos/modules/system/boot/networkd.nix
@@ -386,7 +386,7 @@ let
         (assertValueOneOf "UDP6ZeroChecksumRx" boolValues)
       ];
 
-      sectionL2TPSession = checkUnitConfig "L2TPSession" [
+      sectionL2TPSession = checkUnitConfigWithLegacyKey "l2tpSessionConfig" "L2TPSession" [
         (assertOnlyFields [
           "Name"
           "SessionId"
@@ -421,7 +421,7 @@ let
       # NOTE The PresharedKey directive is missing on purpose here, please
       # do not add it to this list. The nix store is world-readable,let's
       # refrain ourselves from providing a footgun.
-      sectionWireGuardPeer = checkUnitConfig "WireGuardPeer" [
+      sectionWireGuardPeer = checkUnitConfigWithLegacyKey "wireguardPeerConfig" "WireGuardPeer" [
         (assertOnlyFields [
           "PublicKey"
           "PresharedKeyFile"
@@ -712,7 +712,7 @@ let
         (assertValueOneOf "KeepConfiguration" (boolValues ++ ["static" "dhcp-on-stop" "dhcp"]))
       ];
 
-      sectionAddress = checkUnitConfig "Address" [
+      sectionAddress = checkUnitConfigWithLegacyKey "addressConfig" "Address" [
         (assertOnlyFields [
           "Address"
           "Peer"
@@ -737,7 +737,7 @@ let
         (assertValueOneOf "AutoJoin" boolValues)
       ];
 
-      sectionRoutingPolicyRule = checkUnitConfig "RoutingPolicyRule" [
+      sectionRoutingPolicyRule = checkUnitConfigWithLegacyKey "routingPolicyRuleConfig" "RoutingPolicyRule" [
         (assertOnlyFields [
           "TypeOfService"
           "From"
@@ -772,7 +772,7 @@ let
         (assertRange "SuppressInterfaceGroup" 0 2147483647)
       ];
 
-      sectionRoute = checkUnitConfig "Route" [
+      sectionRoute = checkUnitConfigWithLegacyKey "routeConfig" "Route" [
         (assertOnlyFields [
           "Gateway"
           "GatewayOnLink"
@@ -952,6 +952,7 @@ let
           "UseGateway"
           "UseRoutePrefix"
           "Token"
+          "UsePREF64"
         ])
         (assertValueOneOf "UseDNS" boolValues)
         (assertValueOneOf "UseDomains" (boolValues ++ ["route"]))
@@ -962,6 +963,7 @@ let
         (assertValueOneOf "UseMTU" boolValues)
         (assertValueOneOf "UseGateway" boolValues)
         (assertValueOneOf "UseRoutePrefix" boolValues)
+        (assertValueOneOf "UsePREF64" boolValues)
       ];
 
       sectionDHCPServer = checkUnitConfig "DHCPServer" [
@@ -1033,7 +1035,15 @@ let
         (assertValueOneOf "EmitDomains" boolValues)
       ];
 
-      sectionIPv6Prefix = checkUnitConfig "IPv6Prefix" [
+      sectionIPv6PREF64Prefix = checkUnitConfigWithLegacyKey "ipv6PREF64PrefixConfig" "IPv6PREF64Prefix" [
+        (assertOnlyFields [
+          "Prefix"
+          "LifetimeSec"
+        ])
+        (assertInt "LifetimeSec")
+      ];
+
+      sectionIPv6Prefix = checkUnitConfigWithLegacyKey "ipv6PrefixConfig" "IPv6Prefix" [
         (assertOnlyFields [
           "AddressAutoconfiguration"
           "OnLink"
@@ -1048,7 +1058,7 @@ let
         (assertValueOneOf "Assign" boolValues)
       ];
 
-      sectionIPv6RoutePrefix = checkUnitConfig "IPv6RoutePrefix" [
+      sectionIPv6RoutePrefix = checkUnitConfigWithLegacyKey "ipv6RoutePrefixConfig" "IPv6RoutePrefix" [
         (assertOnlyFields [
           "Route"
           "LifetimeSec"
@@ -1057,7 +1067,7 @@ let
         (assertInt "LifetimeSec")
       ];
 
-      sectionDHCPServerStaticLease = checkUnitConfig "DHCPServerStaticLease" [
+      sectionDHCPServerStaticLease = checkUnitConfigWithLegacyKey "dhcpServerStaticLeaseConfig" "DHCPServerStaticLease" [
         (assertOnlyFields [
           "MACAddress"
           "Address"
@@ -1104,7 +1114,7 @@ let
         (assertRange "Priority" 0 63)
       ];
 
-      sectionBridgeFDB = checkUnitConfig "BridgeFDB" [
+      sectionBridgeFDB = checkUnitConfigWithLegacyKey "bridgeFDBConfig" "BridgeFDB" [
         (assertOnlyFields [
           "MACAddress"
           "Destination"
@@ -1121,7 +1131,7 @@ let
         (assertValueOneOf "AssociatedWith" [ "use" "self" "master" "router" ])
       ];
 
-      sectionBridgeMDB = checkUnitConfig "BridgeMDB" [
+      sectionBridgeMDB = checkUnitConfigWithLegacyKey "bridgeMDBConfig" "BridgeMDB" [
         (assertOnlyFields [
           "MulticastGroupAddress"
           "VLANId"
@@ -1524,7 +1534,7 @@ let
         (assertRange "Weight" 1 1023)
       ];
 
-      sectionBridgeVLAN = checkUnitConfig "BridgeVLAN" [
+      sectionBridgeVLAN = checkUnitConfigWithLegacyKey "bridgeVLANConfig" "BridgeVLAN" [
         (assertOnlyFields [
           "VLAN"
           "EgressUntagged"
@@ -1627,34 +1637,21 @@ let
 
   };
 
-
-  l2tpSessionOptions = {
-    options = {
-      l2tpSessionConfig = mkOption {
-        default = {};
-        type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionL2TPSession;
-        description = ''
-          Each attribute in this set specifies an option in the
-          `[L2TPSession]` section of the unit.  See
-          {manpage}`systemd.netdev(5)` for details.
-        '';
-      };
+  mkSubsectionType = oldKey: checkF:
+    let
+      type = types.addCheck (types.attrsOf unitOption) checkF;
+    in type // {
+      merge = loc: defs:
+        let
+          final = type.merge loc defs;
+        in
+        if final?${oldKey}
+          then warn
+            "Using '${oldKey}' is deprecated! Move all attributes inside one level up and remove it."
+            final.${oldKey}
+        else
+          final;
     };
-  };
-
-  wireguardPeerOptions = {
-    options = {
-      wireguardPeerConfig = mkOption {
-        default = {};
-        type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionWireGuardPeer;
-        description = ''
-          Each attribute in this set specifies an option in the
-          `[WireGuardPeer]` section of the unit.  See
-          {manpage}`systemd.netdev(5)` for details.
-        '';
-      };
-    };
-  };
 
   netdevOptions = commonNetworkOptions // {
 
@@ -1805,12 +1802,12 @@ let
 
     l2tpSessions = mkOption {
       default = [];
-      example = [ { l2tpSessionConfig={
+      example = [ {
         SessionId = 25;
         PeerSessionId = 26;
         Name = "l2tp-sess";
-      };}];
-      type = with types; listOf (submodule l2tpSessionOptions);
+      }];
+      type = types.listOf (mkSubsectionType "l2tpSessionConfig" check.netdev.sectionL2TPSession);
       description = ''
         Each item in this array specifies an option in the
         `[L2TPSession]` section of the unit. See
@@ -1838,14 +1835,14 @@ let
 
     wireguardPeers = mkOption {
       default = [];
-      example = [ { wireguardPeerConfig={
+      example = [ {
         Endpoint = "192.168.1.1:51820";
         PublicKey = "27s0OvaBBdHoJYkH9osZpjpgSOVNw+RaKfboT/Sfq0g=";
         PresharedKeyFile = "/etc/wireguard/psk.key";
         AllowedIPs = [ "10.0.0.1/32" ];
         PersistentKeepalive = 15;
-      };}];
-      type = with types; listOf (submodule wireguardPeerOptions);
+      } ];
+      type = types.listOf (mkSubsectionType "wireguardPeerConfig" check.netdev.sectionWireGuardPeer);
       description = ''
         Each item in this array specifies an option in the
         `[WireGuardPeer]` section of the unit. See
@@ -1917,143 +1914,6 @@ let
 
   };
 
-  addressOptions = {
-    options = {
-      addressConfig = mkOption {
-        example = { Address = "192.168.0.100/24"; };
-        type = types.addCheck (types.attrsOf unitOption) check.network.sectionAddress;
-        description = ''
-          Each attribute in this set specifies an option in the
-          `[Address]` section of the unit.  See
-          {manpage}`systemd.network(5)` for details.
-        '';
-      };
-    };
-  };
-
-  routingPolicyRulesOptions = {
-    options = {
-      routingPolicyRuleConfig = mkOption {
-        default = { };
-        example = { Table = 10; IncomingInterface = "eth1"; Family = "both"; };
-        type = types.addCheck (types.attrsOf unitOption) check.network.sectionRoutingPolicyRule;
-        description = ''
-          Each attribute in this set specifies an option in the
-          `[RoutingPolicyRule]` section of the unit.  See
-          {manpage}`systemd.network(5)` for details.
-        '';
-      };
-    };
-  };
-
-  routeOptions = {
-    options = {
-      routeConfig = mkOption {
-        default = {};
-        example = { Gateway = "192.168.0.1"; };
-        type = types.addCheck (types.attrsOf unitOption) check.network.sectionRoute;
-        description = ''
-          Each attribute in this set specifies an option in the
-          `[Route]` section of the unit.  See
-          {manpage}`systemd.network(5)` for details.
-        '';
-      };
-    };
-  };
-
-  ipv6PrefixOptions = {
-    options = {
-      ipv6PrefixConfig = mkOption {
-        default = {};
-        example = { Prefix = "fd00::/64"; };
-        type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6Prefix;
-        description = ''
-          Each attribute in this set specifies an option in the
-          `[IPv6Prefix]` section of the unit.  See
-          {manpage}`systemd.network(5)` for details.
-        '';
-      };
-    };
-  };
-
-  ipv6RoutePrefixOptions = {
-    options = {
-      ipv6RoutePrefixConfig = mkOption {
-        default = {};
-        example = { Route = "fd00::/64"; };
-        type = types.addCheck (types.attrsOf unitOption) check.network.sectionIPv6RoutePrefix;
-        description = ''
-          Each attribute in this set specifies an option in the
-          `[IPv6RoutePrefix]` section of the unit.  See
-          {manpage}`systemd.network(5)` for details.
-        '';
-      };
-    };
-  };
-
-  dhcpServerStaticLeaseOptions = {
-    options = {
-      dhcpServerStaticLeaseConfig = mkOption {
-        default = {};
-        example = { MACAddress = "65:43:4a:5b:d8:5f"; Address = "192.168.1.42"; };
-        type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPServerStaticLease;
-        description = ''
-          Each attribute in this set specifies an option in the
-          `[DHCPServerStaticLease]` section of the unit.  See
-          {manpage}`systemd.network(5)` for details.
-
-          Make sure to configure the corresponding client interface to use
-          `ClientIdentifier=mac`.
-        '';
-      };
-    };
-  };
-
-  bridgeFDBOptions = {
-    options = {
-      bridgeFDBConfig = mkOption {
-        default = {};
-        example = { MACAddress = "65:43:4a:5b:d8:5f"; Destination = "192.168.1.42"; VNI = 20; };
-        type = types.addCheck (types.attrsOf unitOption) check.network.sectionBridgeFDB;
-        description = ''
-          Each attribute in this set specifies an option in the
-          `[BridgeFDB]` section of the unit.  See
-          {manpage}`systemd.network(5)` for details.
-        '';
-      };
-    };
-  };
-
-  bridgeMDBOptions = {
-    options = {
-      bridgeMDBConfig = mkOption {
-        default = {};
-        example = { MulticastGroupAddress = "ff02::1:2:3:4"; VLANId = 10; };
-        type = types.addCheck (types.attrsOf unitOption) check.network.sectionBridgeMDB;
-        description = ''
-          Each attribute in this set specifies an option in the
-          `[BridgeMDB]` section of the unit.  See
-          {manpage}`systemd.network(5)` for details.
-        '';
-      };
-    };
-  };
-
-  bridgeVLANOptions = {
-    options = {
-      bridgeVLANConfig = mkOption {
-        default = {};
-        example = { VLAN = 20; };
-        type = types.addCheck (types.attrsOf unitOption) check.network.sectionBridgeVLAN;
-        description = ''
-          Each attribute in this set specifies an option in the
-          `[BridgeVLAN]` section of the unit.  See
-          {manpage}`systemd.network(5)` for details.
-        '';
-      };
-    };
-  };
-
   networkOptions = commonNetworkOptions // {
 
     linkConfig = mkOption {
@@ -2163,10 +2023,20 @@ let
       '';
     };
 
+    ipv6PREF64Prefixes = mkOption {
+      default = [];
+      example = [ { Prefix = "64:ff9b::/96"; } ];
+      type = types.listOf (mkSubsectionType "ipv6PREF64PrefixConfig" check.network.sectionIPv6PREF64Prefix);
+      description = ''
+        A list of IPv6PREF64Prefix sections to be added to the unit. See
+        {manpage}`systemd.network(5)` for details.
+      '';
+    };
+
     dhcpServerStaticLeases = mkOption {
       default = [];
-      example = [ { dhcpServerStaticLeaseConfig = { MACAddress = "65:43:4a:5b:d8:5f"; Address = "192.168.1.42"; }; } ];
-      type = with types; listOf (submodule dhcpServerStaticLeaseOptions);
+      example = [ { MACAddress = "65:43:4a:5b:d8:5f"; Address = "192.168.1.42"; } ];
+      type = types.listOf (mkSubsectionType "dhcpServerStaticLeaseConfig" check.network.sectionDHCPServerStaticLease);
       description = ''
         A list of DHCPServerStaticLease sections to be added to the unit.  See
         {manpage}`systemd.network(5)` for details.
@@ -2175,8 +2045,8 @@ let
 
     ipv6Prefixes = mkOption {
       default = [];
-      example = [ { ipv6PrefixConfig = { AddressAutoconfiguration = true; OnLink = true; }; } ];
-      type = with types; listOf (submodule ipv6PrefixOptions);
+      example = [ { AddressAutoconfiguration = true; OnLink = true; } ];
+      type = types.listOf (mkSubsectionType "ipv6PrefixConfig" check.network.sectionIPv6Prefix);
       description = ''
         A list of ipv6Prefix sections to be added to the unit.  See
         {manpage}`systemd.network(5)` for details.
@@ -2185,8 +2055,8 @@ let
 
     ipv6RoutePrefixes = mkOption {
       default = [];
-      example = [ { ipv6RoutePrefixConfig = { Route = "fd00::/64"; LifetimeSec = 3600; }; } ];
-      type = with types; listOf (submodule ipv6RoutePrefixOptions);
+      example = [ { Route = "fd00::/64"; LifetimeSec = 3600; } ];
+      type = types.listOf (mkSubsectionType "ipv6RoutePrefixConfig" check.network.sectionIPv6RoutePrefix);
       description = ''
         A list of ipv6RoutePrefix sections to be added to the unit.  See
         {manpage}`systemd.network(5)` for details.
@@ -2206,8 +2076,8 @@ let
 
     bridgeFDBs = mkOption {
       default = [];
-      example = [ { bridgeFDBConfig = { MACAddress = "90:e2:ba:43:fc:71"; Destination = "192.168.100.4"; VNI = 3600; }; } ];
-      type = with types; listOf (submodule bridgeFDBOptions);
+      example = [ { MACAddress = "90:e2:ba:43:fc:71"; Destination = "192.168.100.4"; VNI = 3600; } ];
+      type = types.listOf (mkSubsectionType "bridgeFDBConfig" check.network.sectionBridgeFDB);
       description = ''
         A list of BridgeFDB sections to be added to the unit.  See
         {manpage}`systemd.network(5)` for details.
@@ -2216,8 +2086,8 @@ let
 
     bridgeMDBs = mkOption {
       default = [];
-      example = [ { bridgeMDBConfig = { MulticastGroupAddress = "ff02::1:2:3:4"; VLANId = 10; } ; } ];
-      type = with types; listOf (submodule bridgeMDBOptions);
+      example = [ { MulticastGroupAddress = "ff02::1:2:3:4"; VLANId = 10; } ];
+      type = types.listOf (mkSubsectionType "bridgeMDBConfig" check.network.sectionBridgeMDB);
       description = ''
         A list of BridgeMDB sections to be added to the unit.  See
         {manpage}`systemd.network(5)` for details.
@@ -2534,8 +2404,8 @@ let
 
     bridgeVLANs = mkOption {
       default = [];
-      example = [ { bridgeVLANConfig = { VLAN = "10-20"; }; } ];
-      type = with types; listOf (submodule bridgeVLANOptions);
+      example = [ { VLAN = "10-20"; } ];
+      type = types.listOf (mkSubsectionType "bridgeVLANConfig" check.network.sectionBridgeVLAN);
       description = ''
         A list of BridgeVLAN sections to be added to the unit.  See
         {manpage}`systemd.network(5)` for details.
@@ -2685,7 +2555,8 @@ let
 
     addresses = mkOption {
       default = [ ];
-      type = with types; listOf (submodule addressOptions);
+      example = [ { Address = "192.168.0.100/24"; } ];
+      type = types.listOf (mkSubsectionType "addressConfig" check.network.sectionAddress);
       description = ''
         A list of address sections to be added to the unit.  See
         {manpage}`systemd.network(5)` for details.
@@ -2694,7 +2565,8 @@ let
 
     routingPolicyRules = mkOption {
       default = [ ];
-      type = with types; listOf (submodule routingPolicyRulesOptions);
+      example = [ { Table = 10; IncomingInterface = "eth1"; Family = "both"; } ];
+      type = types.listOf (mkSubsectionType "routingPolicyRuleConfig" check.network.sectionRoutingPolicyRule);
       description = ''
         A list of routing policy rules sections to be added to the unit.  See
         {manpage}`systemd.network(5)` for details.
@@ -2703,7 +2575,8 @@ let
 
     routes = mkOption {
       default = [ ];
-      type = with types; listOf (submodule routeOptions);
+      example = [ { Gateway = "192.168.0.1"; } ];
+      type = types.listOf (mkSubsectionType "routeConfig" check.network.sectionRoute);
       description = ''
         A list of route sections to be added to the unit.  See
         {manpage}`systemd.network(5)` for details.
diff --git a/nixpkgs/nixos/modules/system/boot/resolved.nix b/nixpkgs/nixos/modules/system/boot/resolved.nix
index 64a15179438f..b658a7a2dc05 100644
--- a/nixpkgs/nixos/modules/system/boot/resolved.nix
+++ b/nixpkgs/nixos/modules/system/boot/resolved.nix
@@ -7,6 +7,20 @@ let
   dnsmasqResolve = config.services.dnsmasq.enable &&
                    config.services.dnsmasq.resolveLocalQueries;
 
+  resolvedConf = ''
+    [Resolve]
+    ${optionalString (config.networking.nameservers != [])
+      "DNS=${concatStringsSep " " config.networking.nameservers}"}
+    ${optionalString (cfg.fallbackDns != null)
+      "FallbackDNS=${concatStringsSep " " cfg.fallbackDns}"}
+    ${optionalString (cfg.domains != [])
+      "Domains=${concatStringsSep " " cfg.domains}"}
+    LLMNR=${cfg.llmnr}
+    DNSSEC=${cfg.dnssec}
+    DNSOverTLS=${cfg.dnsovertls}
+    ${config.services.resolved.extraConfig}
+  '';
+
 in
 {
 
@@ -126,60 +140,87 @@ in
       '';
     };
 
-  };
-
-  config = mkIf cfg.enable {
-
-    assertions = [
-      { assertion = !config.networking.useHostResolvConf;
-        message = "Using host resolv.conf is not supported with systemd-resolved";
-      }
-    ];
-
-    users.users.systemd-resolve.group = "systemd-resolve";
-
-    # add resolve to nss hosts database if enabled and nscd enabled
-    # system.nssModules is configured in nixos/modules/system/boot/systemd.nix
-    # added with order 501 to allow modules to go before with mkBefore
-    system.nssDatabases.hosts = (mkOrder 501 ["resolve [!UNAVAIL=return]"]);
-
-    systemd.additionalUpstreamSystemUnits = [
-      "systemd-resolved.service"
-    ];
-
-    systemd.services.systemd-resolved = {
-      wantedBy = [ "multi-user.target" ];
-      aliases = [ "dbus-org.freedesktop.resolve1.service" ];
-      restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ];
-    };
-
-    environment.etc = {
-      "systemd/resolved.conf".text = ''
-        [Resolve]
-        ${optionalString (config.networking.nameservers != [])
-          "DNS=${concatStringsSep " " config.networking.nameservers}"}
-        ${optionalString (cfg.fallbackDns != null)
-          "FallbackDNS=${concatStringsSep " " cfg.fallbackDns}"}
-        ${optionalString (cfg.domains != [])
-          "Domains=${concatStringsSep " " cfg.domains}"}
-        LLMNR=${cfg.llmnr}
-        DNSSEC=${cfg.dnssec}
-        DNSOverTLS=${cfg.dnsovertls}
-        ${config.services.resolved.extraConfig}
+    boot.initrd.services.resolved.enable = mkOption {
+      default = config.boot.initrd.systemd.network.enable;
+      defaultText = "config.boot.initrd.systemd.network.enable";
+      description = ''
+        Whether to enable resolved for stage 1 networking.
+        Uses the toplevel 'services.resolved' options for 'resolved.conf'
       '';
-
-      # symlink the dynamic stub resolver of resolv.conf as recommended by upstream:
-      # https://www.freedesktop.org/software/systemd/man/systemd-resolved.html#/etc/resolv.conf
-      "resolv.conf".source = "/run/systemd/resolve/stub-resolv.conf";
-    } // optionalAttrs dnsmasqResolve {
-      "dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf";
     };
 
-    # If networkmanager is enabled, ask it to interface with resolved.
-    networking.networkmanager.dns = "systemd-resolved";
-
-    networking.resolvconf.package = pkgs.systemd;
-
   };
 
+  config = mkMerge [
+    (mkIf cfg.enable {
+
+      assertions = [
+        { assertion = !config.networking.useHostResolvConf;
+          message = "Using host resolv.conf is not supported with systemd-resolved";
+        }
+      ];
+
+      users.users.systemd-resolve.group = "systemd-resolve";
+
+      # add resolve to nss hosts database if enabled and nscd enabled
+      # system.nssModules is configured in nixos/modules/system/boot/systemd.nix
+      # added with order 501 to allow modules to go before with mkBefore
+      system.nssDatabases.hosts = (mkOrder 501 ["resolve [!UNAVAIL=return]"]);
+
+      systemd.additionalUpstreamSystemUnits = [
+        "systemd-resolved.service"
+      ];
+
+      systemd.services.systemd-resolved = {
+        wantedBy = [ "sysinit.target" ];
+        aliases = [ "dbus-org.freedesktop.resolve1.service" ];
+        restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ];
+      };
+
+      environment.etc = {
+        "systemd/resolved.conf".text = resolvedConf;
+
+        # symlink the dynamic stub resolver of resolv.conf as recommended by upstream:
+        # https://www.freedesktop.org/software/systemd/man/systemd-resolved.html#/etc/resolv.conf
+        "resolv.conf".source = "/run/systemd/resolve/stub-resolv.conf";
+      } // optionalAttrs dnsmasqResolve {
+        "dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf";
+      };
+
+      # If networkmanager is enabled, ask it to interface with resolved.
+      networking.networkmanager.dns = "systemd-resolved";
+
+      networking.resolvconf.package = pkgs.systemd;
+
+    })
+
+    (mkIf config.boot.initrd.services.resolved.enable {
+
+      assertions = [
+        {
+          assertion = config.boot.initrd.systemd.enable;
+          message = "'boot.initrd.services.resolved.enable' can only be enabled with systemd stage 1.";
+        }
+      ];
+
+      boot.initrd.systemd = {
+        contents = {
+          "/etc/tmpfiles.d/resolv.conf".text =
+            "L /etc/resolv.conf - - - - /run/systemd/resolve/stub-resolv.conf";
+          "/etc/systemd/resolved.conf".text = resolvedConf;
+        };
+
+        additionalUpstreamUnits = ["systemd-resolved.service"];
+        users.systemd-resolve = {};
+        groups.systemd-resolve = {};
+        storePaths = ["${config.boot.initrd.systemd.package}/lib/systemd/systemd-resolved"];
+        services.systemd-resolved = {
+          wantedBy = ["sysinit.target"];
+          aliases = [ "dbus-org.freedesktop.resolve1.service" ];
+        };
+      };
+
+    })
+  ];
+
 }
diff --git a/nixpkgs/nixos/modules/system/boot/stage-1-init.sh b/nixpkgs/nixos/modules/system/boot/stage-1-init.sh
index 59cf1a47fb7f..23e9df2189e7 100644
--- a/nixpkgs/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixpkgs/nixos/modules/system/boot/stage-1-init.sh
@@ -576,6 +576,7 @@ while read -u 3 mountPoint; do
       mount -t "$fsType" /dev/root /tmp-iso
       mountFS tmpfs /iso size="$fsSize" tmpfs
 
+      echo "copying ISO contents to RAM..."
       cp -r /tmp-iso/* /mnt-root/iso/
 
       umount /tmp-iso
diff --git a/nixpkgs/nixos/modules/system/boot/systemd.nix b/nixpkgs/nixos/modules/system/boot/systemd.nix
index c82924763d5e..14a4ab596b52 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd.nix
@@ -503,8 +503,8 @@ in
     environment.systemPackages = [ cfg.package ];
 
     environment.etc = let
-      # generate contents for /etc/systemd/system-${type} from attrset of links and packages
-      hooks = type: links: pkgs.runCommand "system-${type}" {
+      # generate contents for /etc/systemd/${dir} from attrset of links and packages
+      hooks = dir: links: pkgs.runCommand "${dir}" {
           preferLocalBuild = true;
           packages = cfg.packages;
       } ''
@@ -512,7 +512,7 @@ in
         mkdir -p $out
         for package in $packages
         do
-          for hook in $package/lib/systemd/system-${type}/*
+          for hook in $package/lib/systemd/${dir}/*
           do
             ln -s $hook $out/
           done
@@ -562,8 +562,9 @@ in
         ${cfg.sleep.extraConfig}
       '';
 
-      "systemd/system-generators" = { source = hooks "generators" cfg.generators; };
-      "systemd/system-shutdown" = { source = hooks "shutdown" cfg.shutdown; };
+      "systemd/user-generators" = { source = hooks "user-generators" cfg.user.generators; };
+      "systemd/system-generators" = { source = hooks "system-generators" cfg.generators; };
+      "systemd/system-shutdown" = { source = hooks "system-shutdown" cfg.shutdown; };
     });
 
     services.dbus.enable = true;
diff --git a/nixpkgs/nixos/modules/system/boot/systemd/coredump.nix b/nixpkgs/nixos/modules/system/boot/systemd/coredump.nix
index 1f29f6686d0d..ccf5d449b94a 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd/coredump.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd/coredump.nix
@@ -53,7 +53,7 @@ in {
           pkgs.substitute {
             src = "${systemd}/example/sysctl.d/50-coredump.conf";
             substitutions = [
-              "--replace"
+              "--replace-fail"
               "${systemd}"
               "${pkgs.symlinkJoin { name = "systemd"; paths = [ systemd ]; }}"
             ];
diff --git a/nixpkgs/nixos/modules/system/boot/systemd/sysusers.nix b/nixpkgs/nixos/modules/system/boot/systemd/sysusers.nix
index de7000970597..476251e14045 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd/sysusers.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd/sysusers.nix
@@ -12,7 +12,7 @@ let
     ${lib.concatLines (lib.mapAttrsToList
       (username: opts:
         let
-          uid = if opts.uid == null then "-" else toString opts.uid;
+          uid = if opts.uid == null then "/var/lib/nixos/uid/${username}" else toString opts.uid;
         in
           ''u ${username} ${uid}:${opts.group} "${opts.description}" ${opts.home} ${utils.toShellPath opts.shell}''
       )
@@ -21,7 +21,7 @@ let
 
     # Groups
     ${lib.concatLines (lib.mapAttrsToList
-      (groupname: opts: ''g ${groupname} ${if opts.gid == null then "-" else toString opts.gid}'') userCfg.groups)
+      (groupname: opts: ''g ${groupname} ${if opts.gid == null then "/var/lib/nixos/gid/${groupname}" else toString opts.gid}'') userCfg.groups)
     }
 
     # Group membership
@@ -106,6 +106,23 @@ in
             };
           })
           (lib.filterAttrs (_username: opts: opts.home != "/var/empty") userCfg.users);
+
+        # Create uid/gid marker files for those without an explicit id
+        tmpfiles.settings.nixos-uid = lib.mapAttrs'
+          (username: opts: lib.nameValuePair "/var/lib/nixos/uid/${username}" {
+            f = {
+              user = username;
+            };
+          })
+          (lib.filterAttrs (_username: opts: opts.uid == null) userCfg.users);
+
+        tmpfiles.settings.nixos-gid = lib.mapAttrs'
+          (groupname: opts: lib.nameValuePair "/var/lib/nixos/gid/${groupname}" {
+            f = {
+              group = groupname;
+            };
+          })
+          (lib.filterAttrs (_groupname: opts: opts.gid == null) userCfg.groups);
       })
 
       (lib.mkIf config.users.mutableUsers {
diff --git a/nixpkgs/nixos/modules/system/boot/systemd/user.nix b/nixpkgs/nixos/modules/system/boot/systemd/user.nix
index 2685cf7e283a..53fca631678c 100644
--- a/nixpkgs/nixos/modules/system/boot/systemd/user.nix
+++ b/nixpkgs/nixos/modules/system/boot/systemd/user.nix
@@ -144,6 +144,18 @@ in {
       };
     };
 
+    systemd.user.generators = mkOption {
+      type = types.attrsOf types.path;
+      default = {};
+      example = { systemd-gpt-auto-generator = "/dev/null"; };
+      description = ''
+        Definition of systemd generators; see {manpage}`systemd.generator(5)`.
+
+        For each `NAME = VALUE` pair of the attrSet, a link is generated from
+        `/etc/systemd/user-generators/NAME` to `VALUE`.
+      '';
+    };
+
     systemd.additionalUpstreamUserUnits = mkOption {
       default = [];
       type = types.listOf types.str;