#!/usr/bin/env bash # Reviewed, disposable Nextcloud29 protocol fixture. Never an installed node. set -euo pipefail CONTROL=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) image=${ARCHY_CLOUD_NEXTCLOUD_IMAGE:?Exact reviewed local Nextcloud29 image ID required} [[ "$image" =~ ^(sha256:)?[a-f0-9]{64}$ ]] || { echo 'Immutable fixture image required' >&2; exit 2; } scratch=$(mktemp -d /tmp/archy-nextcloud.XXXXXXXX) name="archy-cloud-nextcloud-contract-${scratch##*.}" cid= cleanup() { if [[ -n "$cid" ]]; then podman logs "$cid" 2>&1 | python3 "$CONTROL/scripts/limit-test-output.py" || true podman rm -f "$cid" >/dev/null 2>&1 || true fi rm -rf -- "$scratch" } trap cleanup EXIT cp "$CONTROL/tests/cloud/nextcloud-upstream-contract.php" "$scratch/nextcloud-upstream-contract.php" : > "$scratch/empty-resolv.conf" cid=$(podman create --name "$name" --pull=never --network none --ipc private --pid private \ --no-hosts --hostname cloud-nextcloud --http-proxy=false --log-driver=k8s-file --log-opt=max-size=8mb --timeout=2400 \ --read-only --cpus 2 --memory 3g --memory-swap 3g --pids-limit 256 \ --label org.archipelago.cloud-fixture=nextcloud29-v1 \ --cap-drop all --cap-add chown,dac_override,fowner,setuid,setgid,net_bind_service \ --security-opt no-new-privileges \ --tmpfs /var/www/html:rw,size=2g --tmpfs /run:rw,size=32m \ --tmpfs /run/lock:rw,size=16m --tmpfs /tmp:rw,size=128m \ --env NEXTCLOUD_ADMIN_USER=alice --env NEXTCLOUD_ADMIN_PASSWORD=Synthetic-Cloud-A-Only-2026! \ --env SQLITE_DATABASE=fixture --env NEXTCLOUD_TRUSTED_DOMAINS='127.0.0.1 localhost' \ --volume "$scratch/nextcloud-upstream-contract.php:/contract.php:ro" \ --volume "$scratch/empty-resolv.conf:/etc/resolv.conf:ro" "$image") [[ "$cid" =~ ^[a-f0-9]{64}$ ]] || { echo 'Unexpected fixture identity' >&2; cid=; exit 2; } podman start "$cid" >/dev/null deadline=$(( $(date +%s) + 180 )) ready=0 while (( $(date +%s) < deadline )); do if timeout --kill-after=2s 5 podman exec "$cid" php -r ' $c=stream_context_create(["http"=>["timeout"=>2]]); $j=json_decode(@file_get_contents("http://127.0.0.1/status.php",false,$c)?:"",true); exit(($j["installed"]??false) && !($j["maintenance"]??true)?0:1);' >/dev/null 2>&1; then ready=1; break fi sleep 2 done [[ "$ready" == 1 ]] || { echo 'Disposable Nextcloud did not become ready' >&2; exit 1; } podman inspect "$cid" --format '{{json .HostConfig.Tmpfs}}' podman inspect "$cid" | python3 "$CONTROL/scripts/validate-cloud-test-fixture.py" "$name" "$image" >/dev/null timeout --kill-after=5s 60 podman exec --user www-data --env OC_PASS=Synthetic-Cloud-B-Only-2026! "$cid" php occ user:add --password-from-env bob timeout --kill-after=5s 180 podman exec --user www-data "$cid" php /contract.php if [[ ${ARCHY_CLOUD_RUST_QUALIFY:-0} == 1 || ${ARCHY_CLOUD_BROWSER_QUALIFY:-0} == 1 ]]; then test_name=cloud_sources::upstream_tests::nextcloud_actual_upstream_connector_without_filebrowser if [[ ${ARCHY_CLOUD_BROWSER_QUALIFY:-0} == 1 ]]; then : "${ARCHY_TEST_CLOUD_RUNTIME_IMAGE:?Browser runtime image required}" test_name=api::handler::cloud_browser_tests::nextcloud_browser_rpc_without_filebrowser fi ARCHY_TEST_ISOLATOR=podman ARCHY_TEST_CLOUD_FIXTURE_CONTAINER="$name" \ ARCHY_TEST_CLOUD_FIXTURE_IMAGE="$image" \ bash "$CONTROL/scripts/test-backend-isolated.sh" --ignored --exact "$test_name" --nocapture fi timeout --kill-after=5s 60 podman exec --user www-data "$cid" php occ user:disable alice timeout --kill-after=5s 180 podman exec --user www-data "$cid" php /contract.php revoked echo 'Disposable upstream protocol passed; installed/native/independent acceptance not claimed.'