add multi-arch docker installer
This commit is contained in:
@@ -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"
|
||||
Reference in New Issue
Block a user