75 lines
2.3 KiB
Bash
75 lines
2.3 KiB
Bash
#!/usr/bin/env bash
|
|
# rollback.sh — atomic-swap the live registry tree with the most
|
|
# recent snapshot under /srv/registry/.previous/.
|
|
#
|
|
# Usage (on the OVH host, as deploy-registry or root):
|
|
# bash /srv/registry/ops/rollback.sh
|
|
#
|
|
# Idempotent within reason: a second invocation immediately after the
|
|
# first promotes what was previously live (effectively roll-forward).
|
|
# Exits non-zero with a clear message if no snapshot exists.
|
|
|
|
set -euo pipefail
|
|
|
|
REGISTRY_ROOT="${REGISTRY_ROOT:-/srv/registry}"
|
|
LIVE_R="${REGISTRY_ROOT}/r"
|
|
LIVE_SB="${REGISTRY_ROOT}/storybook"
|
|
SNAPSHOT_ROOT="${REGISTRY_ROOT}/.previous"
|
|
ROLLBACK_PARK="${REGISTRY_ROOT}/.rollback-park"
|
|
|
|
log() {
|
|
printf '[rollback %s] %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$*" >&2
|
|
}
|
|
|
|
err() {
|
|
log "ERROR: $*"
|
|
exit 1
|
|
}
|
|
|
|
if [[ ! -d "${SNAPSHOT_ROOT}" ]]; then
|
|
err "no snapshot directory at ${SNAPSHOT_ROOT}; nothing to roll back to"
|
|
fi
|
|
|
|
# Pick the most recent snapshot directory by name (ISO-8601 lexically sorts).
|
|
LATEST="$(find "${SNAPSHOT_ROOT}" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' 2>/dev/null | sort | tail -n 1)"
|
|
|
|
if [[ -z "${LATEST}" ]]; then
|
|
err "no snapshots present under ${SNAPSHOT_ROOT}; cannot roll back"
|
|
fi
|
|
|
|
SNAPSHOT_DIR="${SNAPSHOT_ROOT}/${LATEST}"
|
|
log "rolling back to snapshot: ${SNAPSHOT_DIR}"
|
|
|
|
# Park the current tree as the next-snapshot so we can roll-forward
|
|
# by re-running the script.
|
|
PARK_DIR="${ROLLBACK_PARK}/$(date -u +%Y%m%dT%H%M%SZ)"
|
|
mkdir -p "${PARK_DIR}"
|
|
|
|
if [[ -d "${LIVE_R}" ]]; then
|
|
mv "${LIVE_R}" "${PARK_DIR}/r"
|
|
fi
|
|
if [[ -d "${LIVE_SB}" ]]; then
|
|
mv "${LIVE_SB}" "${PARK_DIR}/storybook"
|
|
fi
|
|
|
|
# Promote snapshot to live.
|
|
if [[ -d "${SNAPSHOT_DIR}/r" ]]; then
|
|
mv "${SNAPSHOT_DIR}/r" "${LIVE_R}"
|
|
fi
|
|
if [[ -d "${SNAPSHOT_DIR}/storybook" ]]; then
|
|
mv "${SNAPSHOT_DIR}/storybook" "${LIVE_SB}"
|
|
fi
|
|
|
|
# Move the parked tree into the snapshots dir so the next rollback
|
|
# call (a roll-forward) can find it.
|
|
NEW_SNAPSHOT="${SNAPSHOT_ROOT}/$(basename "${PARK_DIR}")"
|
|
mv "${PARK_DIR}" "${NEW_SNAPSHOT}"
|
|
|
|
# Drained snapshot dir is now empty — clean up so next rollback picks
|
|
# the right "latest".
|
|
rmdir "${SNAPSHOT_DIR}" 2>/dev/null || true
|
|
rmdir "${ROLLBACK_PARK}" 2>/dev/null || true
|
|
|
|
log "rollback complete; live tree now serves contents from ${LATEST}"
|
|
log "previous live tree parked at ${NEW_SNAPSHOT} (re-run to roll forward)"
|