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:
parent
1a491f24f7
commit
f60a1ed689
|
@ -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
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue