1 # | Build a script to install and start a set of systemd units on any
2 # systemd-based system.
4 # Creates a symlink at /etc/systemd-static/${namespace} for slightly
13 { units # : AttrSet String (Either Path { path : Path, wanted-by : [ String ] })
14 # ^ A set whose names are unit names and values are
15 # either paths to the corresponding unit files or a set
16 # containing the path and the list of units this unit
17 # should be wanted-by (none by default).
19 # The names should include the unit suffix
21 , namespace # : String
22 # The namespace for the unit files, to allow for
23 # multiple independent unit sets managed by
24 # `setupSystemdUnits`.
26 let static = runCommand "systemd-static" {}
29 ${lib.concatStringsSep "\n" (lib.mapAttrsToList (nm: file:
30 "ln -sv ${file.path or file} $out/${nm}"
33 add-unit-snippet = name: file:
35 oldUnit=$(readlink -f "$unitDir/${name}" || echo "$unitDir/${name}")
36 if [ -f "$oldUnit" -a "$oldUnit" != "${file.path or file}" ]; then
37 unitsToStop+=("${name}")
39 ln -sf "/etc/systemd-static/${namespace}/${name}" \
40 "$unitDir/.${name}.tmp"
41 mv -T "$unitDir/.${name}.tmp" "$unitDir/${name}"
42 ${lib.concatStringsSep "\n" (map (unit:
44 mkdir -p "$unitDir/${unit}.wants"
46 "$unitDir/${unit}.wants/.${name}.tmp"
47 mv -T "$unitDir/${unit}.wants/.${name}.tmp" \
48 "$unitDir/${unit}.wants/${name}"
50 ) file.wanted-by or [])}
51 unitsToStart+=("${name}")
54 writeScriptBin "setup-systemd-units"
57 export PATH=${coreutils}/bin:${systemd}/bin
59 unitDir=/etc/systemd/system
60 if [ ! -w "$unitDir" ]; then
61 unitDir=/nix/var/nix/profiles/default/lib/systemd/system
64 declare -a unitsToStop unitsToStart
66 oldStatic=$(readlink -f /etc/systemd-static/${namespace} || true)
67 if [ "$oldStatic" != "${static}" ]; then
68 ${lib.concatStringsSep "\n"
69 (lib.mapAttrsToList add-unit-snippet units)}
70 if [ ''${#unitsToStop[@]} -ne 0 ]; then
71 echo "Stopping unit(s) ''${unitsToStop[@]}" >&2
72 systemctl stop "''${unitsToStop[@]}"
74 mkdir -p /etc/systemd-static
75 ln -sfT ${static} /etc/systemd-static/.${namespace}.tmp
76 mv -T /etc/systemd-static/.${namespace}.tmp /etc/systemd-static/${namespace}
77 systemctl daemon-reload
78 echo "Starting unit(s) ''${unitsToStart[@]}" >&2
79 systemctl start "''${unitsToStart[@]}"
81 echo "Units unchanged, doing nothing" >&2