43fd747ba7
Before we put only user files in the generation directory but that was quite limiting. In particular, we lost track of the activation script.
120 lines
3.2 KiB
Nix
120 lines
3.2 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
toSystemdIni = (import lib/generators.nix).toINI {
|
|
mkKeyValue = key: value:
|
|
let
|
|
value' =
|
|
if isBool value then (if value then "true" else "false")
|
|
else toString value;
|
|
in
|
|
"${key}=${value'}";
|
|
};
|
|
|
|
buildService = style: name: serviceCfg:
|
|
let
|
|
source = pkgs.writeText "${name}.${style}" (toSystemdIni serviceCfg);
|
|
|
|
wantedBy = target:
|
|
{
|
|
name = ".config/systemd/user/${target}.wants/${name}.${style}";
|
|
value = { inherit source; };
|
|
};
|
|
in
|
|
singleton {
|
|
name = ".config/systemd/user/${name}.${style}";
|
|
value = { inherit source; };
|
|
}
|
|
++
|
|
map wantedBy (serviceCfg.Install.WantedBy or []);
|
|
|
|
buildServices = style: serviceCfgs:
|
|
concatLists (mapAttrsToList (buildService style) serviceCfgs);
|
|
|
|
in
|
|
|
|
{
|
|
options = {
|
|
systemd.user = {
|
|
services = mkOption {
|
|
default = {};
|
|
type = types.attrs;
|
|
description = "Definition of systemd per-user service units.";
|
|
};
|
|
|
|
timers = mkOption {
|
|
default = {};
|
|
type = types.attrs;
|
|
description = "Definition of systemd per-user timers";
|
|
};
|
|
};
|
|
};
|
|
|
|
config = {
|
|
home.file =
|
|
listToAttrs (
|
|
(buildServices "service" config.systemd.user.services)
|
|
++
|
|
(buildServices "timer" config.systemd.user.timers)
|
|
);
|
|
|
|
home.activation.reloadSystemD = stringAfter ["linkages"] ''
|
|
function systemdPostReload() {
|
|
local servicesDiffFile="$(mktemp)"
|
|
local oldUserServicePath="$oldGenPath/home-files/.config/systemd/user"
|
|
local newUserServicePath="$newGenPath/home-files/.config/systemd/user"
|
|
|
|
diff \
|
|
--new-line-format='+%L' \
|
|
--old-line-format='-%L' \
|
|
--unchanged-line-format=' %L' \
|
|
<(basename -a $(echo "$oldUserServicePath/*.service") | sort) \
|
|
<(basename -a $(echo "$newUserServicePath/*.service") | sort) \
|
|
> $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
|
|
echo "Adding '$f' to restart list";
|
|
toRestart+=("$f")
|
|
fi
|
|
done
|
|
|
|
rm $servicesDiffFile
|
|
|
|
local sugg=""
|
|
|
|
if [[ -n "''${toRestart[@]}" ]] ; then
|
|
sugg="$sugg\nsystemctl --user restart ''${toRestart[@]}"
|
|
fi
|
|
|
|
if [[ -n "''${toStop[@]}" ]] ; then
|
|
sugg="$sugg\nsystemctl --user stop ''${toStop[@]}"
|
|
fi
|
|
|
|
if [[ -n "''${toStart[@]}" ]] ; then
|
|
sugg="$sugg\nsystemctl --user start ''${toStart[@]}"
|
|
fi
|
|
|
|
if [[ -n "$sugg" ]] ; then
|
|
echo "Suggested commands:"
|
|
echo -e "$sugg"
|
|
fi
|
|
}
|
|
|
|
systemctl --user daemon-reload
|
|
systemdPostReload
|
|
'';
|
|
};
|
|
}
|