run.sh RawHistoryFolder
1#!/usr/bin/env bash
2set -euo pipefail
3
4usage() {
5 cat >&2 <<'USAGE'
6Usage: scripts/remote-picker-harness/run.sh
7
8Builds the current vev binary into a disposable two-container environment and
9runs the unified same-connection local-picker proof plus SSH-stdio, UDP,
10catalog, preview, lifecycle-fence, and environment acceptance checks. Docker is
11invoked normally,
12so DOCKER_HOST and the active
13Docker context select the daemon; no socket path is assumed.
14
15Environment:
16 DOCKER_HOST Docker endpoint, when the active context does not
17 already select the rootless daemon.
18 VEV_HARNESS_BASE_IMAGE Base image for the disposable containers
19 (default: ubuntu:24.04).
20 VEV_HARNESS_ARTIFACT_DIR Host directory for the bounded probe artifact.
21 The JSON report is copied there before container
22 cleanup; no report is written when unset.
23USAGE
24}
25
26case "${1:-}" in
27 -h|--help)
28 usage
29 exit 0
30 ;;
31 "") ;;
32 *)
33 usage
34 exit 2
35 ;;
36esac
37
38repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
39base_image="${VEV_HARNESS_BASE_IMAGE:-ubuntu:24.04}"
40artifact_dir="${VEV_HARNESS_ARTIFACT_DIR:-}"
41if [ -n "$artifact_dir" ]; then
42 umask 077
43 mkdir -p "$artifact_dir"
44fi
45run_id="$(date +%s)-$$"
46image="vev-remote-picker-harness:${run_id}"
47network="vev-remote-picker-harness-${run_id}"
48local_container="${network}-local"
49remote_container="${network}-remote"
50context_dir="$(mktemp -d "${TMPDIR:-/tmp}/vev-remote-picker-harness.XXXXXX")"
51
52cleanup() {
53 status=$?
54 trap - EXIT INT TERM
55 set +e
56 if [ "$status" -ne 0 ]; then
57 printf 'remote picker harness: local container logs:\n' >&2
58 docker logs "$local_container" >&2
59 printf 'remote picker harness: remote container logs:\n' >&2
60 docker logs "$remote_container" >&2
61 fi
62 docker rm -f "$local_container" "$remote_container" >/dev/null 2>&1
63 docker network rm "$network" >/dev/null 2>&1
64 docker image rm "$image" >/dev/null 2>&1
65 rm -rf "$context_dir"
66 exit "$status"
67}
68trap cleanup EXIT INT TERM
69
70command -v docker >/dev/null || { echo 'remote picker harness: docker is required' >&2; exit 127; }
71command -v ssh-keygen >/dev/null || { echo 'remote picker harness: ssh-keygen is required' >&2; exit 127; }
72
73if ! docker info >/dev/null 2>&1; then
74 echo 'remote picker harness: Docker is unavailable through the active DOCKER_HOST/context' >&2
75 exit 1
76fi
77
78printf 'remote picker harness: building %s\n' "$image"
79docker pull "$base_image" >/dev/null
80image_arch="$(docker image inspect "$base_image" --format '{{.Architecture}}')"
81GOOS=linux GOARCH="$image_arch" CGO_ENABLED=0 go build -o "$context_dir/vev" "$repo_root"
82GOOS=linux GOARCH="$image_arch" CGO_ENABLED=0 go build -o "$context_dir/harness" "$repo_root/scripts/remote-picker-harness"
83ssh-keygen -q -t ed25519 -N '' -f "$context_dir/id_ed25519"
84cp "$repo_root/scripts/remote-picker-harness/Dockerfile" "$context_dir/Dockerfile"
85cp "$repo_root/scripts/remote-picker-harness/vev-wrapper" "$context_dir/vev-wrapper"
86printf '%s\n' 'id_ed25519' > "$context_dir/.dockerignore"
87chmod 0600 "$context_dir/id_ed25519"
88
89docker build --build-arg "BASE_IMAGE=$base_image" -t "$image" "$context_dir" >/dev/null
90docker network create "$network" >/dev/null
91
92docker run -d --name "$remote_container" \
93 --network "$network" --network-alias remote \
94 -e VEV_UDP_PORT_RANGE=61000 \
95 "$image" >/dev/null
96
97docker create --name "$local_container" \
98 --network "$network" --network-alias local \
99 "$image" sleep infinity >/dev/null
100docker cp "$context_dir/id_ed25519" "$local_container:/home/test/.ssh/id_ed25519"
101docker start "$local_container" >/dev/null
102docker exec "$local_container" chown test:test /home/test/.ssh/id_ed25519
103docker exec "$local_container" chmod 0600 /home/test/.ssh/id_ed25519
104
105printf 'remote picker harness: waiting for SSH service\n'
106for _ in $(seq 1 60); do
107 if docker exec --user test -e HOME=/home/test "$local_container" ssh -o BatchMode=yes -o ConnectTimeout=1 test@remote true >/dev/null 2>&1; then
108 break
109 fi
110 sleep 0.2
111done
112if ! docker exec --user test -e HOME=/home/test "$local_container" ssh -o BatchMode=yes -o ConnectTimeout=2 test@remote true >/dev/null 2>&1; then
113 echo 'remote picker harness: SSH service did not become ready' >&2
114 exit 1
115fi
116
117printf 'remote picker harness: running acceptance checks\n'
118harness_status=0
119if [ -n "$artifact_dir" ]; then
120 docker exec --user test -e HOME=/home/test -e VEV_HARNESS_ARTIFACT_DIR=/tmp/vev-harness-artifact "$local_container" /usr/local/bin/remote-picker-harness || harness_status=$?
121 if ! docker cp "$local_container:/tmp/vev-harness-artifact/remote-picker-harness.json" "$artifact_dir/remote-picker-harness.json"; then
122 echo "remote picker harness: failed to collect probe artifact (acceptance status $harness_status)" >&2
123 if [ "$harness_status" -ne 0 ]; then
124 exit "$harness_status"
125 fi
126 exit 1
127 fi
128 chmod 0600 "$artifact_dir/remote-picker-harness.json"
129else
130 docker exec --user test -e HOME=/home/test "$local_container" /usr/local/bin/remote-picker-harness || harness_status=$?
131fi
132exit "$harness_status"