Files
RustProxy/update.sh
T
2026-10-11 17:10:04 +02:00

155 lines
3.5 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
KEEP_RELEASES=3
KEEP_BACKUPS=3
prune_directories() {
local base="$1"
local keep="$2"
local protected="${3:-}"
local kept=0
local entry
local name
[[ -d "$base" ]] || return 0
if [[ -L "$base" ]]; then
printf 'WARNING: retention cleanup skipped for symlink: %s\n' "$base" >&2
return 0
fi
if [[ -n "$protected" && -d "$base/$protected" && ! -L "$base/$protected" ]]; then
kept=1
fi
while IFS= read -r -d '' entry; do
name="${entry##*/}"
if [[ -n "$protected" && "$name" == "$protected" ]]; then
continue
fi
if (( kept < keep )); then
kept=$((kept + 1))
continue
fi
printf 'Removing old retained item: %s\n' "$entry"
rm -rf -- "$entry"
done < <(
find "$base" \
-mindepth 1 \
-maxdepth 1 \
-type d \
-printf '%T@ %p\0' |
sort -z -nr
)
}
cleanup_installed_releases() {
local prefix="$1"
local releases="$prefix/releases"
local backups="$prefix/backups"
local current="$prefix/current"
local releases_real
local current_real
local current_release
prune_directories "$backups" "$KEEP_BACKUPS"
[[ -d "$releases" && ! -L "$releases" ]] || return 0
if [[ ! -L "$current" ]]; then
printf 'WARNING: release cleanup skipped: %s is not a symlink\n' "$current" >&2
return 0
fi
releases_real="$(readlink -f -- "$releases" || true)"
current_real="$(readlink -f -- "$current" || true)"
if [[ -z "$releases_real" || -z "$current_real" ]]; then
printf 'WARNING: release cleanup skipped: cannot resolve current release\n' >&2
return 0
fi
case "$current_real" in
"$releases_real"/*)
current_release="${current_real##*/}"
;;
*)
printf 'WARNING: release cleanup skipped: current points outside %s\n' \
"$releases" >&2
return 0
;;
esac
prune_directories "$releases" "$KEEP_RELEASES" "$current_release"
}
cleanup_source_backups() {
local target="$1"
local backup_dir
target="$(cd -- "$target" 2>/dev/null && pwd -P)" || return 0
backup_dir="$target/.upgrade-backup"
prune_directories "$backup_dir" "$KEEP_BACKUPS"
}
if [[ "${1:-}" == "--source-tree" ]]; then
shift
if (($# == 0)); then
exec python3 "$ROOT/scripts/deploy/upgrade.py"
fi
source_target="$1"
python3 "$ROOT/scripts/deploy/upgrade.py" "$@"
cleanup_source_backups "$source_target"
exit 0
fi
prefix="/opt/rustproxy"
plan=0
args=("$@")
for ((i = 0; i < ${#args[@]}; i++)); do
case "${args[i]}" in
--prefix)
if ((i + 1 < ${#args[@]})); then
prefix="${args[i + 1]}"
i=$((i + 1))
fi
;;
--prefix=*)
prefix="${args[i]#--prefix=}"
;;
--plan)
plan=1
;;
esac
done
python3 "$ROOT/scripts/deploy/deploy.py" update "$@"
if ((plan)); then
exit 0
fi
if command -v flock >/dev/null 2>&1; then
exec {cleanup_lock_fd}>>"$prefix/.deploy.lock"
flock -x "$cleanup_lock_fd"
cleanup_installed_releases "$prefix"
flock -u "$cleanup_lock_fd"
exec {cleanup_lock_fd}>&-
else
printf 'WARNING: flock unavailable; retention cleanup skipped\n' >&2
fi