Compare commits

..
2 Commits
Author SHA1 Message Date
Felitendo 6514c4d859 Trim the package cache by default, and split it from orphan removal
CleanCache was off, so nothing ever pruned /var/cache/pacman/pkg - 23 GB on the
machine this was found on, with three 3.2 GB copies of one package. Trimming
only drops older versions of installed packages and cached versions of
uninstalled ones, so the cost is downgrade depth, not working software.

flatpak uninstall --unused moves from CleanCache to RemoveOrphans, where it
belongs: unused runtimes are the Flatpak equivalent of orphaned packages, and
removing installed software should not hide behind a flag named for cache
trimming. RemoveOrphans stays off - 'orphaned' only means nothing depends on
it, which is also true of something installed deliberately.

The log now reports what a trim reclaimed, since a real paccache run says
almost nothing and there was otherwise no way to tell it was working.
2026-08-08 15:33:03 +02:00
Felitendo 243115ea19 Show what a run is doing, and record when one is cut short
A run that held back a blocker then upgraded 214 packages printed one line and
then nothing for nearly five minutes while pacman downloaded and installed. It
looked hung, so it got killed - during pacman's uninterruptible commit phase,
which meant the packages landed but our bookkeeping never did. The menu then
kept showing a failure from a previous run on a fully up-to-date machine.

pacman, the AUR helper and flatpak now stream their output when a person is
watching, and the progress bar is left enabled for that case. Timer runs are
unchanged: quiet, --noprogressbar, everything captured in the log.

Interactivity is decided once at startup rather than tested at the point of
use. cau_pacman_flags runs inside a process substitution, so its stdout is
always a pipe and a -t 1 check there would have silently always been false.

INT/TERM/HUP now record last_result=interrupted, so a run that is stopped says
so instead of leaving the previous verdict standing.
2026-08-08 15:24:42 +02:00
11 changed files with 108 additions and 15 deletions

No files matched your search

+1 -1
View File
@@ -8,7 +8,7 @@
# Overridable so a packager can pass the version it is actually building # Overridable so a packager can pass the version it is actually building
# (`make VERSION=$pkgver`). The literal below is the fallback for builds # (`make VERSION=$pkgver`). The literal below is the fallback for builds
# straight from a checkout, and is what a release tag has to carry. # straight from a checkout, and is what a release tag has to carry.
VERSION ?= 1.0.5 VERSION ?= 1.0.7
PREFIX ?= /usr PREFIX ?= /usr
DESTDIR ?= DESTDIR ?=
+9 -2
View File
@@ -55,8 +55,15 @@ business rebuilding somebody's system before being asked.
| Flatpak | system and per-user installations | | Flatpak | system and per-user installations |
| AppImages | via [Gear Lever](https://github.com/mijorus/gearlever), if installed | | AppImages | via [Gear Lever](https://github.com/mijorus/gearlever), if installed |
`-git`/`-devel` AUR packages, cache trimming and orphan removal exist as It also trims the pacman package cache after each run (`paccache`, keeping the
options but are off by default. 3 most recent versions), because otherwise `/var/cache/pacman/pkg` grows
forever — tens of gigabytes on a machine with a few large packages. Set
`KeepOldPackages=1` if disk space matters more than the ability to downgrade.
`-git`/`-devel` AUR packages and orphan removal exist as options but are off by
default. Orphan removal deletes installed software, and "orphaned" only means
nothing else depends on it — which is also true of something installed
deliberately.
## When it holds back ## When it holds back
+3
View File
@@ -254,3 +254,6 @@ msgstr ""
#, c-format #, c-format
msgid "Held back: %s" msgid "Held back: %s"
msgstr "" msgstr ""
msgid "The last run was stopped before it finished."
msgstr ""
+3
View File
@@ -255,3 +255,6 @@ msgstr "%s konnte nicht aktualisiert werden und wurde übersprungen. Alles ander
#, c-format #, c-format
msgid "Held back: %s" msgid "Held back: %s"
msgstr "Zurückgehalten: %s" msgstr "Zurückgehalten: %s"
msgid "The last run was stopped before it finished."
msgstr "Der letzte Lauf wurde abgebrochen, bevor er fertig war."
+18 -5
View File
@@ -66,16 +66,29 @@ AutoResolveConflicts=yes
IgnorePkg= IgnorePkg=
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Housekeeping - all off by default # Housekeeping
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Trim the pacman package cache after an update. # Trim the pacman package cache after an update: drop the older versions of
CleanCache=no # installed packages, and every cached version of packages that are no longer
# installed. Nothing that is currently installed is ever touched, so this only
# costs the ability to downgrade further back than KeepOldPackages.
# Without it /var/cache/pacman/pkg grows forever - tens of gigabytes on a
# machine with a few large packages.
CleanCache=yes
# How many old versions per package to keep when CleanCache is on. # How many old versions per package to keep when CleanCache is on. 3 is the
# Arch default and leaves room to downgrade. Set it to 1 if disk space matters
# more than that; on a machine with a handful of multi-gigabyte packages the
# difference is easily ten gigabytes.
KeepOldPackages=3 KeepOldPackages=3
# Remove packages that were installed as dependencies and are no longer needed. # Remove packages nothing depends on any more: pacman packages that were pulled
# in as dependencies and are now unreferenced, plus Flatpak runtimes no
# installed application uses.
# Off by default, and unlike CleanCache this one deletes installed software:
# "orphaned" only means no other package requires it, which is also true of
# something installed deliberately as a dependency of nothing.
RemoveOrphans=no RemoveOrphans=no
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
+15
View File
@@ -63,6 +63,21 @@ fi
cau_config_load cau_config_load
cau_log_open cau_log_open
# Record an interruption rather than leaving the previous run's verdict behind.
# Without this, killing an interactive run leaves last_result at whatever it was
# before - so the menu can keep reporting a problem from hours ago while the
# machine is in fact fully up to date, which is worse than saying nothing.
# pacman makes the commit phase itself uninterruptible, so the packages either
# all landed or none did; only our own bookkeeping is at risk here.
_cau_interrupted() {
cau_error "Update run interrupted ($1)"
cau_state_write last_result interrupted
exit 130
}
trap '_cau_interrupted SIGINT' INT
trap '_cau_interrupted SIGTERM' TERM
trap '_cau_interrupted SIGHUP' HUP
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Should this run happen at all? # Should this run happen at all?
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
+18 -2
View File
@@ -91,7 +91,14 @@ cau_msg_in() {
# Output and logging # Output and logging
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
if [[ -t 1 && -z ${NO_COLOR:-} ]]; then # Is a person watching? Decided once, here, while stdout is still whatever the
# process was started with. Testing `-t 1` at the point of use is unreliable:
# any function called through $(...) or <(...) sees a pipe on stdout and would
# conclude nobody is there.
CAU_INTERACTIVE=''
[[ -t 1 ]] && CAU_INTERACTIVE=1
if [[ -n $CAU_INTERACTIVE && -z ${NO_COLOR:-} ]]; then
CAU_C_RESET=$'\033[0m' CAU_C_RESET=$'\033[0m'
CAU_C_BOLD=$'\033[1m' CAU_C_BOLD=$'\033[1m'
CAU_C_DIM=$'\033[2m' CAU_C_DIM=$'\033[2m'
@@ -132,10 +139,19 @@ cau_log_open() {
CAU_LOG_OPEN=1 CAU_LOG_OPEN=1
} }
# Runs a command, streaming its combined output into the run log. Returns the # Runs a command, capturing its combined output in the run log. Returns the
# command's exit status. # command's exit status.
#
# When a person is watching - `cachy-auto-update run` from a terminal - the
# output is shown as well. Building an AUR package or pulling a few hundred
# megabytes of Flatpak can take minutes, and silence for that long is
# indistinguishable from a hang.
cau_run_logged() { cau_run_logged() {
if [[ -n ${CAU_LOG_OPEN:-} ]]; then if [[ -n ${CAU_LOG_OPEN:-} ]]; then
if [[ -n $CAU_INTERACTIVE ]]; then
"$@" 2>&1 | tee -a "$CAU_RUNLOG"
return "${PIPESTATUS[0]}"
fi
"$@" >> "$CAU_RUNLOG" 2>&1 "$@" >> "$CAU_RUNLOG" 2>&1
else else
"$@" >&2 "$@" >&2
+1 -1
View File
@@ -96,7 +96,7 @@ cau_config_load() {
CFG_APPIMAGE=no; cau_config_bool UpdateAppImages yes && CFG_APPIMAGE=yes CFG_APPIMAGE=no; cau_config_bool UpdateAppImages yes && CFG_APPIMAGE=yes
CFG_DEVEL=no; cau_config_bool UpdateDevel no && CFG_DEVEL=yes CFG_DEVEL=no; cau_config_bool UpdateDevel no && CFG_DEVEL=yes
CFG_RESOLVE_CONFLICTS=no; cau_config_bool AutoResolveConflicts yes && CFG_RESOLVE_CONFLICTS=yes CFG_RESOLVE_CONFLICTS=no; cau_config_bool AutoResolveConflicts yes && CFG_RESOLVE_CONFLICTS=yes
CFG_CLEAN_CACHE=no; cau_config_bool CleanCache no && CFG_CLEAN_CACHE=yes CFG_CLEAN_CACHE=no; cau_config_bool CleanCache yes && CFG_CLEAN_CACHE=yes
CFG_REMOVE_ORPHANS=no; cau_config_bool RemoveOrphans no && CFG_REMOVE_ORPHANS=yes CFG_REMOVE_ORPHANS=no; cau_config_bool RemoveOrphans no && CFG_REMOVE_ORPHANS=yes
CFG_NOTIFY_SUCCESS=no; cau_config_bool NotifyOnSuccess yes && CFG_NOTIFY_SUCCESS=yes CFG_NOTIFY_SUCCESS=no; cau_config_bool NotifyOnSuccess yes && CFG_NOTIFY_SUCCESS=yes
CFG_NOTIFY_ERROR=no; cau_config_bool NotifyOnError yes && CFG_NOTIFY_ERROR=yes CFG_NOTIFY_ERROR=no; cau_config_bool NotifyOnError yes && CFG_NOTIFY_ERROR=yes
+4
View File
@@ -81,6 +81,10 @@ cau_ui_status() {
printf '\n %s%s%s\n' "$CAU_C_YELLOW" \ printf '\n %s%s%s\n' "$CAU_C_YELLOW" \
"$(cau_msg "The last run reported a problem - see 'cachy-auto-update log'.")" \ "$(cau_msg "The last run reported a problem - see 'cachy-auto-update log'.")" \
"$CAU_C_RESET" "$CAU_C_RESET"
elif [[ $result == interrupted ]]; then
printf '\n %s%s%s\n' "$CAU_C_YELLOW" \
"$(cau_msg "The last run was stopped before it finished.")" \
"$CAU_C_RESET"
fi fi
if [[ $reboot == 1 ]]; then if [[ $reboot == 1 ]]; then
printf '\n %s%s%s\n' "$CAU_C_YELLOW" \ printf '\n %s%s%s\n' "$CAU_C_YELLOW" \
+4 -1
View File
@@ -63,7 +63,10 @@ cau_flatpak_update() {
fi fi
done < <(cau_human_users) done < <(cau_human_users)
if [[ $CFG_CLEAN_CACHE == yes ]]; then # Unused runtimes are the Flatpak equivalent of orphaned packages - this is
# removal of installed software, not cache trimming, so it belongs behind
# RemoveOrphans rather than CleanCache.
if [[ $CFG_REMOVE_ORPHANS == yes ]]; then
cau_run_logged flatpak uninstall --system --unused --noninteractive --assumeyes || true cau_run_logged flatpak uninstall --system --unused --noninteractive --assumeyes || true
fi fi
+32 -3
View File
@@ -15,13 +15,35 @@ CAU_PACMAN_HELD=''
# Base flags for every unattended pacman invocation. # Base flags for every unattended pacman invocation.
cau_pacman_flags() { cau_pacman_flags() {
printf '%s\n' --noconfirm --color never --noprogressbar --disable-download-timeout printf '%s\n' --noconfirm --color never --disable-download-timeout
# A progress bar is worth having when somebody is watching a `run` from a
# terminal; in the timer's log it is only carriage-return noise.
[[ -n $CAU_INTERACTIVE ]] || printf '%s\n' --noprogressbar
local pkg local pkg
for pkg in $CFG_IGNORE_PKG; do for pkg in $CFG_IGNORE_PKG; do
printf '%s\n' --ignore "$pkg" printf '%s\n' --ignore "$pkg"
done done
} }
# _cau_pacman_exec <logfile> <pacman args...>
# Captures pacman's output for classification, and streams it as well when a
# person is watching. Upgrading a few hundred packages takes minutes; without
# this an interactive run shows one line and then nothing at all, which is
# indistinguishable from a hang and invites someone to kill it mid-transaction.
_cau_pacman_exec() {
local log="$1"
shift
if [[ -n $CAU_INTERACTIVE ]]; then
pacman "$@" 2>&1 | tee "$log"
return "${PIPESTATUS[0]}"
fi
pacman "$@" > "$log" 2>&1
}
# cau_pacman_pending # cau_pacman_pending
# Fills CAU_PACMAN_PENDING and returns 1 when there is nothing to do. # Fills CAU_PACMAN_PENDING and returns 1 when there is nothing to do.
cau_pacman_pending() { cau_pacman_pending() {
@@ -121,7 +143,7 @@ cau_pacman_update() {
local attempt=0 b local attempt=0 b
while true; do while true; do
if pacman -Syu "${flags[@]}" "${extra[@]}" > "$log" 2>&1; then if _cau_pacman_exec "$log" -Syu "${flags[@]}" "${extra[@]}"; then
cat "$log" >> "$CAU_RUNLOG" 2>/dev/null cat "$log" >> "$CAU_RUNLOG" 2>/dev/null
grep -E '^(removing|replacing) ' "$log" 2>/dev/null \ grep -E '^(removing|replacing) ' "$log" 2>/dev/null \
| while read -r line; do cau_info " $line"; done | while read -r line; do cau_info " $line"; done
@@ -232,7 +254,14 @@ cau_pacman_cleanup() {
fi fi
if [[ $CFG_CLEAN_CACHE == yes ]] && cau_have paccache; then if [[ $CFG_CLEAN_CACHE == yes ]] && cau_have paccache; then
cau_info "Trimming the package cache" # paccache's dry run reports what a real run would reclaim; logging it
# first is the only way to tell afterwards whether trimming is doing
# anything, since the real run says little.
local reclaim
reclaim="$( { paccache -d --nocolor -k"$CFG_KEEP_OLD"; paccache -du --nocolor -k0; } 2>&1 \
| grep -oE 'disk space saved: [^)]*' | paste -sd', ' -)"
cau_info "Trimming the package cache (keeping $CFG_KEEP_OLD old version(s))${reclaim:+ - $reclaim}"
cau_run_logged paccache -r --nocolor -k"$CFG_KEEP_OLD" || cau_warn "paccache -r failed" cau_run_logged paccache -r --nocolor -k"$CFG_KEEP_OLD" || cau_warn "paccache -r failed"
cau_run_logged paccache -ru --nocolor -k0 || cau_warn "paccache -ru failed" cau_run_logged paccache -ru --nocolor -k0 || cau_warn "paccache -ru failed"
fi fi