Skip to content

Commit

Permalink
Add setupSystemdUnits function.
Browse files Browse the repository at this point in the history
Allows setting up and managing a set of systemd units on any systemd distribution.
  • Loading branch information
shlevy committed Mar 24, 2017
1 parent e3c1e37 commit 9a77701
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
83 changes: 83 additions & 0 deletions pkgs/build-support/setup-systemd-units.nix
@@ -0,0 +1,83 @@
# | Build a script to install and start a set of systemd units on any
# systemd-based system.
#
# Creates a symlink at /etc/systemd-static/${namespace} for slightly
# improved atomicity.
{ writeScriptBin
, bash
, coreutils
, systemd
, runCommand
, lib
}:
{ units # : AttrSet String (Either Path { path : Path, wanted-by : [ String ] })
# ^ A set whose names are unit names and values are
# either paths to the corresponding unit files or a set
# containing the path and the list of units this unit
# should be wanted-by (none by default).
#
# The names should include the unit suffix
# (e.g. ".service")
, namespace # : String
# The namespace for the unit files, to allow for
# multiple independent unit sets managed by
# `setupSystemdUnits`.
}:
let static = runCommand "systemd-static" {}
''
mkdir -p $out
${lib.concatStringsSep "\n" (lib.mapAttrsToList (nm: file:
"ln -sv ${file.path or file} $out/${nm}"
) units)}
'';
add-unit-snippet = name: file:
''
oldUnit=$(readlink -f "$unitDir/${name}" || echo "$unitDir/${name}")
if [ -f "$oldUnit" -a "$oldUnit" != "${file.path or file}" ]; then
unitsToStop+=("${name}")
fi
ln -sf "/etc/systemd-static/${namespace}/${name}" \
"$unitDir/.${name}.tmp"
mv -T "$unitDir/.${name}.tmp" "$unitDir/${name}"
${lib.concatStringsSep "\n" (map (unit:
''
mkdir -p "$unitDir/${unit}.wants"
ln -sf "../${name}" \
"$unitDir/${unit}.wants/.${name}.tmp"
mv -T "$unitDir/${unit}.wants/.${name}.tmp" \
"$unitDir/${unit}.wants/${name}"
''
) file.wanted-by or [])}
unitsToStart+=("${name}")
'';
in
writeScriptBin "setup-systemd-units"
''
#!${bash}/bin/bash -e
export PATH=${coreutils}/bin:${systemd}/bin
unitDir=/etc/systemd/system
if [ ! -w "$unitDir" ]; then
unitDir=/etc/systemd-mutable/system
mkdir -p "$unitDir"
fi
declare -a unitsToStop unitsToStart
oldStatic=$(readlink -f /etc/systemd-static/${namespace} || true)
if [ "$oldStatic" != "${static}" ]; then
${lib.concatStringsSep "\n"
(lib.mapAttrsToList add-unit-snippet units)}
if [ ''${#unitsToStop[@]} -ne 0 ]; then
echo "Stopping unit(s) ''${unitsToStop[@]}" >&2
systemctl stop "''${unitsToStop[@]}"
fi
mkdir -p /etc/systemd-static
ln -sfT ${static} /etc/systemd-static/.${namespace}.tmp
mv -T /etc/systemd-static/.${namespace}.tmp /etc/systemd-static/${namespace}
systemctl daemon-reload
echo "Starting unit(s) ''${unitsToStart[@]}" >&2
systemctl start "''${unitsToStart[@]}"
else
echo "Units unchanged, doing nothing" >&2
fi
''
2 changes: 2 additions & 0 deletions pkgs/top-level/all-packages.nix
Expand Up @@ -281,6 +281,8 @@ with pkgs;

pathsFromGraph = ../build-support/kernel/paths-from-graph.pl;

setupSystemdUnits = callPackage ../build-support/setup-systemd-units.nix { };

singularity-tools = callPackage ../build-support/singularity-tools { };

srcOnly = args: callPackage ../build-support/src-only args;
Expand Down

2 comments on commit 9a77701

@copumpkin
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting! Are you going to make NixOS use this?

@shlevy
Copy link
Member Author

@shlevy shlevy commented on 9a77701 Mar 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't be opposed to the code paths being shared, but note that NixOS gets the benefit of owning all of /etc in a way that this doesn't rely on.

Please sign in to comment.