Stop treating Firecracker, kernels, modules, and guest images as tracked source files. Source checkouts now resolve runtime assets from ./runtime, while installed binaries keep using ../lib/banger. Add a small runtimebundle helper plus runtime-bundle.toml so make can bootstrap, package, and install a runtime bundle with checksum validation. Update the shell helpers and daemon path hints to fail clearly when the bundle is missing instead of assuming repo-root artifacts. This removes the tracked runtime blobs from HEAD in favor of an ignored local runtime/ tree. Verified with go test ./..., make build, bash -n on the shell helpers, make -n install, and a temporary package/fetch smoke test. The manifest URL/SHA still need a published bundle before fresh clones can bootstrap, and history rewrite remains a separate rollout step.
153 lines
3.8 KiB
Bash
Executable file
153 lines
3.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
log() {
|
|
printf '[verify] %s\n' "$*"
|
|
}
|
|
|
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
DEFAULT_RUNTIME_DIR="$DIR"
|
|
if [[ -d "$DIR/runtime" ]]; then
|
|
DEFAULT_RUNTIME_DIR="$DIR/runtime"
|
|
fi
|
|
RUNTIME_DIR="${BANGER_RUNTIME_DIR:-$DEFAULT_RUNTIME_DIR}"
|
|
SSH_KEY="$RUNTIME_DIR/id_ed25519"
|
|
if [[ ! -d "$RUNTIME_DIR" ]]; then
|
|
log "runtime bundle not found: $RUNTIME_DIR"
|
|
log "run 'make runtime-bundle' or set BANGER_RUNTIME_DIR"
|
|
exit 1
|
|
fi
|
|
if [[ ! -f "$SSH_KEY" ]]; then
|
|
log "ssh key not found: $SSH_KEY"
|
|
exit 1
|
|
fi
|
|
|
|
wait_for_ssh() {
|
|
local guest_ip="$1"
|
|
local deadline=$((SECONDS + 60))
|
|
|
|
while ((SECONDS < deadline)); do
|
|
if ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
|
-o ConnectTimeout=2 "root@${guest_ip}" "true" >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage: ./verify.sh [--nat]
|
|
|
|
Run a basic smoke test for the Go VM workflow.
|
|
Use --nat to additionally verify outbound NAT and host rule cleanup.
|
|
EOF
|
|
}
|
|
|
|
NAT_ENABLED=0
|
|
if [[ "${1:-}" == "--nat" ]]; then
|
|
NAT_ENABLED=1
|
|
shift
|
|
fi
|
|
if (($# != 0)); then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
VM_NAME="verify-$(date +%s)"
|
|
VM_JSON=""
|
|
TAP=""
|
|
VM_DIR=""
|
|
GUEST_IP=""
|
|
UPLINK=""
|
|
|
|
cleanup() {
|
|
if [[ -n "${VM_NAME:-}" ]]; then
|
|
./banger vm delete "$VM_NAME" >/dev/null 2>&1 || true
|
|
fi
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
|
|
log "starting VM"
|
|
CREATE_ARGS=(./banger vm create --name "$VM_NAME")
|
|
if (( NAT_ENABLED )); then
|
|
CREATE_ARGS+=(--nat)
|
|
fi
|
|
"${CREATE_ARGS[@]}" >/dev/null
|
|
|
|
VM_JSON="$(./banger vm show "$VM_NAME")"
|
|
name="$(printf '%s\n' "$VM_JSON" | jq -r '.name // empty')"
|
|
guest_ip="$(printf '%s\n' "$VM_JSON" | jq -r '.runtime.guest_ip // empty')"
|
|
tap="$(printf '%s\n' "$VM_JSON" | jq -r '.runtime.tap_device // empty')"
|
|
vm_dir="$(printf '%s\n' "$VM_JSON" | jq -r '.runtime.vm_dir // empty')"
|
|
|
|
if [[ -z "$name" || -z "$guest_ip" || -z "$tap" || -z "$vm_dir" ]]; then
|
|
log "missing VM metadata from banger vm show"
|
|
exit 1
|
|
fi
|
|
|
|
TAP="$tap"
|
|
VM_DIR="$vm_dir"
|
|
GUEST_IP="$guest_ip"
|
|
|
|
if (( NAT_ENABLED )); then
|
|
UPLINK="$(ip route show default 2>/dev/null | awk '/default/ {print $5; exit}')"
|
|
if [[ -z "$UPLINK" ]]; then
|
|
log "failed to detect uplink interface"
|
|
exit 1
|
|
fi
|
|
log "asserting NAT rules are installed"
|
|
sudo iptables -t nat -C POSTROUTING -s "${GUEST_IP}/32" -o "$UPLINK" -j MASQUERADE
|
|
sudo iptables -C FORWARD -i "$TAP" -o "$UPLINK" -j ACCEPT
|
|
sudo iptables -C FORWARD -i "$UPLINK" -o "$TAP" -m state --state RELATED,ESTABLISHED -j ACCEPT
|
|
fi
|
|
|
|
log "asserting VM is reachable via SSH"
|
|
if ! wait_for_ssh "$guest_ip"; then
|
|
log "ssh did not become ready for ${guest_ip}"
|
|
exit 1
|
|
fi
|
|
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
|
"root@${guest_ip}" "uname -a" >/dev/null
|
|
|
|
if (( NAT_ENABLED )); then
|
|
log "asserting VM has outbound network access"
|
|
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
|
"root@${guest_ip}" "curl -fsS https://example.com >/dev/null" >/dev/null
|
|
fi
|
|
|
|
log "cleaning up VM"
|
|
cleanup
|
|
|
|
log "asserting cleanup success"
|
|
if ./banger vm show "$VM_NAME" >/dev/null 2>&1; then
|
|
log "vm still exists after delete: $VM_NAME"
|
|
exit 1
|
|
fi
|
|
if ip link show "$TAP" >/dev/null 2>&1; then
|
|
log "tap still exists: $TAP"
|
|
exit 1
|
|
fi
|
|
if [[ -d "$VM_DIR" ]]; then
|
|
log "vm dir still exists: $VM_DIR"
|
|
exit 1
|
|
fi
|
|
if (( NAT_ENABLED )); then
|
|
if sudo iptables -t nat -C POSTROUTING -s "${GUEST_IP}/32" -o "$UPLINK" -j MASQUERADE 2>/dev/null; then
|
|
log "nat rule still exists for ${GUEST_IP}"
|
|
exit 1
|
|
fi
|
|
if sudo iptables -C FORWARD -i "$TAP" -o "$UPLINK" -j ACCEPT 2>/dev/null; then
|
|
log "forward-out rule still exists for ${TAP}"
|
|
exit 1
|
|
fi
|
|
if sudo iptables -C FORWARD -i "$UPLINK" -o "$TAP" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; then
|
|
log "forward-in rule still exists for ${TAP}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
log "ok"
|