add multi-arch docker installer
This commit is contained in:
parent
371c819126
commit
6c45cc94f3
@ -1,8 +1,14 @@
|
||||
# ours RP ARM64 installer configuration
|
||||
# ours RP Docker installer configuration
|
||||
# `build_docker_installer_package.sh` rewrites package-specific defaults below.
|
||||
# 中文说明见 docs/README.zh-CN.md。English guide: docs/README.en.md
|
||||
|
||||
# Package metadata and architecture guardrails.
|
||||
PACKAGE_ARCH=arm64
|
||||
PACKAGE_PLATFORM=linux/arm64
|
||||
ALLOW_CROSS_ARCH=0
|
||||
|
||||
# Compose project name.
|
||||
COMPOSE_PROJECT_NAME=ours-rp-arm64
|
||||
COMPOSE_PROJECT_NAME=ours-rp-arm64-installer
|
||||
|
||||
# Runtime image loaded from images/*.tar.gz by install.sh.
|
||||
RPKI_IMAGE=ours-rp-runtime-arm64:dev
|
||||
@ -13,7 +19,7 @@ RPKI_PLATFORM=linux/arm64
|
||||
SOAK_RESTART_POLICY=unless-stopped
|
||||
|
||||
# Host-side persistent data directory. All state/runs/logs/monitoring data are bind-mounted here.
|
||||
HOST_DATA_DIR=/var/lib/ours-rp-arm64
|
||||
HOST_DATA_DIR=/var/lib/ours-rp-arm64-installer
|
||||
|
||||
# RIR list. Options: afrinic,apnic,arin,lacnic,ripe
|
||||
RIRS=afrinic,apnic,arin,lacnic,ripe
|
||||
@ -72,7 +78,7 @@ METRICS_PORT=9556
|
||||
METRICS_POLL_SECS=10
|
||||
|
||||
# Prometheus / Grafana.
|
||||
# Monitor images are packaged as ARM64 docker-save archives and loaded by install.sh.
|
||||
# Monitor images are packaged as docker-save archives and loaded by install.sh.
|
||||
MONITOR_PLATFORM=linux/arm64
|
||||
PROMETHEUS_IMAGE=prom/prometheus:v2.55.1
|
||||
GRAFANA_IMAGE=grafana/grafana:11.3.1
|
||||
|
||||
@ -2,7 +2,7 @@ services:
|
||||
ours-rp-soak:
|
||||
image: ${RPKI_IMAGE:-ours-rp-runtime-arm64:dev}
|
||||
platform: ${RPKI_PLATFORM:-linux/arm64}
|
||||
container_name: ${COMPOSE_PROJECT_NAME:-ours-rp-arm64}-soak
|
||||
container_name: ${COMPOSE_PROJECT_NAME:-ours-rp-package-installer}-soak
|
||||
env_file:
|
||||
- ../.env
|
||||
environment:
|
||||
@ -13,10 +13,10 @@ services:
|
||||
FIXTURE_DIR: /opt/ours-rp/fixtures
|
||||
volumes:
|
||||
- ../.env:/opt/ours-rp/.env:ro
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-arm64}/state:/var/lib/ours-rp/state
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-arm64}/runs:/var/lib/ours-rp/runs
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-arm64}/logs:/var/lib/ours-rp/logs
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-arm64}/tmp:/var/lib/ours-rp/tmp
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-package-installer}/state:/var/lib/ours-rp/state
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-package-installer}/runs:/var/lib/ours-rp/runs
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-package-installer}/logs:/var/lib/ours-rp/logs
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-package-installer}/tmp:/var/lib/ours-rp/tmp
|
||||
restart: ${SOAK_RESTART_POLICY:-unless-stopped}
|
||||
profiles:
|
||||
- core
|
||||
@ -24,7 +24,7 @@ services:
|
||||
artifact-metrics:
|
||||
image: ${RPKI_IMAGE:-ours-rp-runtime-arm64:dev}
|
||||
platform: ${RPKI_PLATFORM:-linux/arm64}
|
||||
container_name: ${COMPOSE_PROJECT_NAME:-ours-rp-arm64}-artifact-metrics
|
||||
container_name: ${COMPOSE_PROJECT_NAME:-ours-rp-package-installer}-artifact-metrics
|
||||
env_file:
|
||||
- ../.env
|
||||
command:
|
||||
@ -36,13 +36,13 @@ services:
|
||||
- --poll-secs
|
||||
- ${METRICS_POLL_SECS:-10}
|
||||
- --instance
|
||||
- ${METRICS_INSTANCE:-arm64-installer}
|
||||
- ${METRICS_INSTANCE:-package-installer}
|
||||
ports:
|
||||
- "${METRICS_PORT:-9556}:9556"
|
||||
volumes:
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-arm64}/state:/var/lib/ours-rp/state:ro
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-arm64}/runs:/var/lib/ours-rp/runs:ro
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-arm64}/logs:/var/lib/ours-rp/logs:ro
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-package-installer}/state:/var/lib/ours-rp/state:ro
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-package-installer}/runs:/var/lib/ours-rp/runs:ro
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-package-installer}/logs:/var/lib/ours-rp/logs:ro
|
||||
restart: unless-stopped
|
||||
profiles:
|
||||
- sidecar
|
||||
@ -50,7 +50,7 @@ services:
|
||||
prometheus:
|
||||
image: ${PROMETHEUS_IMAGE:-prom/prometheus:v2.55.1}
|
||||
platform: ${MONITOR_PLATFORM:-linux/arm64}
|
||||
container_name: ${COMPOSE_PROJECT_NAME:-ours-rp-arm64}-prometheus
|
||||
container_name: ${COMPOSE_PROJECT_NAME:-ours-rp-package-installer}-prometheus
|
||||
command:
|
||||
- --config.file=/etc/prometheus/prometheus.yml
|
||||
- --storage.tsdb.path=/prometheus
|
||||
@ -63,7 +63,7 @@ services:
|
||||
- "${PROMETHEUS_PORT:-9090}:9090"
|
||||
volumes:
|
||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-arm64}/prometheus:/prometheus
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-package-installer}/prometheus:/prometheus
|
||||
restart: unless-stopped
|
||||
profiles:
|
||||
- monitor
|
||||
@ -71,7 +71,7 @@ services:
|
||||
grafana:
|
||||
image: ${GRAFANA_IMAGE:-grafana/grafana:11.3.1}
|
||||
platform: ${MONITOR_PLATFORM:-linux/arm64}
|
||||
container_name: ${COMPOSE_PROJECT_NAME:-ours-rp-arm64}-grafana
|
||||
container_name: ${COMPOSE_PROJECT_NAME:-ours-rp-package-installer}-grafana
|
||||
depends_on:
|
||||
- prometheus
|
||||
user: "0:0"
|
||||
@ -82,7 +82,7 @@ services:
|
||||
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:-admin}
|
||||
GF_USERS_ALLOW_SIGN_UP: "false"
|
||||
volumes:
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-arm64}/grafana:/var/lib/grafana
|
||||
- ${HOST_DATA_DIR:-/var/lib/ours-rp-package-installer}/grafana:/var/lib/grafana
|
||||
- ./grafana/provisioning:/etc/grafana/provisioning:ro
|
||||
- ./grafana/dashboards:/var/lib/grafana/dashboards:ro
|
||||
restart: unless-stopped
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: ours-rp-arm64
|
||||
- name: ours-rp-docker-installer
|
||||
orgId: 1
|
||||
folder: Ours RP ARM64
|
||||
folder: Ours RP Docker Installer
|
||||
type: file
|
||||
disableDeletion: false
|
||||
updateIntervalSeconds: 10
|
||||
|
||||
@ -10,4 +10,4 @@ scrape_configs:
|
||||
- artifact-metrics:9556
|
||||
labels:
|
||||
rp: ours-rp
|
||||
source: arm64-compose-artifact-sidecar
|
||||
source: docker-installer-artifact-sidecar
|
||||
|
||||
@ -1,16 +1,22 @@
|
||||
# ours RP ARM64 Installer Guide
|
||||
# ours RP Docker Installer Guide (`__PACKAGE_ARCH__` / `__PACKAGE_PLATFORM__`)
|
||||
|
||||
## Goal
|
||||
|
||||
This package deploys ours RP on a `linux/arm64` server with Docker Compose and continuously runs all five RIR validation.
|
||||
This package deploys ours RP on Linux servers whose host architecture matches the packaged installer metadata, using Docker Compose and continuous all-five RIR validation.
|
||||
|
||||
The package includes the ours RP ARM64 runtime image, Prometheus ARM64 image and Grafana ARM64 image, so deployment does not 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 architecture-matched ours RP runtime, Prometheus and Grafana images, so 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.
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
ALLOW_CROSS_ARCH=1
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
tar -xzf ours-rp-arm64-installer-*.tar.gz
|
||||
cd ours-rp-arm64-installer-*
|
||||
tar -xzf ours-rp-docker-installer-__PACKAGE_ARCH__-*.tar.gz
|
||||
cd ours-rp-docker-installer-__PACKAGE_ARCH__-*
|
||||
|
||||
./install.sh
|
||||
cp .env.example .env # install.sh creates .env automatically if missing
|
||||
@ -21,6 +27,8 @@ vim .env
|
||||
|
||||
Defaults:
|
||||
|
||||
- `PACKAGE_ARCH=__PACKAGE_ARCH__`
|
||||
- `PACKAGE_PLATFORM=__PACKAGE_PLATFORM__`
|
||||
- `RIRS=afrinic,apnic,arin,lacnic,ripe`
|
||||
- `MAX_RUNS=-1`
|
||||
- `INTERVAL_SECS=600`
|
||||
@ -28,9 +36,10 @@ Defaults:
|
||||
- `LIVE_TA_REFRESH_BEFORE_SNAPSHOT=1`
|
||||
- `PERIODIC_SNAPSHOT_RESET=0`
|
||||
- `PERIODIC_SNAPSHOT_MAX_DELTAS=100`
|
||||
- `HOST_DATA_DIR=/var/lib/ours-rp-arm64`
|
||||
- `HOST_DATA_DIR=__HOST_DATA_DIR__`
|
||||
- `SOAK_RESTART_POLICY=unless-stopped`
|
||||
- `MONITOR_PLATFORM=linux/arm64`
|
||||
- `MONITOR_PLATFORM=__PACKAGE_PLATFORM__`
|
||||
- `ALLOW_CROSS_ARCH=0`
|
||||
|
||||
## First Start Semantics
|
||||
|
||||
@ -38,6 +47,22 @@ If there is no successful run under `HOST_DATA_DIR/runs`, `start.sh` starts the
|
||||
|
||||
The first snapshot refreshes live TA certificates before starting the RP process.
|
||||
|
||||
## Architecture Guardrails
|
||||
|
||||
The key scripts read:
|
||||
|
||||
- `PACKAGE_ARCH` / `PACKAGE_PLATFORM` from `.env`
|
||||
- `PACKAGE-MANIFEST.env`
|
||||
- the current host `uname -m`
|
||||
|
||||
Default behavior:
|
||||
|
||||
1. matching host and package architectures: run natively;
|
||||
2. mismatched host and package architectures: fail with an explicit error;
|
||||
3. only when `ALLOW_CROSS_ARCH=1` is set do the scripts attempt to enable matching `binfmt/qemu`.
|
||||
|
||||
That means an `arm64` package on an `x86_64` host does not silently switch to emulation by default.
|
||||
|
||||
## Ports
|
||||
|
||||
Default ports:
|
||||
@ -60,7 +85,7 @@ Change the password and restrict public access for production deployments.
|
||||
Default host directory:
|
||||
|
||||
```text
|
||||
/var/lib/ours-rp-arm64/
|
||||
__HOST_DATA_DIR__/
|
||||
state/
|
||||
runs/
|
||||
logs/
|
||||
@ -109,12 +134,6 @@ Check the latest `run-meta.json` for:
|
||||
./uninstall.sh
|
||||
```
|
||||
|
||||
`uninstall.sh` keeps data by default. Use the following only when you really want to delete `HOST_DATA_DIR`:
|
||||
|
||||
```bash
|
||||
./uninstall.sh --purge-data
|
||||
```
|
||||
|
||||
For finite acceptance tests, for example `MAX_RUNS=3`, also set:
|
||||
|
||||
```bash
|
||||
@ -122,3 +141,9 @@ SOAK_RESTART_POLICY=no
|
||||
```
|
||||
|
||||
Otherwise Compose `unless-stopped` will restart the container after it exits successfully.
|
||||
|
||||
`uninstall.sh` keeps data by default. Use the following only when you really want to delete `HOST_DATA_DIR`:
|
||||
|
||||
```bash
|
||||
./uninstall.sh --purge-data
|
||||
```
|
||||
|
||||
@ -1,16 +1,22 @@
|
||||
# ours RP ARM64 安装包使用说明
|
||||
# ours RP Docker 安装包使用说明(`__PACKAGE_ARCH__` / `__PACKAGE_PLATFORM__`)
|
||||
|
||||
## 目标
|
||||
|
||||
本安装包用于在 `linux/arm64` 服务器上通过 Docker Compose 部署 ours RP,并持续运行 all5 RIR 同步验证任务。
|
||||
本安装包用于在目标架构与包元数据匹配的 Linux 服务器上,通过 Docker Compose 部署 ours RP,并持续运行 all5 RIR 同步验证任务。
|
||||
|
||||
安装包内置 ours RP ARM64 runtime、Prometheus ARM64、Grafana ARM64 镜像,部署时不需要现场拉取应用镜像。运行产物、状态数据库、日志、Prometheus 和 Grafana 数据均通过宿主机目录挂载保存。
|
||||
安装包内置与包架构一致的 ours RP runtime、Prometheus、Grafana 镜像,部署时不需要现场拉取应用镜像。运行产物、状态数据库、日志、Prometheus 和 Grafana 数据均通过宿主机目录挂载保存。
|
||||
|
||||
默认情况下,宿主架构必须与 `PACKAGE-MANIFEST.env` 中的 `PACKAGE_ARCH` 匹配;若确需在异构主机上通过 QEMU/binfmt 运行,必须显式设置:
|
||||
|
||||
```bash
|
||||
ALLOW_CROSS_ARCH=1
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
tar -xzf ours-rp-arm64-installer-*.tar.gz
|
||||
cd ours-rp-arm64-installer-*
|
||||
tar -xzf ours-rp-docker-installer-__PACKAGE_ARCH__-*.tar.gz
|
||||
cd ours-rp-docker-installer-__PACKAGE_ARCH__-*
|
||||
|
||||
./install.sh
|
||||
cp .env.example .env # 如 install.sh 已自动创建,可直接编辑现有 .env
|
||||
@ -21,6 +27,8 @@ vim .env
|
||||
|
||||
默认配置:
|
||||
|
||||
- `PACKAGE_ARCH=__PACKAGE_ARCH__`
|
||||
- `PACKAGE_PLATFORM=__PACKAGE_PLATFORM__`
|
||||
- `RIRS=afrinic,apnic,arin,lacnic,ripe`
|
||||
- `MAX_RUNS=-1`
|
||||
- `INTERVAL_SECS=600`
|
||||
@ -28,9 +36,10 @@ vim .env
|
||||
- `LIVE_TA_REFRESH_BEFORE_SNAPSHOT=1`
|
||||
- `PERIODIC_SNAPSHOT_RESET=0`
|
||||
- `PERIODIC_SNAPSHOT_MAX_DELTAS=100`
|
||||
- `HOST_DATA_DIR=/var/lib/ours-rp-arm64`
|
||||
- `HOST_DATA_DIR=__HOST_DATA_DIR__`
|
||||
- `SOAK_RESTART_POLICY=unless-stopped`
|
||||
- `MONITOR_PLATFORM=linux/arm64`
|
||||
- `MONITOR_PLATFORM=__PACKAGE_PLATFORM__`
|
||||
- `ALLOW_CROSS_ARCH=0`
|
||||
|
||||
## 首次启动语义
|
||||
|
||||
@ -38,6 +47,22 @@ vim .env
|
||||
|
||||
第一轮 snapshot 会先拉取 live TA,避免 clean state 使用旧 fixture TA。
|
||||
|
||||
## 架构检查
|
||||
|
||||
关键脚本会读取:
|
||||
|
||||
- `.env` 中的 `PACKAGE_ARCH` / `PACKAGE_PLATFORM`
|
||||
- `PACKAGE-MANIFEST.env`
|
||||
- 当前宿主 `uname -m`
|
||||
|
||||
默认行为:
|
||||
|
||||
1. 宿主与包架构匹配:直接运行;
|
||||
2. 宿主与包架构不匹配:明确报错并停止;
|
||||
3. 仅当 `ALLOW_CROSS_ARCH=1` 时,脚本才会尝试启用对应架构的 `binfmt/qemu`。
|
||||
|
||||
因此在 `x86_64` 主机上运行 `arm64` 包,不会默认静默进入模拟执行。
|
||||
|
||||
## 访问端口
|
||||
|
||||
默认端口:
|
||||
@ -60,7 +85,7 @@ GRAFANA_ADMIN_PASSWORD=admin
|
||||
默认宿主机目录:
|
||||
|
||||
```text
|
||||
/var/lib/ours-rp-arm64/
|
||||
__HOST_DATA_DIR__/
|
||||
state/
|
||||
runs/
|
||||
logs/
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Operations Guide
|
||||
# Operations Guide (`__PACKAGE_ARCH__`)
|
||||
|
||||
## Install
|
||||
|
||||
@ -10,8 +10,9 @@ The installer is idempotent:
|
||||
|
||||
- existing `.env` is kept;
|
||||
- existing Docker/Compose installation is reused;
|
||||
- repeated loading of packaged ours RP, Prometheus and Grafana ARM64 images is safe;
|
||||
- existing data directory is reused.
|
||||
- repeated loading of packaged ours RP, Prometheus and Grafana images for the package architecture is safe;
|
||||
- existing data directory is reused;
|
||||
- matching host/package architecture is required by default.
|
||||
|
||||
## Start
|
||||
|
||||
@ -25,6 +26,14 @@ Start without waiting for the first snapshot:
|
||||
./start.sh --no-wait-first-run
|
||||
```
|
||||
|
||||
If you intentionally want to run this package on a different host architecture through QEMU/binfmt, first set:
|
||||
|
||||
```bash
|
||||
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.
|
||||
|
||||
## Stop and Restart
|
||||
|
||||
```bash
|
||||
@ -46,10 +55,14 @@ Important checks:
|
||||
- `HOST_DATA_DIR` is writable;
|
||||
- Compose config is valid;
|
||||
- latest run status;
|
||||
- metrics, Prometheus and Grafana endpoints.
|
||||
- metrics, Prometheus and Grafana endpoints;
|
||||
- whether `host_arch`, `package_arch`, and `arch_mode` match expectations.
|
||||
|
||||
`status.sh` also prints:
|
||||
|
||||
- `package_arch`
|
||||
- `package_platform`
|
||||
- `allow_cross_arch`
|
||||
- `periodic_snapshot_reset`
|
||||
- `periodic_snapshot_max_deltas`
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# 运维手册
|
||||
# 运维手册(`__PACKAGE_ARCH__`)
|
||||
|
||||
## 安装
|
||||
|
||||
@ -10,8 +10,9 @@
|
||||
|
||||
- 已有 `.env` 不覆盖;
|
||||
- 已安装 Docker/Compose 则跳过;
|
||||
- 包内 ours RP、Prometheus、Grafana ARM64 镜像重复加载是安全的;
|
||||
- 数据目录已存在则复用。
|
||||
- 包内 ours RP、Prometheus、Grafana 对应架构镜像重复加载是安全的;
|
||||
- 数据目录已存在则复用;
|
||||
- 默认要求宿主与包架构匹配。
|
||||
|
||||
## 启动
|
||||
|
||||
@ -25,6 +26,14 @@
|
||||
./start.sh --no-wait-first-run
|
||||
```
|
||||
|
||||
如需显式允许异构主机通过 QEMU/binfmt 跑包,先在 `.env` 中设置:
|
||||
|
||||
```bash
|
||||
ALLOW_CROSS_ARCH=1
|
||||
```
|
||||
|
||||
然后重新执行 `./install.sh` 或 `./self-check.sh`,脚本才会尝试启用对应 binfmt。
|
||||
|
||||
## 停止和重启
|
||||
|
||||
```bash
|
||||
@ -46,10 +55,14 @@
|
||||
- `HOST_DATA_DIR` 可写;
|
||||
- Compose 配置合法;
|
||||
- 最新 run 状态;
|
||||
- metrics、Prometheus、Grafana endpoint。
|
||||
- metrics、Prometheus、Grafana endpoint;
|
||||
- `host_arch`、`package_arch`、`arch_mode` 是否符合预期。
|
||||
|
||||
`status.sh` 还会显示:
|
||||
|
||||
- `package_arch`
|
||||
- `package_platform`
|
||||
- `allow_cross_arch`
|
||||
- `periodic_snapshot_reset`
|
||||
- `periodic_snapshot_max_deltas`
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Troubleshooting
|
||||
# Troubleshooting (`__PACKAGE_ARCH__` / `__PACKAGE_PLATFORM__`)
|
||||
|
||||
## Docker or Compose Is Unavailable
|
||||
|
||||
@ -15,16 +15,34 @@ If missing, run:
|
||||
./install.sh
|
||||
```
|
||||
|
||||
## ARM64 Image Cannot Run
|
||||
## Package Architecture Mismatch
|
||||
|
||||
Running ARM64 images on x86_64 requires binfmt/qemu:
|
||||
If `status.sh`, `install.sh`, or `self-check.sh` reports:
|
||||
|
||||
```bash
|
||||
docker run --rm --privileged tonistiigi/binfmt --install arm64
|
||||
docker run --rm --platform linux/arm64 debian:bookworm-slim uname -m
|
||||
```text
|
||||
package architecture mismatch
|
||||
```
|
||||
|
||||
Expected output: `aarch64`.
|
||||
the host `uname -m` does not match the packaged `PACKAGE_ARCH=__PACKAGE_ARCH__`. The default behavior is to fail clearly rather than silently switching to emulation.
|
||||
|
||||
Only if you intentionally accept QEMU/binfmt cross-architecture execution should you set:
|
||||
|
||||
```bash
|
||||
ALLOW_CROSS_ARCH=1
|
||||
```
|
||||
|
||||
Then rerun install or self-check.
|
||||
|
||||
## `__PACKAGE_ARCH__` Image Cannot Run
|
||||
|
||||
Running `__PACKAGE_PLATFORM__` images on a different host architecture requires binfmt/qemu. The installer only attempts this automatically when `ALLOW_CROSS_ARCH=1`; you can also enable it manually:
|
||||
|
||||
```bash
|
||||
docker run --rm --privileged tonistiigi/binfmt --install __PACKAGE_ARCH__
|
||||
docker run --rm --platform __PACKAGE_PLATFORM__ debian:bookworm-slim uname -m
|
||||
```
|
||||
|
||||
For `arm64` packages the expected output is `aarch64`; for `amd64` packages the expected output is `x86_64`.
|
||||
|
||||
## First Snapshot Times Out
|
||||
|
||||
@ -40,8 +58,8 @@ Check:
|
||||
|
||||
```bash
|
||||
grep LIVE_TA_REFRESH_BEFORE_SNAPSHOT .env
|
||||
ls -l /var/lib/ours-rp-arm64/state/live-ta
|
||||
tail -100 /var/lib/ours-rp-arm64/logs/live-ta-refresh-*.log
|
||||
ls -l __HOST_DATA_DIR__/state/live-ta
|
||||
tail -100 __HOST_DATA_DIR__/logs/live-ta-refresh-*.log
|
||||
```
|
||||
|
||||
In `file-live-ta` mode, snapshot should wait until live TA refresh succeeds.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# 故障排查
|
||||
# 故障排查(`__PACKAGE_ARCH__` / `__PACKAGE_PLATFORM__`)
|
||||
|
||||
## Docker 或 Compose 不可用
|
||||
|
||||
@ -15,16 +15,34 @@ docker compose version
|
||||
./install.sh
|
||||
```
|
||||
|
||||
## ARM64 镜像无法运行
|
||||
## 架构不匹配报错
|
||||
|
||||
在 x86_64 机器上运行 ARM64 镜像需要 binfmt/qemu:
|
||||
当 `status.sh` / `install.sh` / `self-check.sh` 报出:
|
||||
|
||||
```bash
|
||||
docker run --rm --privileged tonistiigi/binfmt --install arm64
|
||||
docker run --rm --platform linux/arm64 debian:bookworm-slim uname -m
|
||||
```text
|
||||
package architecture mismatch
|
||||
```
|
||||
|
||||
预期输出 `aarch64`。
|
||||
说明宿主 `uname -m` 与包的 `PACKAGE_ARCH=__PACKAGE_ARCH__` 不一致。默认行为就是失败而不是静默模拟运行。
|
||||
|
||||
只有在你明确接受 QEMU/binfmt 跨架构运行时,才设置:
|
||||
|
||||
```bash
|
||||
ALLOW_CROSS_ARCH=1
|
||||
```
|
||||
|
||||
然后重新执行安装或自检。
|
||||
|
||||
## `__PACKAGE_ARCH__` 镜像无法运行
|
||||
|
||||
在异构主机上运行 `__PACKAGE_PLATFORM__` 镜像需要 binfmt/qemu。安装脚本只有在 `ALLOW_CROSS_ARCH=1` 时才会自动尝试启用;也可以手动执行:
|
||||
|
||||
```bash
|
||||
docker run --rm --privileged tonistiigi/binfmt --install __PACKAGE_ARCH__
|
||||
docker run --rm --platform __PACKAGE_PLATFORM__ debian:bookworm-slim uname -m
|
||||
```
|
||||
|
||||
对于 `arm64` 包,预期输出 `aarch64`;对于 `amd64` 包,预期输出 `x86_64`。
|
||||
|
||||
## 首轮 snapshot 超时
|
||||
|
||||
@ -40,8 +58,8 @@ all5 snapshot 可能很慢,尤其在 QEMU 环境。可以提高超时:
|
||||
|
||||
```bash
|
||||
grep LIVE_TA_REFRESH_BEFORE_SNAPSHOT .env
|
||||
ls -l /var/lib/ours-rp-arm64/state/live-ta
|
||||
tail -100 /var/lib/ours-rp-arm64/logs/live-ta-refresh-*.log
|
||||
ls -l __HOST_DATA_DIR__/state/live-ta
|
||||
tail -100 __HOST_DATA_DIR__/logs/live-ta-refresh-*.log
|
||||
```
|
||||
|
||||
`file-live-ta` 模式下,snapshot 应等待 live TA 成功刷新。
|
||||
|
||||
@ -8,7 +8,7 @@ usage() {
|
||||
cat <<'USAGE'
|
||||
Usage: ./install.sh [--skip-dep-install]
|
||||
|
||||
Install or update the ours RP ARM64 compose package idempotently.
|
||||
Install or update the ours RP Docker installer package idempotently.
|
||||
USAGE
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ while [[ $# -gt 0 ]]; do
|
||||
done
|
||||
|
||||
load_env
|
||||
assert_arch_compatibility
|
||||
install_docker_if_missing
|
||||
require_cmd curl
|
||||
require_cmd jq
|
||||
@ -40,6 +41,8 @@ load_installer_images
|
||||
ensure_binfmt_if_needed
|
||||
verify_runtime_image
|
||||
verify_monitor_images
|
||||
compose_cmd --profile core --profile sidecar --profile monitor config >/tmp/ours-rp-arm64-compose-config.yml
|
||||
compose_config_path="$(mktemp "${TMPDIR:-/tmp}/ours-rp-compose-config.XXXXXX.yml")"
|
||||
compose_cmd --profile core --profile sidecar --profile monitor config >"$compose_config_path"
|
||||
"$SCRIPT_DIR/self-check.sh" --quick
|
||||
rm -f "$compose_config_path"
|
||||
log "install complete"
|
||||
|
||||
167
deploy/arm64-installer/scripts/common.sh
Executable file → Normal file
167
deploy/arm64-installer/scripts/common.sh
Executable file → Normal file
@ -5,6 +5,7 @@ INSTALLER_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ENV_FILE="${ENV_FILE:-$INSTALLER_ROOT/.env}"
|
||||
ENV_EXAMPLE="$INSTALLER_ROOT/.env.example"
|
||||
COMPOSE_FILE="$INSTALLER_ROOT/compose/docker-compose.yml"
|
||||
MANIFEST_FILE="${MANIFEST_FILE:-$INSTALLER_ROOT/PACKAGE-MANIFEST.env}"
|
||||
|
||||
log() {
|
||||
printf '[ours-rp-installer] %s\n' "$*"
|
||||
@ -23,7 +24,114 @@ require_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || die "missing command: $1"
|
||||
}
|
||||
|
||||
normalize_arch() {
|
||||
case "$1" in
|
||||
amd64|x86_64|linux/amd64)
|
||||
printf 'amd64\n'
|
||||
;;
|
||||
arm64|aarch64|linux/arm64)
|
||||
printf 'arm64\n'
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
platform_for_arch() {
|
||||
printf 'linux/%s\n' "$1"
|
||||
}
|
||||
|
||||
env_flag_enabled() {
|
||||
case "${1:-0}" in
|
||||
1|true|TRUE|yes|YES|on|ON)
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
detect_host_arch() {
|
||||
local raw_arch
|
||||
raw_arch="$(uname -m)"
|
||||
normalize_arch "$raw_arch" || die "unsupported host architecture: $raw_arch"
|
||||
}
|
||||
|
||||
load_manifest() {
|
||||
MANIFEST_PACKAGE_ARCH_RAW=""
|
||||
MANIFEST_PACKAGE_PLATFORM_RAW=""
|
||||
if [[ -f "$MANIFEST_FILE" ]]; then
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
source "$MANIFEST_FILE"
|
||||
set +a
|
||||
MANIFEST_PACKAGE_ARCH_RAW="${PACKAGE_ARCH:-${package_arch:-}}"
|
||||
MANIFEST_PACKAGE_PLATFORM_RAW="${PACKAGE_PLATFORM:-${package_platform:-}}"
|
||||
fi
|
||||
}
|
||||
|
||||
effective_package_arch() {
|
||||
if [[ -n "${PACKAGE_ARCH:-}" ]]; then
|
||||
normalize_arch "$PACKAGE_ARCH" || die "unsupported PACKAGE_ARCH=${PACKAGE_ARCH}"
|
||||
return 0
|
||||
fi
|
||||
if [[ -n "${PACKAGE_PLATFORM:-}" ]]; then
|
||||
normalize_arch "$PACKAGE_PLATFORM" || die "unsupported PACKAGE_PLATFORM=${PACKAGE_PLATFORM}"
|
||||
return 0
|
||||
fi
|
||||
if [[ -n "${RPKI_PLATFORM:-}" ]]; then
|
||||
normalize_arch "$RPKI_PLATFORM" || die "unsupported RPKI_PLATFORM=${RPKI_PLATFORM}"
|
||||
return 0
|
||||
fi
|
||||
if [[ -n "${MONITOR_PLATFORM:-}" ]]; then
|
||||
normalize_arch "$MONITOR_PLATFORM" || die "unsupported MONITOR_PLATFORM=${MONITOR_PLATFORM}"
|
||||
return 0
|
||||
fi
|
||||
die "unable to determine package architecture from manifest or env"
|
||||
}
|
||||
|
||||
arch_mode() {
|
||||
local host_arch package_arch
|
||||
host_arch="$(detect_host_arch)"
|
||||
package_arch="$(effective_package_arch)"
|
||||
if [[ "$host_arch" == "$package_arch" ]]; then
|
||||
printf 'native\n'
|
||||
return 0
|
||||
fi
|
||||
if env_flag_enabled "${ALLOW_CROSS_ARCH:-0}"; then
|
||||
printf 'cross-arch-enabled\n'
|
||||
return 0
|
||||
fi
|
||||
printf 'mismatch-blocked\n'
|
||||
}
|
||||
|
||||
assert_arch_compatibility() {
|
||||
local host_arch package_arch package_platform mode
|
||||
host_arch="$(detect_host_arch)"
|
||||
package_arch="$(effective_package_arch)"
|
||||
package_platform="${PACKAGE_PLATFORM:-${RPKI_PLATFORM:-$(platform_for_arch "$package_arch")}}"
|
||||
mode="$(arch_mode)"
|
||||
case "$mode" in
|
||||
native)
|
||||
return 0
|
||||
;;
|
||||
cross-arch-enabled)
|
||||
log "cross-arch execution explicitly enabled: host_arch=$host_arch package_arch=$package_arch package_platform=$package_platform"
|
||||
return 0
|
||||
;;
|
||||
mismatch-blocked)
|
||||
die "package architecture mismatch: host_arch=$host_arch package_arch=$package_arch package_platform=$package_platform. Set ALLOW_CROSS_ARCH=1 in $ENV_FILE to allow explicit QEMU/binfmt emulation."
|
||||
;;
|
||||
*)
|
||||
die "unknown arch compatibility mode: $mode"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
load_env() {
|
||||
load_manifest
|
||||
if [[ ! -f "$ENV_FILE" ]]; then
|
||||
[[ -f "$ENV_EXAMPLE" ]] || die "missing $ENV_EXAMPLE"
|
||||
cp "$ENV_EXAMPLE" "$ENV_FILE"
|
||||
@ -33,18 +141,45 @@ load_env() {
|
||||
# shellcheck disable=SC1090
|
||||
source "$ENV_FILE"
|
||||
set +a
|
||||
HOST_DATA_DIR="${HOST_DATA_DIR:-/var/lib/ours-rp-arm64}"
|
||||
COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-ours-rp-arm64}"
|
||||
RPKI_IMAGE="${RPKI_IMAGE:-ours-rp-runtime-arm64:dev}"
|
||||
RPKI_PLATFORM="${RPKI_PLATFORM:-linux/arm64}"
|
||||
MONITOR_PLATFORM="${MONITOR_PLATFORM:-linux/arm64}"
|
||||
|
||||
if [[ -n "${MANIFEST_PACKAGE_ARCH_RAW:-}" ]]; then
|
||||
manifest_package_arch="$(normalize_arch "$MANIFEST_PACKAGE_ARCH_RAW")" || die "unsupported manifest package arch: $MANIFEST_PACKAGE_ARCH_RAW"
|
||||
if [[ -n "${PACKAGE_ARCH:-}" ]]; then
|
||||
env_package_arch="$(normalize_arch "$PACKAGE_ARCH")" || die "unsupported env package arch: $PACKAGE_ARCH"
|
||||
[[ "$env_package_arch" == "$manifest_package_arch" ]] || die "env PACKAGE_ARCH=$env_package_arch mismatches manifest PACKAGE_ARCH=$manifest_package_arch"
|
||||
fi
|
||||
PACKAGE_ARCH="$manifest_package_arch"
|
||||
else
|
||||
if [[ -z "${PACKAGE_ARCH:-}" ]]; then
|
||||
PACKAGE_ARCH="$(effective_package_arch)"
|
||||
else
|
||||
PACKAGE_ARCH="$(normalize_arch "$PACKAGE_ARCH")"
|
||||
fi
|
||||
fi
|
||||
if [[ -n "${MANIFEST_PACKAGE_PLATFORM_RAW:-}" ]]; then
|
||||
manifest_package_platform="$MANIFEST_PACKAGE_PLATFORM_RAW"
|
||||
if [[ -n "${PACKAGE_PLATFORM:-}" && "$PACKAGE_PLATFORM" != "$manifest_package_platform" ]]; then
|
||||
die "env PACKAGE_PLATFORM=$PACKAGE_PLATFORM mismatches manifest PACKAGE_PLATFORM=$manifest_package_platform"
|
||||
fi
|
||||
PACKAGE_PLATFORM="$manifest_package_platform"
|
||||
else
|
||||
PACKAGE_PLATFORM="${PACKAGE_PLATFORM:-$(platform_for_arch "$PACKAGE_ARCH")}"
|
||||
fi
|
||||
|
||||
HOST_DATA_DIR="${HOST_DATA_DIR:-/var/lib/ours-rp-${PACKAGE_ARCH}-installer}"
|
||||
COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-ours-rp-${PACKAGE_ARCH}-installer}"
|
||||
RPKI_IMAGE="${RPKI_IMAGE:-ours-rp-runtime-${PACKAGE_ARCH}:dev}"
|
||||
RPKI_PLATFORM="${RPKI_PLATFORM:-$PACKAGE_PLATFORM}"
|
||||
MONITOR_PLATFORM="${MONITOR_PLATFORM:-$PACKAGE_PLATFORM}"
|
||||
PROMETHEUS_IMAGE="${PROMETHEUS_IMAGE:-prom/prometheus:v2.55.1}"
|
||||
GRAFANA_IMAGE="${GRAFANA_IMAGE:-grafana/grafana:11.3.1}"
|
||||
METRICS_INSTANCE="${METRICS_INSTANCE:-${PACKAGE_ARCH}-installer}"
|
||||
ALLOW_CROSS_ARCH="${ALLOW_CROSS_ARCH:-0}"
|
||||
FIRST_RUN_WAIT_TIMEOUT_SECS="${FIRST_RUN_WAIT_TIMEOUT_SECS:-7200}"
|
||||
}
|
||||
|
||||
compose_cmd() {
|
||||
docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" -p "${COMPOSE_PROJECT_NAME:-ours-rp-arm64}" "$@"
|
||||
docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" -p "$COMPOSE_PROJECT_NAME" "$@"
|
||||
}
|
||||
|
||||
create_data_dirs() {
|
||||
@ -225,21 +360,27 @@ load_installer_images() {
|
||||
ensure_binfmt_if_needed() {
|
||||
require_cmd docker
|
||||
load_env
|
||||
local host_arch
|
||||
host_arch="$(uname -m)"
|
||||
if [[ "$RPKI_PLATFORM" == "linux/arm64" && "$host_arch" != "aarch64" && "$host_arch" != "arm64" ]]; then
|
||||
log "host arch is $host_arch; ensuring binfmt/qemu for arm64"
|
||||
docker run --rm --privileged tonistiigi/binfmt --install arm64
|
||||
local host_arch package_arch
|
||||
host_arch="$(detect_host_arch)"
|
||||
package_arch="$(effective_package_arch)"
|
||||
if [[ "$host_arch" == "$package_arch" ]]; then
|
||||
return 0
|
||||
fi
|
||||
assert_arch_compatibility
|
||||
log "host arch is $host_arch; enabling binfmt/qemu for package arch $package_arch"
|
||||
docker run --rm --privileged tonistiigi/binfmt --install "$package_arch"
|
||||
}
|
||||
|
||||
verify_runtime_image() {
|
||||
load_env
|
||||
require_cmd docker
|
||||
local help_path
|
||||
help_path="$(mktemp "${TMPDIR:-/tmp}/ours-rp-rpki-help.XXXXXX")"
|
||||
log "verifying runtime image $RPKI_IMAGE on $RPKI_PLATFORM"
|
||||
docker image inspect "$RPKI_IMAGE" >/dev/null
|
||||
docker run --rm --platform "$RPKI_PLATFORM" "$RPKI_IMAGE" /opt/ours-rp/bin/rpki --help >/tmp/ours-rp-arm64-rpki-help.txt
|
||||
head -5 /tmp/ours-rp-arm64-rpki-help.txt || true
|
||||
docker run --rm --platform "$RPKI_PLATFORM" "$RPKI_IMAGE" /opt/ours-rp/bin/rpki --help >"$help_path"
|
||||
head -5 "$help_path" || true
|
||||
rm -f "$help_path"
|
||||
}
|
||||
|
||||
verify_image_platform() {
|
||||
|
||||
@ -22,6 +22,7 @@ while [[ $# -gt 0 ]]; do
|
||||
done
|
||||
|
||||
load_env
|
||||
assert_arch_compatibility
|
||||
require_cmd docker
|
||||
require_cmd jq
|
||||
docker compose version >/dev/null
|
||||
|
||||
@ -37,6 +37,7 @@ while [[ $# -gt 0 ]]; do
|
||||
done
|
||||
|
||||
load_env
|
||||
assert_arch_compatibility
|
||||
create_data_dirs
|
||||
timeout_secs="${TIMEOUT_SECS:-$FIRST_RUN_WAIT_TIMEOUT_SECS}"
|
||||
before_latest="$(latest_run_dir || true)"
|
||||
|
||||
@ -22,8 +22,16 @@ while [[ $# -gt 0 ]]; do
|
||||
done
|
||||
|
||||
load_env
|
||||
host_arch="$(detect_host_arch)"
|
||||
mode="$(arch_mode)"
|
||||
echo "installer_root=$INSTALLER_ROOT"
|
||||
echo "manifest_file=$MANIFEST_FILE"
|
||||
echo "host_data_dir=$HOST_DATA_DIR"
|
||||
echo "host_arch=$host_arch"
|
||||
echo "package_arch=$PACKAGE_ARCH"
|
||||
echo "package_platform=$PACKAGE_PLATFORM"
|
||||
echo "allow_cross_arch=$ALLOW_CROSS_ARCH"
|
||||
echo "arch_mode=$mode"
|
||||
echo "image=$RPKI_IMAGE"
|
||||
echo "platform=$RPKI_PLATFORM"
|
||||
echo "rirs=${RIRS:-}"
|
||||
|
||||
@ -95,6 +95,7 @@ if [[ -n "$REUSE_ENV_FROM" ]]; then
|
||||
fi
|
||||
|
||||
load_env
|
||||
assert_arch_compatibility
|
||||
create_data_dirs
|
||||
install_docker_if_missing
|
||||
load_installer_images
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
ARG BUILDER_IMAGE=ours-rp-base-rust-amd64:1-bookworm
|
||||
ARG RUNTIME_IMAGE=ours-rp-base-debian-arm64:bookworm-slim
|
||||
ARG BUILDER_IMAGE=rust:1-bookworm
|
||||
ARG RUNTIME_IMAGE=debian:bookworm-slim
|
||||
|
||||
FROM --platform=$BUILDPLATFORM ${BUILDER_IMAGE} AS builder
|
||||
|
||||
ARG BUILDARCH
|
||||
ARG TARGETARCH
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
RUN apt-get update \
|
||||
@ -11,47 +15,89 @@ RUN apt-get update \
|
||||
ca-certificates \
|
||||
clang \
|
||||
cmake \
|
||||
g++-aarch64-linux-gnu \
|
||||
gcc-aarch64-linux-gnu \
|
||||
git \
|
||||
libclang-dev \
|
||||
libc6-dev-arm64-cross \
|
||||
make \
|
||||
perl \
|
||||
pkg-config \
|
||||
python3 \
|
||||
&& if [ "$TARGETARCH" != "$BUILDARCH" ]; then \
|
||||
case "$TARGETARCH" in \
|
||||
arm64) \
|
||||
apt-get install -y --no-install-recommends \
|
||||
g++-aarch64-linux-gnu \
|
||||
gcc-aarch64-linux-gnu \
|
||||
libc6-dev-arm64-cross \
|
||||
;; \
|
||||
amd64) \
|
||||
apt-get install -y --no-install-recommends \
|
||||
g++-x86-64-linux-gnu \
|
||||
gcc-x86-64-linux-gnu \
|
||||
libc6-dev-amd64-cross \
|
||||
;; \
|
||||
*) \
|
||||
echo "unsupported TARGETARCH=$TARGETARCH" >&2; exit 2 \
|
||||
;; \
|
||||
esac; \
|
||||
fi \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& rustup target add aarch64-unknown-linux-gnu
|
||||
|
||||
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
|
||||
CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc \
|
||||
CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++ \
|
||||
AR_aarch64_unknown_linux_gnu=aarch64-linux-gnu-ar \
|
||||
CARGO_BUILD_TARGET=aarch64-unknown-linux-gnu \
|
||||
PKG_CONFIG_ALLOW_CROSS=1
|
||||
&& case "$TARGETARCH" in \
|
||||
amd64|arm64) ;; \
|
||||
*) echo "unsupported TARGETARCH=$TARGETARCH" >&2; exit 2 ;; \
|
||||
esac
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/usr/local/cargo/git \
|
||||
--mount=type=cache,target=/src/target \
|
||||
cargo build --release --target aarch64-unknown-linux-gnu \
|
||||
set -eux; \
|
||||
case "$TARGETARCH" in \
|
||||
amd64) target_triple=x86_64-unknown-linux-gnu ;; \
|
||||
arm64) target_triple=aarch64-unknown-linux-gnu ;; \
|
||||
*) echo "unsupported TARGETARCH=$TARGETARCH" >&2; exit 2 ;; \
|
||||
esac; \
|
||||
rustup target add "$target_triple"; \
|
||||
if [ "$TARGETARCH" != "$BUILDARCH" ]; then \
|
||||
case "$TARGETARCH" in \
|
||||
arm64) \
|
||||
export \
|
||||
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
|
||||
CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc \
|
||||
CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++ \
|
||||
AR_aarch64_unknown_linux_gnu=aarch64-linux-gnu-ar \
|
||||
PKG_CONFIG_ALLOW_CROSS=1 \
|
||||
;; \
|
||||
amd64) \
|
||||
export \
|
||||
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc \
|
||||
CC_x86_64_unknown_linux_gnu=x86_64-linux-gnu-gcc \
|
||||
CXX_x86_64_unknown_linux_gnu=x86_64-linux-gnu-g++ \
|
||||
AR_x86_64_unknown_linux_gnu=x86_64-linux-gnu-ar \
|
||||
PKG_CONFIG_ALLOW_CROSS=1 \
|
||||
;; \
|
||||
*) \
|
||||
echo "unsupported TARGETARCH=$TARGETARCH" >&2; exit 2 \
|
||||
;; \
|
||||
esac; \
|
||||
fi; \
|
||||
cargo build --release --target "$target_triple" \
|
||||
--bin rpki \
|
||||
--bin rpki_daemon \
|
||||
--bin db_stats \
|
||||
--bin rpki_artifact_metrics \
|
||||
&& mkdir -p /build-out/bin \
|
||||
&& cp \
|
||||
target/aarch64-unknown-linux-gnu/release/rpki \
|
||||
target/aarch64-unknown-linux-gnu/release/rpki_daemon \
|
||||
target/aarch64-unknown-linux-gnu/release/db_stats \
|
||||
target/aarch64-unknown-linux-gnu/release/rpki_artifact_metrics \
|
||||
--bin rpki_artifact_metrics; \
|
||||
mkdir -p /build-out/bin; \
|
||||
cp \
|
||||
"target/$target_triple/release/rpki" \
|
||||
"target/$target_triple/release/rpki_daemon" \
|
||||
"target/$target_triple/release/db_stats" \
|
||||
"target/$target_triple/release/rpki_artifact_metrics" \
|
||||
/build-out/bin/
|
||||
|
||||
FROM --platform=$TARGETPLATFORM ${RUNTIME_IMAGE} AS runtime
|
||||
|
||||
LABEL org.opencontainers.image.title="ours-rp-runtime" \
|
||||
org.opencontainers.image.description="Ours RP runtime image for ARM64 Docker Compose deployment"
|
||||
org.opencontainers.image.description="Ours RP runtime image for multi-arch Docker Compose deployment"
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
|
||||
@ -2,215 +2,4 @@
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
IMAGE_TAG="${IMAGE_TAG:-ours-rp-runtime-arm64:dev}"
|
||||
IMAGE_TAR="${IMAGE_TAR:-}"
|
||||
PROMETHEUS_IMAGE="${PROMETHEUS_IMAGE:-prom/prometheus:v2.55.1}"
|
||||
PROMETHEUS_IMAGE_TAR="${PROMETHEUS_IMAGE_TAR:-}"
|
||||
GRAFANA_IMAGE="${GRAFANA_IMAGE:-grafana/grafana:11.3.1}"
|
||||
GRAFANA_IMAGE_TAR="${GRAFANA_IMAGE_TAR:-}"
|
||||
OUT_DIR="${OUT_DIR:-$REPO_ROOT/target/arm64-installer}"
|
||||
PACKAGE_PREFIX="${PACKAGE_PREFIX:-ours-rp-arm64-installer}"
|
||||
TEMPLATE_DIR="${TEMPLATE_DIR:-$REPO_ROOT/deploy/arm64-installer}"
|
||||
MONITOR_PLATFORM="${MONITOR_PLATFORM:-linux/arm64}"
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
scripts/docker/build_arm64_installer_package.sh [options]
|
||||
|
||||
Options:
|
||||
--image <tag> Runtime image tag recorded in package manifest.
|
||||
--image-tar <path> Existing docker save tar/tar.gz to include.
|
||||
--prometheus-image <tag>
|
||||
Prometheus image tag to record and package.
|
||||
--prometheus-image-tar <path>
|
||||
Existing Prometheus docker save tar/tar.gz to include.
|
||||
--grafana-image <tag>
|
||||
Grafana image tag to record and package.
|
||||
--grafana-image-tar <path>
|
||||
Existing Grafana docker save tar/tar.gz to include.
|
||||
--out-dir <path> Output directory.
|
||||
--prefix <name> Package directory/tar prefix.
|
||||
-h, --help Show help.
|
||||
|
||||
If --image-tar is omitted, the script uses the newest
|
||||
target/arm64-docker/*.tar.gz file.
|
||||
USAGE
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--image)
|
||||
IMAGE_TAG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--image-tar)
|
||||
IMAGE_TAR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--prometheus-image)
|
||||
PROMETHEUS_IMAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--prometheus-image-tar)
|
||||
PROMETHEUS_IMAGE_TAR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--grafana-image)
|
||||
GRAFANA_IMAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--grafana-image-tar)
|
||||
GRAFANA_IMAGE_TAR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--out-dir)
|
||||
OUT_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--prefix)
|
||||
PACKAGE_PREFIX="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -d "$TEMPLATE_DIR" ]] || {
|
||||
echo "missing template dir: $TEMPLATE_DIR" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
if [[ -z "$IMAGE_TAR" ]]; then
|
||||
IMAGE_TAR="$(find "$REPO_ROOT/target/arm64-docker" -maxdepth 1 -type f \( -name '*.tar.gz' -o -name '*.tar' \) -printf '%T@ %p\n' 2>/dev/null | sort -nr | awk 'NR==1 {print $2}')"
|
||||
fi
|
||||
|
||||
[[ -n "$IMAGE_TAR" && -f "$IMAGE_TAR" ]] || {
|
||||
cat >&2 <<EOF
|
||||
missing runtime image tar.
|
||||
|
||||
Build one first, for example:
|
||||
scripts/docker/build_arm64_runtime_image.sh --image $IMAGE_TAG
|
||||
EOF
|
||||
exit 2
|
||||
}
|
||||
|
||||
safe_tag_name() {
|
||||
printf '%s' "$1" | tr '/:' '--'
|
||||
}
|
||||
|
||||
save_image_if_needed() {
|
||||
local image="$1"
|
||||
local existing_tar="$2"
|
||||
local out_dir="$3"
|
||||
local role="$4"
|
||||
if [[ -n "$existing_tar" ]]; then
|
||||
[[ -f "$existing_tar" ]] || {
|
||||
echo "missing $role image tar: $existing_tar" >&2
|
||||
exit 2
|
||||
}
|
||||
printf '%s\n' "$existing_tar"
|
||||
return 0
|
||||
fi
|
||||
if ! docker image inspect "$image" >/dev/null 2>&1; then
|
||||
cat >&2 <<EOF
|
||||
missing local $role image: $image
|
||||
|
||||
Prepare it before building the installer package, for example:
|
||||
docker pull --platform $MONITOR_PLATFORM $image
|
||||
EOF
|
||||
exit 2
|
||||
fi
|
||||
local actual_platform
|
||||
actual_platform="$(docker image inspect --format '{{.Os}}/{{.Architecture}}' "$image" 2>/dev/null || echo unknown)"
|
||||
if [[ "$actual_platform" != "$MONITOR_PLATFORM" ]]; then
|
||||
cat >&2 <<EOF
|
||||
wrong platform for $role image: $image
|
||||
expected: $MONITOR_PLATFORM
|
||||
actual: $actual_platform
|
||||
|
||||
Pull the ARM64 variant explicitly:
|
||||
docker pull --platform $MONITOR_PLATFORM $image
|
||||
EOF
|
||||
exit 2
|
||||
fi
|
||||
local tar_path="$out_dir/$(safe_tag_name "$image").tar.gz"
|
||||
echo "saving $role image to $tar_path" >&2
|
||||
docker save "$image" | gzip -c > "$tar_path"
|
||||
printf '%s\n' "$tar_path"
|
||||
}
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
commit="$(git -C "$REPO_ROOT" rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||
timestamp="$(date -u +%Y%m%dT%H%M%SZ)"
|
||||
package_name="${PACKAGE_PREFIX}-${timestamp}-${commit}"
|
||||
stage="$OUT_DIR/$package_name"
|
||||
tar_path="$OUT_DIR/$package_name.tar.gz"
|
||||
|
||||
rm -rf "$stage"
|
||||
rsync -a --delete "$TEMPLATE_DIR"/ "$stage"/
|
||||
mkdir -p "$stage/images"
|
||||
cp "$IMAGE_TAR" "$stage/images/"
|
||||
|
||||
monitor_image_stage="$OUT_DIR/.monitor-images-$timestamp"
|
||||
rm -rf "$monitor_image_stage"
|
||||
mkdir -p "$monitor_image_stage"
|
||||
prometheus_tar="$(save_image_if_needed "$PROMETHEUS_IMAGE" "$PROMETHEUS_IMAGE_TAR" "$monitor_image_stage" "prometheus")"
|
||||
grafana_tar="$(save_image_if_needed "$GRAFANA_IMAGE" "$GRAFANA_IMAGE_TAR" "$monitor_image_stage" "grafana")"
|
||||
cp "$prometheus_tar" "$stage/images/"
|
||||
cp "$grafana_tar" "$stage/images/"
|
||||
|
||||
if [[ -f "$stage/.env.example" ]]; then
|
||||
tmp_env="$stage/.env.example.tmp"
|
||||
awk -v image="$IMAGE_TAG" -v prometheus="$PROMETHEUS_IMAGE" -v grafana="$GRAFANA_IMAGE" -v monitor_platform="$MONITOR_PLATFORM" '
|
||||
BEGIN { done=0 }
|
||||
/^RPKI_IMAGE=/ { print "RPKI_IMAGE=" image; done=1; next }
|
||||
/^PROMETHEUS_IMAGE=/ { print "PROMETHEUS_IMAGE=" prometheus; next }
|
||||
/^GRAFANA_IMAGE=/ { print "GRAFANA_IMAGE=" grafana; next }
|
||||
/^MONITOR_PLATFORM=/ { print "MONITOR_PLATFORM=" monitor_platform; next }
|
||||
{ print }
|
||||
END { if (!done) print "RPKI_IMAGE=" image }
|
||||
' "$stage/.env.example" > "$tmp_env"
|
||||
mv "$tmp_env" "$stage/.env.example"
|
||||
fi
|
||||
|
||||
cat > "$stage/PACKAGE-MANIFEST.env" <<EOF
|
||||
package_name=$package_name
|
||||
created_at_utc=$timestamp
|
||||
git_commit=$commit
|
||||
git_status_count=$(git -C "$REPO_ROOT" status --short 2>/dev/null | wc -l | tr -d ' ')
|
||||
image_tag=$IMAGE_TAG
|
||||
image_tar=$(basename "$IMAGE_TAR")
|
||||
image_tar_size_bytes=$(wc -c < "$IMAGE_TAR")
|
||||
prometheus_image=$PROMETHEUS_IMAGE
|
||||
prometheus_image_tar=$(basename "$prometheus_tar")
|
||||
prometheus_image_tar_size_bytes=$(wc -c < "$prometheus_tar")
|
||||
grafana_image=$GRAFANA_IMAGE
|
||||
grafana_image_tar=$(basename "$grafana_tar")
|
||||
grafana_image_tar_size_bytes=$(wc -c < "$grafana_tar")
|
||||
target_platform=linux/arm64
|
||||
monitor_platform=$MONITOR_PLATFORM
|
||||
EOF
|
||||
|
||||
chmod +x "$stage"/*.sh "$stage/scripts"/*.sh
|
||||
tar -C "$OUT_DIR" -czf "$tar_path" "$package_name"
|
||||
rm -rf "$monitor_image_stage"
|
||||
|
||||
{
|
||||
echo "package=$tar_path"
|
||||
echo "package_dir=$stage"
|
||||
echo "package_size_bytes=$(wc -c < "$tar_path")"
|
||||
echo "manifest=$stage/PACKAGE-MANIFEST.env"
|
||||
} > "$OUT_DIR/$package_name.summary.env"
|
||||
|
||||
echo "package built: $tar_path"
|
||||
exec "$SCRIPT_DIR/build_docker_installer_package.sh" --arch arm64 "$@"
|
||||
|
||||
@ -2,184 +2,4 @@
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
IMAGE_TAG="${IMAGE_TAG:-ours-rp-runtime-arm64:dev}"
|
||||
BUILDER_IMAGE="${BUILDER_IMAGE:-ours-rp-base-rust-amd64:1-bookworm}"
|
||||
RUNTIME_IMAGE="${RUNTIME_IMAGE:-ours-rp-base-debian-arm64:bookworm-slim}"
|
||||
OUT_DIR="${OUT_DIR:-$REPO_ROOT/target/arm64-docker}"
|
||||
DOCKERFILE="${DOCKERFILE:-$REPO_ROOT/docker/ours-rp-runtime.Dockerfile}"
|
||||
BUILDER_NAME="${BUILDER_NAME:-default}"
|
||||
INSTALL_BINFMT="${INSTALL_BINFMT:-1}"
|
||||
SAVE_IMAGE="${SAVE_IMAGE:-1}"
|
||||
LOAD_IMAGE="${LOAD_IMAGE:-1}"
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
scripts/docker/build_arm64_runtime_image.sh [options]
|
||||
|
||||
Options:
|
||||
--image <tag> Docker image tag (default: ours-rp-runtime-arm64:dev)
|
||||
--out-dir <path> Directory for docker save tar.gz (default: target/arm64-docker)
|
||||
--dockerfile <path> Dockerfile path
|
||||
--builder <name> buildx builder name
|
||||
--no-binfmt Do not install binfmt/qemu
|
||||
--no-save Build image but do not docker save it
|
||||
--no-load Use buildx output tar instead of --load
|
||||
-h, --help Show this help
|
||||
USAGE
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--image)
|
||||
IMAGE_TAG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--out-dir)
|
||||
OUT_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--dockerfile)
|
||||
DOCKERFILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--builder)
|
||||
BUILDER_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
--no-binfmt)
|
||||
INSTALL_BINFMT=0
|
||||
shift
|
||||
;;
|
||||
--no-save)
|
||||
SAVE_IMAGE=0
|
||||
shift
|
||||
;;
|
||||
--no-load)
|
||||
LOAD_IMAGE=0
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
require_command() {
|
||||
command -v "$1" >/dev/null 2>&1 || {
|
||||
echo "missing required command: $1" >&2
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
|
||||
safe_tag_name() {
|
||||
printf '%s' "$1" | tr '/:' '--'
|
||||
}
|
||||
|
||||
require_command docker
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
require_docker_image() {
|
||||
local image="$1"
|
||||
if ! docker image inspect "$image" >/dev/null 2>&1; then
|
||||
cat >&2 <<EOF
|
||||
missing required local Docker image: $image
|
||||
|
||||
This script intentionally builds with local base image tags to avoid
|
||||
multi-architecture tag ambiguity during cross builds.
|
||||
|
||||
Prepare the default base tags with:
|
||||
docker pull --platform linux/amd64 rust:1-bookworm
|
||||
docker tag rust:1-bookworm ours-rp-base-rust-amd64:1-bookworm
|
||||
docker pull --platform linux/arm64 debian:bookworm-slim
|
||||
docker tag debian:bookworm-slim ours-rp-base-debian-arm64:bookworm-slim
|
||||
EOF
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
require_docker_image "$BUILDER_IMAGE"
|
||||
require_docker_image "$RUNTIME_IMAGE"
|
||||
|
||||
if [[ "$INSTALL_BINFMT" == "1" ]]; then
|
||||
echo "installing binfmt/qemu for arm64"
|
||||
docker run --rm --privileged tonistiigi/binfmt --install arm64
|
||||
fi
|
||||
|
||||
if [[ "$BUILDER_NAME" != "default" ]] && ! docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then
|
||||
docker buildx create --name "$BUILDER_NAME" --driver docker-container --use >/dev/null
|
||||
else
|
||||
docker buildx use "$BUILDER_NAME" >/dev/null
|
||||
fi
|
||||
docker buildx inspect --bootstrap >/dev/null
|
||||
|
||||
metadata_path="$OUT_DIR/$(safe_tag_name "$IMAGE_TAG").build-metadata.json"
|
||||
tar_path="$OUT_DIR/$(safe_tag_name "$IMAGE_TAG").tar.gz"
|
||||
build_log="$OUT_DIR/$(safe_tag_name "$IMAGE_TAG").build.log"
|
||||
|
||||
echo "building linux/arm64 image: $IMAGE_TAG"
|
||||
echo "repo: $REPO_ROOT"
|
||||
echo "dockerfile: $DOCKERFILE"
|
||||
echo "builder_image: $BUILDER_IMAGE"
|
||||
echo "runtime_image: $RUNTIME_IMAGE"
|
||||
start_epoch="$(date +%s)"
|
||||
|
||||
if [[ "$LOAD_IMAGE" == "1" ]]; then
|
||||
docker buildx build \
|
||||
--platform linux/arm64 \
|
||||
--builder "$BUILDER_NAME" \
|
||||
--load \
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
||||
--build-arg "BUILDER_IMAGE=$BUILDER_IMAGE" \
|
||||
--build-arg "RUNTIME_IMAGE=$RUNTIME_IMAGE" \
|
||||
--metadata-file "$metadata_path" \
|
||||
-t "$IMAGE_TAG" \
|
||||
-f "$DOCKERFILE" \
|
||||
"$REPO_ROOT" 2>&1 | tee "$build_log"
|
||||
else
|
||||
raw_tar_path="$OUT_DIR/$(safe_tag_name "$IMAGE_TAG").tar"
|
||||
docker buildx build \
|
||||
--platform linux/arm64 \
|
||||
--builder "$BUILDER_NAME" \
|
||||
--output "type=docker,dest=$raw_tar_path" \
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
||||
--build-arg "BUILDER_IMAGE=$BUILDER_IMAGE" \
|
||||
--build-arg "RUNTIME_IMAGE=$RUNTIME_IMAGE" \
|
||||
--metadata-file "$metadata_path" \
|
||||
-t "$IMAGE_TAG" \
|
||||
-f "$DOCKERFILE" \
|
||||
"$REPO_ROOT" 2>&1 | tee "$build_log"
|
||||
gzip -f "$raw_tar_path"
|
||||
tar_path="${raw_tar_path}.gz"
|
||||
fi
|
||||
|
||||
elapsed_secs=$(( $(date +%s) - start_epoch ))
|
||||
|
||||
if [[ "$SAVE_IMAGE" == "1" && "$LOAD_IMAGE" == "1" ]]; then
|
||||
echo "saving image to $tar_path"
|
||||
docker save "$IMAGE_TAG" | gzip -c > "$tar_path"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "image=$IMAGE_TAG"
|
||||
echo "platform=linux/arm64"
|
||||
echo "builder_image=$BUILDER_IMAGE"
|
||||
echo "runtime_image=$RUNTIME_IMAGE"
|
||||
echo "elapsed_secs=$elapsed_secs"
|
||||
echo "metadata=$metadata_path"
|
||||
echo "tar=$tar_path"
|
||||
echo "tar_size_bytes=$(wc -c < "$tar_path" 2>/dev/null || echo 0)"
|
||||
echo "git_commit=$(git -C "$REPO_ROOT" rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||
echo "git_status_count=$(git -C "$REPO_ROOT" status --short 2>/dev/null | wc -l | tr -d ' ')"
|
||||
echo "built_at_utc=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
} > "$OUT_DIR/$(safe_tag_name "$IMAGE_TAG").build-summary.env"
|
||||
|
||||
echo "build complete: elapsed=${elapsed_secs}s tar=$tar_path"
|
||||
exec "$SCRIPT_DIR/build_docker_runtime_image.sh" --arch arm64 "$@"
|
||||
|
||||
367
scripts/docker/build_docker_installer_package.sh
Executable file
367
scripts/docker/build_docker_installer_package.sh
Executable file
@ -0,0 +1,367 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
TARGET_ARCH="${TARGET_ARCH:-}"
|
||||
IMAGE_TAG="${IMAGE_TAG:-}"
|
||||
IMAGE_TAR="${IMAGE_TAR:-}"
|
||||
PROMETHEUS_IMAGE="${PROMETHEUS_IMAGE:-prom/prometheus:v2.55.1}"
|
||||
PROMETHEUS_IMAGE_TAR="${PROMETHEUS_IMAGE_TAR:-}"
|
||||
GRAFANA_IMAGE="${GRAFANA_IMAGE:-grafana/grafana:11.3.1}"
|
||||
GRAFANA_IMAGE_TAR="${GRAFANA_IMAGE_TAR:-}"
|
||||
OUT_DIR="${OUT_DIR:-}"
|
||||
PACKAGE_PREFIX="${PACKAGE_PREFIX:-}"
|
||||
TEMPLATE_DIR="${TEMPLATE_DIR:-$REPO_ROOT/deploy/arm64-installer}"
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
scripts/docker/build_docker_installer_package.sh --arch amd64|arm64 [options]
|
||||
|
||||
Options:
|
||||
--arch <arch> Target architecture: amd64|arm64
|
||||
--image <tag> Runtime image tag recorded in package manifest.
|
||||
--image-tar <path> Existing docker save tar/tar.gz to include.
|
||||
--prometheus-image <tag>
|
||||
Prometheus image tag to record and package.
|
||||
--prometheus-image-tar <path>
|
||||
Existing Prometheus docker save tar/tar.gz to include.
|
||||
--grafana-image <tag>
|
||||
Grafana image tag to record and package.
|
||||
--grafana-image-tar <path>
|
||||
Existing Grafana docker save tar/tar.gz to include.
|
||||
--out-dir <path> Output directory.
|
||||
--prefix <name> Package directory/tar prefix.
|
||||
--template-dir <path>
|
||||
Package template directory.
|
||||
-h, --help Show help.
|
||||
|
||||
If --image-tar is omitted, the script uses the newest
|
||||
target/<arch>-docker/*.tar.gz file.
|
||||
USAGE
|
||||
}
|
||||
|
||||
normalize_arch() {
|
||||
case "$1" in
|
||||
amd64|x86_64)
|
||||
printf 'amd64\n'
|
||||
;;
|
||||
arm64|aarch64)
|
||||
printf 'arm64\n'
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
platform_for_arch() {
|
||||
printf 'linux/%s\n' "$1"
|
||||
}
|
||||
|
||||
safe_tag_name() {
|
||||
printf '%s' "$1" | tr '/:' '--'
|
||||
}
|
||||
|
||||
default_runtime_tag() {
|
||||
printf 'ours-rp-runtime-%s:dev\n' "$1"
|
||||
}
|
||||
|
||||
default_package_prefix() {
|
||||
printf 'ours-rp-docker-installer-%s\n' "$1"
|
||||
}
|
||||
|
||||
default_host_data_dir() {
|
||||
printf '/var/lib/ours-rp-%s-installer\n' "$1"
|
||||
}
|
||||
|
||||
default_compose_project() {
|
||||
printf 'ours-rp-%s-installer\n' "$1"
|
||||
}
|
||||
|
||||
default_metrics_instance() {
|
||||
printf '%s-installer\n' "$1"
|
||||
}
|
||||
|
||||
replace_or_append_env() {
|
||||
local env_path="$1"
|
||||
local key="$2"
|
||||
local value="$3"
|
||||
local tmp_env
|
||||
tmp_env="${env_path}.tmp"
|
||||
awk -v key="$key" -v value="$value" '
|
||||
BEGIN { done=0 }
|
||||
$0 ~ "^" key "=" { print key "=" value; done=1; next }
|
||||
{ print }
|
||||
END { if (!done) print key "=" value }
|
||||
' "$env_path" > "$tmp_env"
|
||||
mv "$tmp_env" "$env_path"
|
||||
}
|
||||
|
||||
replace_text_in_file() {
|
||||
local file_path="$1"
|
||||
local old_text="$2"
|
||||
local new_text="$3"
|
||||
OLD_TEXT="$old_text" NEW_TEXT="$new_text" perl -0pi -e 's/\Q$ENV{OLD_TEXT}\E/$ENV{NEW_TEXT}/g' "$file_path"
|
||||
}
|
||||
|
||||
ensure_image_for_platform() {
|
||||
local image="$1"
|
||||
local expected_platform="$2"
|
||||
local role="$3"
|
||||
local actual_platform
|
||||
if ! docker image inspect "$image" >/dev/null 2>&1; then
|
||||
echo "pulling $role image for $expected_platform: $image" >&2
|
||||
docker pull --platform "$expected_platform" "$image" >&2
|
||||
fi
|
||||
actual_platform="$(docker image inspect --format '{{.Os}}/{{.Architecture}}' "$image" 2>/dev/null || echo unknown)"
|
||||
if [[ "$actual_platform" != "$expected_platform" ]]; then
|
||||
echo "re-pulling $role image for $expected_platform: $image (current=$actual_platform)" >&2
|
||||
docker pull --platform "$expected_platform" "$image" >&2
|
||||
actual_platform="$(docker image inspect --format '{{.Os}}/{{.Architecture}}' "$image" 2>/dev/null || echo unknown)"
|
||||
fi
|
||||
[[ "$actual_platform" == "$expected_platform" ]] || {
|
||||
cat >&2 <<EOF
|
||||
wrong platform for $role image: $image
|
||||
expected: $expected_platform
|
||||
actual: $actual_platform
|
||||
EOF
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
|
||||
save_image_if_needed() {
|
||||
local image="$1"
|
||||
local existing_tar="$2"
|
||||
local out_dir="$3"
|
||||
local role="$4"
|
||||
local expected_platform="$5"
|
||||
if [[ -n "$existing_tar" ]]; then
|
||||
[[ -f "$existing_tar" ]] || {
|
||||
echo "missing $role image tar: $existing_tar" >&2
|
||||
exit 2
|
||||
}
|
||||
printf '%s\n' "$existing_tar"
|
||||
return 0
|
||||
fi
|
||||
ensure_image_for_platform "$image" "$expected_platform" "$role"
|
||||
local tar_path="$out_dir/$(safe_tag_name "$image")-${TARGET_ARCH}.tar.gz"
|
||||
echo "saving $role image to $tar_path" >&2
|
||||
docker save "$image" | gzip -c > "$tar_path"
|
||||
printf '%s\n' "$tar_path"
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--arch)
|
||||
TARGET_ARCH="$(normalize_arch "$2")" || {
|
||||
echo "unsupported target architecture: $2" >&2
|
||||
exit 2
|
||||
}
|
||||
shift 2
|
||||
;;
|
||||
--image)
|
||||
IMAGE_TAG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--image-tar)
|
||||
IMAGE_TAR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--prometheus-image)
|
||||
PROMETHEUS_IMAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--prometheus-image-tar)
|
||||
PROMETHEUS_IMAGE_TAR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--grafana-image)
|
||||
GRAFANA_IMAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--grafana-image-tar)
|
||||
GRAFANA_IMAGE_TAR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--out-dir)
|
||||
OUT_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--prefix)
|
||||
PACKAGE_PREFIX="$2"
|
||||
shift 2
|
||||
;;
|
||||
--template-dir)
|
||||
TEMPLATE_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -n "$TARGET_ARCH" ]] || {
|
||||
echo "--arch is required" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
[[ -d "$TEMPLATE_DIR" ]] || {
|
||||
echo "missing template dir: $TEMPLATE_DIR" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
if [[ -z "$IMAGE_TAG" ]]; then
|
||||
IMAGE_TAG="$(default_runtime_tag "$TARGET_ARCH")"
|
||||
fi
|
||||
if [[ -z "$OUT_DIR" ]]; then
|
||||
OUT_DIR="$REPO_ROOT/target/${TARGET_ARCH}-installer"
|
||||
fi
|
||||
if [[ -z "$PACKAGE_PREFIX" ]]; then
|
||||
PACKAGE_PREFIX="$(default_package_prefix "$TARGET_ARCH")"
|
||||
fi
|
||||
|
||||
TARGET_PLATFORM="$(platform_for_arch "$TARGET_ARCH")"
|
||||
HOST_DATA_DIR_DEFAULT="$(default_host_data_dir "$TARGET_ARCH")"
|
||||
COMPOSE_PROJECT_DEFAULT="$(default_compose_project "$TARGET_ARCH")"
|
||||
METRICS_INSTANCE_DEFAULT="$(default_metrics_instance "$TARGET_ARCH")"
|
||||
|
||||
if [[ -z "$IMAGE_TAR" ]]; then
|
||||
IMAGE_TAR="$(find "$REPO_ROOT/target/${TARGET_ARCH}-docker" -maxdepth 1 -type f \( -name '*.tar.gz' -o -name '*.tar' \) -printf '%T@ %p\n' 2>/dev/null | sort -nr | awk 'NR==1 {print $2}')"
|
||||
fi
|
||||
|
||||
[[ -n "$IMAGE_TAR" && -f "$IMAGE_TAR" ]] || {
|
||||
cat >&2 <<EOF
|
||||
missing runtime image tar for $TARGET_ARCH.
|
||||
|
||||
Build one first, for example:
|
||||
scripts/docker/build_docker_runtime_image.sh --arch $TARGET_ARCH --image $IMAGE_TAG
|
||||
EOF
|
||||
exit 2
|
||||
}
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
commit="$(git -C "$REPO_ROOT" rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||
timestamp="$(date -u +%Y%m%dT%H%M%SZ)"
|
||||
package_name="${PACKAGE_PREFIX}-${timestamp}-${commit}"
|
||||
stage="$OUT_DIR/$package_name"
|
||||
tar_path="$OUT_DIR/$package_name.tar.gz"
|
||||
|
||||
rm -rf "$stage"
|
||||
rsync -a --delete "$TEMPLATE_DIR"/ "$stage"/
|
||||
mkdir -p "$stage/images"
|
||||
cp "$IMAGE_TAR" "$stage/images/"
|
||||
|
||||
monitor_image_stage="$OUT_DIR/.monitor-images-$TARGET_ARCH-$timestamp"
|
||||
rm -rf "$monitor_image_stage"
|
||||
mkdir -p "$monitor_image_stage"
|
||||
prometheus_tar="$(save_image_if_needed "$PROMETHEUS_IMAGE" "$PROMETHEUS_IMAGE_TAR" "$monitor_image_stage" "prometheus" "$TARGET_PLATFORM")"
|
||||
grafana_tar="$(save_image_if_needed "$GRAFANA_IMAGE" "$GRAFANA_IMAGE_TAR" "$monitor_image_stage" "grafana" "$TARGET_PLATFORM")"
|
||||
cp "$prometheus_tar" "$stage/images/"
|
||||
cp "$grafana_tar" "$stage/images/"
|
||||
|
||||
if [[ -f "$stage/.env.example" ]]; then
|
||||
replace_or_append_env "$stage/.env.example" "PACKAGE_ARCH" "$TARGET_ARCH"
|
||||
replace_or_append_env "$stage/.env.example" "PACKAGE_PLATFORM" "$TARGET_PLATFORM"
|
||||
replace_or_append_env "$stage/.env.example" "COMPOSE_PROJECT_NAME" "$COMPOSE_PROJECT_DEFAULT"
|
||||
replace_or_append_env "$stage/.env.example" "RPKI_IMAGE" "$IMAGE_TAG"
|
||||
replace_or_append_env "$stage/.env.example" "RPKI_PLATFORM" "$TARGET_PLATFORM"
|
||||
replace_or_append_env "$stage/.env.example" "HOST_DATA_DIR" "$HOST_DATA_DIR_DEFAULT"
|
||||
replace_or_append_env "$stage/.env.example" "ALLOW_CROSS_ARCH" "0"
|
||||
replace_or_append_env "$stage/.env.example" "METRICS_INSTANCE" "$METRICS_INSTANCE_DEFAULT"
|
||||
replace_or_append_env "$stage/.env.example" "MONITOR_PLATFORM" "$TARGET_PLATFORM"
|
||||
replace_or_append_env "$stage/.env.example" "PROMETHEUS_IMAGE" "$PROMETHEUS_IMAGE"
|
||||
replace_or_append_env "$stage/.env.example" "GRAFANA_IMAGE" "$GRAFANA_IMAGE"
|
||||
fi
|
||||
|
||||
replace_text_in_file "$stage/docs/README.zh-CN.md" "__PACKAGE_ARCH__" "$TARGET_ARCH"
|
||||
replace_text_in_file "$stage/docs/README.en.md" "__PACKAGE_ARCH__" "$TARGET_ARCH"
|
||||
replace_text_in_file "$stage/docs/operations.zh-CN.md" "__PACKAGE_ARCH__" "$TARGET_ARCH"
|
||||
replace_text_in_file "$stage/docs/operations.en.md" "__PACKAGE_ARCH__" "$TARGET_ARCH"
|
||||
replace_text_in_file "$stage/docs/troubleshooting.zh-CN.md" "__PACKAGE_ARCH__" "$TARGET_ARCH"
|
||||
replace_text_in_file "$stage/docs/troubleshooting.en.md" "__PACKAGE_ARCH__" "$TARGET_ARCH"
|
||||
replace_text_in_file "$stage/docs/README.zh-CN.md" "__PACKAGE_PLATFORM__" "$TARGET_PLATFORM"
|
||||
replace_text_in_file "$stage/docs/README.en.md" "__PACKAGE_PLATFORM__" "$TARGET_PLATFORM"
|
||||
replace_text_in_file "$stage/docs/troubleshooting.zh-CN.md" "__PACKAGE_PLATFORM__" "$TARGET_PLATFORM"
|
||||
replace_text_in_file "$stage/docs/troubleshooting.en.md" "__PACKAGE_PLATFORM__" "$TARGET_PLATFORM"
|
||||
replace_text_in_file "$stage/docs/README.zh-CN.md" "__HOST_DATA_DIR__" "$HOST_DATA_DIR_DEFAULT"
|
||||
replace_text_in_file "$stage/docs/README.en.md" "__HOST_DATA_DIR__" "$HOST_DATA_DIR_DEFAULT"
|
||||
replace_text_in_file "$stage/docs/operations.zh-CN.md" "__HOST_DATA_DIR__" "$HOST_DATA_DIR_DEFAULT"
|
||||
replace_text_in_file "$stage/docs/operations.en.md" "__HOST_DATA_DIR__" "$HOST_DATA_DIR_DEFAULT"
|
||||
replace_text_in_file "$stage/docs/troubleshooting.zh-CN.md" "__HOST_DATA_DIR__" "$HOST_DATA_DIR_DEFAULT"
|
||||
replace_text_in_file "$stage/docs/troubleshooting.en.md" "__HOST_DATA_DIR__" "$HOST_DATA_DIR_DEFAULT"
|
||||
|
||||
runtime_tar_sha256="$(sha256sum "$IMAGE_TAR" | awk '{print $1}')"
|
||||
prometheus_tar_sha256="$(sha256sum "$prometheus_tar" | awk '{print $1}')"
|
||||
grafana_tar_sha256="$(sha256sum "$grafana_tar" | awk '{print $1}')"
|
||||
|
||||
cat > "$stage/PACKAGE-MANIFEST.env" <<EOF
|
||||
package_name=$package_name
|
||||
created_at_utc=$timestamp
|
||||
git_commit=$commit
|
||||
git_status_count=$(git -C "$REPO_ROOT" status --short 2>/dev/null | wc -l | tr -d ' ')
|
||||
PACKAGE_ARCH=$TARGET_ARCH
|
||||
PACKAGE_PLATFORM=$TARGET_PLATFORM
|
||||
package_arch=$TARGET_ARCH
|
||||
package_platform=$TARGET_PLATFORM
|
||||
cross_arch_default=deny
|
||||
cross_arch_enable_var=ALLOW_CROSS_ARCH
|
||||
image_tag=$IMAGE_TAG
|
||||
image_tar=$(basename "$IMAGE_TAR")
|
||||
image_tar_size_bytes=$(wc -c < "$IMAGE_TAR")
|
||||
image_tar_sha256=$runtime_tar_sha256
|
||||
prometheus_image=$PROMETHEUS_IMAGE
|
||||
prometheus_image_tar=$(basename "$prometheus_tar")
|
||||
prometheus_image_tar_size_bytes=$(wc -c < "$prometheus_tar")
|
||||
prometheus_image_tar_sha256=$prometheus_tar_sha256
|
||||
grafana_image=$GRAFANA_IMAGE
|
||||
grafana_image_tar=$(basename "$grafana_tar")
|
||||
grafana_image_tar_size_bytes=$(wc -c < "$grafana_tar")
|
||||
grafana_image_tar_sha256=$grafana_tar_sha256
|
||||
target_platform=$TARGET_PLATFORM
|
||||
monitor_platform=$TARGET_PLATFORM
|
||||
default_host_data_dir=$HOST_DATA_DIR_DEFAULT
|
||||
default_compose_project_name=$COMPOSE_PROJECT_DEFAULT
|
||||
default_metrics_instance=$METRICS_INSTANCE_DEFAULT
|
||||
EOF
|
||||
|
||||
cat > "$stage/PACKAGE-SUMMARY.txt" <<EOF
|
||||
package_name: $package_name
|
||||
package_arch: $TARGET_ARCH
|
||||
package_platform: $TARGET_PLATFORM
|
||||
runtime_image: $IMAGE_TAG
|
||||
prometheus_image: $PROMETHEUS_IMAGE
|
||||
grafana_image: $GRAFANA_IMAGE
|
||||
default_host_data_dir: $HOST_DATA_DIR_DEFAULT
|
||||
default_compose_project_name: $COMPOSE_PROJECT_DEFAULT
|
||||
cross_arch_default: deny
|
||||
cross_arch_enable_var: ALLOW_CROSS_ARCH
|
||||
EOF
|
||||
|
||||
chmod +x "$stage"/*.sh "$stage/scripts"/*.sh
|
||||
tar -C "$OUT_DIR" -czf "$tar_path" "$package_name"
|
||||
package_sha256="$(sha256sum "$tar_path" | awk '{print $1}')"
|
||||
rm -rf "$monitor_image_stage"
|
||||
|
||||
{
|
||||
echo "package=$tar_path"
|
||||
echo "package_dir=$stage"
|
||||
echo "package_size_bytes=$(wc -c < "$tar_path")"
|
||||
echo "package_sha256=$package_sha256"
|
||||
echo "package_arch=$TARGET_ARCH"
|
||||
echo "package_platform=$TARGET_PLATFORM"
|
||||
echo "manifest=$stage/PACKAGE-MANIFEST.env"
|
||||
echo "summary=$stage/PACKAGE-SUMMARY.txt"
|
||||
} > "$OUT_DIR/$package_name.summary.env"
|
||||
|
||||
echo "package built: $tar_path"
|
||||
238
scripts/docker/build_docker_runtime_image.sh
Executable file
238
scripts/docker/build_docker_runtime_image.sh
Executable file
@ -0,0 +1,238 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
TARGET_ARCH="${TARGET_ARCH:-}"
|
||||
IMAGE_TAG="${IMAGE_TAG:-}"
|
||||
BUILDER_IMAGE="${BUILDER_IMAGE:-rust:1-bookworm}"
|
||||
RUNTIME_IMAGE="${RUNTIME_IMAGE:-debian:bookworm-slim}"
|
||||
OUT_DIR="${OUT_DIR:-}"
|
||||
DOCKERFILE="${DOCKERFILE:-$REPO_ROOT/docker/ours-rp-runtime.Dockerfile}"
|
||||
BUILDER_NAME="${BUILDER_NAME:-default}"
|
||||
INSTALL_BINFMT="${INSTALL_BINFMT:-1}"
|
||||
SAVE_IMAGE="${SAVE_IMAGE:-1}"
|
||||
LOAD_IMAGE="${LOAD_IMAGE:-1}"
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
scripts/docker/build_docker_runtime_image.sh --arch amd64|arm64 [options]
|
||||
|
||||
Options:
|
||||
--arch <arch> Target architecture: amd64|arm64
|
||||
--image <tag> Docker image tag (default: ours-rp-runtime-<arch>:dev)
|
||||
--out-dir <path> Directory for docker save tar.gz (default: target/<arch>-docker)
|
||||
--dockerfile <path> Dockerfile path
|
||||
--builder <name> buildx builder name
|
||||
--builder-image <tag>
|
||||
Builder base image (default: rust:1-bookworm)
|
||||
--runtime-image <tag>
|
||||
Runtime base image (default: debian:bookworm-slim)
|
||||
--no-binfmt Do not install binfmt/qemu for cross-architecture builds
|
||||
--no-save Build image but do not docker save it
|
||||
--no-load Use buildx output tar instead of --load
|
||||
-h, --help Show this help
|
||||
USAGE
|
||||
}
|
||||
|
||||
normalize_arch() {
|
||||
case "$1" in
|
||||
amd64|x86_64)
|
||||
printf 'amd64\n'
|
||||
;;
|
||||
arm64|aarch64)
|
||||
printf 'arm64\n'
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
safe_tag_name() {
|
||||
printf '%s' "$1" | tr '/:' '--'
|
||||
}
|
||||
|
||||
platform_for_arch() {
|
||||
printf 'linux/%s\n' "$1"
|
||||
}
|
||||
|
||||
default_image_tag() {
|
||||
printf 'ours-rp-runtime-%s:dev\n' "$1"
|
||||
}
|
||||
|
||||
require_command() {
|
||||
command -v "$1" >/dev/null 2>&1 || {
|
||||
echo "missing required command: $1" >&2
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
|
||||
host_arch() {
|
||||
local raw_arch
|
||||
raw_arch="$(uname -m)"
|
||||
normalize_arch "$raw_arch" || {
|
||||
echo "unsupported host architecture: $raw_arch" >&2
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--arch)
|
||||
TARGET_ARCH="$(normalize_arch "$2")" || {
|
||||
echo "unsupported target architecture: $2" >&2
|
||||
exit 2
|
||||
}
|
||||
shift 2
|
||||
;;
|
||||
--image)
|
||||
IMAGE_TAG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--out-dir)
|
||||
OUT_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--dockerfile)
|
||||
DOCKERFILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--builder)
|
||||
BUILDER_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
--builder-image)
|
||||
BUILDER_IMAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--runtime-image)
|
||||
RUNTIME_IMAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--no-binfmt)
|
||||
INSTALL_BINFMT=0
|
||||
shift
|
||||
;;
|
||||
--no-save)
|
||||
SAVE_IMAGE=0
|
||||
shift
|
||||
;;
|
||||
--no-load)
|
||||
LOAD_IMAGE=0
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -n "$TARGET_ARCH" ]] || {
|
||||
echo "--arch is required" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
if [[ -z "$IMAGE_TAG" ]]; then
|
||||
IMAGE_TAG="$(default_image_tag "$TARGET_ARCH")"
|
||||
fi
|
||||
if [[ -z "$OUT_DIR" ]]; then
|
||||
OUT_DIR="$REPO_ROOT/target/${TARGET_ARCH}-docker"
|
||||
fi
|
||||
|
||||
require_command docker
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
target_platform="$(platform_for_arch "$TARGET_ARCH")"
|
||||
local_host_arch="$(host_arch)"
|
||||
|
||||
if [[ "$INSTALL_BINFMT" == "1" && "$local_host_arch" != "$TARGET_ARCH" ]]; then
|
||||
echo "installing binfmt/qemu for $TARGET_ARCH"
|
||||
docker run --rm --privileged tonistiigi/binfmt --install "$TARGET_ARCH"
|
||||
fi
|
||||
|
||||
if [[ "$BUILDER_NAME" != "default" ]] && ! docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then
|
||||
docker buildx create --name "$BUILDER_NAME" --driver docker-container --use >/dev/null
|
||||
else
|
||||
docker buildx use "$BUILDER_NAME" >/dev/null
|
||||
fi
|
||||
docker buildx inspect --bootstrap >/dev/null
|
||||
|
||||
metadata_path="$OUT_DIR/$(safe_tag_name "$IMAGE_TAG").build-metadata.json"
|
||||
tar_path="$OUT_DIR/$(safe_tag_name "$IMAGE_TAG").tar.gz"
|
||||
build_log="$OUT_DIR/$(safe_tag_name "$IMAGE_TAG").build.log"
|
||||
|
||||
echo "building $target_platform image: $IMAGE_TAG"
|
||||
echo "repo: $REPO_ROOT"
|
||||
echo "dockerfile: $DOCKERFILE"
|
||||
echo "builder_image: $BUILDER_IMAGE"
|
||||
echo "runtime_image: $RUNTIME_IMAGE"
|
||||
start_epoch="$(date +%s)"
|
||||
|
||||
if [[ "$LOAD_IMAGE" == "1" ]]; then
|
||||
docker buildx build \
|
||||
--platform "$target_platform" \
|
||||
--builder "$BUILDER_NAME" \
|
||||
--load \
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
||||
--build-arg "BUILDER_IMAGE=$BUILDER_IMAGE" \
|
||||
--build-arg "RUNTIME_IMAGE=$RUNTIME_IMAGE" \
|
||||
--metadata-file "$metadata_path" \
|
||||
-t "$IMAGE_TAG" \
|
||||
-f "$DOCKERFILE" \
|
||||
"$REPO_ROOT" 2>&1 | tee "$build_log"
|
||||
else
|
||||
raw_tar_path="$OUT_DIR/$(safe_tag_name "$IMAGE_TAG").tar"
|
||||
docker buildx build \
|
||||
--platform "$target_platform" \
|
||||
--builder "$BUILDER_NAME" \
|
||||
--output "type=docker,dest=$raw_tar_path" \
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
||||
--build-arg "BUILDER_IMAGE=$BUILDER_IMAGE" \
|
||||
--build-arg "RUNTIME_IMAGE=$RUNTIME_IMAGE" \
|
||||
--metadata-file "$metadata_path" \
|
||||
-t "$IMAGE_TAG" \
|
||||
-f "$DOCKERFILE" \
|
||||
"$REPO_ROOT" 2>&1 | tee "$build_log"
|
||||
gzip -f "$raw_tar_path"
|
||||
tar_path="${raw_tar_path}.gz"
|
||||
fi
|
||||
|
||||
elapsed_secs=$(( $(date +%s) - start_epoch ))
|
||||
|
||||
if [[ "$SAVE_IMAGE" == "1" && "$LOAD_IMAGE" == "1" ]]; then
|
||||
echo "saving image to $tar_path"
|
||||
docker save "$IMAGE_TAG" | gzip -c > "$tar_path"
|
||||
fi
|
||||
|
||||
tar_sha256=""
|
||||
if [[ -f "$tar_path" ]]; then
|
||||
tar_sha256="$(sha256sum "$tar_path" | awk '{print $1}')"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "image=$IMAGE_TAG"
|
||||
echo "platform=$target_platform"
|
||||
echo "arch=$TARGET_ARCH"
|
||||
echo "builder_image=$BUILDER_IMAGE"
|
||||
echo "runtime_image=$RUNTIME_IMAGE"
|
||||
echo "elapsed_secs=$elapsed_secs"
|
||||
echo "metadata=$metadata_path"
|
||||
echo "tar=$tar_path"
|
||||
echo "tar_size_bytes=$(wc -c < "$tar_path" 2>/dev/null || echo 0)"
|
||||
echo "tar_sha256=$tar_sha256"
|
||||
echo "git_commit=$(git -C "$REPO_ROOT" rev-parse --short HEAD 2>/dev/null || echo unknown)"
|
||||
echo "git_status_count=$(git -C "$REPO_ROOT" status --short 2>/dev/null | wc -l | tr -d ' ')"
|
||||
echo "built_at_utc=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
} > "$OUT_DIR/$(safe_tag_name "$IMAGE_TAG").build-summary.env"
|
||||
|
||||
echo "build complete: elapsed=${elapsed_secs}s tar=$tar_path"
|
||||
Loading…
x
Reference in New Issue
Block a user