diff --git a/modules/launchd/default.nix b/modules/launchd/default.nix index faf60c2..d7c5054 100644 --- a/modules/launchd/default.nix +++ b/modules/launchd/default.nix @@ -35,7 +35,7 @@ let path = mkOption { type = types.listOf types.path; default = []; - apply = ps: "${makeBinPath ps}"; + apply = ps: makeBinPath ps; description = '' Packages added to the service's PATH environment variable. Both the bin @@ -117,6 +117,22 @@ in ''; }; + launchd.user.agents = mkOption { + default = {}; + type = types.attrsOf (types.submodule serviceOptions); + description = '' + Definition of per-user launchd agents. + + When a user logs in, a per-user launchd is started. + It does the following: + 1. It loads the parameters for each launch-on-demand user agent from the property list files found in /System/Library/LaunchAgents, /Library/LaunchAgents, and the user’s individual Library/LaunchAgents directory. + 2. It registers the sockets and file descriptors requested by those user agents. + 3. It launches any user agents that requested to be running all the time. + 4. As requests for a particular service arrive, it launches the corresponding user agent and passes the request to it. + 5. When the user logs out, it sends a SIGTERM signal to all of the user agents that it started. + ''; + }; + }; config = { @@ -124,5 +140,7 @@ in environment.launchAgents = mapAttrs' toEnvironmentText cfg.agents; environment.launchDaemons = mapAttrs' toEnvironmentText cfg.daemons; + environment.userLaunchAgents = mapAttrs' toEnvironmentText cfg.user.agents; + }; } diff --git a/modules/system/activation-scripts.nix b/modules/system/activation-scripts.nix index 4a66996..5de7595 100644 --- a/modules/system/activation-scripts.nix +++ b/modules/system/activation-scripts.nix @@ -84,6 +84,7 @@ in umask 0022 ${cfg.activationScripts.defaults.text} + ${cfg.activationScripts.userLaunchd.text} ${cfg.activationScripts.extraUserActivation.text} exit $_status diff --git a/modules/system/default.nix b/modules/system/default.nix index efc6511..16731ed 100644 --- a/modules/system/default.nix +++ b/modules/system/default.nix @@ -92,6 +92,7 @@ in ln -s ${cfg.path} $out/sw mkdir -p $out/Library + ln -s ${cfg.build.launchd}/Library/LaunchAgents $out/Library/LaunchAgents ln -s ${cfg.build.launchd}/Library/LaunchDaemons $out/Library/LaunchDaemons echo "$activationScript" > $out/activate diff --git a/modules/system/launchd.nix b/modules/system/launchd.nix index a79c0dd..8020a08 100644 --- a/modules/system/launchd.nix +++ b/modules/system/launchd.nix @@ -13,14 +13,23 @@ let launchdActivation = basedir: target: '' if test -f '/Library/${basedir}/${target}'; then - launchctl unload '/Library/${basedir}/${target}' + launchctl unload '/Library/${basedir}/${target}' || true fi cp -f '${cfg.build.launchd}/Library/${basedir}/${target}' '/Library/${basedir}/${target}' launchctl load '/Library/${basedir}/${target}' ''; + userLaunchdActivation = target: '' + if test -f ~/Library/LaunchAgents/${target}; then + launchctl unload ~/Library/LaunchAgents/${target} || true + fi + cp -f ${cfg.build.userLaunchd}/Library/LaunchAgents/${target} ~/Library/LaunchAgents/${target} + launchctl load ~/Library/LaunchAgents/${target} + ''; + launchAgents = filter (f: f.enable) (attrValues config.environment.launchAgents); launchDaemons = filter (f: f.enable) (attrValues config.environment.launchDaemons); + userLaunchAgents = filter (f: f.enable) (attrValues config.environment.userLaunchAgents); in @@ -43,6 +52,14 @@ in ''; }; + environment.userLaunchAgents = mkOption { + type = types.loaOf (types.submodule text); + default = {}; + description = '' + Set of files that have to be linked in ~/Library/LaunchAgents. + ''; + }; + }; config = { @@ -55,6 +72,12 @@ in ${concatMapStringsSep "\n" (attr: "ln -s '${attr.source}' '${attr.target}'") launchDaemons} ''; + system.build.userLaunchd = pkgs.runCommand "user-launchd" {} '' + mkdir -p $out/Library/LaunchAgents $out/Library/LaunchDaemons + cd $out/Library/LaunchAgents + ${concatMapStringsSep "\n" (attr: "ln -s '${attr.source}' '${attr.target}'") userLaunchAgents} + ''; + system.activationScripts.launchd.text = '' # Set up launchd services in /Library/LaunchAgents and /Library/LaunchDaemons echo "setting up launchd services..." @@ -63,5 +86,12 @@ in ${concatMapStringsSep "\n" (attr: launchdActivation "LaunchDaemons" attr.target) launchDaemons} ''; + system.activationScripts.userLaunchd.text = '' + # Set up launchd services in ~/Library/LaunchAgents + echo "setting up user launchd services..." + + ${concatMapStringsSep "\n" (attr: userLaunchdActivation attr.target) userLaunchAgents} + ''; + }; }