11#! /usr/bin/env bash
2- # deploy-azure-dev.sh — Quick dev deployment on Azure D96as_v5 with QEMU backend.
2+ # deploy-azure-dev.sh — Quick dev deployment on Azure with QEMU backend.
33# Usage: ./deploy-azure-dev.sh [create|deploy|ssh|status|destroy]
44set -euo pipefail
55
@@ -8,7 +8,7 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
88
99# --- Defaults ---
1010AZURE_LOCATION=" ${AZURE_LOCATION:- eastus} "
11- AZURE_VM_SIZE=" ${AZURE_VM_SIZE:- Standard_D96as_v5 } "
11+ AZURE_VM_SIZE=" ${AZURE_VM_SIZE:- Standard_D48as_v6 } "
1212AZURE_RG=" ${AZURE_RG:- opensandbox-dev} "
1313AZURE_VM_NAME=" ${AZURE_VM_NAME:- opensandbox-dev} "
1414AZURE_IMAGE=" ${AZURE_IMAGE:- Canonical: ubuntu-24_04-lts: server: latest} "
@@ -170,6 +170,10 @@ CGO_ENABLED=0 go build -o bin/opensandbox-worker ./cmd/worker/
170170echo "Building agent..."
171171CGO_ENABLED=0 GOARCH=amd64 go build -o bin/osb-agent ./cmd/agent/
172172
173+ # Stop services before overwriting binaries (avoids "text file busy")
174+ sudo systemctl stop opensandbox-worker 2>/dev/null || true
175+ sudo systemctl stop opensandbox-server 2>/dev/null || true
176+
173177sudo cp bin/opensandbox-server /usr/local/bin/
174178sudo cp bin/opensandbox-worker /usr/local/bin/
175179sudo cp bin/osb-agent /usr/local/bin/
@@ -179,14 +183,49 @@ BUILD
179183 # Build rootfs if needed
180184 ssh_cmd << 'ROOTFS '
181185set -euo pipefail
186+ export PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"
182187if [ ! -f /data/firecracker/images/default.ext4 ]; then
183188 echo "Building rootfs image..."
184189 cd ~/opensandbox
185- export PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"
186- sudo bash deploy/ec2/build-rootfs-docker.sh
190+ sudo -E bash deploy/ec2/build-rootfs-docker.sh /usr/local/bin/osb-agent /data/firecracker/images default
187191else
188192 echo "Rootfs image already exists."
189193fi
194+
195+ # Patch rootfs with guest kernel modules (vsock, overlay) and insmod symlink
196+ GUEST_MODDIR="/opt/opensandbox/guest-modules"
197+ if [ -d "$GUEST_MODDIR" ] && [ -f /data/firecracker/images/default.ext4 ]; then
198+ echo "Patching rootfs with guest kernel modules..."
199+ MNTDIR=$(mktemp -d)
200+ sudo mount -o loop /data/firecracker/images/default.ext4 "$MNTDIR"
201+
202+ # Copy modules
203+ sudo mkdir -p "$MNTDIR/lib/modules/vsock"
204+ sudo cp "$GUEST_MODDIR"/*.ko "$MNTDIR/lib/modules/vsock/" 2>/dev/null || true
205+
206+ # Create insmod symlink (busybox applet)
207+ if [ -f "$MNTDIR/bin/busybox" ] && [ ! -e "$MNTDIR/sbin/insmod" ]; then
208+ sudo ln -sf /bin/busybox "$MNTDIR/sbin/insmod"
209+ fi
210+
211+ # Update init script: load modules early (before overlay mount)
212+ if ! grep -q 'lib/modules/vsock' "$MNTDIR/sbin/init" 2>/dev/null; then
213+ # Insert module loading after the first "mount -t devtmpfs" line
214+ sudo sed -i '/^mount -t devtmpfs devtmpfs \/dev$/a\
215+ \
216+ # Load kernel modules (needed for QEMU with modular kernel)\
217+ if [ -d /lib/modules/vsock ]; then\
218+ for mod in /lib/modules/vsock/overlay.ko /lib/modules/vsock/vsock.ko /lib/modules/vsock/vmw_vsock_virtio_transport_common.ko /lib/modules/vsock/vmw_vsock_virtio_transport.ko; do\
219+ [ -f "$mod" ] \&\& insmod "$mod" 2>/dev/null || true\
220+ done\
221+ echo "init: kernel modules loaded"\
222+ fi' "$MNTDIR/sbin/init"
223+ fi
224+
225+ sudo umount "$MNTDIR"
226+ rmdir "$MNTDIR"
227+ echo "Rootfs patched."
228+ fi
190229ROOTFS
191230
192231 # Setup env files
@@ -259,22 +298,30 @@ RESTART
259298 ssh_cmd << SEED
260299set -euo pipefail
261300export PGPASSWORD=opensandbox
262- # Create org and API key if not exists
301+ KEY_HASH=\$ (echo -n "${OPENSANDBOX_API_KEY} " | sha256sum | cut -d' ' -f1)
302+
303+ # Create org (UUID id, table is "orgs")
263304psql -h localhost -U opensandbox -d opensandbox -c "
264- INSERT INTO organizations (id, name, slug) VALUES ('org-dev ', 'Dev Org', 'dev')
305+ INSERT INTO orgs (id, name, slug) VALUES ('00000000-0000-0000-0000-000000000001 ', 'Dev Org', 'dev')
265306 ON CONFLICT DO NOTHING;
266- INSERT INTO api_keys (id, org_id, key_hash, name)
267- VALUES ('key-dev', 'org-dev', '$( echo -n " ${OPENSANDBOX_API_KEY} " | sha256sum | cut -d' ' -f1) ', 'dev-key')
307+ " 2>/dev/null || echo "DB seed: orgs table not ready yet"
308+
309+ # Create API key (UUID id, requires key_prefix)
310+ psql -h localhost -U opensandbox -d opensandbox -c "
311+ INSERT INTO api_keys (id, org_id, key_hash, key_prefix, name)
312+ VALUES ('00000000-0000-0000-0000-000000000002', '00000000-0000-0000-0000-000000000001', '\$ {KEY_HASH}', '$( echo -n " ${OPENSANDBOX_API_KEY} " | cut -c1-8) ', 'dev-key')
268313 ON CONFLICT DO NOTHING;
269- " 2>/dev/null || echo "DB seed skipped (tables may not exist yet)"
314+ " 2>/dev/null || echo "DB seed: api_keys table not ready yet"
315+
316+ echo "DB seeded (org + API key)"
270317SEED
271318
272319 log " === Deployment complete ==="
273320 log " Server: http://${VM_PUBLIC_IP} :8080"
274321 log " Worker: http://${VM_PUBLIC_IP} :8081"
275322 log " API key: ${OPENSANDBOX_API_KEY} "
276323 log " "
277- log " Test: curl -X POST http://${VM_PUBLIC_IP} :8080/api/sandboxes -H 'Authorization: Bearer ${OPENSANDBOX_API_KEY} '"
324+ log " Test: curl -X POST http://${VM_PUBLIC_IP} :8080/api/sandboxes -H 'X-API-Key: ${OPENSANDBOX_API_KEY} '"
278325}
279326
280327# --- SSH ---
@@ -342,7 +389,7 @@ case "$CMD" in
342389 echo " "
343390 echo " Environment variables:"
344391 echo " AZURE_LOCATION Azure region (default: eastus)"
345- echo " AZURE_VM_SIZE VM size (default: Standard_D96as_v5 )"
392+ echo " AZURE_VM_SIZE VM size (default: Standard_D48as_v6 )"
346393 echo " AZURE_DATA_DISK_GB Data disk size (default: 500)"
347394 ;;
348395esac
0 commit comments