nix-files/modules/users/systemd.nix

70 lines
2.6 KiB
Nix

{ lib, utils, ... }:
let
# see: <repo:nixos/nixpkgs:nixos/lib/utils.nix>
# see: <repo:nix-community/home-manager:modules/systemd.nix>
mkUnit = serviceName: value: utils.systemdUtils.lib.serviceToUnit serviceName {
inherit (value)
script
wantedBy
;
serviceConfig = lib.filterAttrs (_: v: v != null) value.serviceConfig;
unitConfig = {
inherit (value.unitConfig)
ConditionEnvironment
;
After = value.after;
Before = value.before;
BindsTo = value.bindsTo;
Description = value.description;
Documentation = value.documentation;
Wants = value.wants;
};
environment = {
# clear PATH to allow inheriting it from environment.
# otherwise, nixos would force it to `systemd.globalEnvironment.PATH`, which is mostly tools like sed/find/etc.
# clearing PATH here allows user services to inherit whatever PATH the graphical session sets
# (see `dbus-update-activation-environment` call in ~/.config/sway/config),
# which is critical to making it so user services can see user *programs*/packages.
#
# note that systemd provides no way to *append* to the PATH, only to override it (or not).
# nor do they intend to ever support that:
# - <https://github.com/systemd/systemd/issues/1082>
PATH = null;
} // (value.environment or {});
};
in
{
# create fs entries for every service, in the systemd user dir.
options.sane.users = with lib; mkOption {
type = types.attrsOf (types.submodule ({ config, ...}: {
fs = lib.concatMapAttrs
(serviceName: value: let
cleanName = utils.systemdUtils.lib.mkPathSafeName serviceName;
generatedUnit = mkUnit serviceName value;
#^ generatedUnit contains keys:
# - text
# - aliases (IGNORED)
# - wantedBy
# - requiredBy
# - enabled (IGNORED)
# - overrideStrategy (IGNORED)
# TODO: error if one of the above ignored fields are set
symlinkData = {
text = generatedUnit.text;
targetName = "${cleanName}.service"; # systemd derives unit name from symlink target
};
serviceEntry = {
".config/systemd/user/${serviceName}.service".symlink = symlinkData;
};
wants = builtins.map (wantedBy: {
".config/systemd/user/${wantedBy}.wants/${serviceName}.service".symlink = symlinkData;
}) generatedUnit.wantedBy;
in
lib.mergeAttrsList ([ serviceEntry ] ++ wants)
)
config.services
;
}));
};
}