mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-08-26 21:13:57 +02:00
feat(nixos): manage scattered trash dirs with trash-cli retention timer (#265)
* feat(nushell): add trash command using the home trash can On a tmpfs root with persistent dirs bind-mounted in, `rm --trash` scatters items into per-mount .Trash-$uid dirs that file managers never show, and gio refuses to trash on those internal mounts. Add a `trash` command implementing the freedesktop trash spec 'failsafe' mode: items are moved to ~/.local/share/Trash with spec-compliant .trashinfo entries, so Thunar can list and restore them. Also preserve ~/.local/share/Trash on idols-ai so the trash survives reboots. * feat(nixos): manage scattered trash dirs with trash-cli retention timer Replace the hand-written nushell trash command with the established trash-cli tooling. On a tmpfs root with persistent dirs bind-mounted in, the trash crate (nushell rm --trash) scatters items into per-mount .Trash-$uid dirs that file managers never show and nothing cleans up. - add trash-cli to system packages: trash-list scans/trash-restore handles every mount point's trash dir - daily systemd timer runs 'trash-empty 30 -f', purging items older than 30 days across the home trash and all mount points - drop the hand-written trash.nu module - note in preservation.nix: do NOT persist ~/.local/share/Trash; a bind-mounted trash dir breaks the trash crate's home-topdir match for files straight under $HOME (it would try /.Trash-$uid, EACCES) * fix(nixos): order trash-empty after preservation.target The scattered .Trash-$uid dirs live inside the preservation bind mounts, which use DefaultDependencies=no and are therefore NOT ordered after local-fs.target. Add preservation.target to After= so trash-empty only runs once all those mounts are up.
This commit is contained in:
@@ -110,6 +110,14 @@ in
|
|||||||
# Keep .cache off tmpfs to avoid high RAM usage; many apps use it and it is storage-heavy.
|
# Keep .cache off tmpfs to avoid high RAM usage; many apps use it and it is storage-heavy.
|
||||||
".cache"
|
".cache"
|
||||||
|
|
||||||
|
# NOTE: do NOT persist ~/.local/share/Trash here. The trash crate (nushell
|
||||||
|
# `rm --trash`) picks the home trash only when the file's mount topdir equals
|
||||||
|
# the trash dir's topdir; a bind-mounted Trash dir would make files straight
|
||||||
|
# under $HOME fail with EACCES (it would try /.Trash-$uid). The home trash on
|
||||||
|
# tmpfs is lost on reboot, which is acceptable: scattered per-mount
|
||||||
|
# .Trash-$uid dirs on persistent volumes are covered by the trash-empty
|
||||||
|
# retention timer (modules/nixos/base/trash.nix).
|
||||||
|
|
||||||
# ======================================
|
# ======================================
|
||||||
# Codes / Work / Playground
|
# Codes / Work / Playground
|
||||||
# ======================================
|
# ======================================
|
||||||
|
|||||||
@@ -86,5 +86,6 @@
|
|||||||
which
|
which
|
||||||
tree
|
tree
|
||||||
tealdeer # a very fast version of tldr
|
tealdeer # a very fast version of tldr
|
||||||
|
trash-cli # freedesktop trash can CLI: trash-list / trash-restore / trash-put / trash-empty
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
{
|
||||||
|
# ==================================================================
|
||||||
|
#
|
||||||
|
# Trash retention cleanup (nixpkgs `trash-cli`)
|
||||||
|
# https://github.com/andreafrancia/trash-cli
|
||||||
|
#
|
||||||
|
# On a tmpfs root with persistent dirs bind-mounted in, the trash
|
||||||
|
# crate (nushell `rm --trash`, GUI file managers) scatters items into
|
||||||
|
# per-mount .Trash-$uid dirs that file managers never show. This timer
|
||||||
|
# purges trash items older than RETENTION_DAYS across the home trash
|
||||||
|
# and all mount points.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# trash-list # view items in all trash dirs
|
||||||
|
# trash-restore <file> # restore an item
|
||||||
|
# trash-rm <file> # remove a single item from the trash
|
||||||
|
# trash-empty 30 -f # run the retention purge manually
|
||||||
|
#
|
||||||
|
# ==================================================================
|
||||||
|
|
||||||
|
myvars,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
retentionDays = 30;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.services.trash-empty = {
|
||||||
|
description = "Purge trash items older than ${toString retentionDays} days";
|
||||||
|
script = ''
|
||||||
|
${pkgs.trash-cli}/bin/trash-empty ${toString retentionDays} -f
|
||||||
|
'';
|
||||||
|
# The scattered .Trash-$uid dirs live inside the preservation bind mounts, so we
|
||||||
|
# must run after preservation.target (reached only once all those mounts are up).
|
||||||
|
# preservation.mount units use DefaultDependencies=no, so they are NOT ordered
|
||||||
|
# after local-fs.target on their own; list both to be safe on every host.
|
||||||
|
# On hosts without preservation, the After=preservation.target edge is a no-op.
|
||||||
|
after = [
|
||||||
|
"local-fs.target"
|
||||||
|
"preservation.target"
|
||||||
|
];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = myvars.username;
|
||||||
|
Environment = [
|
||||||
|
"HOME=/home/${myvars.username}"
|
||||||
|
"XDG_DATA_HOME=/home/${myvars.username}/.local/share"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.trash-empty = {
|
||||||
|
description = "Timer for the trash-empty service";
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "daily";
|
||||||
|
RandomizedDelaySec = "15min";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user