summary refs log tree commit diff
path: root/nixos/modules/system/boot/systemd-lib.nix
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2015-04-20 11:31:17 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2015-04-20 11:32:29 +0200
commit56f66dad97758a049f8f05e734cf41d936f7b476 (patch)
tree6c70789838256aa7d5a030c7e4d25ec7b27ad6af /nixos/modules/system/boot/systemd-lib.nix
parent51fe214218512fbd277ede0075cccac9f9d2b562 (diff)
downloadnixlib-56f66dad97758a049f8f05e734cf41d936f7b476.tar
nixlib-56f66dad97758a049f8f05e734cf41d936f7b476.tar.gz
nixlib-56f66dad97758a049f8f05e734cf41d936f7b476.tar.bz2
nixlib-56f66dad97758a049f8f05e734cf41d936f7b476.tar.lz
nixlib-56f66dad97758a049f8f05e734cf41d936f7b476.tar.xz
nixlib-56f66dad97758a049f8f05e734cf41d936f7b476.tar.zst
nixlib-56f66dad97758a049f8f05e734cf41d936f7b476.zip
Fix #7476
Diffstat (limited to 'nixos/modules/system/boot/systemd-lib.nix')
-rw-r--r--nixos/modules/system/boot/systemd-lib.nix118
1 files changed, 118 insertions, 0 deletions
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
+      # <unit-name>.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/
+      ''}
+    ''; # */
+
+}