#!/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"