]> git.scottworley.com Git - nix-profile-gc/blobdiff - modules/profile-gc.nix
Manage profiles in users' $HOME/.local/state/nix/profiles/
[nix-profile-gc] / modules / profile-gc.nix
index 5444798568249e38724cb965ea3068d0747d2afd..e2f0e3ddfdde276072829f0abdc69f84f637ee21 100644 (file)
@@ -22,10 +22,23 @@ let
     parsed=$(systemd-analyze timespan ${escapeShellArg duration} | awk '$1 == "μs:" { print $2 }')
     echo "$parsed" > "$out"
   '';
+  gather_home_profiles = lib.optionalString cfg.manageHomeProfiles ''
+    while read -r home_dir;do
+      home_profile_dir="$home_dir/.local/state/nix/profiles"
+      if [[ -d "$home_profile_dir" ]];then
+        home_profile_dirs+=( "$home_profile_dir" )
+      fi
+    done < <(${pkgs.coreutils}/bin/cut -d: -f6 /etc/passwd | ${pkgs.coreutils}/bin/sort -u)
+  '';
 in {
   options = {
     nix.profile-gc = {
       enable = lib.mkEnableOption "Automatic profile garbage collection";
+      manageHomeProfiles = lib.mkOption {
+        description = "Manage profiles in users' $HOME/.local/state/nix/profiles/";
+        type = lib.types.bool;
+        default = false;  # Will flip to true later
+      };
       dryRun = lib.mkOption {
         description = "Say what would have been deleted rather than actually deleting profiles";
         type = lib.types.bool;
@@ -153,21 +166,24 @@ in {
       }
 
       declare -A active_targets
-      while read target;do
+      while read -r target;do
         active_targets[$target]=1
       done < <(
         verbose_topn ${cfg.logdir}/active-system "" ${escapeShellArg cfg.keepLastActiveSystem}
         verbose_topn ${cfg.logdir}/active-boot   "" ${escapeShellArg cfg.keepLastActiveBoot  }
       )
 
+      home_profile_dirs=()
+      ${gather_home_profiles}
+
       now=$(${pkgs.coreutils}/bin/date +%s)
       age_threshold="$(< ${parse-duration cfg.keepLatest})"
-      while read profile;do
+      while read -r profile;do
         echo "Contemplating profiles for $profile:" >&2
         unset active
         declare -A active
-        while read p;do
-          active[$p]=1
+        while read -r pname;do
+          active[$pname]=1
         done < <(verbose_topn ${cfg.logdir}/active-profiles "$profile" ${escapeShellArg cfg.keepLastActive})
         current=$(${pkgs.coreutils}/bin/readlink "$profile")
         currentgen=''${current%-link}
@@ -179,7 +195,8 @@ in {
             echo "(Disregarding unrelated profile $p)" >&2
             continue
           fi
-          if [[ "$p" == "$current" ]];then
+          pname=$(${pkgs.coreutils}/bin/basename "$p")
+          if [[ "$pname" == "$current" ]];then
             echo "Keeeping current profile $p" >&2
             continue
           fi
@@ -187,7 +204,7 @@ in {
             echo "Keeeping active system/boot profile $p" >&2
             continue
           fi
-          if [[ "''${active[$p]:-}" ]];then
+          if [[ "''${active[$pname]:-}" ]];then
             echo "Keeeping active profile $p" >&2
             continue
           fi
@@ -208,7 +225,7 @@ in {
             rm "$p"
           ''}
         done
-      done < <(${pkgs.findutils}/bin/find ''${NIX_STATE_DIR:-/nix/var/nix}/profiles/ -type l -not -name '*[0-9]-link')
+      done < <(${pkgs.findutils}/bin/find "''${NIX_STATE_DIR:-/nix/var/nix}/profiles/" "''${home_profile_dirs[@]}" -type l -not -name '*[0-9]-link')
     '';
     systemd.timers.profile-gc-log-active = {
       wantedBy = [ "timers.target" ];
@@ -220,10 +237,13 @@ in {
         "Log the active profiles for gc collection policy evaluation";
       serviceConfig.Type = "oneshot";
       script = ''
+        home_profile_dirs=()
+        ${gather_home_profiles}
+
         ${pkgs.coreutils}/bin/mkdir -p ${cfg.logdir}
         ${pkgs.coreutils}/bin/readlink /run/current-system >> ${cfg.logdir}/active-system
         ${pkgs.coreutils}/bin/readlink /run/booted-system  >> ${cfg.logdir}/active-boot
-        ${pkgs.findutils}/bin/find ''${NIX_STATE_DIR:-/nix/var/nix}/profiles/ \
+        ${pkgs.findutils}/bin/find ''${NIX_STATE_DIR:-/nix/var/nix}/profiles/ "''${home_profile_dirs[@]}" \
           -type l -not -name '*[0-9]-link' \
           -exec ${pkgs.stdenv.shell} -c '
             for f;do