puppet-prod/site/profiles/templates/reposync/autopromoter.erb
Ben Vincent 012e842d7d feat: add cleanup to autopromoter (#393)
- ensure the autopromoter removes hardlinks/replicas for repos older
  than the current promoted monthly
- this is to reduce MDS load for ceph, as hardlinks require memory

Reviewed-on: #393
2025-09-13 20:08:32 +10:00

108 lines
3.2 KiB
Plaintext

#!/usr/bin/env bash
set -euo pipefail
: "${DRY_RUN:=}" # set DRY_RUN=1 to preview deletions
log() { printf '[%(%F %T)T] %s\n' -1 "$*" >&2; }
# Function to create symlink for snapshots
create_symlink() {
local osname="$1" # e.g. almalinux
local release="$2" # e.g. 9.6
local repository="$3" # e.g. appstream
local basepath="$4" # e.g. /shared/apps/packagerepo
local label="$5" # monthly|weekly|daily
local date_value="$6" # YYYYMMDD for the snapshot to promote
local snap_path="${basepath}/snap/${osname}/${release}/${repository}-${date_value}"
local symlink_target="${basepath}/snap/${osname}/${release}/${repository}-${label}"
if [[ -d "$snap_path" ]]; then
ln -sfn "$snap_path" "$symlink_target"
log "Symlink set: ${symlink_target} -> ${snap_path}"
return 0
else
log "Snapshot path does not exist: $snap_path"
return 1
fi
}
# Cleanup snapshot directories older than a cutoff date (YYYYMMDD)
cleanup_older_than_monthly() {
local osname="$1"
local release="$2"
local repository="$3"
local basepath="$4"
local cutoff_date="$5" # newly promoted monthly date, YYYYMMDD
local root="${basepath}/snap/${osname}/${release}"
local pattern="${repository}-"[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
shopt -s nullglob
for dir in "${root}"/${pattern}; do
# Skip symlinks and non-directories
[[ -L "$dir" ]] && continue
[[ -d "$dir" ]] || continue
# Extract the date suffix
local name base datepart
name="$(basename -- "$dir")"
base="${name%-????????}" # remove last 8 chars
datepart="${name#${base}-}" # after "<repo>-"
# Only act on valid YYYYMMDD dates
if [[ "$datepart" =~ ^[0-9]{8}$ ]]; then
if [[ "$datepart" -lt "$cutoff_date" ]]; then
if [[ -n "${DRY_RUN}" ]]; then
log "[DRY_RUN] Would remove: $dir"
else
log "Removing: $dir"
rm -rf --one-file-system -- "$dir"
fi
fi
fi
done
shopt -u nullglob
}
# Determine which snapshot to promote based on the passed argument
case "${1:-}" in
monthly)
promote_date=$(date --date="$(date +%Y%m01) -1 month" +%Y%m%d)
;;
weekly)
promote_date=$(date --date="last Sunday" +%Y%m%d)
;;
daily)
promote_date=$(date --date="yesterday" +%Y%m%d)
;;
*)
echo "Usage: $0 {monthly|weekly|daily}"
exit 1
;;
esac
label="$1"
# Process each repo conf
for conf in /etc/reposync/conf.d/*.conf; do
# shellcheck disable=SC1090
source "$conf"
# Expecting these vars in the conf: OSNAME, RELEASE, REPOSITORY, BASEPATH
: "${OSNAME:?missing OSNAME in $conf}"
: "${RELEASE:?missing RELEASE in $conf}"
: "${REPOSITORY:?missing REPOSITORY in $conf}"
: "${BASEPATH:?missing BASEPATH in $conf}"
# 1) Promote the symlink for this label
if create_symlink "$OSNAME" "$RELEASE" "$REPOSITORY" "$BASEPATH" "$label" "$promote_date"; then
# 2) If monthly, clean up older snapshot dirs for this repo
if [[ "$label" == "monthly" ]]; then
cleanup_older_than_monthly "$OSNAME" "$RELEASE" "$REPOSITORY" "$BASEPATH" "$promote_date"
fi
else
log "Skipping cleanup for ${OSNAME}/${RELEASE}/${REPOSITORY} due to missing ${REPOSITORY}-${promote_date}"
fi
done