rpki/scripts/04_cleanup.sh
2026-07-17 09:51:53 +08:00

153 lines
3.5 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
SERVER_DIR="${ROOT_DIR}/deploy/server"
SERVER_ENV_FILE="${SERVER_DIR}/.env"
SERVER_COMPOSE_FILE="${SERVER_DIR}/docker-compose.tcp.yml"
COMPOSE_PROJECT="${RPKI_RTR_COMPOSE_PROJECT:-rpki-rtr}"
FORCE=0
usage() {
cat <<'EOF'
Usage: scripts/04_cleanup.sh [options]
Remove server generated directories: logs, reports, and RTR database.
Options:
--force Clean even if the server container appears to be running.
-h, --help Show this help.
EOF
}
log() {
printf '[04_cleanup] %s\n' "$*" >&2
}
stage() {
printf '\n====== %s ======\n' "$*" >&2
}
die() {
printf '[04_cleanup] ERROR: %s\n' "$*" >&2
exit 1
}
env_value() {
local key="$1"
local default_value="$2"
local line
line="$(grep -E "^[[:space:]]*${key}=" "${SERVER_ENV_FILE}" | tail -n 1 || true)"
if [ -n "${line}" ]; then
printf '%s\n' "${line#*=}"
else
printf '%s\n' "${default_value}"
fi
}
resolve_host_path() {
local raw_path="$1"
case "${raw_path}" in
/*|[A-Za-z]:/*|[A-Za-z]:\\*)
printf '%s\n' "${raw_path}"
;;
*)
(cd "${SERVER_DIR}" && cd "${raw_path}" 2>/dev/null && pwd -P) || printf '%s/%s\n' "${SERVER_DIR}" "${raw_path}"
;;
esac
}
compose_available() {
if docker compose version >/dev/null 2>&1; then
COMPOSE_BIN=(docker compose)
return 0
fi
if command -v docker-compose >/dev/null 2>&1 && docker-compose version >/dev/null 2>&1; then
COMPOSE_BIN=(docker-compose)
return 0
fi
return 1
}
server_running() {
local cid state
[ -f "${SERVER_COMPOSE_FILE}" ] || return 1
compose_available || return 1
cid="$("${COMPOSE_BIN[@]}" --env-file "${SERVER_ENV_FILE}" -p "${COMPOSE_PROJECT}" -f "${SERVER_COMPOSE_FILE}" ps -q rpki-rtr 2>/dev/null || true)"
[ -n "${cid}" ] || return 1
state="$(docker inspect -f '{{.State.Running}}' "${cid}" 2>/dev/null || true)"
[ "${state}" = "true" ]
}
clean_dir() {
local label="$1"
local path="$2"
local root_with_slash
if [ ! -d "${path}" ]; then
log "${label}: ${path} not found, skip"
return 0
fi
root_with_slash="${ROOT_DIR}/"
case "${path}/" in
"${root_with_slash}"*) ;;
*)
log "ERROR: ${label} path is outside repo root, refuse to remove: ${path}"
return 1
;;
esac
log "${label}: removing ${path}"
if ! rm -rf "${path}"; then
log "ERROR: failed to remove ${label}: ${path}"
return 1
fi
}
while [ "$#" -gt 0 ]; do
case "$1" in
--force)
FORCE=1
shift
;;
-h|--help)
usage
exit 0
;;
*)
die "unknown option: $1"
;;
esac
done
stage "Checking Server"
[ -f "${SERVER_ENV_FILE}" ] || die "server env file not found: ${SERVER_ENV_FILE}"
if [ "${FORCE}" -ne 1 ] && command -v docker >/dev/null 2>&1 && server_running; then
die "rpki-rtr is still running, run scripts/03_shutdown.sh first or use --force"
fi
LOG_DIR="${ROOT_DIR}/logs"
REPORT_DIR="$(resolve_host_path "$(env_value RPKI_RTR_REPORT_HOST_DIR '../../report')")"
DB_DIR="$(resolve_host_path "$(env_value RPKI_RTR_DB_HOST_DIR '../../rtr-db')")"
stage "Removing Server Files"
failed_count=0
clean_dir "logs" "${LOG_DIR}" || failed_count=$((failed_count + 1))
clean_dir "report" "${REPORT_DIR}" || failed_count=$((failed_count + 1))
clean_dir "rtr-db" "${DB_DIR}" || failed_count=$((failed_count + 1))
if [ "${failed_count}" -gt 0 ]; then
die "${failed_count} cleanup item(s) failed"
fi
stage "Cleanup Finished"