modify scripts

This commit is contained in:
xiuting.xu 2026-07-17 09:51:53 +08:00
parent 490b79f22c
commit 5fb79a7c8d
3 changed files with 444 additions and 12 deletions

View File

@ -4,23 +4,25 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
COMMON_ENV_FILE="${ROOT_DIR}/environment"
COMMON_ENV_FILE="${ROOT_DIR}/environment.server"
SERVER_ENV_FILE="${ROOT_DIR}/deploy/server/.env"
CONSOLE_ENV_FILE="${ROOT_DIR}/deploy/console/.env"
CONSOLE_COMPOSE_FILE="${ROOT_DIR}/deploy/console/docker-compose.yml"
MODE="${RPKI_RTR_SERVER_MODE:-tcp}"
COMPOSE_PROJECT="${RPKI_RTR_COMPOSE_PROJECT:-rpki-rtr}"
CONSOLE_COMPOSE_PROJECT="${RPKI_CONSOLE_COMPOSE_PROJECT:-rpki-console}"
WAIT_SECS="${RPKI_START_WAIT_SECS:-20}"
usage() {
cat <<'EOF'
Usage: scripts/01_start.sh [options]
Read root ./environment, update deploy/server/.env, then start the RTR server and console.
Read root ./environment.server, update deploy/server/.env, then start the RTR server and console.
Options:
--env FILE Common env file. Default: ./environment
--env FILE Common env file. Default: ./environment.server
--mode MODE Server mode: tcp|tls|ssh|base. Default: tcp
--wait SECS Wait timeout for container running checks. Default: 20
-h, --help Show this help.
EOF
}
@ -94,6 +96,63 @@ update_env_from_common() {
printf '%s\n' "${updated_count}"
}
server_compose() {
"${COMPOSE_BIN[@]}" --env-file "${SERVER_ENV_FILE}" -p "${COMPOSE_PROJECT}" -f "${SERVER_COMPOSE_FILE}" "$@"
}
console_compose() {
"${COMPOSE_BIN[@]}" --env-file "${CONSOLE_ENV_FILE}" -p "${CONSOLE_COMPOSE_PROJECT}" -f "${CONSOLE_COMPOSE_FILE}" "$@"
}
container_running() {
local compose_kind="$1"
local service="$2"
local cid state
if [ "${compose_kind}" = "server" ]; then
cid="$(server_compose ps -q "${service}" 2>/dev/null || true)"
else
cid="$(console_compose ps -q "${service}" 2>/dev/null || true)"
fi
[ -n "${cid}" ] || return 1
state="$(docker inspect -f '{{.State.Running}}' "${cid}" 2>/dev/null || true)"
[ "${state}" = "true" ]
}
show_service_debug() {
local compose_kind="$1"
local service="$2"
log "${service} is not running, current compose status:"
if [ "${compose_kind}" = "server" ]; then
server_compose ps "${service}" >&2 || true
log "${service} recent logs:"
server_compose logs --tail=80 "${service}" >&2 || true
else
console_compose ps "${service}" >&2 || true
log "${service} recent logs:"
console_compose logs --tail=80 "${service}" >&2 || true
fi
}
wait_for_running() {
local compose_kind="$1"
local service="$2"
local deadline=$((SECONDS + WAIT_SECS))
while [ "${SECONDS}" -lt "${deadline}" ]; do
if container_running "${compose_kind}" "${service}"; then
log "${service} is running"
return 0
fi
sleep 1
done
show_service_debug "${compose_kind}" "${service}"
die "${service} failed to reach running state after ${WAIT_SECS}s"
}
while [ "$#" -gt 0 ]; do
case "$1" in
--env)
@ -106,6 +165,11 @@ while [ "$#" -gt 0 ]; do
MODE="$2"
shift 2
;;
--wait)
[ "$#" -ge 2 ] || die "--wait requires a value"
WAIT_SECS="$2"
shift 2
;;
-h|--help)
usage
exit 0
@ -139,21 +203,19 @@ if [ -f "${COMMON_ENV_FILE}" ]; then
log "updated ${server_updated_count} server env variable(s)"
else
stage "Reading Environment"
log "environment file not found, skip env update"
log "environment.server file not found, skip env update"
fi
stage "Starting RTR Server"
log "starting docker compose service: rpki-rtr"
"${COMPOSE_BIN[@]}" --env-file "${SERVER_ENV_FILE}" -p "${COMPOSE_PROJECT}" -f "${SERVER_COMPOSE_FILE}" up -d --no-build rpki-rtr
log "checking server compose status"
"${COMPOSE_BIN[@]}" --env-file "${SERVER_ENV_FILE}" -p "${COMPOSE_PROJECT}" -f "${SERVER_COMPOSE_FILE}" ps rpki-rtr
server_compose up -d --no-build rpki-rtr
log "waiting for rpki-rtr to be running"
wait_for_running server rpki-rtr
stage "Starting Console"
log "starting docker compose service: rpki-console-ui"
"${COMPOSE_BIN[@]}" --env-file "${CONSOLE_ENV_FILE}" -p "${CONSOLE_COMPOSE_PROJECT}" -f "${CONSOLE_COMPOSE_FILE}" up -d --no-build rpki-console-ui
log "checking console compose status"
"${COMPOSE_BIN[@]}" --env-file "${CONSOLE_ENV_FILE}" -p "${CONSOLE_COMPOSE_PROJECT}" -f "${CONSOLE_COMPOSE_FILE}" ps rpki-console-ui
console_compose up -d --no-build rpki-console-ui
log "waiting for rpki-console-ui to be running"
wait_for_running console rpki-console-ui
stage "Start Finished"

152
scripts/04_cleanup.sh Normal file
View File

@ -0,0 +1,152 @@
#!/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"

218
scripts/README.md Normal file
View File

@ -0,0 +1,218 @@
# 脚本说明
`scripts/` 目录用于离线安装、启动、健康检查、关闭和清理。
所有脚本建议在仓库根目录执行:
```bash
bash scripts/00_0_install.sh
```
## 目录
- [推荐流程](#推荐流程)
- [环境变量文件](#环境变量文件)
- [00 安装](#00-安装)
- [00 Pre-Check](#00-pre-check)
- [01 启动 Server 和 Console](#01-启动-server-和-console)
- [02 自检](#02-自检)
- [03 关闭 Server 和 Console](#03-关闭-server-和-console)
- [04 清理](#04-清理)
- [10 生成证书](#10-生成证书)
- [11 启动 Client](#11-启动-client)
- [12 关闭 Client](#12-关闭-client)
- [Windows 路径注意事项](#windows-路径注意事项)
## 推荐流程
```bash
# 1. 加载镜像并执行 pre-check。
bash scripts/00_0_install.sh
# 2. 启动真实 server 和 console。
bash scripts/01_start.sh --mode tcp
# 3. 检查 server 和 console 是否正常。
bash scripts/02_self_check.sh
# 4. 关闭 server 和 console。
bash scripts/03_shutdown.sh --mode tcp
# 5. 清理 server 运行产生的文件。
bash scripts/04_cleanup.sh
```
client 单独启动和关闭:
```bash
bash scripts/11_start_client.sh --mode tcp
bash scripts/12_shutdown_client.sh --mode tcp
```
支持的模式:
- server`tcp``tls``ssh``base`
- client`tcp``tls``ssh`
## 环境变量文件
`01_start.sh` 会读取根目录下的 `environment.server`。如果文件存在,会将其中所有 `KEY=VALUE` 同步到 `deploy/server/.env`
示例:
```env
RPKI_RTR_CCR_HOST_DIR=/opt/rpki-rtr/data
RPKI_RTR_SLURM_HOST_DIR=/opt/rpki-rtr/data
RPKI_RTR_DB_HOST_DIR=/opt/rpki-rtr/rtr-db
RPKI_RTR_LOG_HOST_DIR=/opt/rpki-rtr/logs/server
RPKI_RTR_REPORT_HOST_DIR=/opt/rpki-rtr/report
```
`11_start_client.sh` 会读取根目录下的 `environment.client`。如果文件存在,会将其中所有 `KEY=VALUE` 同步到 `deploy/client/.env`
如果 `environment.server``environment.client` 不存在,对应脚本会跳过更新,直接使用已有的 deploy `.env` 文件。
## 00 安装
`00_0_install.sh` 用于从 `images/` 目录加载离线 Docker 镜像,更新 deploy `.env` 中的镜像名,然后执行 pre-check。
默认镜像包查找规则:
- server`images/rpki-rtr-*.tar`,排除 `rpki-rtr-debug-client-*.tar`
- client`images/rpki-rtr-debug-client-*.tar`
- console`images/rpki-console-ui-*.tar`
也可以显式指定镜像包:
```bash
bash scripts/00_0_install.sh \
--server-tar images/rpki-rtr-amd64-v1.2.tar \
--client-tar images/rpki-rtr-debug-client-amd64-v1.2.tar \
--console-tar images/rpki-console-ui-amd64-v1.0.tar
```
脚本会从 `docker load` 输出中解析真实镜像名,并写入:
- `deploy/server/.env``RPKI_RTR_SERVER_IMAGE`
- `deploy/console/.env``RPKI_CONSOLE_UI_IMAGE`
## 00 Pre-Check
`00_1_pre_check.sh` 会在 `.precheck/` 下准备隔离测试数据,使用仓库里的 Docker Compose 文件启动 server 和 debug client然后检查
- admin health 接口返回正常。
- server 写出了 source report。
- debug client 收到了 EndOfData 和 payload summary。
- pre-check 日志中没有 fatal 错误模式。
相关辅助脚本:
- `00_2_generate_ccr.sh`:生成固定的 CCR 测试文件。
- `00_2_pre_check_prepare.sh`:创建 `.precheck/` 数据、SLURM 文件和 env 文件。
- `00_3_pre_check_cleanup.sh`:停止 pre-check 容器并清理 `.precheck/`
## 01 启动 Server 和 Console
`01_start.sh` 用于启动真实的 RTR server 和 console。
```bash
bash scripts/01_start.sh --mode tcp
```
启动后脚本会检查容器是否进入 `running` 状态。如果容器启动后退出,脚本会打印 compose 状态和最近日志,然后报错退出,不会继续打印 `Start Finished`
常用参数:
```bash
bash scripts/01_start.sh --mode tls
bash scripts/01_start.sh --mode ssh
bash scripts/01_start.sh --wait 60
bash scripts/01_start.sh --env ./environment.server
```
注意console 不读取 `environment.server`,只使用 `deploy/console/.env`
## 02 自检
`02_self_check.sh` 用于检查 `01_start.sh` 启动的 server 和 console 是否正常。
```bash
bash scripts/02_self_check.sh
```
检查内容包括:
- server 容器是否 running。
- console 容器是否 running。
- RTR TCP 端口是否可连接。
- admin health 接口是否健康。
- console 端口和 HTTP 根路径是否可访问。
如果启动较慢,可以增加等待时间:
```bash
bash scripts/02_self_check.sh --wait 120
```
## 03 关闭 Server 和 Console
`03_shutdown.sh` 用于关闭 `01_start.sh` 启动的服务。
```bash
bash scripts/03_shutdown.sh --mode tcp
```
脚本会先关闭 console再关闭 RTR server。
## 04 清理
`04_cleanup.sh` 用于删除 server 运行产生的目录:
- `logs/`
- `report/`
- `rtr-db/`
推荐先关闭服务,再清理:
```bash
bash scripts/03_shutdown.sh
bash scripts/04_cleanup.sh
```
清理前脚本会检查 `rpki-rtr` 是否仍在运行。如果仍在运行,会拒绝清理。只有明确需要强制清理时才使用:
```bash
bash scripts/04_cleanup.sh --force
```
清理脚本会拒绝删除仓库根目录之外的路径。如果某一项清理失败,会继续清理后续项,最后返回失败。
## 10 生成证书
`10_generate_certs.sh` 用于生成 TLS/SSH 模式需要的本地证书材料(测试用)。
```bash
bash scripts/10_generate_certs.sh
```
## 11 启动 Client
`11_start_client.sh` 用于启动 RTR debug client。
```bash
bash scripts/11_start_client.sh --mode tcp
bash scripts/11_start_client.sh --mode tls
bash scripts/11_start_client.sh --mode ssh
```
如果 `environment.client` 存在,脚本会将其中所有 `KEY=VALUE` 同步到 `deploy/client/.env`;如果不存在,则直接使用已有的 `deploy/client/.env`
## 12 关闭 Client
`12_shutdown_client.sh` 用于关闭 `11_start_client.sh` 启动的 client。
```bash
bash scripts/12_shutdown_client.sh --mode tcp
```
关闭时建议使用和启动时相同的 mode。