Ctrl K
ComunidadGuías…

scripts/test-publish-installer-r2.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/bin/sh
set -eu

script_dir="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)"
project_dir="$(CDPATH='' cd -- "$script_dir/.." && pwd)"
temporary_dir="$(mktemp -d "${TMPDIR:-/tmp}/vastora-r2-test.XXXXXX")"
cleanup() { rm -rf "$temporary_dir"; }
trap cleanup EXIT HUP INT TERM

fake_bin="$temporary_dir/bin"
fake_r2="$temporary_dir/r2"
source_dir="$temporary_dir/dist"
bundle_dir="$temporary_dir/bundle"
mkdir -p "$fake_bin" "$fake_r2/objects" "$source_dir" "$bundle_dir"

create_bundle() {
  bundle_version="$1"
  bundle_content="$2"
  printf 'VASTORA_VERSION=%s\n' "$bundle_version" > "$bundle_dir/release.env"
  printf 'VASTORA_CENTER_IMAGE=ghcr.io/petauron/vastora-center@sha256:%064d\n' 0 >> "$bundle_dir/release.env"
  printf '%s\n' "$bundle_content" > "$bundle_dir/content.txt"
  tar -czf "$source_dir/vastora-center-install.tar.gz" -C "$bundle_dir" .
  (cd "$source_dir" && sha256sum vastora-center-install.tar.gz > vastora-center-install.tar.gz.sha256)
}

cat > "$fake_bin/aws" <<'EOF'
#!/bin/sh
set -eu
while [ "$#" -gt 0 ] && [ "$1" != "s3api" ]; do shift; done
[ "${1:-}" = "s3api" ] || exit 2
shift
operation="${1:-}"
shift
key=""
body=""
metadata=""
query=""
destination=""
prefix=""
continuation=""
delete_request=""
max_keys="1000"
while [ "$#" -gt 0 ]; do
  case "$1" in
    --key) key="$2"; shift 2 ;;
    --body) body="$2"; shift 2 ;;
    --metadata) metadata="$2"; shift 2 ;;
    --query) query="$2"; shift 2 ;;
    --prefix) prefix="$2"; shift 2 ;;
    --continuation-token) continuation="$2"; shift 2 ;;
    --delete) delete_request="$2"; shift 2 ;;
    --max-keys) max_keys="$2"; shift 2 ;;
    --bucket|--content-type|--cache-control|--endpoint-url|--output) shift 2 ;;
    --no-cli-pager) shift ;;
    *) destination="$1"; shift ;;
  esac
done
object="$FAKE_R2_DIR/objects/$key"
meta="$FAKE_R2_DIR/metadata/$key"
case "$operation" in
  head-object)
    if [ ! -f "$object" ]; then
      echo 'An error occurred (404) when calling the HeadObject operation: Not Found' >&2
      exit 254
    fi
    digest="$(cat "$meta")"
    if [ -n "$query" ]; then
      printf '%s\n' "$digest"
    else
      printf '{"Metadata":{"sha256":"%s"}}\n' "$digest"
    fi
    ;;
  put-object)
    mkdir -p "$(dirname "$object")" "$(dirname "$meta")"
    cp "$body" "$object"
    digest="$(printf '%s' "$metadata" | sed -n 's/^sha256=\([^,]*\).*$/\1/p')"
    printf '%s' "$digest" > "$meta"
    printf '{}\n'
    ;;
  get-object)
    [ -f "$object" ] || exit 254
    if [ "$key" = "vastora/current.json" ] && [ -f "$FAKE_R2_DIR/change-pointer" ]; then
      count_file="$FAKE_R2_DIR/current-read-count"
      count=0
      [ ! -f "$count_file" ] || count="$(cat "$count_file")"
      count=$((count + 1))
      printf '%s\n' "$count" > "$count_file"
      if [ "$count" -ge 2 ]; then
        printf '{"schema":0}\n' > "$destination"
      else
        cp "$object" "$destination"
      fi
    else
      cp "$object" "$destination"
    fi
    printf '{}\n'
    ;;
  list-objects-v2)
    [ "$prefix" = "vastora/releases/" ] || { echo 'Installer cleanup listed outside its release prefix.' >&2; exit 2; }
    keys_file="$FAKE_R2_DIR/list-keys"
    find "$FAKE_R2_DIR/objects" -type f | sed "s|^$FAKE_R2_DIR/objects/||" | sort |
      awk -v prefix="$prefix" 'index($0, prefix) == 1' > "$keys_file"
    start="${continuation:-0}"
    total="$(wc -l < "$keys_file" | tr -d ' ')"
    page_file="$FAKE_R2_DIR/list-page"
    tail -n "+$((start + 1))" "$keys_file" | head -n "$max_keys" > "$page_file"
    count="$(wc -l < "$page_file" | tr -d ' ')"
    next=$((start + count))
    if [ "$next" -lt "$total" ]; then truncated=true; else truncated=false; fi
    jq -R -s --argjson truncated "$truncated" --arg token "$next" '{IsTruncated:$truncated, NextContinuationToken:(if $truncated then $token else null end), Contents:(split("\n") | map(select(length > 0) | {Key:.}))}' "$page_file"
    ;;
  delete-objects)
    request="${delete_request#file://}"
    if [ -f "$FAKE_R2_DIR/fail-delete" ]; then
      failed_key="$(jq -r '.Objects[0].Key' "$request")"
      jq -n --arg key "$failed_key" '{Errors:[{Key:$key,Code:"AccessDenied",Message:"denied"}]}'
      exit 0
    fi
    skip_key=""
    if [ -f "$FAKE_R2_DIR/skip-delete" ]; then skip_key="$(jq -r '.Objects[0].Key' "$request")"; fi
    jq -r '.Objects[].Key' "$request" | while IFS= read -r delete_key; do
      [ "$delete_key" = "$skip_key" ] && continue
      rm -f "$FAKE_R2_DIR/objects/$delete_key" "$FAKE_R2_DIR/metadata/$delete_key"
    done
    jq '{Deleted:.Objects}' "$request"
    ;;
  *) exit 2 ;;
esac
EOF
chmod 0755 "$fake_bin/aws"

export FAKE_R2_DIR="$fake_r2"
export PATH="$fake_bin:$PATH"
endpoint="https://0123456789abcdef0123456789abcdef.r2.cloudflarestorage.com"
bucket="petauron-downloads"
version="0.1.0-alpha.10"
create_bundle "$version" initial
cp "$project_dir/install.sh" "$source_dir/install.sh"
"$script_dir/create-installer-release-manifest.sh" --version "$version" --source-dir "$source_dir" >/dev/null

"$script_dir/publish-installer-r2.sh" stage --version "$version" --bucket "$bucket" --endpoint "$endpoint" --source-dir "$source_dir" >/dev/null
manifest="$fake_r2/objects/vastora/releases/v$version/manifest.json"
test -f "$manifest"
test ! -e "$fake_r2/objects/vastora/releases/v$version/activated.json"
jq -e --arg version "$version" '.schema == 1 and .version == $version and (.centerImage | startswith("ghcr.io/petauron/vastora-center@sha256:")) and (.assets | length) == 3' "$manifest" >/dev/null

"$script_dir/publish-installer-r2.sh" activate --version "$version" --bucket "$bucket" --endpoint "$endpoint" >/dev/null
cmp -s "$manifest" "$fake_r2/objects/vastora/releases/v$version/activated.json"
cmp -s "$manifest" "$fake_r2/objects/vastora/current.json"
"$script_dir/publish-installer-r2.sh" activate --version "$version" --bucket "$bucket" --endpoint "$endpoint" >/dev/null

current_digest="$(sha256sum "$fake_r2/objects/vastora/current.json" | awk 'NR == 1 {print $1}')"
downgrade_version="0.1.0-alpha.9"
create_bundle "$downgrade_version" downgrade
"$script_dir/create-installer-release-manifest.sh" --version "$downgrade_version" --source-dir "$source_dir" >/dev/null
"$script_dir/publish-installer-r2.sh" stage --version "$downgrade_version" --bucket "$bucket" --endpoint "$endpoint" --source-dir "$source_dir" >/dev/null
if "$script_dir/publish-installer-r2.sh" activate --version "$downgrade_version" --bucket "$bucket" --endpoint "$endpoint" >/dev/null 2>&1; then
  echo "R2 publication moved the current release pointer backward." >&2
  exit 1
fi
test "$(sha256sum "$fake_r2/objects/vastora/current.json" | awk 'NR == 1 {print $1}')" = "$current_digest"
test ! -e "$fake_r2/objects/vastora/releases/v$downgrade_version/activated.json"

newer_version="0.1.0-alpha.11"
create_bundle "$newer_version" newer
"$script_dir/create-installer-release-manifest.sh" --version "$newer_version" --source-dir "$source_dir" >/dev/null
"$script_dir/publish-installer-r2.sh" stage --version "$newer_version" --bucket "$bucket" --endpoint "$endpoint" --source-dir "$source_dir" >/dev/null
"$script_dir/publish-installer-r2.sh" activate --version "$newer_version" --bucket "$bucket" --endpoint "$endpoint" >/dev/null
jq -e --arg version "$newer_version" '.version == $version' "$fake_r2/objects/vastora/current.json" >/dev/null

create_bundle "$newer_version" changed
"$script_dir/create-installer-release-manifest.sh" --version "$newer_version" --source-dir "$source_dir" >/dev/null
if "$script_dir/publish-installer-r2.sh" stage --version "$newer_version" --bucket "$bucket" --endpoint "$endpoint" --source-dir "$source_dir" >/dev/null 2>&1; then
  echo "Immutable R2 release assets accepted changed content." >&2
  exit 1
fi

mkdir -p "$fake_r2/objects/vastora/releases/v0.0.0-stale"
# Installer cleanup must coexist with independently published catalog files
# and other objects in the shared download bucket.
mkdir -p "$fake_r2/objects/vastora/catalog/targets" "$fake_r2/objects/pulse"
printf 'catalog root\n' > "$fake_r2/objects/vastora/catalog/1.root.json"
printf 'catalog target\n' > "$fake_r2/objects/vastora/catalog/targets/catalog.json"
printf 'unrelated\n' > "$fake_r2/objects/vastora/unexpected-object"
printf 'pulse release\n' > "$fake_r2/objects/pulse/release.json"
stale_number=1
while [ "$stale_number" -le 1002 ]; do
  : > "$fake_r2/objects/vastora/releases/v0.0.0-stale/object-$stale_number"
  stale_number=$((stale_number + 1))
done
"$script_dir/reconcile-installer-r2.sh" --bucket "$bucket" --endpoint "$endpoint" --dry-run > "$temporary_dir/dry-run.txt"
grep -Fq "vastora/releases/v$version/install.sh" "$temporary_dir/dry-run.txt"
if grep -Eq 'Would delete: (vastora/catalog/|vastora/unexpected-object|pulse/)' "$temporary_dir/dry-run.txt"; then
  echo "R2 reconciliation included unrelated objects in its deletion plan." >&2
  exit 1
fi

printf 'unsafe\n' > "$fake_r2/objects/vastora/releases/unsafe object"
if "$script_dir/reconcile-installer-r2.sh" --bucket "$bucket" --endpoint "$endpoint" >/dev/null 2>&1; then
  echo "R2 reconciliation accepted an unsafe release object key." >&2
  exit 1
fi
rm "$fake_r2/objects/vastora/releases/unsafe object"

touch "$fake_r2/change-pointer"
if "$script_dir/reconcile-installer-r2.sh" --bucket "$bucket" --endpoint "$endpoint" >/dev/null 2>&1; then
  echo "R2 reconciliation deleted after the current pointer changed." >&2
  exit 1
fi
rm "$fake_r2/change-pointer" "$fake_r2/current-read-count"

touch "$fake_r2/fail-delete"
if "$script_dir/reconcile-installer-r2.sh" --bucket "$bucket" --endpoint "$endpoint" >/dev/null 2>&1; then
  echo "R2 reconciliation ignored a per-object deletion error." >&2
  exit 1
fi
rm "$fake_r2/fail-delete"

touch "$fake_r2/skip-delete"
if "$script_dir/reconcile-installer-r2.sh" --bucket "$bucket" --endpoint "$endpoint" >/dev/null 2>&1; then
  echo "R2 reconciliation ignored post-delete leftovers." >&2
  exit 1
fi
rm "$fake_r2/skip-delete"

"$script_dir/reconcile-installer-r2.sh" --bucket "$bucket" --endpoint "$endpoint" >/dev/null
test "$(find "$fake_r2/objects/vastora/releases" -type f | wc -l | tr -d ' ')" = "5"
test "$(cat "$fake_r2/objects/vastora/catalog/1.root.json")" = 'catalog root'
test "$(cat "$fake_r2/objects/vastora/catalog/targets/catalog.json")" = 'catalog target'
test "$(cat "$fake_r2/objects/vastora/unexpected-object")" = 'unrelated'
test "$(cat "$fake_r2/objects/pulse/release.json")" = 'pulse release'
test -f "$fake_r2/objects/vastora/current.json"
test -f "$fake_r2/objects/vastora/releases/v$newer_version/activated.json"
test ! -e "$fake_r2/objects/vastora/releases/v$version/manifest.json"

if "$script_dir/publish-installer-r2.sh" stage --version "0.1.0-other" --bucket "$bucket" --endpoint "$endpoint" --source-dir "$source_dir" >/dev/null 2>&1; then
  echo "R2 publication accepted a bundle for a different version." >&2
  exit 1
fi

echo "R2 installer publication tests: OK"