#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=common.sh source "$SCRIPT_DIR/common.sh" REUSE_ENV_FROM="" UPDATE_PACKAGE_IMAGE=1 usage() { cat <<'USAGE' Usage: ./scripts/upgrade.sh [--reuse-env-from /path/to/.env] [--keep-reused-image] By default, --reuse-env-from creates the new .env from this package's .env.example first, then overlays existing user settings from the old .env. For declared configuration keys, explicit invocation variables have highest priority, for example: INTERVAL_SECS=300 ./scripts/upgrade.sh ... Image tags are intentionally kept from the new package so the upgraded service actually runs the new packaged runtime and monitor images. Use --keep-reused-image only when you intentionally want to keep previous image tags. USAGE } while [[ $# -gt 0 ]]; do case "$1" in --reuse-env-from) REUSE_ENV_FROM="$2" shift 2 ;; --keep-reused-image) UPDATE_PACKAGE_IMAGE=0 shift ;; -h|--help) usage exit 0 ;; *) die "unknown option: $1" ;; esac done overlay_reused_env() { local source_env="$1" local target_env="$2" local key local value local -a reused_keys=() local -a ignored_removed_keys=() local -a preserved_package_keys=() REUSED_ENV_KEYS=() parse_env_file "$source_env" || die "unable to parse reused environment: $source_env" while IFS= read -r key; do if ! template_has_env_key "$key"; then ignored_removed_keys+=("$key") continue fi case "$key" in PACKAGE_ARCH|PACKAGE_PLATFORM|RPKI_PLATFORM|METRICS_PLATFORM|MONITOR_PLATFORM) preserved_package_keys+=("$key") continue ;; RPKI_IMAGE|METRICS_IMAGE|PROMETHEUS_IMAGE|GRAFANA_IMAGE) if [[ "$UPDATE_PACKAGE_IMAGE" != "0" ]]; then preserved_package_keys+=("$key") continue fi ;; esac [[ -n "${ENV_PARSED_VALUES[$key]+x}" ]] || die "unable to read $key from reused environment: $source_env" value="${ENV_PARSED_VALUES[$key]}" env_file_set_value "$target_env" "$key" "$value" REUSED_ENV_KEYS["$key"]=1 reused_keys+=("$key") done < <(env_file_assignment_keys "$source_env") log_env_key_group "reused_keys" "${reused_keys[@]}" log_env_key_group "ignored_removed_old_keys" "${ignored_removed_keys[@]}" log_env_key_group "preserved_package_keys" "${preserved_package_keys[@]}" } apply_invocation_env_overrides() { local target_env="$1" local key local -a overridden_keys=() for key in "${ENV_TEMPLATE_KEYS[@]}"; do [[ -n "${INVOCATION_ENV_OVERRIDES[$key]+x}" ]] || continue env_file_set_value "$target_env" "$key" "${INVOCATION_ENV_OVERRIDES[$key]}" overridden_keys+=("$key") done log_env_key_group "command_override_keys" "${overridden_keys[@]}" } log_template_only_keys() { local key local -a template_only_keys=() for key in "${ENV_TEMPLATE_KEYS[@]}"; do [[ -n "${REUSED_ENV_KEYS[$key]+x}" ]] && continue [[ -n "${INVOCATION_ENV_OVERRIDES[$key]+x}" ]] && continue template_only_keys+=("$key") done log_env_key_group "template_only_keys" "${template_only_keys[@]}" } load_env_template_keys "$ENV_EXAMPLE" validate_env_file_contract "$ENV_EXAMPLE" capture_invocation_env_overrides REUSED_ENV_KEYS=() if [[ -n "$REUSE_ENV_FROM" ]]; then [[ -f "$REUSE_ENV_FROM" ]] || die "missing reuse env file: $REUSE_ENV_FROM" if [[ ! -f "$ENV_FILE" ]]; then cp "$ENV_EXAMPLE" "$ENV_FILE" overlay_reused_env "$REUSE_ENV_FROM" "$ENV_FILE" log "created new package env from .env.example and overlaid user settings from $REUSE_ENV_FROM" else log "keeping existing env at $ENV_FILE; reuse source ignored: $REUSE_ENV_FROM" fi fi if [[ ! -f "$ENV_FILE" ]]; then cp "$ENV_EXAMPLE" "$ENV_FILE" log "created new package env from .env.example" fi apply_invocation_env_overrides "$ENV_FILE" log_template_only_keys validate_env_file_contract "$ENV_FILE" load_env assert_arch_compatibility create_data_dirs install_docker_if_missing load_installer_images ensure_binfmt_if_needed verify_runtime_image verify_metrics_image verify_monitor_images compose_cmd --profile core --profile sidecar --profile monitor up -d --force-recreate "$SCRIPT_DIR/status.sh" --brief || true