20260713 unify installer scripts and RTR registration

This commit is contained in:
yuyr 2026-07-13 12:46:40 +08:00
parent b66b425512
commit 9f4f4cf069
20 changed files with 346 additions and 100 deletions

View File

@ -45,7 +45,7 @@
"pluginVersion": "11.3.1", "pluginVersion": "11.3.1",
"targets": [ "targets": [
{ {
"expr": "ours_rp_cir_trust_anchors", "expr": "max(ours_rp_cir_trust_anchors and on (exported_instance) topk(1, ours_rp_run_sequence))",
"legendFormat": "RIRs", "legendFormat": "RIRs",
"refId": "A" "refId": "A"
} }
@ -89,7 +89,7 @@
"pluginVersion": "11.3.1", "pluginVersion": "11.3.1",
"targets": [ "targets": [
{ {
"expr": "ours_rp_run_duration_seconds", "expr": "max(ours_rp_run_duration_seconds and on (exported_instance) topk(1, ours_rp_run_sequence))",
"legendFormat": "wall", "legendFormat": "wall",
"refId": "A" "refId": "A"
} }
@ -133,7 +133,7 @@
"pluginVersion": "11.3.1", "pluginVersion": "11.3.1",
"targets": [ "targets": [
{ {
"expr": "ours_rp_run_max_rss_bytes", "expr": "max(ours_rp_run_max_rss_bytes and on (exported_instance) topk(1, ours_rp_run_sequence))",
"legendFormat": "rss", "legendFormat": "rss",
"refId": "A" "refId": "A"
} }
@ -178,7 +178,7 @@
"pluginVersion": "11.3.1", "pluginVersion": "11.3.1",
"targets": [ "targets": [
{ {
"expr": "ours_rp_publication_points", "expr": "max(ours_rp_publication_points and on (exported_instance) topk(1, ours_rp_run_sequence))",
"legendFormat": "publication points", "legendFormat": "publication points",
"refId": "A" "refId": "A"
} }
@ -223,7 +223,7 @@
"pluginVersion": "11.3.1", "pluginVersion": "11.3.1",
"targets": [ "targets": [
{ {
"expr": "ours_rp_run_sequence", "expr": "max(ours_rp_run_sequence)",
"legendFormat": "seq", "legendFormat": "seq",
"refId": "A" "refId": "A"
} }
@ -287,7 +287,7 @@
"pluginVersion": "11.3.1", "pluginVersion": "11.3.1",
"targets": [ "targets": [
{ {
"expr": "100 * sum by (job, instance, exported_instance) (ours_rp_repo_terminal_state_count{terminal_state=\"publication_point_cache\"}) / sum by (job, instance, exported_instance) (ours_rp_publication_points)", "expr": "max((100 * sum by (exported_instance) (ours_rp_repo_terminal_state_count{terminal_state=\"publication_point_cache\"}) / sum by (exported_instance) (ours_rp_publication_points)) and on (exported_instance) topk(1, ours_rp_run_sequence))",
"legendFormat": "PP cache hit ratio", "legendFormat": "PP cache hit ratio",
"refId": "A" "refId": "A"
} }
@ -332,7 +332,7 @@
"pluginVersion": "11.3.1", "pluginVersion": "11.3.1",
"targets": [ "targets": [
{ {
"expr": "ours_rp_vrps{kind=\"total\"}", "expr": "max(ours_rp_vrps{kind=\"total\"} and on (exported_instance) topk(1, ours_rp_run_sequence))",
"legendFormat": "VRPs raw", "legendFormat": "VRPs raw",
"refId": "A" "refId": "A"
} }
@ -377,7 +377,7 @@
"pluginVersion": "11.3.1", "pluginVersion": "11.3.1",
"targets": [ "targets": [
{ {
"expr": "ours_rp_vaps", "expr": "max(ours_rp_vaps and on (exported_instance) topk(1, ours_rp_run_sequence))",
"legendFormat": "VAPs", "legendFormat": "VAPs",
"refId": "A" "refId": "A"
} }

View File

@ -6,7 +6,7 @@ This package deploys ours RP on Linux servers whose host architecture matches th
The package includes four architecture-matched images: ours RP runtime, artifact metrics, Prometheus, and Grafana. Deployment does not need to pull application images on the target host. Runtime state, run artifacts, logs, Prometheus data and Grafana data are persisted through host bind mounts. The package includes four architecture-matched images: ours RP runtime, artifact metrics, Prometheus, and Grafana. Deployment does not need to pull application images on the target host. Runtime state, run artifacts, logs, Prometheus data and Grafana data are persisted through host bind mounts.
Every installer build rebuilds the ours RP runtime and artifact metrics images. The deliverable name is `ours-rp-installer-{arch}-{git8}-{YYYYMMDDTHHMMSSZ}.tar.gz`, and both ours RP image tags use the current source commit. `PACKAGE-MANIFEST.env` records the full commit, UTC build time, dirty state, and image archive hashes; `./status.sh --brief` displays that provenance after installation. Every installer build rebuilds the ours RP runtime and artifact metrics images. The deliverable name is `ours-rp-installer-{arch}-{git8}-{YYYYMMDDTHHMMSSZ}.tar.gz`, and both ours RP image tags use the current source commit. `PACKAGE-MANIFEST.env` records the full commit, UTC build time, dirty state, and image archive hashes; `./scripts/status.sh --brief` displays that provenance after installation.
By default the host architecture must match `PACKAGE_ARCH` from `PACKAGE-MANIFEST.env`. If you intentionally want to run this package on a different host architecture through QEMU/binfmt, set: By default the host architecture must match `PACKAGE_ARCH` from `PACKAGE-MANIFEST.env`. If you intentionally want to run this package on a different host architecture through QEMU/binfmt, set:
@ -18,7 +18,7 @@ ALLOW_CROSS_ARCH=1
`compose/` is the single production Docker Compose template source. The Docker installer build script copies this directory directly. Do not maintain a second copy of the Compose, Prometheus, or Grafana dashboard files elsewhere. `compose/` is the single production Docker Compose template source. The Docker installer build script copies this directory directly. Do not maintain a second copy of the Compose, Prometheus, or Grafana dashboard files elsewhere.
The legacy direct Compose deployment entry point has been removed. For either amd64 or arm64, build the matching installer package with `scripts/docker/build_docker_installer_package.sh`, then use `install.sh`, `start.sh`, and `status.sh` as described here. The legacy direct Compose deployment entry point has been removed. For either amd64 or arm64, build the matching installer package with `scripts/docker/build_docker_installer_package.sh`, then use `scripts/install.sh`, `scripts/start.sh`, and `scripts/status.sh` as described here.
## Quick Start ## Quick Start
@ -26,11 +26,11 @@ The legacy direct Compose deployment entry point has been removed. For either am
tar -xzf ours-rp-installer-__PACKAGE_ARCH__-*.tar.gz tar -xzf ours-rp-installer-__PACKAGE_ARCH__-*.tar.gz
cd ours-rp-installer-__PACKAGE_ARCH__-* cd ours-rp-installer-__PACKAGE_ARCH__-*
./install.sh ./scripts/install.sh
cp .env.example .env # install.sh creates .env automatically if missing cp .env.example .env # install.sh creates .env automatically if missing
vim .env vim .env
./start.sh ./scripts/start.sh
./status.sh ./scripts/status.sh
``` ```
Defaults: Defaults:
@ -52,7 +52,7 @@ Defaults:
- `METRICS_PLATFORM=__PACKAGE_PLATFORM__` - `METRICS_PLATFORM=__PACKAGE_PLATFORM__`
- `MONITOR_PLATFORM=__PACKAGE_PLATFORM__` - `MONITOR_PLATFORM=__PACKAGE_PLATFORM__`
- `ALLOW_CROSS_ARCH=0` - `ALLOW_CROSS_ARCH=0`
- `RTR_REPORT_DIR=__HOST_DATA_DIR__/empty-rtr-report`, which mounts an empty fallback directory by default; set it to a real host directory such as `/root/rpki/report` to ingest reports from a separately deployed RTR service - `RTR_REPORT_DIR=__HOST_DATA_DIR__/empty-rtr-report`, which mounts an empty fallback directory by default; after deploying a separate RTR service, register its same-host report directory through `scripts/register_rtr_monitor.sh`
## First Start Semantics ## First Start Semantics
@ -117,14 +117,13 @@ Change the password and restrict public access for production deployments.
## Optional RTR report metrics input ## Optional RTR report metrics input
If a separately deployed RTR service on the same host continuously writes `rtr-source-*`, `rtr-runtime-*`, and `rtr-clients-*` JSON reports, configure: If a separately deployed RTR service on the same host continuously writes `rtr-source-*`, `rtr-runtime-*`, and `rtr-clients-*` JSON reports, run:
```bash ```bash
RTR_REPORT_DIR=/root/rpki/report ./scripts/register_rtr_monitor.sh --report-dir /root/rpki/report
RTR_REPORT_CONTAINER_DIR=/var/lib/ours-rp/rtr-report
``` ```
The `artifact-metrics` container mounts the host directory read-only and reads it through `RPKI_METRICS_RTR_REPORT_DIR`, producing `ours_rp_rtr_*` metrics. By default, `RTR_REPORT_DIR` points at an empty fallback directory under the installer data root, so the metrics container also starts cleanly without an RTR service. The command accepts only an absolute path on the same host, validates the candidate Compose mount, and atomically updates `.env`. It recreates only `artifact-metrics`, Prometheus, and Grafana; it does not restart or recreate `ours-rp-soak`. The `artifact-metrics` container mounts the directory read-only and reads it through `RPKI_METRICS_RTR_REPORT_DIR`, producing `ours_rp_rtr_*` metrics. By default, `RTR_REPORT_DIR` points at an empty fallback directory under the installer data root, so the metrics container also starts cleanly without an RTR service.
## Data Directory ## Data Directory
@ -172,12 +171,12 @@ Check the latest `run-meta.json` for:
## Common Commands ## Common Commands
```bash ```bash
./status.sh ./scripts/status.sh
./logs.sh ours-rp-soak --tail 200 ./scripts/logs.sh ours-rp-soak --tail 200
./restart.sh ./scripts/restart.sh
./stop.sh ./scripts/stop.sh
./cleanup.sh --keep-runs 100 --execute ./scripts/cleanup.sh --keep-runs 100 --execute
./uninstall.sh ./scripts/uninstall.sh
``` ```
For finite acceptance tests, for example `MAX_RUNS=3`, also set: For finite acceptance tests, for example `MAX_RUNS=3`, also set:
@ -191,5 +190,5 @@ Otherwise Compose `unless-stopped` will restart the container after it exits suc
`uninstall.sh` keeps data by default. Use the following only when you really want to delete `HOST_DATA_DIR`: `uninstall.sh` keeps data by default. Use the following only when you really want to delete `HOST_DATA_DIR`:
```bash ```bash
./uninstall.sh --purge-data ./scripts/uninstall.sh --purge-data
``` ```

View File

@ -6,7 +6,7 @@
安装包内置与包架构一致的四类镜像ours RP runtime、artifact metrics、Prometheus、Grafana。部署时不需要现场拉取应用镜像。运行产物、状态数据库、日志、Prometheus 和 Grafana 数据均通过宿主机目录挂载保存。 安装包内置与包架构一致的四类镜像ours RP runtime、artifact metrics、Prometheus、Grafana。部署时不需要现场拉取应用镜像。运行产物、状态数据库、日志、Prometheus 和 Grafana 数据均通过宿主机目录挂载保存。
每次构建安装包都会重新构建 ours RP runtime 与 artifact metrics 镜像。交付包命名为 `ours-rp-installer-{arch}-{git8}-{YYYYMMDDTHHMMSSZ}.tar.gz`,两类 ours RP 镜像分别使用当前源码 commit 的 tag。完整 commit、UTC 构建时间、dirty 状态和镜像归档 hash 保存在 `PACKAGE-MANIFEST.env`,可通过 `./status.sh --brief` 查看。 每次构建安装包都会重新构建 ours RP runtime 与 artifact metrics 镜像。交付包命名为 `ours-rp-installer-{arch}-{git8}-{YYYYMMDDTHHMMSSZ}.tar.gz`,两类 ours RP 镜像分别使用当前源码 commit 的 tag。完整 commit、UTC 构建时间、dirty 状态和镜像归档 hash 保存在 `PACKAGE-MANIFEST.env`,可通过 `./scripts/status.sh --brief` 查看。
默认情况下,宿主架构必须与 `PACKAGE-MANIFEST.env` 中的 `PACKAGE_ARCH` 匹配;若确需在异构主机上通过 QEMU/binfmt 运行,必须显式设置: 默认情况下,宿主架构必须与 `PACKAGE-MANIFEST.env` 中的 `PACKAGE_ARCH` 匹配;若确需在异构主机上通过 QEMU/binfmt 运行,必须显式设置:
@ -18,7 +18,7 @@ ALLOW_CROSS_ARCH=1
`compose/` 是唯一的生产 Docker Compose 模板来源Docker 安装包构建脚本会直接复制该目录。不要在其他目录维护第二份 compose、Prometheus 或 Grafana dashboard 文件。 `compose/` 是唯一的生产 Docker Compose 模板来源Docker 安装包构建脚本会直接复制该目录。不要在其他目录维护第二份 compose、Prometheus 或 Grafana dashboard 文件。
旧的直接 Compose 部署入口已经移除。需要部署 amd64 或 arm64 时,统一先用 `scripts/docker/build_docker_installer_package.sh` 构建对应架构安装包,再按本说明执行 `install.sh`、`start.sh` 和 `status.sh`。 旧的直接 Compose 部署入口已经移除。需要部署 amd64 或 arm64 时,统一先用 `scripts/docker/build_docker_installer_package.sh` 构建对应架构安装包,再按本说明执行 `scripts/install.sh`、`scripts/start.sh` 和 `scripts/status.sh`。
## 快速开始 ## 快速开始
@ -26,11 +26,11 @@ ALLOW_CROSS_ARCH=1
tar -xzf ours-rp-installer-__PACKAGE_ARCH__-*.tar.gz tar -xzf ours-rp-installer-__PACKAGE_ARCH__-*.tar.gz
cd ours-rp-installer-__PACKAGE_ARCH__-* cd ours-rp-installer-__PACKAGE_ARCH__-*
./install.sh ./scripts/install.sh
cp .env.example .env # 如 install.sh 已自动创建,可直接编辑现有 .env cp .env.example .env # 如 install.sh 已自动创建,可直接编辑现有 .env
vim .env vim .env
./start.sh ./scripts/start.sh
./status.sh ./scripts/status.sh
``` ```
默认配置: 默认配置:
@ -52,7 +52,7 @@ vim .env
- `METRICS_PLATFORM=__PACKAGE_PLATFORM__` - `METRICS_PLATFORM=__PACKAGE_PLATFORM__`
- `MONITOR_PLATFORM=__PACKAGE_PLATFORM__` - `MONITOR_PLATFORM=__PACKAGE_PLATFORM__`
- `ALLOW_CROSS_ARCH=0` - `ALLOW_CROSS_ARCH=0`
- `RTR_REPORT_DIR=__HOST_DATA_DIR__/empty-rtr-report`,默认挂载空目录;如需接入独立 RTR 服务 report可设置为宿主机真实目录例如 `/root/rpki/report` - `RTR_REPORT_DIR=__HOST_DATA_DIR__/empty-rtr-report`,默认挂载空目录;独立 RTR 服务部署完成后,使用 `scripts/register_rtr_monitor.sh` 注册同机 report 目录
## 首次启动语义 ## 首次启动语义
@ -117,14 +117,13 @@ GRAFANA_ADMIN_PASSWORD=admin
## 可选 RTR report 监控接入 ## 可选 RTR report 监控接入
如果同一台机器上已经有独立部署的 RTR 服务,并且它持续输出 `rtr-source-*``rtr-runtime-*``rtr-clients-*` JSON report可在 `.env` 中配置 如果同一台机器上已经有独立部署的 RTR 服务,并且它持续输出 `rtr-source-*``rtr-runtime-*``rtr-clients-*` JSON report执行
```bash ```bash
RTR_REPORT_DIR=/root/rpki/report ./scripts/register_rtr_monitor.sh --report-dir /root/rpki/report
RTR_REPORT_CONTAINER_DIR=/var/lib/ours-rp/rtr-report
``` ```
`artifact-metrics` 容器会以只读方式挂载该目录,并通过 `RPKI_METRICS_RTR_REPORT_DIR` 读取 report输出 `ours_rp_rtr_*` 指标。默认 `RTR_REPORT_DIR` 指向安装包数据目录下的空 fallback 目录,因此未接入 RTR 服务时 metrics 容器也能稳定启动。 该命令只接受本机绝对路径,会先校验候选 Compose 挂载,再原子更新 `.env`。随后只重建 `artifact-metrics`、Prometheus 和 Grafana不重启或重建 `ours-rp-soak``artifact-metrics` 以只读方式挂载该目录,并通过 `RPKI_METRICS_RTR_REPORT_DIR` 读取 report输出 `ours_rp_rtr_*` 指标。默认 `RTR_REPORT_DIR` 指向安装包数据目录下的空 fallback 目录,因此未接入 RTR 服务时 metrics 容器也能稳定启动。
## 数据目录 ## 数据目录
@ -172,12 +171,12 @@ PERIODIC_SNAPSHOT_MAX_DELTAS=100
## 常用命令 ## 常用命令
```bash ```bash
./status.sh ./scripts/status.sh
./logs.sh ours-rp-soak --tail 200 ./scripts/logs.sh ours-rp-soak --tail 200
./restart.sh ./scripts/restart.sh
./stop.sh ./scripts/stop.sh
./cleanup.sh --keep-runs 100 --execute ./scripts/cleanup.sh --keep-runs 100 --execute
./uninstall.sh ./scripts/uninstall.sh
``` ```
如果做有限轮次验收,例如 `MAX_RUNS=3`,建议同时设置: 如果做有限轮次验收,例如 `MAX_RUNS=3`,建议同时设置:
@ -191,7 +190,7 @@ SOAK_RESTART_POLICY=no
`uninstall.sh` 默认不删除数据。只有显式执行: `uninstall.sh` 默认不删除数据。只有显式执行:
```bash ```bash
./uninstall.sh --purge-data ./scripts/uninstall.sh --purge-data
``` ```
才会删除 `HOST_DATA_DIR` 才会删除 `HOST_DATA_DIR`

View File

@ -3,7 +3,7 @@
## Install ## Install
```bash ```bash
./install.sh ./scripts/install.sh
``` ```
The installer is idempotent: The installer is idempotent:
@ -17,13 +17,13 @@ The installer is idempotent:
## Start ## Start
```bash ```bash
./start.sh ./scripts/start.sh
``` ```
Start without waiting for the first snapshot: Start without waiting for the first snapshot:
```bash ```bash
./start.sh --no-wait-first-run ./scripts/start.sh --no-wait-first-run
``` ```
If you intentionally want to run this package on a different host architecture through QEMU/binfmt, first set: If you intentionally want to run this package on a different host architecture through QEMU/binfmt, first set:
@ -32,20 +32,20 @@ If you intentionally want to run this package on a different host architecture t
ALLOW_CROSS_ARCH=1 ALLOW_CROSS_ARCH=1
``` ```
Then rerun `./install.sh` or `./self-check.sh`, and only then will the scripts attempt to enable the matching binfmt handler. Then rerun `./scripts/install.sh` or `./scripts/self-check.sh`, and only then will the scripts attempt to enable the matching binfmt handler.
## Stop and Restart ## Stop and Restart
```bash ```bash
./stop.sh ./scripts/stop.sh
./restart.sh ./scripts/restart.sh
``` ```
## Status Checks ## Status Checks
```bash ```bash
./status.sh ./scripts/status.sh
./self-check.sh ./scripts/self-check.sh
``` ```
Important checks: Important checks:
@ -73,15 +73,20 @@ Important checks:
To verify RTR report ingestion: To verify RTR report ingestion:
```bash ```bash
./scripts/register_rtr_monitor.sh --report-dir /root/rpki/report --dry-run
./scripts/register_rtr_monitor.sh --report-dir /root/rpki/report
./scripts/status.sh
curl -s "http://127.0.0.1:${METRICS_PORT:-9556}/metrics" | grep '^ours_rp_rtr_' | head curl -s "http://127.0.0.1:${METRICS_PORT:-9556}/metrics" | grep '^ours_rp_rtr_' | head
``` ```
Registration accepts only an absolute directory on the same host. The command retains a timestamped `.env` backup and updates only the metrics, Prometheus, and Grafana sidecars; the `ours-rp-soak` container ID must remain unchanged.
## Upgrade ## Upgrade
Extract the new package into a new directory and explicitly reuse the existing `.env` through the upgrade script: Extract the new package into a new directory and explicitly reuse the existing `.env` through the upgrade script:
```bash ```bash
./upgrade.sh --reuse-env-from /path/to/old-installer/.env ./scripts/upgrade.sh --reuse-env-from /path/to/old-installer/.env
``` ```
If the new package directory already has a `.env`, the upgrade script keeps it. If the new package directory already has a `.env`, the upgrade script keeps it.
@ -125,8 +130,8 @@ PERIODIC_SNAPSHOT_MAX_DELTAS=100
## Cleanup ## Cleanup
```bash ```bash
./cleanup.sh --keep-runs 100 ./scripts/cleanup.sh --keep-runs 100
./cleanup.sh --keep-runs 100 --execute ./scripts/cleanup.sh --keep-runs 100 --execute
``` ```
Cleanup is dry-run by default. Add `--execute` after reviewing the output. Cleanup is dry-run by default. Add `--execute` after reviewing the output.

View File

@ -3,7 +3,7 @@
## 安装 ## 安装
```bash ```bash
./install.sh ./scripts/install.sh
``` ```
安装脚本是幂等的: 安装脚本是幂等的:
@ -17,13 +17,13 @@
## 启动 ## 启动
```bash ```bash
./start.sh ./scripts/start.sh
``` ```
如需后台启动后不等待首轮 snapshot 如需后台启动后不等待首轮 snapshot
```bash ```bash
./start.sh --no-wait-first-run ./scripts/start.sh --no-wait-first-run
``` ```
如需显式允许异构主机通过 QEMU/binfmt 跑包,先在 `.env` 中设置: 如需显式允许异构主机通过 QEMU/binfmt 跑包,先在 `.env` 中设置:
@ -32,20 +32,20 @@
ALLOW_CROSS_ARCH=1 ALLOW_CROSS_ARCH=1
``` ```
然后重新执行 `./install.sh` 或 `./self-check.sh`,脚本才会尝试启用对应 binfmt。 然后重新执行 `./scripts/install.sh` 或 `./scripts/self-check.sh`,脚本才会尝试启用对应 binfmt。
## 停止和重启 ## 停止和重启
```bash ```bash
./stop.sh ./scripts/stop.sh
./restart.sh ./scripts/restart.sh
``` ```
## 状态检查 ## 状态检查
```bash ```bash
./status.sh ./scripts/status.sh
./self-check.sh ./scripts/self-check.sh
``` ```
重点检查项: 重点检查项:
@ -73,15 +73,20 @@ ALLOW_CROSS_ARCH=1
如需确认 RTR report 已接入: 如需确认 RTR report 已接入:
```bash ```bash
./scripts/register_rtr_monitor.sh --report-dir /root/rpki/report --dry-run
./scripts/register_rtr_monitor.sh --report-dir /root/rpki/report
./scripts/status.sh
curl -s "http://127.0.0.1:${METRICS_PORT:-9556}/metrics" | grep '^ours_rp_rtr_' | head curl -s "http://127.0.0.1:${METRICS_PORT:-9556}/metrics" | grep '^ours_rp_rtr_' | head
``` ```
注册只支持同机的绝对目录。注册命令会保留一份带时间戳的 `.env` 备份,并且只更新 metrics、Prometheus、Grafana 三个旁路容器;`ours-rp-soak` 的容器 ID 应保持不变。
## 升级 ## 升级
把新安装包解压到新目录后,推荐通过升级脚本显式复用旧 `.env` 把新安装包解压到新目录后,推荐通过升级脚本显式复用旧 `.env`
```bash ```bash
./upgrade.sh --reuse-env-from /path/to/old-installer/.env ./scripts/upgrade.sh --reuse-env-from /path/to/old-installer/.env
``` ```
如果新目录已经存在 `.env`,升级脚本会保留它,不覆盖。 如果新目录已经存在 `.env`,升级脚本会保留它,不覆盖。
@ -125,8 +130,8 @@ PERIODIC_SNAPSHOT_MAX_DELTAS=100
## 清理 ## 清理
```bash ```bash
./cleanup.sh --keep-runs 100 ./scripts/cleanup.sh --keep-runs 100
./cleanup.sh --keep-runs 100 --execute ./scripts/cleanup.sh --keep-runs 100 --execute
``` ```
默认 dry-run确认后加 `--execute` 默认 dry-run确认后加 `--execute`

View File

@ -12,7 +12,7 @@ docker compose version
If missing, run: If missing, run:
```bash ```bash
./install.sh ./scripts/install.sh
``` ```
## Package Architecture Mismatch ## Package Architecture Mismatch
@ -55,11 +55,11 @@ docker run --rm --platform __PACKAGE_PLATFORM__ \
## RTR report metrics are empty ## RTR report metrics are empty
Check `.env`: First check registration and the report directory:
```bash ```bash
grep '^RTR_REPORT_DIR=' .env ./scripts/status.sh
test -d "$(grep '^RTR_REPORT_DIR=' .env | cut -d= -f2-)" && echo ok ./scripts/register_rtr_monitor.sh --report-dir /root/rpki/report --dry-run
``` ```
Check the metrics container mount: Check the metrics container mount:
@ -74,7 +74,7 @@ docker inspect "$(grep '^COMPOSE_PROJECT_NAME=' .env | cut -d= -f2-)-artifact-me
All-five snapshot can be slow, especially under QEMU. Increase timeout: All-five snapshot can be slow, especially under QEMU. Increase timeout:
```bash ```bash
./start.sh --timeout-secs 14400 ./scripts/start.sh --timeout-secs 14400
``` ```
## Output Counts Are Too Low ## Output Counts Are Too Low

View File

@ -12,7 +12,7 @@ docker compose version
如果缺失,重新执行: 如果缺失,重新执行:
```bash ```bash
./install.sh ./scripts/install.sh
``` ```
## 架构不匹配报错 ## 架构不匹配报错
@ -55,11 +55,11 @@ docker run --rm --platform __PACKAGE_PLATFORM__ \
## RTR report 指标为空 ## RTR report 指标为空
检查 `.env` 先检查注册状态和 report 目录
```bash ```bash
grep '^RTR_REPORT_DIR=' .env ./scripts/status.sh
test -d "$(grep '^RTR_REPORT_DIR=' .env | cut -d= -f2-)" && echo ok ./scripts/register_rtr_monitor.sh --report-dir /root/rpki/report --dry-run
``` ```
检查 metrics 容器是否挂载该目录: 检查 metrics 容器是否挂载该目录:
@ -74,7 +74,7 @@ docker inspect "$(grep '^COMPOSE_PROJECT_NAME=' .env | cut -d= -f2-)-artifact-me
all5 snapshot 可能很慢,尤其在 QEMU 环境。可以提高超时: all5 snapshot 可能很慢,尤其在 QEMU 环境。可以提高超时:
```bash ```bash
./start.sh --timeout-secs 14400 ./scripts/start.sh --timeout-secs 14400
``` ```
## 产物数量异常偏低 ## 产物数量异常偏低

View File

@ -1,14 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/common.sh # shellcheck source=common.sh
source "$SCRIPT_DIR/scripts/common.sh" source "$SCRIPT_DIR/common.sh"
DRY_RUN=1 DRY_RUN=1
KEEP_RUNS="" KEEP_RUNS=""
usage() { usage() {
cat <<'USAGE' cat <<'USAGE'
Usage: ./cleanup.sh [--execute] [--keep-runs N] Usage: ./scripts/cleanup.sh [--execute] [--keep-runs N]
By default this is a dry-run. It removes old run_* directories beyond KEEP_RUNS By default this is a dry-run. It removes old run_* directories beyond KEEP_RUNS
and clears tmp contents. and clears tmp contents.

View File

@ -224,6 +224,82 @@ validate_rtr_report_dir() {
[[ -d "$RTR_REPORT_DIR" ]] || die "RTR_REPORT_DIR does not exist or is not a directory: $RTR_REPORT_DIR" [[ -d "$RTR_REPORT_DIR" ]] || die "RTR_REPORT_DIR does not exist or is not a directory: $RTR_REPORT_DIR"
} }
validate_rtr_registration_dir() {
local report_dir="$1"
[[ -n "$report_dir" ]] || die "--report-dir is required"
[[ "$report_dir" = /* ]] || die "--report-dir must be an absolute host path: $report_dir"
[[ "$report_dir" =~ ^/[A-Za-z0-9._/@:+,-]+$ ]] || die "--report-dir contains unsupported characters: $report_dir"
[[ -d "$report_dir" ]] || die "--report-dir does not exist: $report_dir"
[[ -r "$report_dir" ]] || die "--report-dir is not readable: $report_dir"
}
rtr_report_file_count() {
local report_dir="$1"
{
find "$report_dir" -maxdepth 1 -type f \( \
-name 'rtr-source-*.json' -o \
-name 'rtr-runtime-*.json' -o \
-name 'rtr-clients-*.json' \
\) -print 2>/dev/null || true
} | wc -l | tr -d '[:space:]'
}
latest_rtr_report_file() {
local report_dir="$1"
{
find "$report_dir" -maxdepth 1 -type f \( \
-name 'rtr-source-*.json' -o \
-name 'rtr-runtime-*.json' -o \
-name 'rtr-clients-*.json' \
\) -printf '%T@ %p\n' 2>/dev/null || true
} | sort -nr | awk 'NR == 1 { sub(/^[^ ]+ /, ""); print }'
}
replace_env_key_file() {
local env_path="$1"
local key="$2"
local value="$3"
local temp_path
[[ "$key" =~ ^[A-Z][A-Z0-9_]*$ ]] || die "invalid environment key: $key"
[[ "$value" != *$'\n'* && "$value" != *$'\r'* ]] || die "environment value must be single-line"
temp_path="$(mktemp "${env_path}.tmp.XXXXXX")"
awk -v key="$key" -v value="$value" '
BEGIN { replaced = 0 }
$0 ~ "^" key "=" {
print key "=" value
replaced = 1
next
}
{ print }
END {
if (!replaced) {
print key "=" value
}
}
' "$env_path" > "$temp_path"
chmod --reference="$env_path" "$temp_path" 2>/dev/null || true
mv "$temp_path" "$env_path"
}
wait_for_endpoint() {
local url="$1"
local timeout_secs="$2"
local elapsed=0
while (( elapsed < timeout_secs )); do
if endpoint_ok "$url"; then
return 0
fi
sleep 2
elapsed=$((elapsed + 2))
done
return 1
}
create_data_dirs() { create_data_dirs() {
load_env load_env
mkdir -p \ mkdir -p \

View File

@ -1,12 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/common.sh # shellcheck source=common.sh
source "$SCRIPT_DIR/scripts/common.sh" source "$SCRIPT_DIR/common.sh"
usage() { usage() {
cat <<'USAGE' cat <<'USAGE'
Usage: ./install.sh [--skip-dep-install] Usage: ./scripts/install.sh [--skip-dep-install]
Install or update the ours RP Docker installer package idempotently. Install or update the ours RP Docker installer package idempotently.
USAGE USAGE

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/common.sh # shellcheck source=common.sh
source "$SCRIPT_DIR/scripts/common.sh" source "$SCRIPT_DIR/common.sh"
load_env load_env
compose_cmd --profile core --profile sidecar --profile monitor logs "$@" compose_cmd --profile core --profile sidecar --profile monitor logs "$@"

View File

@ -0,0 +1,149 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/common.sh"
REPORT_DIR=""
DRY_RUN=0
CANDIDATE_ENV=""
CONFIG_FILE=""
ORIGINAL_ENV_FILE=""
ENV_BACKUP=""
REGISTRATION_APPLIED=0
usage() {
cat <<'EOF'
Usage: ./scripts/register_rtr_monitor.sh --report-dir <absolute-host-path> [--dry-run]
Registers one local RTR report directory for the artifact metrics sidecar.
The directory must be on the same host as this installer and may contain
rtr-source-*.json, rtr-runtime-*.json, and rtr-clients-*.json report files.
This command recreates only artifact-metrics, Prometheus, and Grafana. It does
not restart or recreate the ours-rp-soak container.
EOF
}
cleanup() {
[[ -n "$CANDIDATE_ENV" && -f "$CANDIDATE_ENV" ]] && rm -f "$CANDIDATE_ENV"
[[ -n "$CONFIG_FILE" && -f "$CONFIG_FILE" ]] && rm -f "$CONFIG_FILE"
return 0
}
trap cleanup EXIT
restore_failed_registration() {
if (( REGISTRATION_APPLIED == 0 )) || [[ -z "$ENV_BACKUP" || ! -f "$ENV_BACKUP" ]]; then
return 0
fi
warn "registration failed after .env replacement; restoring previous metrics configuration"
cp -p "$ENV_BACKUP" "$ORIGINAL_ENV_FILE"
ENV_FILE="$ORIGINAL_ENV_FILE"
load_env || warn "unable to reload restored .env"
compose_cmd --profile sidecar up -d --force-recreate artifact-metrics \
|| warn "unable to recreate artifact-metrics with restored configuration"
}
fail_after_apply() {
restore_failed_registration
die "$*"
}
while (( $# > 0 )); do
case "$1" in
--report-dir)
[[ $# -ge 2 ]] || die "--report-dir requires a value"
REPORT_DIR="$2"
shift 2
;;
--dry-run)
DRY_RUN=1
shift
;;
-h|--help)
usage
exit 0
;;
*)
die "unknown argument: $1"
;;
esac
done
require_cmd docker
require_cmd curl
require_cmd grep
require_cmd jq
validate_rtr_registration_dir "$REPORT_DIR"
load_env
assert_arch_compatibility
ORIGINAL_ENV_FILE="$ENV_FILE"
REPORT_FILE_COUNT="$(rtr_report_file_count "$REPORT_DIR")"
LATEST_REPORT_FILE="$(latest_rtr_report_file "$REPORT_DIR")"
if (( REPORT_FILE_COUNT == 0 )); then
warn "no recognized RTR report JSON files are currently present in $REPORT_DIR"
fi
CANDIDATE_ENV="$(mktemp "$INSTALLER_ROOT/.env.rtr-register.XXXXXX")"
cp -p "$ORIGINAL_ENV_FILE" "$CANDIDATE_ENV"
replace_env_key_file "$CANDIDATE_ENV" "RTR_REPORT_DIR" "$REPORT_DIR"
ENV_FILE="$CANDIDATE_ENV"
load_env
CONFIG_FILE="$(mktemp "$INSTALLER_ROOT/.rtr-compose-config.XXXXXX")"
compose_cmd --profile sidecar --profile monitor config --format json > "$CONFIG_FILE"
jq -e --arg source "$REPORT_DIR" --arg target "$RTR_REPORT_CONTAINER_DIR" '
.services["artifact-metrics"].volumes
| any(.[]; .type == "bind" and .source == $source and .target == $target and .read_only == true)
' "$CONFIG_FILE" >/dev/null || die "candidate compose configuration is missing expected read-only RTR bind mount"
if (( DRY_RUN == 1 )); then
printf 'dry_run=ok\n'
printf 'report_dir=%s\n' "$REPORT_DIR"
printf 'recognized_report_files=%s\n' "$REPORT_FILE_COUNT"
printf 'latest_report=%s\n' "${LATEST_REPORT_FILE:--}"
printf 'expected_mount_source=%s\n' "$REPORT_DIR"
printf 'expected_mount_target=%s\n' "$RTR_REPORT_CONTAINER_DIR"
exit 0
fi
ENV_FILE="$ORIGINAL_ENV_FILE"
load_env
soak_container_before="$(compose_cmd ps -q ours-rp-soak || true)"
ENV_BACKUP="${ORIGINAL_ENV_FILE}.rtr-register-$(date -u +%Y%m%dT%H%M%SZ).bak"
cp -p "$ORIGINAL_ENV_FILE" "$ENV_BACKUP"
mv "$CANDIDATE_ENV" "$ORIGINAL_ENV_FILE"
CANDIDATE_ENV=""
REGISTRATION_APPLIED=1
load_env
compose_cmd --profile sidecar up -d --force-recreate artifact-metrics \
|| fail_after_apply "unable to recreate artifact-metrics"
compose_cmd --profile sidecar --profile monitor up -d prometheus grafana \
|| fail_after_apply "unable to start Prometheus and Grafana"
soak_container_after="$(compose_cmd ps -q ours-rp-soak || true)"
if [[ -n "$soak_container_before" && "$soak_container_before" != "$soak_container_after" ]]; then
fail_after_apply "ours-rp-soak container changed during RTR registration; investigate before continuing"
fi
wait_for_endpoint "http://127.0.0.1:${METRICS_PORT:-9556}/metrics" 60 \
|| fail_after_apply "artifact-metrics did not become ready"
wait_for_endpoint "http://127.0.0.1:${PROMETHEUS_PORT:-9090}/-/ready" 60 \
|| fail_after_apply "Prometheus did not become ready"
wait_for_endpoint "http://127.0.0.1:${GRAFANA_PORT:-3000}/api/health" 60 \
|| fail_after_apply "Grafana did not become ready"
if (( REPORT_FILE_COUNT > 0 )); then
curl -fsS "http://127.0.0.1:${METRICS_PORT:-9556}/metrics" | grep -q '^ours_rp_rtr_' \
|| fail_after_apply "artifact-metrics exposes no RTR metrics after registration"
fi
printf 'registration=ok\n'
printf 'report_dir=%s\n' "$REPORT_DIR"
printf 'recognized_report_files=%s\n' "$REPORT_FILE_COUNT"
printf 'latest_report=%s\n' "${LATEST_REPORT_FILE:--}"
printf 'env_backup=%s\n' "$ENV_BACKUP"
printf 'ours_rp_soak_container_unchanged=%s\n' "${soak_container_before:-not-running}"

View File

@ -1,8 +1,8 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/common.sh # shellcheck source=common.sh
source "$SCRIPT_DIR/scripts/common.sh" source "$SCRIPT_DIR/common.sh"
QUICK=0 QUICK=0
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
@ -12,7 +12,7 @@ while [[ $# -gt 0 ]]; do
shift shift
;; ;;
-h|--help) -h|--help)
echo "Usage: ./self-check.sh [--quick]" echo "Usage: ./scripts/self-check.sh [--quick]"
exit 0 exit 0
;; ;;
*) *)

View File

@ -1,15 +1,15 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/common.sh # shellcheck source=common.sh
source "$SCRIPT_DIR/scripts/common.sh" source "$SCRIPT_DIR/common.sh"
WAIT_FIRST_RUN=1 WAIT_FIRST_RUN=1
TIMEOUT_SECS="" TIMEOUT_SECS=""
usage() { usage() {
cat <<'USAGE' cat <<'USAGE'
Usage: ./start.sh [--no-wait-first-run] [--timeout-secs N] Usage: ./scripts/start.sh [--no-wait-first-run] [--timeout-secs N]
Start ours RP. If no successful run exists, wait for the first snapshot to succeed Start ours RP. If no successful run exists, wait for the first snapshot to succeed
before starting metrics, Prometheus and Grafana. before starting metrics, Prometheus and Grafana.

View File

@ -1,8 +1,8 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/common.sh # shellcheck source=common.sh
source "$SCRIPT_DIR/scripts/common.sh" source "$SCRIPT_DIR/common.sh"
BRIEF=0 BRIEF=0
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
@ -12,7 +12,7 @@ while [[ $# -gt 0 ]]; do
shift shift
;; ;;
-h|--help) -h|--help)
echo "Usage: ./status.sh [--brief]" echo "Usage: ./scripts/status.sh [--brief]"
exit 0 exit 0
;; ;;
*) *)
@ -76,4 +76,12 @@ if [[ "$BRIEF" == "0" ]]; then
endpoint_ok "http://127.0.0.1:${METRICS_PORT:-9556}/metrics" && echo "metrics=ok" || echo "metrics=unavailable" endpoint_ok "http://127.0.0.1:${METRICS_PORT:-9556}/metrics" && echo "metrics=ok" || echo "metrics=unavailable"
endpoint_ok "http://127.0.0.1:${PROMETHEUS_PORT:-9090}/-/ready" && echo "prometheus=ok" || echo "prometheus=unavailable" endpoint_ok "http://127.0.0.1:${PROMETHEUS_PORT:-9090}/-/ready" && echo "prometheus=ok" || echo "prometheus=unavailable"
endpoint_ok "http://127.0.0.1:${GRAFANA_PORT:-3000}/api/health" && echo "grafana=ok" || echo "grafana=unavailable" endpoint_ok "http://127.0.0.1:${GRAFANA_PORT:-3000}/api/health" && echo "grafana=ok" || echo "grafana=unavailable"
echo
if [[ "$RTR_REPORT_DIR" == "$HOST_DATA_DIR/empty-rtr-report" ]]; then
echo "rtr_registration=fallback-empty-directory"
else
echo "rtr_registration=registered"
fi
echo "rtr_report_files=$(rtr_report_file_count "$RTR_REPORT_DIR")"
echo "rtr_latest_report=$(latest_rtr_report_file "$RTR_REPORT_DIR" || true)"
fi fi

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/common.sh # shellcheck source=common.sh
source "$SCRIPT_DIR/scripts/common.sh" source "$SCRIPT_DIR/common.sh"
load_env load_env
compose_cmd --profile core --profile sidecar --profile monitor stop "$@" compose_cmd --profile core --profile sidecar --profile monitor stop "$@"

View File

@ -1,8 +1,8 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/common.sh # shellcheck source=common.sh
source "$SCRIPT_DIR/scripts/common.sh" source "$SCRIPT_DIR/common.sh"
PURGE_DATA=0 PURGE_DATA=0
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
@ -12,7 +12,7 @@ while [[ $# -gt 0 ]]; do
shift shift
;; ;;
-h|--help) -h|--help)
echo "Usage: ./uninstall.sh [--purge-data]" echo "Usage: ./scripts/uninstall.sh [--purge-data]"
exit 0 exit 0
;; ;;
*) *)

View File

@ -1,15 +1,15 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/common.sh # shellcheck source=common.sh
source "$SCRIPT_DIR/scripts/common.sh" source "$SCRIPT_DIR/common.sh"
REUSE_ENV_FROM="" REUSE_ENV_FROM=""
UPDATE_PACKAGE_IMAGE=1 UPDATE_PACKAGE_IMAGE=1
usage() { usage() {
cat <<'USAGE' cat <<'USAGE'
Usage: ./upgrade.sh [--reuse-env-from /path/to/.env] [--keep-reused-image] Usage: ./scripts/upgrade.sh [--reuse-env-from /path/to/.env] [--keep-reused-image]
By default, --reuse-env-from creates the new .env from this package's By default, --reuse-env-from creates the new .env from this package's
.env.example first, then overlays existing user settings from the old .env. .env.example first, then overlays existing user settings from the old .env.

View File

@ -437,7 +437,12 @@ cross_arch_default: deny
cross_arch_enable_var: ALLOW_CROSS_ARCH cross_arch_enable_var: ALLOW_CROSS_ARCH
EOF EOF
chmod +x "$stage"/*.sh "$stage/scripts"/*.sh chmod +x "$stage/scripts"/*.sh
if find "$stage" -maxdepth 1 -type f -name '*.sh' -print -quit | grep -q .; then
echo "error: operational scripts must be installed under scripts/ only" >&2
exit 1
fi
tar -C "$OUT_DIR" -czf "$tar_path" "$package_name" tar -C "$OUT_DIR" -czf "$tar_path" "$package_name"
package_sha256="$(sha256sum "$tar_path" | awk '{print $1}')" package_sha256="$(sha256sum "$tar_path" | awk '{print $1}')"
rm -rf "$monitor_image_stage" rm -rf "$monitor_image_stage"