openclaw/scripts/e2e/cli-installer-distribution-docker.sh

164 lines
5.6 KiB
Bash
Executable file

#!/usr/bin/env bash
# Proves hosted npm installation plus dedicated-prefix source installation.
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
source "$ROOT_DIR/scripts/lib/docker-e2e-image.sh"
IMAGE_NAME="$(docker_e2e_resolve_image "openclaw-cli-installer-distribution:local")"
PACKAGE_TGZ="$(
docker_e2e_prepare_package_tgz cli-installer-distribution "${OPENCLAW_CURRENT_PACKAGE_TGZ:-}"
)"
HOSTED_PROOF_CONTAINER="openclaw-hosted-installer-proof-$$"
SOURCE_PROOF_CONTAINER="openclaw-source-installer-proof-$$"
SOURCE_BUNDLE="$(mktemp "${TMPDIR:-/tmp}/openclaw-source.XXXXXX.bundle")"
SOURCE_PROOF_SCRIPT="$(mktemp "${TMPDIR:-/tmp}/openclaw-source-proof.XXXXXX.sh")"
SOURCE_SHA="$(git -C "$ROOT_DIR" rev-parse HEAD)"
SOURCE_MEMORY="${OPENCLAW_CLI_INSTALLER_SOURCE_MEMORY:-16g}"
cleanup() {
docker_e2e_docker_cmd rm -f \
"$HOSTED_PROOF_CONTAINER" \
"$SOURCE_PROOF_CONTAINER" >/dev/null 2>&1 || true
docker_e2e_cleanup_package_tgz "$PACKAGE_TGZ"
rm -f "$SOURCE_BUNDLE" "$SOURCE_PROOF_SCRIPT"
}
trap cleanup EXIT
git -C "$ROOT_DIR" bundle create "$SOURCE_BUNDLE" HEAD
cat >"$SOURCE_PROOF_SCRIPT" <<'SOURCE_PROOF'
#!/usr/bin/env bash
set -euo pipefail
test -r "$0"
test -x "$0"
command -v curl >/dev/null
git clone -q /tmp/openclaw-source.bundle /tmp/openclaw-source
git -C /tmp/openclaw-source checkout -q --detach "$OPENCLAW_SOURCE_SHA"
bash /tmp/openclaw-source/scripts/install-cli.sh \
--install-method git \
--git-dir /tmp/openclaw-source \
--version "$OPENCLAW_SOURCE_SHA" \
--no-git-update \
--prefix /tmp/openclaw-prefix \
--node-version 24.15.0 \
--no-onboard
prefix_node=/tmp/openclaw-prefix/tools/node/bin/node
prefix_cli=/tmp/openclaw-prefix/bin/openclaw
test -x "$prefix_node"
test -x "$prefix_cli"
grep -Fq "exec \"$prefix_node\"" "$prefix_cli"
grep -Fq "/tmp/openclaw-source/dist/entry.js" "$prefix_cli"
export PATH="/tmp/openclaw-prefix/bin:$PATH"
test "$(command -v openclaw)" = "$prefix_cli"
test "$(git -C /tmp/openclaw-source rev-parse HEAD)" = "$OPENCLAW_SOURCE_SHA"
openclaw_version="$(openclaw --version)"
openclaw --help >/tmp/openclaw-help
test -s /tmp/openclaw-help
status_json="$(openclaw update status --json)"
STATUS_JSON="$status_json" node -e "
const status = JSON.parse(process.env.STATUS_JSON);
if (status.update?.installKind !== \"git\") {
throw new Error(\`expected git install kind, got \${status.update?.installKind}\`);
}
"
printf "prefixNode=%s@%s\n" "$prefix_node" "$("$prefix_node" --version)"
printf "prefixOpenClaw=%s@%s\n" "$prefix_cli" "$openclaw_version"
printf "sourceHead=%s installKind=git\n" "$OPENCLAW_SOURCE_SHA"
printf "sourceOnboard=disabled\n"
touch /tmp/openclaw-proof-ready
exec sleep infinity
SOURCE_PROOF
chmod 0555 "$SOURCE_PROOF_SCRIPT"
docker_e2e_build_or_reuse \
"$IMAGE_NAME" \
cli-installer-distribution \
"$ROOT_DIR/scripts/e2e/Dockerfile" \
"$ROOT_DIR" \
bare
echo "==> Hosted install.sh exact-candidate proof"
docker_e2e_docker_run_cmd run -d \
--name "$HOSTED_PROOF_CONTAINER" \
-e HOME=/tmp/openclaw-hosted-home \
-e OPENCLAW_NO_ONBOARD=1 \
-e OPENCLAW_NO_PROMPT=1 \
-v "$PACKAGE_TGZ:/tmp/openclaw-current.tgz:ro" \
-v "$ROOT_DIR/scripts/install.sh:/tmp/install.sh:ro" \
"$IMAGE_NAME" \
bash -lc '
set -euo pipefail
mkdir -p "$HOME"
bash /tmp/install.sh \
--install-method npm \
--version file:/tmp/openclaw-current.tgz \
--no-onboard \
--no-prompt
source "$HOME/.bashrc"
hash -r
openclaw_path="$(command -v openclaw)"
test -n "$openclaw_path"
node_path="$(command -v node)"
node_version="$(node --version)"
openclaw_version="$(openclaw --version)"
openclaw --help >/tmp/openclaw-help
test -s /tmp/openclaw-help
printf "hostedNode=%s@%s\n" "$node_path" "$node_version"
printf "hostedOpenClaw=%s@%s\n" "$openclaw_path" "$openclaw_version"
printf "hostedOnboard=disabled\n"
touch /tmp/openclaw-proof-ready
exec sleep infinity
' >/dev/null
# A full source install builds every workspace package; the shared 8g cap OOMs before wrapper creation.
echo "==> install-cli.sh dedicated-prefix source-checkout proof"
docker_e2e_docker_run_cmd run -d \
--name "$SOURCE_PROOF_CONTAINER" \
--memory "$SOURCE_MEMORY" \
-e HOME=/tmp/openclaw-source-home \
-e OPENCLAW_NO_ONBOARD=1 \
-e OPENCLAW_NO_PROMPT=1 \
-e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \
-e "OPENCLAW_SOURCE_SHA=$SOURCE_SHA" \
--user root \
-v "$SOURCE_BUNDLE:/tmp/openclaw-source.bundle:ro" \
-v "$SOURCE_PROOF_SCRIPT:/tmp/source-proof.sh:ro" \
"$IMAGE_NAME" \
bash -lc '
set -euo pipefail
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends curl
rm -rf /var/lib/apt/lists/*
command -v curl >/dev/null
install -d -o appuser -g appuser "$HOME"
exec runuser -u appuser -- env \
HOME="$HOME" \
OPENCLAW_NO_ONBOARD="$OPENCLAW_NO_ONBOARD" \
OPENCLAW_NO_PROMPT="$OPENCLAW_NO_PROMPT" \
COREPACK_ENABLE_DOWNLOAD_PROMPT="$COREPACK_ENABLE_DOWNLOAD_PROMPT" \
OPENCLAW_SOURCE_SHA="$OPENCLAW_SOURCE_SHA" \
bash /tmp/source-proof.sh
' >/dev/null
wait_for_proof() {
local container_name="$1"
for _ in $(seq 1 1200); do
if docker exec "$container_name" test -f /tmp/openclaw-proof-ready; then
docker logs "$container_name"
return 0
fi
if [ "$(docker inspect --format '{{.State.Running}}' "$container_name")" != "true" ]; then
docker logs "$container_name" >&2
return 1
fi
sleep 1
done
docker logs "$container_name" >&2
return 1
}
wait_for_proof "$HOSTED_PROOF_CONTAINER"
wait_for_proof "$SOURCE_PROOF_CONTAINER"
echo "CLI installer distribution proof passed."