From 034c45dd0cac806b527e64c143020676e1070769 Mon Sep 17 00:00:00 2001 From: will Date: Sat, 31 Aug 2024 18:27:10 +1000 Subject: [PATCH] feat: use wait4path with script launchd option addresses https://github.com/LnL7/nix-darwin/issues/1043 fix: use exec in launchd daemon config fix: dont use a script thats in the nix store fix: remove manual wait4path in linux-builder fix: remove manual wait4path in karabiner elements fix: remove manual wait4path in nix-daemon fix: remove manual wait4path in nix-optimise fix: remove manual wait4path in tailscaled fix: autossh test Revert "fix: remove manual wait4path in nix-daemon" This reverts commit 6aec084fa5d095666e81676e78f7054c83703faa. fix: remove bad exec Reapply "fix: remove manual wait4path in nix-daemon" This reverts commit c8f136ecc555f803124af471324bc6ed1163d6dd. fix: update autossh test to reflect changes in f86e6133d957becb1958da638516b0860fbd7491 fix: services-activate-system-changed-label-prefix test fix: services-buildkite-agent test fix: services-activate-system test fix: escape ampersand fix: services-lorri test fix: services-nix-optimise test fix: services-nix-gc test refactor: use script rather than command in daemon fix: use config.command for clarity style: fix indentation fix: use lib.getExe rather than directly pointing to file revert: a87fc7bbbbdb7c25c5ad6721c93990ea035affdd - mistaken refactor meant that service waited for nix store and not the relevant path --- modules/launchd/default.nix | 7 ++-- modules/nix/linux-builder.nix | 35 +++++++++---------- .../services/karabiner-elements/default.nix | 20 +++-------- modules/services/nix-daemon.nix | 5 +-- modules/services/nix-optimise/default.nix | 5 +-- modules/services/tailscale.nix | 5 +-- tests/autossh.nix | 16 +++++---- ...s-activate-system-changed-label-prefix.nix | 2 +- tests/services-activate-system.nix | 2 +- tests/services-buildkite-agent.nix | 4 +-- tests/services-lorri.nix | 25 ++++++++++--- tests/services-nix-gc.nix | 4 +-- tests/services-nix-optimise.nix | 4 +-- 13 files changed, 66 insertions(+), 68 deletions(-) diff --git a/modules/launchd/default.nix b/modules/launchd/default.nix index ccb6cc69..64b6af70 100644 --- a/modules/launchd/default.nix +++ b/modules/launchd/default.nix @@ -20,7 +20,6 @@ let { config, name, ... }: let - cmd = config.command; env = config.environment // optionalAttrs (config.path != "") { PATH = config.path; }; in @@ -88,7 +87,11 @@ let ''); serviceConfig.Label = mkDefault "${cfg.labelPrefix}.${name}"; - serviceConfig.ProgramArguments = mkIf (cmd != "") [ "/bin/sh" "-c" "exec ${cmd}" ]; + serviceConfig.ProgramArguments = mkIf (config.command != "") [ + "/bin/sh" + "-c" + "/bin/wait4path /nix/store && exec ${config.command}" + ]; serviceConfig.EnvironmentVariables = mkIf (env != {}) env; }; }; diff --git a/modules/nix/linux-builder.nix b/modules/nix/linux-builder.nix index 9756fe46..2bcb62ea 100644 --- a/modules/nix/linux-builder.nix +++ b/modules/nix/linux-builder.nix @@ -4,21 +4,6 @@ with lib; let cfg = config.nix.linux-builder; - - # create-builder uses TMPDIR to share files with the builder, notably certs. - # macOS will clean up files in /tmp automatically that haven't been accessed in 3+ days. - # If we let it use /tmp, leaving the computer asleep for 3 days makes the certs vanish. - # So we'll use /run/org.nixos.linux-builder instead and clean it up ourselves. - script = pkgs.writeShellScript "linux-builder-start" '' - export TMPDIR=/run/org.nixos.linux-builder USE_TMPDIR=1 - rm -rf $TMPDIR - mkdir -p $TMPDIR - trap "rm -rf $TMPDIR" EXIT - ${lib.optionalString cfg.ephemeral '' - rm -f ${cfg.workingDirectory}/${cfg.package.nixosConfig.networking.hostName}.qcow2 - ''} - ${cfg.package}/bin/create-builder - ''; in { @@ -176,11 +161,23 @@ in environment = { inherit (config.environment.variables) NIX_SSL_CERT_FILE; }; + + # create-builder uses TMPDIR to share files with the builder, notably certs. + # macOS will clean up files in /tmp automatically that haven't been accessed in 3+ days. + # If we let it use /tmp, leaving the computer asleep for 3 days makes the certs vanish. + # So we'll use /run/org.nixos.linux-builder instead and clean it up ourselves. + script = '' + export TMPDIR=/run/org.nixos.linux-builder USE_TMPDIR=1 + rm -rf $TMPDIR + mkdir -p $TMPDIR + trap "rm -rf $TMPDIR" EXIT + ${lib.optionalString cfg.ephemeral '' + rm -f ${cfg.workingDirectory}/${cfg.package.nixosConfig.networking.hostName}.qcow2 + ''} + ${cfg.package}/bin/create-builder + ''; + serviceConfig = { - ProgramArguments = [ - "/bin/sh" "-c" - "/bin/wait4path /nix/store && exec ${script}" - ]; KeepAlive = true; RunAtLoad = true; WorkingDirectory = cfg.workingDirectory; diff --git a/modules/services/karabiner-elements/default.nix b/modules/services/karabiner-elements/default.nix index 2f415b2d..0e2bb436 100644 --- a/modules/services/karabiner-elements/default.nix +++ b/modules/services/karabiner-elements/default.nix @@ -38,14 +38,11 @@ in # the system extension is activated, so we can call activate from the manager # which will block until the system extension is activated. launchd.daemons.start_karabiner_daemons = { - serviceConfig.ProgramArguments = [ - "/bin/sh" "-c" - "/bin/wait4path /nix/store && ${pkgs.writeScript "start_karabiner_daemons" '' + script = '' ${parentAppDir}/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager activate launchctl kickstart system/org.pqrs.karabiner.karabiner_grabber launchctl kickstart system/org.pqrs.karabiner.karabiner_observer - ''}" - ]; + ''; serviceConfig.Label = "org.nixos.start_karabiner_daemons"; serviceConfig.RunAtLoad = true; }; @@ -73,11 +70,7 @@ in }; launchd.daemons.Karabiner-DriverKit-VirtualHIDDeviceClient = { - serviceConfig.ProgramArguments = [ - "/bin/sh" "-c" - # For unknown reasons this daemon will fail if VirtualHIDDeviceClient is not exec'd. - "/bin/wait4path /nix/store && exec \"${pkgs.karabiner-elements.driver}/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/Applications/Karabiner-DriverKit-VirtualHIDDeviceClient.app/Contents/MacOS/Karabiner-DriverKit-VirtualHIDDeviceClient\"" - ]; + command = "${pkgs.karabiner-elements.driver}/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/Applications/Karabiner-DriverKit-VirtualHIDDeviceClient.app/Contents/MacOS/Karabiner-DriverKit-VirtualHIDDeviceClient"; serviceConfig.ProcessType = "Interactive"; serviceConfig.Label = "org.pqrs.Karabiner-DriverKit-VirtualHIDDeviceClient"; serviceConfig.KeepAlive = true; @@ -95,14 +88,11 @@ in # We need this to run every reboot as /run gets nuked so we can't put this # inside the preActivation script as it only gets run on darwin-rebuild switch. launchd.daemons.setsuid_karabiner_session_monitor = { - serviceConfig.ProgramArguments = [ - "/bin/sh" "-c" - "/bin/wait4path /nix/store && ${pkgs.writeScript "setsuid_karabiner_session_monitor" '' + script = '' rm -rf /run/wrappers mkdir -p /run/wrappers/bin install -m4555 "${pkgs.karabiner-elements}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_session_monitor" /run/wrappers/bin - ''}" - ]; + ''; serviceConfig.RunAtLoad = true; serviceConfig.KeepAlive.SuccessfulExit = false; }; diff --git a/modules/services/nix-daemon.nix b/modules/services/nix-daemon.nix index 42d31c94..6718ac05 100644 --- a/modules/services/nix-daemon.nix +++ b/modules/services/nix-daemon.nix @@ -44,10 +44,7 @@ in nix.useDaemon = true; launchd.daemons.nix-daemon = { - serviceConfig.ProgramArguments = [ - "/bin/sh" "-c" - "/bin/wait4path ${config.nix.package}/bin/nix-daemon && exec ${config.nix.package}/bin/nix-daemon" - ]; + command = lib.getExe' config.nix.package "nix-daemon"; serviceConfig.ProcessType = config.nix.daemonProcessType; serviceConfig.LowPriorityIO = config.nix.daemonIOLowPriority; serviceConfig.Label = "org.nixos.nix-daemon"; # must match daemon installed by Nix regardless of the launchd label Prefix diff --git a/modules/services/nix-optimise/default.nix b/modules/services/nix-optimise/default.nix index d8dc401c..c0ee0a38 100644 --- a/modules/services/nix-optimise/default.nix +++ b/modules/services/nix-optimise/default.nix @@ -62,11 +62,8 @@ in launchd.daemons.nix-optimise = { environment.NIX_REMOTE = optionalString config.nix.useDaemon "daemon"; + command = "${lib.getExe' config.nix.package "nix-store"} --optimise"; serviceConfig = { - ProgramArguments = [ - "/bin/sh" "-c" - "/bin/wait4path ${config.nix.package} && exec ${config.nix.package}/bin/nix-store --optimise" - ]; RunAtLoad = false; StartCalendarInterval = cfg.interval; UserName = cfg.user; diff --git a/modules/services/tailscale.nix b/modules/services/tailscale.nix index 3c826cff..e7d6b0d4 100644 --- a/modules/services/tailscale.nix +++ b/modules/services/tailscale.nix @@ -54,12 +54,9 @@ in launchd.daemons.tailscaled = { # derived from # https://github.com/tailscale/tailscale/blob/main/cmd/tailscaled/install_darwin.go#L30 + command = lib.getExe' cfg.package "tailscaled"; serviceConfig = { Label = "com.tailscale.tailscaled"; - ProgramArguments = [ - "/bin/sh" "-c" - "/bin/wait4path ${cfg.package} && ${cfg.package}/bin/tailscaled" - ]; RunAtLoad = true; }; }; diff --git a/tests/autossh.nix b/tests/autossh.nix index d1aacd0e..5279bf9d 100644 --- a/tests/autossh.nix +++ b/tests/autossh.nix @@ -1,17 +1,19 @@ { config, pkgs, ... }: { - services.autossh.sessions = [ { - name = "foo"; - user = "jfelice"; - extraArguments = "-i /some/key -T -N bar.eraserhead.net"; - } ]; + services.autossh.sessions = [ + { + name = "foo"; + user = "jfelice"; + extraArguments = "-i /some/key -T -N bar.eraserhead.net"; + } + ]; test = '' plist=${config.out}/Library/LaunchDaemons/org.nixos.autossh-foo.plist test -f $plist - grep 'exec /nix/store/.*/bin/autossh ' $plist - grep 'exec.*-i /some/key ' $plist + grep '/bin/wait4path /nix/store && exec /nix/store/.*/bin/autossh ' $plist + grep '/bin/wait4path /nix/store && exec.*-i /some/key ' $plist tr -d '\n\t ' <$plist |grep 'KeepAlive' ''; } diff --git a/tests/services-activate-system-changed-label-prefix.nix b/tests/services-activate-system-changed-label-prefix.nix index 5ac99691..1ae2bcf5 100644 --- a/tests/services-activate-system-changed-label-prefix.nix +++ b/tests/services-activate-system-changed-label-prefix.nix @@ -9,7 +9,7 @@ grep "org.nix-darwin.activate-system" ${config.out}/Library/LaunchDaemons/org.nix-darwin.activate-system.plist echo checking activation of /run/current-system >&2 - script=$(cat ${config.out}/Library/LaunchDaemons/org.nix-darwin.activate-system.plist | awk -F'[< ]' '$3 ~ "^/nix/store/.*" {print $3}') + script=$(cat ${config.out}/Library/LaunchDaemons/org.nix-darwin.activate-system.plist | awk -F'[< ]' '$6 ~ "^/nix/store/.*" {print $6}') grep "ln -sfn .* /run/current-system" "$script" ''; } diff --git a/tests/services-activate-system.nix b/tests/services-activate-system.nix index 02eaf3cb..c519aa89 100644 --- a/tests/services-activate-system.nix +++ b/tests/services-activate-system.nix @@ -8,7 +8,7 @@ grep "org.nixos.activate-system" ${config.out}/Library/LaunchDaemons/org.nixos.activate-system.plist echo checking activation of /run/current-system >&2 - script=$(cat ${config.out}/Library/LaunchDaemons/org.nixos.activate-system.plist | awk -F'[< ]' '$3 ~ "^/nix/store/.*" {print $3}') + script=$(cat ${config.out}/Library/LaunchDaemons/org.nixos.activate-system.plist | awk -F'[< ]' '$6 ~ "^/nix/store/.*" {print $6}') grep "ln -sfn .* /run/current-system" "$script" ''; } diff --git a/tests/services-buildkite-agent.nix b/tests/services-buildkite-agent.nix index 557aad23..1d8d8247 100644 --- a/tests/services-buildkite-agent.nix +++ b/tests/services-buildkite-agent.nix @@ -1,7 +1,7 @@ { config, pkgs, ... }: let - buildkite-agent = pkgs.runCommand "buildkite-agent-0.0.0" {} "mkdir $out"; + buildkite-agent = pkgs.runCommand "buildkite-agent-0.0.0" { } "mkdir $out"; tokenPath = pkgs.writeText "buildkite_token" "TEST_TOKEN"; in @@ -20,7 +20,7 @@ in grep "org.nixos.buildkite-agent-test" ${config.out}/Library/LaunchDaemons/org.nixos.buildkite-agent-test.plist echo "checking creation of buildkite-agent service config" >&2 - script=$(cat ${config.out}/Library/LaunchDaemons/org.nixos.buildkite-agent-test.plist | awk -F'[< ]' '$3 ~ "^/nix/store/.*" {print $3}') + script=$(cat ${config.out}/Library/LaunchDaemons/org.nixos.buildkite-agent-test.plist | awk -F'[< ]' '$6 ~ "^/nix/store/.*" {print $6}') grep "yolo=1" "$script" grep "${tokenPath}" "$script" diff --git a/tests/services-lorri.nix b/tests/services-lorri.nix index 52dcc91a..7d301524 100644 --- a/tests/services-lorri.nix +++ b/tests/services-lorri.nix @@ -1,14 +1,29 @@ -{ config, pkgs, lib, ... }: +{ + config, + pkgs, + lib, + ... +}: let plistPath = "${config.out}/user/Library/LaunchAgents/org.nixos.lorri.plist"; - expectedPath = "${lib.makeBinPath [config.nix.package pkgs.git pkgs.gnutar pkgs.gzip]}"; - expectedNixPath = "${"nixpkgs="+ toString pkgs.path}"; + expectedPath = "${lib.makeBinPath [ + config.nix.package + pkgs.git + pkgs.gnutar + pkgs.gzip + ]}"; + expectedNixPath = "${"nixpkgs=" + toString pkgs.path}"; in { services.lorri.enable = true; test = '' - PATH=${lib.makeBinPath [ pkgs.xcbuild pkgs.jq ]}:$PATH + PATH=${ + lib.makeBinPath [ + pkgs.xcbuild + pkgs.jq + ] + }:$PATH plutil -lint ${plistPath} plutil -convert json -o service.json ${plistPath} @@ -21,7 +36,7 @@ in &2 grep "org.nixos.nix-gc" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist - grep "exec ${nix}/bin/nix-collect-garbage --delete-older-than 30d" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist + grep "/bin/wait4path /nix/store && exec ${nix}/bin/nix-collect-garbage --delete-older-than 30d" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist grep "UserName" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist grep "nixuser" ${config.out}/Library/LaunchDaemons/org.nixos.nix-gc.plist diff --git a/tests/services-nix-optimise.nix b/tests/services-nix-optimise.nix index b0ecf184..4108eb0f 100644 --- a/tests/services-nix-optimise.nix +++ b/tests/services-nix-optimise.nix @@ -1,7 +1,7 @@ { config, pkgs, ... }: let - nix = pkgs.runCommand "nix-2.2" {} "mkdir -p $out"; + nix = pkgs.runCommand "nix-2.2" { } "mkdir -p $out"; in { @@ -13,7 +13,7 @@ in echo checking nix-optimise service in /Library/LaunchDaemons >&2 grep "org.nixos.nix-optimise" \ ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist - grep "/bin/wait4path ${nix} && exec ${nix}/bin/nix-store --optimise" \ + grep "/bin/wait4path /nix/store && exec ${nix}/bin/nix-store --optimise" \ ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist grep "UserName" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist grep "nixuser" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist