diff --git a/modules/module-list.nix b/modules/module-list.nix index 415ea493..e87f696c 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -71,6 +71,7 @@ ./services/netbird.nix ./services/nix-daemon.nix ./services/nix-gc + ./services/nix-optimise ./services/ofborg ./services/postgresql ./services/privoxy diff --git a/modules/services/nix-optimise/default.nix b/modules/services/nix-optimise/default.nix new file mode 100644 index 00000000..5462bae4 --- /dev/null +++ b/modules/services/nix-optimise/default.nix @@ -0,0 +1,73 @@ +# Based off: +# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/misc/nix-optimise.nix +# When making changes please try to keep it in sync. +{ config, lib, ... }: + + +let + inherit (lib) + mdDoc + mkIf + mkOption + mkRemovedOptionModule + optionalString + types + ; + + cfg = config.nix.optimise; +in + +{ + imports = [ + (mkRemovedOptionModule [ "nix" "optimise" "dates" ] "Use `nix.optimise.interval` instead.") + ]; + + ###### interface + + options = { + + nix.optimise = { + + automatic = mkOption { + type = types.bool; + default = false; + description = mdDoc "Automatically run the nix store optimiser at a specific time."; + }; + + # Not in NixOS module + user = mkOption { + type = types.nullOr types.str; + default = null; + description = mdDoc "User that runs the store optimisation."; + }; + + interval = mkOption { + type = types.attrs; + default = { Hour = 3; Minute = 15; }; + description = mdDoc "The time interval at which the optimiser will run."; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.automatic { + + launchd.daemons.nix-optimise = { + environment.NIX_REMOTE = optionalString config.nix.useDaemon "daemon"; + 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/system/checks.nix b/modules/system/checks.nix index 27188e35..5989dc48 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -191,6 +191,17 @@ let exit 2 fi ''; + + nixStoreOptimiser = '' + if test -O /nix/store; then + echo "error: A single-user install can't run optimiser as root, aborting activation" >&2 + echo "Configure the optimiser to run as the current user:" >&2 + echo >&2 + echo " nix.optimiser.user = \"$USER\";" >&2 + echo >&2 + exit 2 + fi + ''; in { @@ -230,6 +241,7 @@ in (mkIf (!config.nix.useDaemon) singleUser) nixStore (mkIf (config.nix.gc.automatic && config.nix.gc.user == null) nixGarbageCollector) + (mkIf (config.nix.optimise.automatic && config.nix.optimise.user == null) nixStoreOptimiser) (mkIf cfg.verifyNixChannels nixChannels) nixInstaller (mkIf cfg.verifyNixPath nixPath) diff --git a/release.nix b/release.nix index a0436bd7..98a58e72 100644 --- a/release.nix +++ b/release.nix @@ -126,6 +126,7 @@ let tests.services-dnsmasq = makeTest ./tests/services-dnsmasq.nix; tests.services-eternal-terminal = makeTest ./tests/services-eternal-terminal.nix; tests.services-nix-gc = makeTest ./tests/services-nix-gc.nix; + tests.services-nix-optimise = makeTest ./tests/services-nix-optimise.nix; tests.services-nextdns = makeTest ./tests/services-nextdns.nix; tests.services-ofborg = makeTest ./tests/services-ofborg.nix; tests.services-offlineimap = makeTest ./tests/services-offlineimap.nix; diff --git a/tests/services-nix-optimise.nix b/tests/services-nix-optimise.nix new file mode 100644 index 00000000..b0ecf184 --- /dev/null +++ b/tests/services-nix-optimise.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: + +let + nix = pkgs.runCommand "nix-2.2" {} "mkdir -p $out"; +in + +{ + nix.optimise.automatic = true; + nix.optimise.user = "nixuser"; + nix.package = nix; + + test = '' + 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" \ + ${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 + (! grep "KeepAlive" ${config.out}/Library/LaunchDaemons/org.nixos.nix-optimise.plist) + + echo checking nix-optimise validation >&2 + (! grep "nix.optimise.user = " ${config.out}/activate-user) + ''; +}