- filter type=container (a running VM without apt/agent would hang) - skip containers without apt-get instead of erroring - flock against overlapping runs, csv parsing, apt-get instead of apt - capture stderr into the log, report per-container failures and exit non-zero so cron/monitoring can alert Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
41 lines
1.3 KiB
Bash
Executable File
41 lines
1.3 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# apt dist-upgrade of all RUNNING containers (containers only — VMs are
|
|
# excluded, they may not run an agent or apt at all). Containers without
|
|
# apt are skipped. Exits non-zero if any upgrade failed.
|
|
|
|
set -uo pipefail
|
|
|
|
INCUS=/usr/bin/incus
|
|
LOG=/var/log/incus-container-upgrade.log
|
|
LOCKFILE=/run/lock/incus-container-upgrade.lock
|
|
|
|
# refuse to overlap with a previous, still-running invocation
|
|
exec 9> "$LOCKFILE"
|
|
if ! flock -n 9; then
|
|
echo "another incus-container-upgrade run holds $LOCKFILE, aborting" >&2
|
|
exit 1
|
|
fi
|
|
|
|
distUpgrade() {
|
|
local CT=$1
|
|
echo -e "\n*** [$(date '+%F %T')] - Dist-upgrading $CT container ***\n"
|
|
if ! $INCUS exec "$CT" -- sh -c 'command -v apt-get >/dev/null'; then
|
|
echo "$CT: no apt-get in container, skipping"
|
|
return 0
|
|
fi
|
|
$INCUS exec "$CT" --env DEBIAN_FRONTEND=noninteractive -- apt-get -qq update &&
|
|
$INCUS exec "$CT" -- sh -c 'apt list --upgradable 2>/dev/null' &&
|
|
$INCUS exec "$CT" --env DEBIAN_FRONTEND=noninteractive -- apt-get -qq -y dist-upgrade
|
|
}
|
|
|
|
RC=0
|
|
for CT in $($INCUS list -c n -f csv status=RUNNING type=container); do
|
|
if ! distUpgrade "$CT" 2>&1 | tee -a "$LOG"; then
|
|
echo "[$(date '+%F %T')] FAILED: $CT" | tee -a "$LOG" >&2
|
|
RC=1
|
|
fi
|
|
done
|
|
|
|
exit $RC
|