systemd: handle non-Linux systems better

This commit causes an error to be printed if running under a non-Linux
system when a systemd service, target, or timer is active.

It will also prevent running systemd during activation if running
under a non-Linux system.
This commit is contained in:
Robert Helgesson 2017-05-15 23:53:49 +02:00
parent 1a491f24f7
commit f60a1ed689
No known key found for this signature in database
GPG key ID: C3DB11069E65DC86

View file

@ -5,6 +5,10 @@ with import ./lib/dag.nix;
let let
cfg = config.systemd.user;
enabled = cfg.services != {} || cfg.targets != {} || cfg.timers != {};
toSystemdIni = (import lib/generators.nix).toINI { toSystemdIni = (import lib/generators.nix).toINI {
mkKeyValue = key: value: mkKeyValue = key: value:
let let
@ -60,98 +64,117 @@ in
}; };
}; };
config = { config = mkMerge [
home.file = {
listToAttrs ( assertions = [
(buildServices "service" config.systemd.user.services) {
++ assertion = enabled -> pkgs.stdenv.isLinux;
(buildServices "target" config.systemd.user.targets) message =
++ let
(buildServices "timer" config.systemd.user.timers) names = concatStringsSep ", " (
); attrNames (cfg.services // cfg.targets // cfg.timers)
);
in
"Must use Linux for modules that require systemd: " + names;
}
];
}
home.activation.reloadSystemD = dagEntryAfter ["linkGeneration"] '' # If we run under a Linux system we assume that systemd is
function systemdPostReload() { # available, in particular we assume that systemctl is in PATH.
local workDir (mkIf pkgs.stdenv.isLinux {
workDir="$(mktemp -d)" home.file =
listToAttrs (
(buildServices "service" cfg.services)
++
(buildServices "target" cfg.targets)
++
(buildServices "timer" cfg.timers)
);
if [[ -v oldGenPath ]] ; then home.activation.reloadSystemD = dagEntryAfter ["linkGeneration"] ''
local oldUserServicePath="$oldGenPath/home-files/.config/systemd/user" function systemdPostReload() {
fi local workDir
workDir="$(mktemp -d)"
local newUserServicePath="$newGenPath/home-files/.config/systemd/user" if [[ -v oldGenPath ]] ; then
local oldServiceFiles="$workDir/old-files" local oldUserServicePath="$oldGenPath/home-files/.config/systemd/user"
local newServiceFiles="$workDir/new-files"
local servicesDiffFile="$workDir/diff-files"
if [[ ! (-v oldUserServicePath && -d "$oldUserServicePath") \
&& ! -d "$newUserServicePath" ]]; then
return
fi
if [[ ! (-v oldUserServicePath && -d "$oldUserServicePath") ]]; then
touch "$oldServiceFiles"
else
find "$oldUserServicePath" \
-maxdepth 1 -name '*.service' -exec basename '{}' ';' \
| sort \
> "$oldServiceFiles"
fi
if [[ ! -d "$newUserServicePath" ]]; then
touch "$newServiceFiles"
else
find "$newUserServicePath" \
-maxdepth 1 -name '*.service' -exec basename '{}' ';' \
| sort \
> "$newServiceFiles"
fi
diff \
--new-line-format='+%L' \
--old-line-format='-%L' \
--unchanged-line-format=' %L' \
"$oldServiceFiles" "$newServiceFiles" \
> $servicesDiffFile
local -a maybeRestart=( $(grep '^ ' $servicesDiffFile | cut -c2-) )
local -a toStop=( $(grep '^-' $servicesDiffFile | cut -c2-) )
local -a toStart=( $(grep '^+' $servicesDiffFile | cut -c2-) )
local -a toRestart=( )
for f in ''${maybeRestart[@]} ; do
if systemctl --quiet --user is-active "$f" \
&& ! cmp --quiet \
"$oldUserServicePath/$f" \
"$newUserServicePath/$f" ; then
toRestart+=("$f")
fi fi
done
rm -r $workDir local newUserServicePath="$newGenPath/home-files/.config/systemd/user"
local oldServiceFiles="$workDir/old-files"
local newServiceFiles="$workDir/new-files"
local servicesDiffFile="$workDir/diff-files"
local sugg="" if [[ ! (-v oldUserServicePath && -d "$oldUserServicePath") \
&& ! -d "$newUserServicePath" ]]; then
return
fi
if [[ -n "''${toRestart[@]}" ]] ; then if [[ ! (-v oldUserServicePath && -d "$oldUserServicePath") ]]; then
sugg="''${sugg}systemctl --user restart ''${toRestart[@]}\n" touch "$oldServiceFiles"
fi else
find "$oldUserServicePath" \
-maxdepth 1 -name '*.service' -exec basename '{}' ';' \
| sort \
> "$oldServiceFiles"
fi
if [[ -n "''${toStop[@]}" ]] ; then if [[ ! -d "$newUserServicePath" ]]; then
sugg="''${sugg}systemctl --user stop ''${toStop[@]}\n" touch "$newServiceFiles"
fi else
find "$newUserServicePath" \
-maxdepth 1 -name '*.service' -exec basename '{}' ';' \
| sort \
> "$newServiceFiles"
fi
if [[ -n "''${toStart[@]}" ]] ; then diff \
sugg="''${sugg}systemctl --user start ''${toStart[@]}\n" --new-line-format='+%L' \
fi --old-line-format='-%L' \
--unchanged-line-format=' %L' \
"$oldServiceFiles" "$newServiceFiles" \
> $servicesDiffFile
if [[ -n "$sugg" ]] ; then local -a maybeRestart=( $(grep '^ ' $servicesDiffFile | cut -c2-) )
echo "Suggested commands:" local -a toStop=( $(grep '^-' $servicesDiffFile | cut -c2-) )
echo -n -e "$sugg" local -a toStart=( $(grep '^+' $servicesDiffFile | cut -c2-) )
fi local -a toRestart=( )
}
$DRY_RUN_CMD systemctl --user daemon-reload for f in ''${maybeRestart[@]} ; do
systemdPostReload if systemctl --quiet --user is-active "$f" \
''; && ! cmp --quiet \
}; "$oldUserServicePath/$f" \
"$newUserServicePath/$f" ; then
toRestart+=("$f")
fi
done
rm -r $workDir
local sugg=""
if [[ -n "''${toRestart[@]}" ]] ; then
sugg="''${sugg}systemctl --user restart ''${toRestart[@]}\n"
fi
if [[ -n "''${toStop[@]}" ]] ; then
sugg="''${sugg}systemctl --user stop ''${toStop[@]}\n"
fi
if [[ -n "''${toStart[@]}" ]] ; then
sugg="''${sugg}systemctl --user start ''${toStart[@]}\n"
fi
if [[ -n "$sugg" ]] ; then
echo "Suggested commands:"
echo -n -e "$sugg"
fi
}
$DRY_RUN_CMD systemctl --user daemon-reload
systemdPostReload
'';
})
];
} }