#!/usr/bin/env bash set -euo pipefail if [[ "${EUID}" -ne 0 ]]; then echo "ananke-self-update.sh must run as root" >&2 exit 1 fi REPO_URL="${ANANKE_REPO_URL:-ssh://git@scm.bstein.dev:2242/bstein/ananke.git}" BRANCH="${ANANKE_REPO_BRANCH:-main}" REPO_DIR="${ANANKE_REPO_DIR:-/opt/ananke}" HOST_SHORT="$(hostname -s 2>/dev/null || hostname)" LOG_FILE="${ANANKE_UPDATE_LOG_FILE:-/var/log/ananke/update.log}" STATE_FILE="${ANANKE_UPDATE_STATE_FILE:-/var/lib/ananke/update-last.env}" LOCK_FILE="${ANANKE_UPDATE_LOCK_FILE:-/var/lock/ananke-update.lock}" ALLOW_QUALITY_FALLBACK="${ANANKE_UPDATE_ALLOW_QUALITY_FALLBACK:-1}" QUALITY_GATE_MODE="${ANANKE_ENFORCE_QUALITY_GATE:-1}" mkdir -p "$(dirname "${LOG_FILE}")" "$(dirname "${STATE_FILE}")" "$(dirname "${LOCK_FILE}")" touch "${LOG_FILE}" "${STATE_FILE}" chmod 0644 "${LOG_FILE}" "${STATE_FILE}" || true exec 9>"${LOCK_FILE}" if ! flock -n 9; then printf '[self-update] %s another update is already running; exiting\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" | tee -a "${LOG_FILE}" exit 0 fi exec > >(tee -a "${LOG_FILE}") 2>&1 write_state() { local status="$1" local detail="$2" local from_rev="$3" local to_rev="$4" local now now="$(date -u +%Y-%m-%dT%H:%M:%SZ)" cat > "${STATE_FILE}" </dev/null || echo unknown)" git reset --hard "origin/${BRANCH}" if [[ "${CURRENT_FROM_REV}" == "${TARGET_TO_REV}" ]]; then echo "[self-update] already up to date at ${CURRENT_FROM_REV}" else echo "[self-update] update candidate ${CURRENT_FROM_REV} -> ${TARGET_TO_REV}" fi echo "[self-update] running installer" # Keep host configs aligned with tracked templates so startup/shutdown drills # always use the latest checklist and safety logic. if [[ -z "${ANANKE_FORCE_CONFIG_TEMPLATE:-}" ]]; then case "${HOST_SHORT}" in titan-db) export ANANKE_FORCE_CONFIG_TEMPLATE="coordinator" ;; titan-24) export ANANKE_FORCE_CONFIG_TEMPLATE="peer" ;; esac fi export ANANKE_ENFORCE_QUALITY_GATE="${QUALITY_GATE_MODE}" if "${REPO_DIR}/scripts/install.sh"; then write_state "ok" "install-success" "${CURRENT_FROM_REV}" "${TARGET_TO_REV}" echo "[self-update] completed successfully" exit 0 fi if [[ "${ALLOW_QUALITY_FALLBACK}" == "1" || "${ALLOW_QUALITY_FALLBACK}" == "true" ]]; then echo "[self-update] install failed in strict mode; retrying once with ANANKE_ENFORCE_QUALITY_GATE=0" export ANANKE_ENFORCE_QUALITY_GATE=0 "${REPO_DIR}/scripts/install.sh" write_state "degraded-ok" "fallback-no-quality-gate" "${CURRENT_FROM_REV}" "${TARGET_TO_REV}" echo "[self-update] completed via fallback mode" exit 0 fi