diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix index 21ee33a691a0..0221374ab835 100644 --- a/nixos/modules/system/boot/networkd.nix +++ b/nixos/modules/system/boot/networkd.nix @@ -2,6 +2,7 @@ with lib; with import ./systemd-unit-options.nix { inherit config lib; }; +with import ./systemd-lib.nix { inherit config lib pkgs; }; let @@ -632,6 +633,9 @@ in // mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.netdevs // mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.networks; + environment.etc."systemd/network".source = + generateUnits "network" cfg.units [] []; + users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network; users.extraGroups.systemd-network.gid = config.ids.gids.systemd-network; diff --git a/nixos/modules/system/boot/systemd-lib.nix b/nixos/modules/system/boot/systemd-lib.nix new file mode 100644 index 000000000000..e8cfd3395cb0 --- /dev/null +++ b/nixos/modules/system/boot/systemd-lib.nix @@ -0,0 +1,118 @@ +{ config, lib, pkgs }: + +with lib; + +let cfg = config.systemd; in + +rec { + + shellEscape = s: (replaceChars [ "\\" ] [ "\\\\" ] s); + + makeUnit = name: unit: + let + pathSafeName = lib.replaceChars ["@" ":" "\\"] ["-" "-" "-"] name; + in + if unit.enable then + pkgs.runCommand "unit-${pathSafeName}" { preferLocalBuild = true; inherit (unit) text; } + '' + mkdir -p $out + echo -n "$text" > $out/${shellEscape name} + '' + else + pkgs.runCommand "unit-${pathSafeName}-disabled" { preferLocalBuild = true; } + '' + mkdir -p $out + ln -s /dev/null $out/${shellEscape name} + ''; + + generateUnits = type: units: upstreamUnits: upstreamWants: + pkgs.runCommand "${type}-units" { preferLocalBuild = true; } '' + mkdir -p $out + + # Copy the upstream systemd units we're interested in. + for i in ${toString upstreamUnits}; do + fn=${cfg.package}/example/systemd/${type}/$i + if ! [ -e $fn ]; then echo "missing $fn"; false; fi + if [ -L $fn ]; then + target="$(readlink "$fn")" + if [ ''${target:0:3} = ../ ]; then + ln -s "$(readlink -f "$fn")" $out/ + else + cp -pd $fn $out/ + fi + else + ln -s $fn $out/ + fi + done + + # Copy .wants links, but only those that point to units that + # we're interested in. + for i in ${toString upstreamWants}; do + fn=${cfg.package}/example/systemd/${type}/$i + if ! [ -e $fn ]; then echo "missing $fn"; false; fi + x=$out/$(basename $fn) + mkdir $x + for i in $fn/*; do + y=$x/$(basename $i) + cp -pd $i $y + if ! [ -e $y ]; then rm $y; fi + done + done + + # Symlink all units provided listed in systemd.packages. + for i in ${toString cfg.packages}; do + for fn in $i/etc/systemd/${type}/* $i/lib/systemd/${type}/*; do + if ! [[ "$fn" =~ .wants$ ]]; then + ln -s $fn $out/ + fi + done + done + + # Symlink all units defined by systemd.units. If these are also + # provided by systemd or systemd.packages, then add them as + # .d/overrides.conf, which makes them extend the + # upstream unit. + for i in ${toString (mapAttrsToList (n: v: v.unit) units)}; do + fn=$(basename $i/*) + if [ -e $out/$fn ]; then + if [ "$(readlink -f $i/$fn)" = /dev/null ]; then + ln -sfn /dev/null $out/$fn + else + mkdir $out/$fn.d + ln -s $i/$fn $out/$fn.d/overrides.conf + fi + else + ln -fs $i/$fn $out/ + fi + done + + # Created .wants and .requires symlinks from the wantedBy and + # requiredBy options. + ${concatStrings (mapAttrsToList (name: unit: + concatMapStrings (name2: '' + mkdir -p $out/'${name2}.wants' + ln -sfn '../${name}' $out/'${name2}.wants'/ + '') unit.wantedBy) units)} + + ${concatStrings (mapAttrsToList (name: unit: + concatMapStrings (name2: '' + mkdir -p $out/'${name2}.requires' + ln -sfn '../${name}' $out/'${name2}.requires'/ + '') unit.requiredBy) units)} + + ${optionalString (type == "system") '' + # Stupid misc. symlinks. + ln -s ${cfg.defaultUnit} $out/default.target + + ln -s rescue.target $out/kbrequest.target + + mkdir -p $out/getty.target.wants/ + ln -s ../autovt@tty1.service $out/getty.target.wants/ + + ln -s ../local-fs.target ../remote-fs.target ../network.target \ + ../nss-lookup.target ../nss-user-lookup.target ../swap.target \ + $out/multi-user.target.wants/ + ''} + ''; # */ + +} diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 12de5c9b16fb..78aac7fe96f1 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -3,6 +3,7 @@ with utils; with lib; with import ./systemd-unit-options.nix { inherit config lib; }; +with import ./systemd-lib.nix { inherit config lib pkgs; }; let @@ -10,24 +11,6 @@ let systemd = cfg.package; - - makeUnit = name: unit: - let - pathSafeName = lib.replaceChars ["@" ":" "\\"] ["-" "-" "-"] name; - in - if unit.enable then - pkgs.runCommand "unit-${pathSafeName}" { preferLocalBuild = true; inherit (unit) text; } - '' - mkdir -p $out - echo -n "$text" > $out/${shellEscape name} - '' - else - pkgs.runCommand "unit-${pathSafeName}-disabled" { preferLocalBuild = true; } - '' - mkdir -p $out - ln -s /dev/null $out/${shellEscape name} - ''; - upstreamSystemUnits = [ # Targets. "basic.target" @@ -190,8 +173,6 @@ let "timers.target" ]; - shellEscape = s: (replaceChars [ "\\" ] [ "\\\\" ] s); - makeJobScript = name: text: let x = pkgs.writeTextFile { name = "unit-script"; executable = true; destination = "/bin/${shellEscape name}"; inherit text; }; in "${x}/bin/${shellEscape name}"; @@ -393,96 +374,6 @@ let ${attrsToSection def.matchConfig} ''; - generateUnits = type: units: upstreamUnits: upstreamWants: - pkgs.runCommand "${type}-units" { preferLocalBuild = true; } '' - mkdir -p $out - - # Copy the upstream systemd units we're interested in. - for i in ${toString upstreamUnits}; do - fn=${systemd}/example/systemd/${type}/$i - if ! [ -e $fn ]; then echo "missing $fn"; false; fi - if [ -L $fn ]; then - target="$(readlink "$fn")" - if [ ''${target:0:3} = ../ ]; then - ln -s "$(readlink -f "$fn")" $out/ - else - cp -pd $fn $out/ - fi - else - ln -s $fn $out/ - fi - done - - # Copy .wants links, but only those that point to units that - # we're interested in. - for i in ${toString upstreamWants}; do - fn=${systemd}/example/systemd/${type}/$i - if ! [ -e $fn ]; then echo "missing $fn"; false; fi - x=$out/$(basename $fn) - mkdir $x - for i in $fn/*; do - y=$x/$(basename $i) - cp -pd $i $y - if ! [ -e $y ]; then rm $y; fi - done - done - - # Symlink all units provided listed in systemd.packages. - for i in ${toString cfg.packages}; do - for fn in $i/etc/systemd/${type}/* $i/lib/systemd/${type}/*; do - if ! [[ "$fn" =~ .wants$ ]]; then - ln -s $fn $out/ - fi - done - done - - # Symlink all units defined by systemd.units. If these are also - # provided by systemd or systemd.packages, then add them as - # .d/overrides.conf, which makes them extend the - # upstream unit. - for i in ${toString (mapAttrsToList (n: v: v.unit) units)}; do - fn=$(basename $i/*) - if [ -e $out/$fn ]; then - if [ "$(readlink -f $i/$fn)" = /dev/null ]; then - ln -sfn /dev/null $out/$fn - else - mkdir $out/$fn.d - ln -s $i/$fn $out/$fn.d/overrides.conf - fi - else - ln -fs $i/$fn $out/ - fi - done - - # Created .wants and .requires symlinks from the wantedBy and - # requiredBy options. - ${concatStrings (mapAttrsToList (name: unit: - concatMapStrings (name2: '' - mkdir -p $out/'${name2}.wants' - ln -sfn '../${name}' $out/'${name2}.wants'/ - '') unit.wantedBy) units)} - - ${concatStrings (mapAttrsToList (name: unit: - concatMapStrings (name2: '' - mkdir -p $out/'${name2}.requires' - ln -sfn '../${name}' $out/'${name2}.requires'/ - '') unit.requiredBy) units)} - - ${optionalString (type == "system") '' - # Stupid misc. symlinks. - ln -s ${cfg.defaultUnit} $out/default.target - - ln -s rescue.target $out/kbrequest.target - - mkdir -p $out/getty.target.wants/ - ln -s ../autovt@tty1.service $out/getty.target.wants/ - - ln -s ../local-fs.target ../remote-fs.target ../network.target \ - ../nss-lookup.target ../nss-user-lookup.target ../swap.target \ - $out/multi-user.target.wants/ - ''} - ''; # */ - in { @@ -731,10 +622,6 @@ in environment.etc."systemd/system".source = generateUnits "system" cfg.units upstreamSystemUnits upstreamSystemWants; - # FIXME: move to networkd.nix. - environment.etc."systemd/network".source = - generateUnits "network" cfg.network.units [] []; - environment.etc."systemd/user".source = generateUnits "user" cfg.user.units upstreamUserUnits [];