add multi-arch docker installer

This commit is contained in:
2026-06-30 16:18:41 +08:00
parent 371c819126
commit 6c45cc94f3
21 changed files with 1032 additions and 499 deletions

167
deploy/arm64-installer/scripts/common.sh Executable file → Normal file
View 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() {