Delegate make remote-build to sandboxer create when CLI is available; retain legacy rsync path with deprecation notice. Add verify script.
92 lines
3.0 KiB
Makefile
92 lines
3.0 KiB
Makefile
# infra/build-machines/Makefile
|
|
# Usage: make remote-build PROJECT=~/projects/my-haskell-app [VM=haskell-build]
|
|
|
|
VM ?= haskell-build
|
|
PROJECT ?= .
|
|
RDIR := /build/$(notdir $(realpath $(PROJECT)))
|
|
|
|
# Sync project source to VM (exclude build artefacts)
|
|
.PHONY: sync
|
|
sync:
|
|
rsync -av --delete \
|
|
--exclude='.git' \
|
|
--exclude='dist-newstyle' \
|
|
--exclude='.stack-work' \
|
|
--exclude='*.o' --exclude='*.hi' \
|
|
$(PROJECT)/ $(VM):$(RDIR)/
|
|
|
|
# Run cabal build on VM — prefers sand-boxer workspace (SAND-WP-0012 shim)
|
|
.PHONY: remote-build
|
|
remote-build:
|
|
@if command -v sandboxer >/dev/null 2>&1; then \
|
|
$(MAKE) remote-build-sandboxer; \
|
|
else \
|
|
echo "WARN: sandboxer not on PATH — using legacy rsync-only path" >&2; \
|
|
$(MAKE) remote-build-legacy; \
|
|
fi
|
|
|
|
# Legacy rsync + ssh (deprecated — install sand-boxer for isolated workspaces)
|
|
.PHONY: remote-build-legacy
|
|
remote-build-legacy: sync
|
|
ssh $(VM) "cd $(RDIR) && source ~/.ghcup/env && cabal build all 2>&1"
|
|
|
|
.PHONY: remote-build-sandboxer
|
|
remote-build-sandboxer:
|
|
@set -euo pipefail; \
|
|
STATUS=$$(sandboxer create \
|
|
--profile profile.vm-haskell-build \
|
|
--input vm=$(VM) \
|
|
--input repo=$(PROJECT) \
|
|
--actor agt \
|
|
--project the-custodian \
|
|
--host localhost); \
|
|
ID=$$(echo "$$STATUS" | python3 -c "import sys,json; print(json.load(sys.stdin)['sandbox_id'])"); \
|
|
RDIR=$$(echo "$$STATUS" | python3 -c "import sys,json; r=json.load(sys.stdin).get('reachability') or {}; print(r.get('remote_dir',''))"); \
|
|
test -n "$$RDIR"; \
|
|
ssh $(VM) "cd $$RDIR && source ~/.ghcup/env && cabal build all 2>&1"; \
|
|
sandboxer destroy "$$ID"
|
|
|
|
# Run tests on VM
|
|
.PHONY: remote-test
|
|
remote-test: sync
|
|
ssh $(VM) "cd $(RDIR) && source ~/.ghcup/env && cabal test all 2>&1"
|
|
|
|
# Open a GHCi session on the VM
|
|
.PHONY: remote-ghci
|
|
remote-ghci: sync
|
|
ssh -t $(VM) "cd $(RDIR) && source ~/.ghcup/env && cabal repl"
|
|
|
|
# Sync build artefacts back (for local IDE inspection)
|
|
.PHONY: fetch-artifacts
|
|
fetch-artifacts:
|
|
rsync -av $(VM):$(RDIR)/dist-newstyle/ $(PROJECT)/dist-newstyle/
|
|
|
|
# Check which VMs are reachable
|
|
.PHONY: bridge-status
|
|
bridge-status:
|
|
@echo "Scanning build-machine tunnel ports..."
|
|
@for port in 12221 12222 12223 12224 12225; do \
|
|
result=$$(ssh -q -p $$port -o ConnectTimeout=2 \
|
|
-o StrictHostKeyChecking=no build@localhost \
|
|
"echo $$port OK: $$(hostname) — GHC: $$(~/.ghcup/bin/ghc --numeric-version)" \
|
|
2>/dev/null) ; \
|
|
if [ -n "$$result" ]; then echo " $$result"; \
|
|
else echo " port $$port: no tunnel"; fi; \
|
|
done
|
|
|
|
# Show VM system info
|
|
.PHONY: vm-info
|
|
vm-info:
|
|
ssh $(VM) "uname -a; source ~/.ghcup/env && ghc --version && cabal --version"
|
|
|
|
# Install SSH config for the build VM (idempotent)
|
|
.PHONY: install-ssh-config
|
|
install-ssh-config:
|
|
@if grep -q '# Haskell Build VM — tunnel via workstation' ~/.ssh/config 2>/dev/null; then \
|
|
echo "SSH config already present — skipping"; \
|
|
else \
|
|
echo "" >> ~/.ssh/config; \
|
|
cat ssh-config.template >> ~/.ssh/config; \
|
|
echo "Appended build-machine SSH config to ~/.ssh/config"; \
|
|
fi
|