147 lines
5.8 KiB
Bash
147 lines
5.8 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$BASH_SOURCE")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
PATCH_SOURCE="$REPO_ROOT/deploy/docker-installer/custom-tal-patch"
|
|
BASE_COMPONENT_PACKAGE=""
|
|
OUT_DIR="$(printenv OUT_DIR 2>/dev/null || true)"
|
|
PREFIX="$(printenv PREFIX 2>/dev/null || true)"
|
|
ALLOW_DIRTY=0
|
|
[[ -n "$OUT_DIR" ]] || OUT_DIR="$REPO_ROOT/target/custom-tal-patch"
|
|
[[ -n "$PREFIX" ]] || PREFIX="ours-rp-custom-tal-patch"
|
|
|
|
usage() {
|
|
cat <<'USAGE'
|
|
Usage:
|
|
scripts/docker/build_custom_tal_patch.sh \
|
|
--base-component-package <ours-rp-installer-*.tar.gz> \
|
|
[--out-dir <dir>] [--prefix <name>] [--allow-dirty]
|
|
|
|
The patch targets the Arm64 component package from the customer stack. It
|
|
overlays the runner, Compose, fixture mount and test-service tools; it does not
|
|
rebuild or replace the runtime image.
|
|
USAGE
|
|
}
|
|
|
|
die() {
|
|
echo "error: $*" >&2
|
|
exit 2
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--base-component-package) BASE_COMPONENT_PACKAGE="$2"; shift 2 ;;
|
|
--out-dir) OUT_DIR="$2"; shift 2 ;;
|
|
--prefix) PREFIX="$2"; shift 2 ;;
|
|
--allow-dirty) ALLOW_DIRTY=1; shift ;;
|
|
-h|--help) usage; exit 0 ;;
|
|
*) die "unknown option: $1" ;;
|
|
esac
|
|
done
|
|
|
|
[[ -f "$BASE_COMPONENT_PACKAGE" ]] || die "missing base component package: $BASE_COMPONENT_PACKAGE"
|
|
[[ -d "$PATCH_SOURCE" ]] || die "missing patch source: $PATCH_SOURCE"
|
|
|
|
SOURCE_COMMIT="$(git -C "$REPO_ROOT" rev-parse HEAD)"
|
|
SOURCE_COMMIT_SHORT="$(git -C "$REPO_ROOT" rev-parse --short=8 HEAD)"
|
|
SOURCE_DIRTY=false
|
|
if [[ -n "$(git -C "$REPO_ROOT" status --short)" ]]; then
|
|
SOURCE_DIRTY=true
|
|
fi
|
|
if [[ "$SOURCE_DIRTY" == true && "$ALLOW_DIRTY" != 1 ]]; then
|
|
die "source worktree is dirty; use --allow-dirty for a development patch"
|
|
fi
|
|
|
|
package_root="$(tar -tzf "$BASE_COMPONENT_PACKAGE" | awk -F/ '!seen { print $1; seen = 1 }')"
|
|
[[ -n "$package_root" ]] || die "cannot determine component package root"
|
|
manifest_text="$(tar -xOf "$BASE_COMPONENT_PACKAGE" "$package_root/PACKAGE-MANIFEST.env")" \
|
|
|| die "base component package has no PACKAGE-MANIFEST.env"
|
|
read_manifest_value() {
|
|
printf '%s\n' "$manifest_text" | awk -F= -v key="$1" '$1 == key { print substr($0, index($0, "=") + 1); exit }'
|
|
}
|
|
base_source_commit="$(read_manifest_value source_commit)"
|
|
base_package_arch="$(read_manifest_value package_arch)"
|
|
base_runtime_image="$(read_manifest_value runtime_image)"
|
|
[[ "$base_source_commit" == 9f4f4cf069e9fa8f6f97ed0f1065adac38abe82f ]] \
|
|
|| die "base source commit mismatch: $base_source_commit"
|
|
[[ "$base_package_arch" == arm64 ]] || die "base package must be arm64: $base_package_arch"
|
|
|
|
timestamp="$(date -u +%Y%m%dT%H%M%SZ)"
|
|
patch_name="$PREFIX-$SOURCE_COMMIT_SHORT"
|
|
if [[ "$SOURCE_DIRTY" == true ]]; then
|
|
patch_name="$patch_name-dirty"
|
|
fi
|
|
patch_name="$patch_name-$timestamp"
|
|
stage="$OUT_DIR/$patch_name"
|
|
tar_path="$OUT_DIR/$patch_name.tar.gz"
|
|
base_sha256="$(sha256sum "$BASE_COMPONENT_PACKAGE" | awk '{ print $1 }')"
|
|
rm -rf "$stage"
|
|
mkdir -p "$stage/payload/compose" "$stage/payload/scripts/soak" \
|
|
"$stage/payload/custom-fixtures" "$stage/payload/tools"
|
|
|
|
cp "$PATCH_SOURCE/apply_custom_tal_patch.sh" "$stage/"
|
|
cp "$PATCH_SOURCE/rollback_custom_tal_patch.sh" "$stage/"
|
|
cp "$PATCH_SOURCE/custom-tal.env.example" "$stage/"
|
|
cp "$REPO_ROOT/deploy/docker-installer/compose/docker-compose.yml" "$stage/payload/compose/"
|
|
cp "$REPO_ROOT/scripts/soak/run_soak.sh" "$stage/payload/scripts/soak/"
|
|
cp "$REPO_ROOT/deploy/docker-installer/custom-fixtures/README.md" "$stage/payload/custom-fixtures/"
|
|
cp "$PATCH_SOURCE/tools/generate_custom_fixture.py" "$stage/payload/tools/"
|
|
cp "$PATCH_SOURCE/tools/serve_https.py" "$stage/payload/tools/"
|
|
cp "$PATCH_SOURCE/tools/start_fixed_services.sh" "$stage/payload/tools/"
|
|
cp "$PATCH_SOURCE/tools/stop_fixed_services.sh" "$stage/payload/tools/"
|
|
chmod +x "$stage/apply_custom_tal_patch.sh" "$stage/rollback_custom_tal_patch.sh" \
|
|
"$stage/payload/scripts/soak/run_soak.sh" "$stage/payload/tools/"*.sh \
|
|
"$stage/payload/tools/"*.py
|
|
|
|
{
|
|
echo "patch_schema_version=1"
|
|
echo "patch_name=$patch_name"
|
|
echo "created_at_utc=$timestamp"
|
|
echo "source_commit=$SOURCE_COMMIT"
|
|
echo "source_commit_short=$SOURCE_COMMIT_SHORT"
|
|
echo "source_dirty=$SOURCE_DIRTY"
|
|
echo "base_component_archive=$(basename "$BASE_COMPONENT_PACKAGE")"
|
|
echo "base_component_archive_sha256=$base_sha256"
|
|
echo "base_component_root=$package_root"
|
|
echo "base_source_commit=$base_source_commit"
|
|
echo "base_package_arch=$base_package_arch"
|
|
echo "base_runtime_image=$base_runtime_image"
|
|
echo "overlay_runtime_image_unchanged=true"
|
|
echo "custom_mode=RIRS=custom,TAL_INPUT_MODE=custom-file-with-ta"
|
|
echo "rrdp_port=18443"
|
|
echo "rsync_port=1873"
|
|
echo "payload_root=payload"
|
|
while IFS= read -r relative_path; do
|
|
safe_name="$(printf '%s' "$relative_path" | tr '/.' '__')"
|
|
file_sha256="$(sha256sum "$stage/payload/$relative_path" | awk '{ print $1 }')"
|
|
echo "payload_"$safe_name"_sha256=$file_sha256"
|
|
done < <(cd "$stage/payload" && find . -type f -printf '%P\n' | sort)
|
|
} > "$stage/PATCH-MANIFEST.env"
|
|
|
|
cat > "$stage/PATCH-SUMMARY.txt" <<EOF
|
|
patch_name: $patch_name
|
|
base_component_archive: $(basename "$BASE_COMPONENT_PACKAGE")
|
|
base_component_archive_sha256: $base_sha256
|
|
base_source_commit: $base_source_commit
|
|
source_commit: $SOURCE_COMMIT
|
|
source_dirty: $SOURCE_DIRTY
|
|
runtime_image: $base_runtime_image
|
|
runtime_image_changed: false
|
|
custom_fixture_generator: payload/tools/generate_custom_fixture.py
|
|
fixed_services: payload/tools/start_fixed_services.sh
|
|
EOF
|
|
|
|
tar -C "$OUT_DIR" -czf "$tar_path" "$patch_name"
|
|
patch_sha256="$(sha256sum "$tar_path" | awk '{ print $1 }')"
|
|
{
|
|
echo "patch=$tar_path"
|
|
echo "patch_dir=$stage"
|
|
echo "patch_sha256=$patch_sha256"
|
|
echo "manifest=$stage/PATCH-MANIFEST.env"
|
|
echo "base_component_archive_sha256=$base_sha256"
|
|
echo "source_commit=$SOURCE_COMMIT"
|
|
echo "source_dirty=$SOURCE_DIRTY"
|
|
} > "$OUT_DIR/$patch_name.summary.env"
|
|
echo "patch built: $tar_path"
|