#!/usr/bin/env bash # Development VM manager using NixOS # Uses the same service configuration as CI set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' RED='\033[0;31m' NC='\033[0m' VM_DIR="$PROJECT_ROOT/.dev-vm" VM_PID_FILE="$VM_DIR/vm.pid" function build_vm() { echo -e "${BLUE}🔨 Building development VM...${NC}" cd "$PROJECT_ROOT" nix build .#dev-vm -o "$VM_DIR/result" echo -e "${GREEN}✓ VM built${NC}" } function start_vm() { if [ -f "$VM_PID_FILE" ] && kill -0 $(cat "$VM_PID_FILE") 2>/dev/null; then echo -e "${YELLOW}⚠️ VM is already running${NC}" return fi if [ ! -f "$VM_DIR/result/bin/run-nixos-vm" ]; then echo -e "${YELLOW}Building VM first...${NC}" build_vm fi echo -e "${BLUE}🚀 Starting development VM...${NC}" mkdir -p "$VM_DIR" # Start VM in background with port forwarding # PostgreSQL: 5432 -> 5432 # MinIO API: 9000 -> 9000 # MinIO Console: 9001 -> 9001 QEMU_NET_OPTS="hostfwd=tcp::5432-:5432,hostfwd=tcp::9000-:9000,hostfwd=tcp::9001-:9001" \ "$VM_DIR/result/bin/run-nixos-vm" > "$VM_DIR/vm.log" 2>&1 & VM_PID=$! echo $VM_PID > "$VM_PID_FILE" echo -e "${GREEN}✓ VM started (PID: $VM_PID)${NC}" echo -e " Logs: $VM_DIR/vm.log" echo "" echo "Waiting for services to be ready..." # Wait for PostgreSQL for i in {1..30}; do if pg_isready -h localhost -p 5432 -q 2>/dev/null; then echo -e "${GREEN}✓ PostgreSQL ready${NC}" break fi sleep 1 done # Wait for MinIO for i in {1..30}; do if curl -sf http://localhost:9000/minio/health/live > /dev/null 2>&1; then echo -e "${GREEN}✓ MinIO ready${NC}" break fi sleep 1 done echo "" echo -e "${GREEN}✅ Development VM running!${NC}" echo "" echo "Services available at:" echo " PostgreSQL: localhost:5432" echo " MinIO API: http://localhost:9000" echo " MinIO UI: http://localhost:9001" echo "" echo "Environment:" echo " export DATABASE_URL='postgresql://webref@localhost:5432/webref'" echo " export MINIO_ENDPOINT='localhost:9000'" } function stop_vm() { if [ ! -f "$VM_PID_FILE" ]; then echo -e "${YELLOW}⚠️ No VM PID file found${NC}" return fi PID=$(cat "$VM_PID_FILE") if ! kill -0 $PID 2>/dev/null; then echo -e "${YELLOW}⚠️ VM is not running${NC}" rm "$VM_PID_FILE" return fi echo -e "${BLUE}🛑 Stopping VM...${NC}" kill $PID rm "$VM_PID_FILE" echo -e "${GREEN}✓ VM stopped${NC}" } function status() { if [ -f "$VM_PID_FILE" ] && kill -0 $(cat "$VM_PID_FILE") 2>/dev/null; then echo -e "${GREEN}✓ VM is running${NC} (PID: $(cat "$VM_PID_FILE"))" # Check services if pg_isready -h localhost -p 5432 -q 2>/dev/null; then echo -e "${GREEN}✓ PostgreSQL${NC} - responding" else echo -e "${RED}✗ PostgreSQL${NC} - not responding" fi if curl -sf http://localhost:9000/minio/health/live > /dev/null 2>&1; then echo -e "${GREEN}✓ MinIO${NC} - responding" else echo -e "${RED}✗ MinIO${NC} - not responding" fi else echo -e "${RED}✗ VM is not running${NC}" fi } function logs() { if [ ! -f "$VM_DIR/vm.log" ]; then echo -e "${RED}No log file found${NC}" return fi tail -f "$VM_DIR/vm.log" } function clean() { echo -e "${RED}⚠️ Cleaning VM (this will delete the VM image)${NC}" read -p "Are you sure? (yes/no): " -r if [ "$REPLY" = "yes" ]; then stop_vm rm -rf "$VM_DIR" echo -e "${GREEN}✓ VM cleaned${NC}" else echo "Aborted" fi } case "${1:-}" in build) build_vm ;; start) start_vm ;; stop) stop_vm ;; restart) stop_vm sleep 2 start_vm ;; status) status ;; logs) logs ;; clean) clean ;; *) echo "Development VM Manager" echo "" echo "Usage: $0 {build|start|stop|restart|status|logs|clean}" echo "" echo "Commands:" echo " build - Build the NixOS VM image" echo " start - Start the VM with services" echo " stop - Stop the VM" echo " restart - Restart the VM" echo " status - Show VM and service status" echo " logs - Tail VM logs" echo " clean - Remove VM image and data" echo "" echo "Alternative: Use native services (faster)" echo " ./scripts/dev-services.sh start" exit 1 ;; esac