#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PATCH_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" PAYLOAD_ROOT="$SCRIPT_DIR/payload" STATE_DIR_NAME=".custom-tal-patch-state" EXPECTED_SOURCE_COMMIT="9f4f4cf069e9fa8f6f97ed0f1065adac38abe82f" usage() { cat <<'USAGE' Usage: ./apply_custom_tal_patch.sh --component-root ./apply_custom_tal_patch.sh --component-root --enable-custom The default operation installs the overlay but does not change the existing .env. --enable-custom writes the custom TAL/TA/root-cert example values into the component .env so the next run uses the fixed local fixture. Stop the ours RP service before applying or rolling back the overlay. USAGE } die() { echo "error: $*" >&2 exit 2 } COMPONENT_ROOT="" ENABLE_CUSTOM=0 while [[ $# -gt 0 ]]; do case "$1" in --component-root) COMPONENT_ROOT="${2:-}" shift 2 ;; --enable-custom) ENABLE_CUSTOM=1 shift ;; -h|--help) usage exit 0 ;; *) die "unknown option: $1" ;; esac done [[ -n "$COMPONENT_ROOT" ]] || die "--component-root is required" COMPONENT_ROOT="$(cd "$COMPONENT_ROOT" 2>/dev/null && pwd)" \ || die "component root does not exist: $COMPONENT_ROOT" [[ -f "$COMPONENT_ROOT/PACKAGE-MANIFEST.env" ]] \ || die "missing component PACKAGE-MANIFEST.env: $COMPONENT_ROOT" [[ -d "$PAYLOAD_ROOT" ]] || die "missing patch payload: $PAYLOAD_ROOT" # shellcheck disable=SC1091 source "$COMPONENT_ROOT/PACKAGE-MANIFEST.env" [[ "${source_commit:-}" == "$EXPECTED_SOURCE_COMMIT" ]] \ || die "base source commit mismatch: ${source_commit:-missing} != $EXPECTED_SOURCE_COMMIT" [[ "${package_arch:-${PACKAGE_ARCH:-}}" == "arm64" ]] \ || die "this patch is for the customer Arm64 component, got ${package_arch:-${PACKAGE_ARCH:-missing}}" STATE_ROOT="$COMPONENT_ROOT/$STATE_DIR_NAME" BACKUP_ROOT="$STATE_ROOT/original" marker="$COMPONENT_ROOT/CUSTOM-TAL-PATCH-MANIFEST.env" set_env_value() { local env_path="$1" local key="$2" local value="$3" local tmp_path="${env_path}.custom-tal-patch.tmp" [[ -f "$env_path" ]] || die "missing component .env: $env_path" awk -v key="$key" -v value="$value" ' BEGIN { found = 0 } $0 ~ "^" key "=" { print key "=" value; found = 1; next } { print } END { if (!found) print key "=" value } ' "$env_path" > "$tmp_path" mv "$tmp_path" "$env_path" } copy_payload_file() { local source_path="$1" local target_path="$2" mkdir -p "$(dirname "$target_path")" cp "$source_path" "$target_path" chmod --reference="$source_path" "$target_path" 2>/dev/null || true } append_custom_env_example() { local target_path="$1" if ! grep -Eq '^CUSTOM_TAL_URI=' "$target_path"; then { printf '\n# #142 custom TAL patch settings; original package values above are preserved.\n' cat "$SCRIPT_DIR/custom-tal.env.example" } >> "$target_path" fi } if [[ -e "$STATE_ROOT" ]]; then die "patch is already applied or an incomplete state exists: $STATE_ROOT" fi mkdir -p "$BACKUP_ROOT" for relative_path in compose/docker-compose.yml .env.example; do [[ -f "$COMPONENT_ROOT/$relative_path" ]] \ || die "missing base file: $COMPONENT_ROOT/$relative_path" mkdir -p "$BACKUP_ROOT/$(dirname "$relative_path")" cp -a "$COMPONENT_ROOT/$relative_path" "$BACKUP_ROOT/$relative_path" done runner_path="$COMPONENT_ROOT/scripts/soak/run_soak.sh" if [[ -e "$runner_path" ]]; then mkdir -p "$BACKUP_ROOT/scripts/soak" cp -a "$runner_path" "$BACKUP_ROOT/scripts/soak/run_soak.sh" printf 'runner_was_present=1\n' > "$STATE_ROOT/state.env" else printf 'runner_was_present=0\n' > "$STATE_ROOT/state.env" fi if [[ -d "$COMPONENT_ROOT/custom-fixtures" ]]; then cp -a "$COMPONENT_ROOT/custom-fixtures" "$BACKUP_ROOT/custom-fixtures" printf 'custom_fixtures_were_present=1\n' >> "$STATE_ROOT/state.env" else printf 'custom_fixtures_were_present=0\n' >> "$STATE_ROOT/state.env" fi if [[ -d "$COMPONENT_ROOT/custom-tal-patch" ]]; then cp -a "$COMPONENT_ROOT/custom-tal-patch" "$BACKUP_ROOT/custom-tal-patch" printf 'patch_tools_were_present=1\n' >> "$STATE_ROOT/state.env" else printf 'patch_tools_were_present=0\n' >> "$STATE_ROOT/state.env" fi if [[ -f "$COMPONENT_ROOT/custom-tal.env.example" ]]; then cp -a "$COMPONENT_ROOT/custom-tal.env.example" "$BACKUP_ROOT/custom-tal.env.example" printf 'custom_env_example_was_present=1\n' >> "$STATE_ROOT/state.env" else printf 'custom_env_example_was_present=0\n' >> "$STATE_ROOT/state.env" fi if [[ "$ENABLE_CUSTOM" == "1" ]]; then [[ -f "$COMPONENT_ROOT/.env" ]] || die "missing component .env: $COMPONENT_ROOT/.env" cp -a "$COMPONENT_ROOT/.env" "$BACKUP_ROOT/.env" fi copy_payload_file "$PAYLOAD_ROOT/compose/docker-compose.yml" "$COMPONENT_ROOT/compose/docker-compose.yml" append_custom_env_example "$COMPONENT_ROOT/.env.example" copy_payload_file "$PAYLOAD_ROOT/scripts/soak/run_soak.sh" "$runner_path" mkdir -p "$COMPONENT_ROOT/custom-fixtures/tal" \ "$COMPONENT_ROOT/custom-fixtures/ta" \ "$COMPONENT_ROOT/custom-fixtures/certs" \ "$COMPONENT_ROOT/custom-fixtures/services" if [[ -d "$PAYLOAD_ROOT/custom-fixtures" ]]; then cp -a "$PAYLOAD_ROOT/custom-fixtures/." "$COMPONENT_ROOT/custom-fixtures/" fi mkdir -p "$COMPONENT_ROOT/custom-tal-patch/tools" cp -a "$PAYLOAD_ROOT/tools/." "$COMPONENT_ROOT/custom-tal-patch/tools/" copy_payload_file "$SCRIPT_DIR/custom-tal.env.example" \ "$COMPONENT_ROOT/custom-tal.env.example" if [[ "$ENABLE_CUSTOM" == "1" ]]; then set_env_value "$COMPONENT_ROOT/.env" RIRS custom set_env_value "$COMPONENT_ROOT/.env" TAL_INPUT_MODE custom-file-with-ta set_env_value "$COMPONENT_ROOT/.env" CUSTOM_FIXTURE_HOST_DIR ../custom-fixtures set_env_value "$COMPONENT_ROOT/.env" CUSTOM_TAL_PATH /opt/ours-rp/custom-fixtures/tal/custom.tal set_env_value "$COMPONENT_ROOT/.env" CUSTOM_TA_PATH /opt/ours-rp/custom-fixtures/ta/custom-ta.cer set_env_value "$COMPONENT_ROOT/.env" CUSTOM_TAL_URI https://host.docker.internal:18443/tal/custom.tal set_env_value "$COMPONENT_ROOT/.env" HTTP_ROOT_CERT_PATHS /opt/ours-rp/custom-fixtures/certs/rrdp-ca.pem printf 'env_was_enabled=1\n' >> "$STATE_ROOT/state.env" else printf 'env_was_enabled=0\n' >> "$STATE_ROOT/state.env" fi [[ -f "$SCRIPT_DIR/PATCH-MANIFEST.env" ]] \ || die "missing PATCH-MANIFEST.env" cp "$SCRIPT_DIR/PATCH-MANIFEST.env" "$marker" printf 'patch_root=%s\n' "$PATCH_ROOT" >> "$STATE_ROOT/state.env" printf 'applied_at_utc=%s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$STATE_ROOT/state.env" echo "custom TAL patch applied to $COMPONENT_ROOT" if [[ "$ENABLE_CUSTOM" == "1" ]]; then echo "custom mode enabled in $COMPONENT_ROOT/.env" else echo "custom mode remains disabled; review custom-tal.env.example before enabling it" fi