nix-gc: add service

The nix-gc service runs automatically at a specified frequency. It is
managed via launchd on macOS and systemd on Linux.
This commit is contained in:
shivaraj-bh 2024-01-28 09:41:23 +05:30 committed by Robert Helgesson
parent afcedcf2c8
commit 274bd470a5
No known key found for this signature in database
GPG key ID: 96E745BD17AA17ED
10 changed files with 211 additions and 0 deletions

View file

@ -308,6 +308,7 @@ let
./services/muchsync.nix ./services/muchsync.nix
./services/network-manager-applet.nix ./services/network-manager-applet.nix
./services/nextcloud-client.nix ./services/nextcloud-client.nix
./services/nix-gc.nix
./services/notify-osd.nix ./services/notify-osd.nix
./services/opensnitch-ui.nix ./services/opensnitch-ui.nix
./services/osmscout-server.nix ./services/osmscout-server.nix

120
modules/services/nix-gc.nix Normal file
View file

@ -0,0 +1,120 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.nix.gc;
mkCalendarInterval = frequency:
let
freq = {
"hourly" = [{ Minute = 0; }];
"weekly" = [{
Weekday = 1;
Hour = 0;
Minute = 0;
}];
"monthly" = [{
Day = 1;
Hour = 0;
Minute = 0;
}];
"semiannually" = [
{
Month = 1;
Day = 1;
Hour = 0;
Minute = 0;
}
{
Month = 7;
Day = 1;
Hour = 0;
Minute = 0;
}
];
"annually" = [{
Month = 1;
Day = 1;
Hour = 0;
Minute = 0;
}];
};
in freq.${frequency};
nixPackage = if config.nix.enable && config.nix.package != null then
config.nix.package
else
pkgs.nix;
in {
meta.maintainers = [ maintainers.shivaraj-bh ];
options = {
nix.gc = {
automatic = mkOption {
type = types.bool;
default = false;
description = ''
Automatically run the garbage collector at a specific time.
Note: This will only garbage collect the current user's profiles.
'';
};
frequency = mkOption {
type =
types.enum [ "hourly" "weekly" "monthly" "semiannually" "annually" ];
default = "weekly";
example = "monthly";
description = ''
The frequency at which to run the garbage collector.
These enums are based on special expressions from the
{manpage}`systemd.time(7)`
'';
};
options = mkOption {
type = types.nullOr types.str;
default = null;
example = "--max-freed $((64 * 1024**3))";
description = ''
Options given to {file}`nix-collect-garbage` when the
garbage collector is run automatically.
'';
};
};
};
config = lib.mkIf cfg.automatic (mkMerge [
(mkIf pkgs.stdenv.isLinux {
systemd.user.services.nix-gc = {
Unit = { Description = "Nix Garbage Collector"; };
Service = {
ExecStart = "${nixPackage}/bin/nix-collect-garbage ${
lib.optionalString (cfg.options != null) cfg.options
}";
};
};
systemd.user.timers.nix-gc = {
Unit = { Description = "Nix Garbage Collector"; };
Timer = {
OnCalendar = "${cfg.frequency}";
Unit = "nix-gc.service";
};
Install = { WantedBy = [ "timers.target" ]; };
};
})
(mkIf pkgs.stdenv.isDarwin {
launchd.agents.nix-gc = {
enable = true;
config = {
ProgramArguments = [ "${nixPackage}/bin/nix-collect-garbage" ]
++ lib.optional (cfg.options != null) cfg.options;
StartCalendarInterval = mkCalendarInterval cfg.frequency;
};
};
})
]);
}

View file

@ -161,6 +161,7 @@ in import nmtSrc {
./modules/launchd ./modules/launchd
./modules/services/git-sync-darwin ./modules/services/git-sync-darwin
./modules/services/imapnotify-darwin ./modules/services/imapnotify-darwin
./modules/services/nix-gc-darwin
./modules/targets-darwin ./modules/targets-darwin
] ++ lib.optionals isLinux [ ] ++ lib.optionals isLinux [
./modules/config/i18n ./modules/config/i18n
@ -234,6 +235,7 @@ in import nmtSrc {
./modules/services/mpd ./modules/services/mpd
./modules/services/mpd-mpris ./modules/services/mpd-mpris
./modules/services/mpdris2 ./modules/services/mpdris2
./modules/services/nix-gc
./modules/services/osmscout-server ./modules/services/osmscout-server
./modules/services/pantalaimon ./modules/services/pantalaimon
./modules/services/parcellite ./modules/services/parcellite

View file

@ -0,0 +1,19 @@
{ ... }:
{
nix.gc = {
automatic = true;
frequency = "monthly";
options = "--delete-older-than 30d";
};
test.stubs.nix = { name = "nix"; };
nmt.script = ''
serviceFile=LaunchAgents/org.nix-community.home.nix-gc.plist
assertFileExists "$serviceFile"
assertFileContent "$serviceFile" ${./expected-agent.plist}
'';
}

View file

@ -0,0 +1 @@
{ nix-gc = ./basic.nix; }

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.nix-community.home.nix-gc</string>
<key>ProgramArguments</key>
<array>
<string>@nix@/bin/nix-collect-garbage</string>
<string>--delete-older-than 30d</string>
</array>
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Day</key>
<integer>1</integer>
<key>Hour</key>
<integer>0</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</array>
</dict>
</plist>

View file

@ -0,0 +1,29 @@
{ ... }:
{
nix.gc = {
automatic = true;
frequency = "monthly";
options = "--delete-older-than 30d";
};
test.stubs.nix = { name = "nix"; };
nmt.script = ''
serviceFile=home-files/.config/systemd/user/nix-gc.service
assertFileExists $serviceFile
serviceFile=$(normalizeStorePaths $serviceFile)
assertFileContent $serviceFile ${./expected.service}
timerFile=home-files/.config/systemd/user/nix-gc.timer
assertFileExists $timerFile
timerFile=$(normalizeStorePaths $timerFile)
assertFileContent $timerFile ${./expected.timer}
'';
}

View file

@ -0,0 +1 @@
{ nix-gc = ./basic.nix; }

View file

@ -0,0 +1,5 @@
[Service]
ExecStart=@nix@/bin/nix-collect-garbage --delete-older-than 30d
[Unit]
Description=Nix Garbage Collector

View file

@ -0,0 +1,9 @@
[Install]
WantedBy=timers.target
[Timer]
OnCalendar=monthly
Unit=nix-gc.service
[Unit]
Description=Nix Garbage Collector