rpki/scripts/00_1_pre_check.sh
2026-07-14 14:44:40 +08:00

156 lines
4.4 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PRECHECK_WORK_DIR="${PRECHECK_WORK_DIR:-${ROOT_DIR}/.precheck}"
PRECHECK_ENV_FILE="${PRECHECK_ENV_FILE:-${PRECHECK_WORK_DIR}/precheck.env}"
PRECHECK_WAIT_SECS="${PRECHECK_WAIT_SECS:-60}"
KEEP_PRECHECK="${KEEP_PRECHECK:-0}"
log() {
printf '[00_1_pre_check] %s\n' "$*"
}
stage() {
printf '\n====== %s ======\n' "$*"
}
die() {
printf '[00_1_pre_check] ERROR: %s\n' "$*" >&2
exit 1
}
command -v docker >/dev/null 2>&1 || die "docker command not found"
if docker compose version >/dev/null 2>&1; then
COMPOSE_BIN=(docker compose)
elif command -v docker-compose >/dev/null 2>&1 && docker-compose version >/dev/null 2>&1; then
COMPOSE_BIN=(docker-compose)
else
die "docker compose is not available"
fi
stage "Preparing Pre-Check Data"
bash "${SCRIPT_DIR}/00_2_pre_check_prepare.sh" || die "prepare step failed"
set -a
# shellcheck disable=SC1090
. "${PRECHECK_ENV_FILE}"
set +a
ADMIN_PORT="${RPKI_RTR_ADMIN_ADDR##*:}"
ADMIN_TOKEN="${RPKI_RTR_ADMIN_TOKEN}"
server_compose() {
"${COMPOSE_BIN[@]}" --env-file "${PRECHECK_ENV_FILE}" -p "${PRECHECK_PROJECT}" -f "${PRECHECK_SERVER_COMPOSE_FILE}" "$@"
}
client_compose() {
"${COMPOSE_BIN[@]}" --env-file "${PRECHECK_ENV_FILE}" -p "${PRECHECK_PROJECT}" -f "${PRECHECK_CLIENT_COMPOSE_FILE}" "$@"
}
cleanup() {
KEEP_PRECHECK="${KEEP_PRECHECK}" PRECHECK_WORK_DIR="${PRECHECK_WORK_DIR}" PRECHECK_ENV_FILE="${PRECHECK_ENV_FILE}" \
bash "${SCRIPT_DIR}/00_3_pre_check_cleanup.sh"
}
trap cleanup EXIT
http_get() {
local host="$1"
local port="$2"
local path="$3"
local token="$4"
exec 3<>"/dev/tcp/${host}/${port}" || return 1
printf 'GET %s HTTP/1.1\r\nHost: %s:%s\r\nAuthorization: Bearer %s\r\nConnection: close\r\n\r\n' \
"${path}" "${host}" "${port}" "${token}" >&3
cat <&3
exec 3>&-
}
wait_for_admin_health() {
local deadline=$((SECONDS + PRECHECK_WAIT_SECS))
local response
log "waiting for server health"
while [ "${SECONDS}" -lt "${deadline}" ]; do
response="$(http_get 127.0.0.1 "${ADMIN_PORT}" /admin/rtr/health "${ADMIN_TOKEN}" 2>/dev/null || true)"
if printf '%s' "${response}" | grep -q '"status"[[:space:]]*:[[:space:]]*"ok"'; then
log "admin health check passed"
return 0
fi
if [ "$(server_compose ps -q rpki-rtr | wc -l | tr -d ' ')" = "0" ]; then
server_compose logs rpki-rtr || true
die "server container is not running"
fi
sleep 1
done
server_compose logs rpki-rtr || true
die "admin health check did not pass within ${PRECHECK_WAIT_SECS}s"
}
wait_for_client_eod() {
local deadline=$((SECONDS + PRECHECK_WAIT_SECS))
local log_file
log "waiting for client response"
while [ "${SECONDS}" -lt "${deadline}" ]; do
for log_file in "${PRECHECK_WORK_DIR}"/logs/client/*.stdout.log; do
[ -f "${log_file}" ] || continue
if grep -q 'EndOfData:' "${log_file}" && grep -q 'summary[[:space:]]*:' "${log_file}"; then
log "client received EndOfData and payload summary"
return 0
fi
if grep -qi 'Error Report' "${log_file}"; then
cat "${log_file}" >&2
die "client received RTR Error Report"
fi
done
sleep 1
done
find "${PRECHECK_WORK_DIR}/logs/client" -type f -maxdepth 1 -print -exec cat {} \; >&2 || true
die "client did not receive EndOfData and summary within ${PRECHECK_WAIT_SECS}s"
}
assert_no_error_logs() {
local bad
log "checking logs"
bad="$(find "${PRECHECK_WORK_DIR}/logs" -type f -name '*.log' -print0 \
| xargs -0 grep -Ein 'panic|failed|RTR admin config server exited|Error Report' 2>/dev/null || true)"
if [ -n "${bad}" ]; then
printf '%s\n' "${bad}" >&2
die "error pattern found in pre-check logs"
fi
}
assert_report_written() {
local deadline=$((SECONDS + PRECHECK_WAIT_SECS))
log "waiting for source report"
while [ "${SECONDS}" -lt "${deadline}" ]; do
if find "${PRECHECK_WORK_DIR}/report" -type f -name 'rtr-source-*.json' | grep -q .; then
log "source report written"
return 0
fi
sleep 1
done
die "server did not write rtr-source report within ${PRECHECK_WAIT_SECS}s"
}
stage "Starting RTR Server"
server_compose up -d --no-build rpki-rtr
wait_for_admin_health
assert_report_written
stage "Starting Debug Client"
client_compose up -d --no-build rtr-debug-client
wait_for_client_eod
assert_no_error_logs
stage "Pre-Check Passed"