evOo-local/infra/compose/install-images-pull-never.smoke.sh
cynarAI 6c7eed7580 Initial clean evOo-local from f00577b
Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline
(Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/*
packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
2026-09-20 17:15:16 +02:00

240 lines
7.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
root="$(cd "$(dirname "$0")" && pwd)"
src="$root/install-images.sh"
fail() { echo "FAIL: $*" >&2; exit 1; }
# BSD grep needs -e so patterns starting with -- are not flags.
g() { grep -F -e "$1" "$src" >/dev/null || fail "missing $1"; }
g '--pull-never)'
g '--offline)'
g 'RAKAZO_PULL_NEVER'
g 'Skipping image pull'
g '--pull never'
g 'cannot enforce pull-never on this Compose version'
g '${up_pull_args[@]+"${up_pull_args[@]}"}'
g 'HTTP_PROXY/HTTPS_PROXY'
g '[--prepare-only] [--local] [--pull-never] [--offline]'
set +e
out="$(bash "$src" --not-a-flag 2>&1)"
code=$?
set -e
[[ "$code" -eq 2 ]] || fail "expected exit 2 for unknown flag, got $code"
[[ "$out" == *"Usage: bash install-images.sh"* ]] || fail "usage missing from stderr"
bash -n "$src" || fail "bash -n failed"
tmp="$(mktemp -d "${TMPDIR:-/tmp}/install-images-smoke.XXXXXX")"
cleanup_tmp() { rm -rf "$tmp"; }
trap cleanup_tmp EXIT
write_stubs() {
local bin="$1"
mkdir -p "$bin"
cat > "$bin/docker" <<'STUB'
#!/usr/bin/env bash
set -euo pipefail
log="${STUB_DOCKER_LOG:?}"
{
printf 'docker'
for a in "$@"; do
printf ' %s' "$a"
done
printf '\n'
} >> "$log"
if [[ "${1:-}" != compose ]]; then
echo "STUB: unexpected docker $*" >&2
exit 1
fi
shift
help=false
short=false
verb=""
for a in "$@"; do
case "$a" in
--help|-h) help=true ;;
--short) short=true ;;
version|up|pull|config)
if [[ -z "$verb" ]]; then
verb="$a"
fi
;;
esac
done
echo "VERB=${verb:-none}" >> "$log"
if [[ "$verb" == config ]]; then
cat >/dev/null || true
fi
if [[ "$help" == true ]]; then
printf '%s\n' "${STUB_COMPOSE_UP_HELP:-Usage: docker compose up
Options:
--pull string Pull image before running
--wait
--wait-timeout int
}"
exit 0
fi
case "$verb" in
version)
if [[ "$short" == true ]]; then
printf '%s\n' "${STUB_COMPOSE_SHORT:-2.24.0}"
else
echo "Docker Compose version v${STUB_COMPOSE_SHORT:-2.24.0}"
fi
;;
config)
cat <<'EOF'
POSTGRES_PASSWORD=test-postgres
BETTER_AUTH_SECRET=test-auth-secret
ENCRYPTION_KEY=test-encryption-key
SCREEN_PROXY_SECRET=test-screen-secret
SANDBOX_SUPERVISOR_TOKEN=test-supervisor-token
EOF
;;
pull|up)
;;
*)
echo "STUB: unexpected compose verb ${verb:-none} $*" >&2
exit 1
;;
esac
STUB
cat > "$bin/curl" <<'STUB'
#!/usr/bin/env bash
set -euo pipefail
log="${STUB_CURL_LOG:?}"
{
printf 'curl'
for a in "$@"; do
printf ' %s' "$a"
done
printf '\n'
} >> "$log"
if [[ " $* " == *" --help "* ]]; then
echo "--retry-all-errors"
exit 0
fi
out=""
prev=""
for a in "$@"; do
if [[ "$prev" == "-o" ]]; then
out="$a"
fi
prev="$a"
done
if [[ -n "$out" ]]; then
printf 'stub-download\n' > "$out"
exit 0
fi
exit 1
STUB
chmod +x "$bin/docker" "$bin/curl"
}
setup_work() {
local work="$1"
mkdir -p "$work/cwd"
write_stubs "$work/bin"
: > "$work/cwd/docker-compose.images.yml"
: > "$work/cwd/.env.images.example"
cat > "$work/cwd/.env" <<'EOF'
POSTGRES_PASSWORD=test-postgres
BETTER_AUTH_SECRET=test-auth-secret
ENCRYPTION_KEY=test-encryption-key
SCREEN_PROXY_SECRET=test-screen-secret
SANDBOX_SUPERVISOR_TOKEN=test-supervisor-token
EOF
: > "$work/docker.log"
: > "$work/curl.log"
}
run_install() {
local work="$1"
shift
(
export STUB_DOCKER_LOG="$work/docker.log"
export STUB_CURL_LOG="$work/curl.log"
export PATH="$work/bin:$PATH"
cd "$work/cwd"
bash "$src" "$@"
)
}
has_compose_pull() {
grep -q 'VERB=pull' "$1/docker.log"
}
has_up_pull_never() {
grep -F -e 'VERB=up' "$1/docker.log" >/dev/null \
&& grep -F -e ' --pull never' "$1/docker.log" >/dev/null
}
# Flags accepted: --offline takes the local/pull-never path (no curl, no compose pull).
setup_work "$tmp/offline"
set +e
offline_out="$(run_install "$tmp/offline" --offline 2>&1)"
offline_code=$?
set -e
[[ "$offline_code" -eq 0 ]] || fail "--offline exited $offline_code: $offline_out"
[[ "$offline_out" != *"Usage: bash install-images.sh"* ]] || fail "--offline was rejected as unknown"
[[ "$offline_out" == *"Using local docker-compose.images.yml"* ]] || fail "--offline did not keep local compose file"
[[ "$offline_out" == *"Using local .env.images.example"* ]] || fail "--offline did not keep local env example"
[[ "$offline_out" == *"Skipping image pull"* ]] || fail "--offline did not skip image pull"
[[ "$offline_out" == *"Rakazo is starting"* ]] || fail "--offline did not start"
[[ ! -s "$tmp/offline/curl.log" ]] || fail "--offline should not curl when files are local: $(cat "$tmp/offline/curl.log")"
has_compose_pull "$tmp/offline" && fail "--offline should not run compose pull"
has_up_pull_never "$tmp/offline" || fail "--offline should pass --pull never to compose up: $(cat "$tmp/offline/docker.log")"
# --pull-never is accepted and skips pull (may still download Compose files).
setup_work "$tmp/pull-never"
set +e
pull_never_out="$(run_install "$tmp/pull-never" --pull-never 2>&1)"
pull_never_code=$?
set -e
[[ "$pull_never_code" -eq 0 ]] || fail "--pull-never exited $pull_never_code: $pull_never_out"
[[ "$pull_never_out" != *"Usage: bash install-images.sh"* ]] || fail "--pull-never was rejected as unknown"
[[ "$pull_never_out" == *"Skipping image pull"* ]] || fail "--pull-never did not skip image pull"
has_compose_pull "$tmp/pull-never" && fail "--pull-never should not run compose pull"
has_up_pull_never "$tmp/pull-never" || fail "--pull-never should pass --pull never to compose up"
# Old Compose without up --pull: warn and continue instead of hard-fail.
setup_work "$tmp/old"
export STUB_COMPOSE_UP_HELP='Usage: docker compose up
--wait
--wait-timeout int
'
export STUB_COMPOSE_SHORT='2.10.1'
set +e
old_out="$(run_install "$tmp/old" --offline 2>&1)"
old_code=$?
set -e
unset STUB_COMPOSE_UP_HELP STUB_COMPOSE_SHORT
[[ "$old_code" -eq 0 ]] || fail "old Compose --offline exited $old_code: $old_out"
[[ "$old_out" == *"cannot enforce pull-never on this Compose version; startup fails if an image is missing locally"* ]] \
|| fail "old Compose --offline missing soft warning: $old_out"
[[ "$old_out" != *"Rakazo setup failed:"* ]] || fail "old Compose --offline should not hard-fail: $old_out"
[[ "$old_out" == *"Rakazo is starting"* ]] || fail "old Compose --offline should continue: $old_out"
has_compose_pull "$tmp/old" && fail "old Compose --offline should not run compose pull"
if grep -F -e ' --pull never' "$tmp/old/docker.log" >/dev/null; then
fail "old Compose up should not receive --pull never: $(cat "$tmp/old/docker.log")"
fi
grep -q 'VERB=up' "$tmp/old/docker.log" || fail "old Compose --offline should still run compose up"
# Empty up arrays under set -u must not abort a normal install (bash 3.2).
setup_work "$tmp/default"
set +e
default_out="$(run_install "$tmp/default" 2>&1)"
default_code=$?
set -e
[[ "$default_code" -eq 0 ]] || fail "default install exited $default_code: $default_out"
[[ "$default_out" != *"unbound variable"* ]] || fail "empty array expansion aborted: $default_out"
has_compose_pull "$tmp/default" || fail "default install should run compose pull"
grep -q 'VERB=up' "$tmp/default/docker.log" || fail "default install should run compose up"
echo "ok"