Commit e1dc3a2bee67

Vincent Demeester <vincent@sbr.pm>
2026-07-30 11:50:45
feat: auto-expire home-manager generations weekly
Enabled home-manager autoExpire on Fedora hosts with a custom script that expires generations older than 15 days while always keeping at least 5. Runs nix-collect-garbage without -d to safely clean unreferenced store paths.
1 parent c5215d8
Changed files (1)
home
common
home/common/profiles/work-fedora.nix
@@ -1,4 +1,9 @@
-{ pkgs, ... }:
+{
+  pkgs,
+  lib,
+  config,
+  ...
+}:
 let
   jira-wrapped = pkgs.writeShellScriptBin "jira" ''
     export JIRA_API_TOKEN=$(${pkgs.passage}/bin/passage show redhat/issues/atlassian/token)
@@ -36,6 +41,57 @@ in
   systemd.user.services.emacs.Service.ExecStartPre =
     "-/bin/sh -c 'until test -S /var/run/nscd/socket; do sleep 0.2; done'";
 
+  # Expire old home-manager generations weekly, always keeping at least 5.
+  # On NixOS hosts, generations are managed by nixos-rebuild.
+  services.home-manager.autoExpire = {
+    enable = true;
+    timestamp = "-15 days";
+    frequency = "weekly";
+    store.cleanup = true;
+  };
+
+  # Override the expire script to keep at least 5 generations
+  systemd.user.services.home-manager-auto-expire.Service.ExecStart =
+    let
+      hmPkg = config.programs.home-manager.package;
+      script = pkgs.writeShellScript "home-manager-auto-expire-keep5" ''
+        set -euo pipefail
+        echo "Expire old Home Manager generations (keep at least 5)"
+        PROFILE_DIR="${config.home.profileDirectory}"
+        HM_PROFILE_DIR="$(dirname "$PROFILE_DIR")/home-manager"
+
+        # Get all generation IDs sorted newest-first, skip current
+        current=$(readlink "$HM_PROFILE_DIR/home-manager" | sed 's/^.*-\([0-9]*\)-link$/\1/')
+        all_gens=$(find "$HM_PROFILE_DIR" -name 'home-manager-*-link' -printf '%T@ %f\n' \
+          | sort -rn | sed 's/^.* home-manager-\([0-9]*\)-link$/\1/' \
+          | grep -v "^$current$")
+
+        # Find candidates older than 15 days
+        old_gens=$(find "$HM_PROFILE_DIR" -name 'home-manager-*-link' -not -newermt '-15 days' \
+          | sed 's/^.*-\([0-9]*\)-link$/\1/' \
+          | grep -v "^$current$" || true)
+
+        # Count total generations (including current)
+        total=$(echo "$all_gens" | grep -c . || echo 0)
+        total=$((total + 1))  # add current
+
+        # Only remove if we'd still have at least 5
+        for gen in $old_gens; do
+          if [ "$total" -le 5 ]; then
+            echo "Keeping generation $gen (would go below 5)"
+            break
+          fi
+          echo "Removing generation $gen"
+          ${hmPkg}/bin/home-manager remove-generations "$gen"
+          total=$((total - 1))
+        done
+
+        echo "Clean-up Nix store"
+        nix-collect-garbage
+      '';
+    in
+    lib.mkForce (toString script);
+
   # Google Calendar sync to org-mode
   services.gcal-to-org = {
     enable = true;