72 lines
4.2 KiB
Bash
72 lines
4.2 KiB
Bash
#!/usr/bin/env bash
|
|
# Focused wizard upload; no MediaMTX/RTMP or repeated 2GiB protocol suite.
|
|
set -euo pipefail
|
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)
|
|
image=${PODSTEADR_FIXTURE_IMAGE:?Immutable Podsteadr image required}
|
|
blossom=${BLOSSOM_FIXTURE_IMAGE:?Immutable large-upload Blossom candidate required}
|
|
browser=${PODSTEADR_BROWSER_IMAGE:?Immutable browser image required}
|
|
for id in "$image" "$blossom" "$browser"; do
|
|
[[ $id =~ ^(sha256:)?[a-f0-9]{64}$ ]] || exit 2
|
|
podman image exists "$id"
|
|
done
|
|
name="archy-podsteadr-upload-$(date +%s)-$$"
|
|
work=$(mktemp -d)
|
|
containers=(); volumes=()
|
|
cleanup() {
|
|
result=$?; trap - EXIT
|
|
for ((i=${#containers[@]}-1; i>=0; i--)); do
|
|
c=${containers[$i]}
|
|
if ! podman container exists "$c"; then continue; fi
|
|
if ((result)); then podman logs --tail 30 "$c" 2>&1 || true; fi
|
|
timeout 15 podman rm -f --volumes --time 0 "$c" >/dev/null 2>&1 || true
|
|
done
|
|
for v in "${volumes[@]}"; do podman volume rm "$v" >/dev/null 2>&1 || result=1; done
|
|
for c in "${containers[@]}"; do if podman container exists "$c"; then echo "Cleanup failed: $c" >&2; result=1; fi; done
|
|
rm -rf -- "$work"; exit "$result"
|
|
}
|
|
trap cleanup EXIT
|
|
trap 'exit 130' INT
|
|
trap 'exit 143' TERM
|
|
[[ $(podman image inspect "$image" --format '{{.Config.User}}') == 1000:1000 ]]
|
|
[[ $(podman image inspect "$blossom" --format '{{.Config.User}}') == 1000:1000 ]]
|
|
printf '{}\n' > "$work/config.json"
|
|
printf '// No production signer injected by fixture.\n' > "$work/nostr-provider.js"
|
|
: > "$work/resolv.conf"
|
|
common=(--pull=never --image-volume=ignore --pid=private --ipc=private --http-proxy=false --no-hosts
|
|
--read-only --cap-drop=all --security-opt=no-new-privileges --cpus=1
|
|
--memory=512m --memory-swap=512m --pids-limit=128 --timeout=300
|
|
--tmpfs /tmp:rw,notmpcopyup,nosuid,nodev,size=64m --volume "$work/resolv.conf:/etc/resolv.conf:ro")
|
|
containers+=("$name-key")
|
|
pubkey=$(podman run --rm --name "$name-key" "${common[@]}" --network=none --entrypoint node "$image" --input-type=module -e 'import {getPublicKey} from "nostr-tools/pure";console.log(getPublicKey(new Uint8Array(32).fill(1)))')
|
|
[[ $pubkey =~ ^[a-f0-9]{64}$ ]]
|
|
for suffix in data blossom signer; do
|
|
! podman volume exists "$name-$suffix"
|
|
podman volume create "$name-$suffix" >/dev/null; volumes+=("$name-$suffix")
|
|
done
|
|
containers+=("$name-signer-init")
|
|
podman run --rm --name "$name-signer-init" "${common[@]}" --network=none --volume "$name-signer:/signer:U" --entrypoint /bin/sh "$image" -ec 'mkdir /signer/node_modules; cp -a /app/node_modules/. /signer/node_modules/'
|
|
containers+=("$name-net")
|
|
podman run -d --name "$name-net" "${common[@]}" --memory=64m --memory-swap=64m --network=none --entrypoint node "$image" -e 'setInterval(()=>{},10000)' >/dev/null
|
|
common+=(--network="container:$name-net")
|
|
containers+=("$name-app" "$name-blossom")
|
|
podman run -d --name "$name-app" "${common[@]}" --volume "$name-data:/data:U" \
|
|
--env "PODSTEADR_ADMIN_PUBKEYS=$pubkey" --env PUBLIC_URL=http://127.0.0.1:8095 \
|
|
--env NOSTR_RELAYS= --env CASHU_MINT_URL_DEFAULT=http://127.0.0.1:9996 \
|
|
--env BLOSSOM_URL_DEFAULT=http://127.0.0.1:3000 "$image" >/dev/null
|
|
podman run -d --name "$name-blossom" "${common[@]}" --volume "$name-blossom:/data:U" \
|
|
--volume "$work/config.json:/config/config.json:ro" --volume "$work/nostr-provider.js:/bridge/nostr-provider.js:ro" \
|
|
--env "ARCHY_BLOSSOM_PUBKEYS=$pubkey" --env ARCHY_BLOSSOM_MAX_UPLOAD_BYTES=2147483648 "$blossom" >/dev/null
|
|
for url in http://127.0.0.1:8095/api/health http://127.0.0.1:3000/healthz; do
|
|
ready=0
|
|
for _ in $(seq 1 40); do
|
|
if timeout 3 podman exec "$name-app" node -e 'fetch(process.argv[1],{signal:AbortSignal.timeout(1500)}).then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))' "$url" >/dev/null 2>&1; then ready=1; break; fi
|
|
sleep 0.25
|
|
done
|
|
[[ $ready == 1 ]] || { echo "Readiness failed: $url" >&2; exit 1; }
|
|
done
|
|
containers+=("$name-browser")
|
|
timeout --kill-after=5s 120 podman run --rm --name "$name-browser" "${common[@]}" --memory=1g --memory-swap=1g --pids-limit=256 \
|
|
--tmpfs /root:rw,notmpcopyup,nosuid,nodev,size=16m --volume "$name-signer:/signer:ro" \
|
|
--volume "$repo/tests/apps/podsteadr/upload-browser.mjs:/browser/upload-browser.mjs:ro" \
|
|
--entrypoint node "$browser" /browser/upload-browser.mjs
|