Packer build definition, cloud-init autoinstall, GHCup toolchain script, boot-time registration agent (state-hub + autossh dual tunnel), systemd unit, key injection, remote-build Makefile, smoke test, and deployment README. All 15 tasks complete. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
92 lines
2.7 KiB
Bash
Executable File
92 lines
2.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# smoke-test.sh — Validates the full Haskell build machine stack
|
|
#
|
|
# Prerequisites:
|
|
# - VM is booted and tunnel is established
|
|
# - State-hub is running on workstation (port 8000)
|
|
#
|
|
# Usage: ./smoke-test.sh [vm-ssh-host] [state-hub-url]
|
|
set -euo pipefail
|
|
|
|
VM="${1:-haskell-build}"
|
|
STATE_HUB="${2:-http://127.0.0.1:8000}"
|
|
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
check() {
|
|
local desc="$1"
|
|
shift
|
|
if "$@" >/dev/null 2>&1; then
|
|
echo " PASS: $desc"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
echo " FAIL: $desc"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
}
|
|
|
|
echo "=== Haskell Build Machine Smoke Test ==="
|
|
echo "VM: $VM | State Hub: $STATE_HUB"
|
|
echo ""
|
|
|
|
# 1. Check tunnel is up
|
|
echo "[1/5] Tunnel connectivity"
|
|
check "SSH to VM via tunnel" ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$VM" "true"
|
|
|
|
# 2. Check GHC is available
|
|
echo "[2/5] Haskell toolchain"
|
|
check "GHC is installed" ssh "$VM" "source ~/.ghcup/env && ghc --version"
|
|
check "Cabal is installed" ssh "$VM" "source ~/.ghcup/env && cabal --version"
|
|
check "GHCup is installed" ssh "$VM" "source ~/.ghcup/env && ghcup --version"
|
|
|
|
# 3. Check state-hub capability registration
|
|
echo "[3/5] State-hub capability"
|
|
check "State-hub is reachable" curl -sf "${STATE_HUB}/state/health"
|
|
CAPS=$(curl -sf "${STATE_HUB}/capability-catalog/?capability_type=haskell-build-agent" 2>/dev/null || echo "[]")
|
|
if echo "$CAPS" | python3 -c "import sys,json; entries=json.load(sys.stdin); sys.exit(0 if len(entries)>0 else 1)" 2>/dev/null; then
|
|
echo " PASS: haskell-build-agent capability registered"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
echo " FAIL: haskell-build-agent capability not found in catalog"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
|
|
# 4. Build a minimal Haskell project
|
|
echo "[4/5] Remote build"
|
|
TMPDIR=$(mktemp -d)
|
|
mkdir -p "$TMPDIR/hello"
|
|
cat > "$TMPDIR/hello/Main.hs" << 'HASKELL'
|
|
module Main where
|
|
main :: IO ()
|
|
main = putStrLn "Hello from Haskell build machine!"
|
|
HASKELL
|
|
cat > "$TMPDIR/hello/hello.cabal" << 'CABAL'
|
|
cabal-version: 2.4
|
|
name: hello
|
|
version: 0.1.0.0
|
|
build-type: Simple
|
|
|
|
executable hello
|
|
main-is: Main.hs
|
|
build-depends: base >=4.14
|
|
default-language: Haskell2010
|
|
CABAL
|
|
|
|
# Sync and build
|
|
rsync -a --delete "$TMPDIR/hello/" "$VM:/build/hello-smoke/" 2>/dev/null
|
|
check "cabal build succeeds" ssh "$VM" "cd /build/hello-smoke && source ~/.ghcup/env && cabal build all"
|
|
|
|
# 5. Run the built executable
|
|
echo "[5/5] Execution"
|
|
check "built executable runs" ssh "$VM" "cd /build/hello-smoke && source ~/.ghcup/env && cabal run hello"
|
|
|
|
# Cleanup
|
|
rm -rf "$TMPDIR"
|
|
ssh "$VM" "rm -rf /build/hello-smoke" 2>/dev/null || true
|
|
|
|
echo ""
|
|
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
[ "$FAIL" -eq 0 ] && echo "All checks passed." || echo "Some checks failed — review output above."
|
|
exit "$FAIL"
|