# OrbStack Integration Helpers # Utilities for interacting with OrbStack machine "provisioning" use std log # Connect to OrbStack machine export def orbstack-connect [] { let test_config = (load-test-config) let machine_name = $test_config.orbstack.machine_name # Verify OrbStack machine exists let machines = (orb list | from json) if not ($machine_name in ($machines | get name)) { error make { msg: $"OrbStack machine '($machine_name)' not found" label: { text: "Machine not found" } } } # Return connection info { machine: $machine_name docker_socket: $test_config.orbstack.connection.socket network: $test_config.orbstack.network } } # Run command on OrbStack machine export def orbstack-run [ command: string --detach: bool = false ] { let connection = (orbstack-connect) if $detach { docker -H $connection.docker_socket run -d $command } else { docker -H $connection.docker_socket run --rm $command } } # Execute command in running container export def orbstack-exec [ container_name: string command: string ] { let connection = (orbstack-connect) docker -H $connection.docker_socket exec $container_name $command } # Deploy platform service to OrbStack export def orbstack-deploy-service [ service_name: string config: record ] { let connection = (orbstack-connect) let test_config = (load-test-config) log info $"Deploying ($service_name) to OrbStack..." match $service_name { "orchestrator" => { deploy-orchestrator $connection $config } "coredns" => { deploy-coredns $connection $config } "oci_registry" => { deploy-oci-registry $connection $config } "gitea" => { deploy-gitea $connection $config } "postgres" => { deploy-postgres $connection $config } "prometheus" => { deploy-prometheus $connection $config } "grafana" => { deploy-grafana $connection $config } _ => { error make { msg: $"Unknown service: ($service_name)" } } } } # Deploy orchestrator service def deploy-orchestrator [connection: record, config: record] { let test_config = (load-test-config) let service_config = $test_config.services.orchestrator # Build orchestrator image if needed let orchestrator_path = $"($env.PWD)/provisioning/platform/orchestrator" cd $orchestrator_path docker -H $connection.docker_socket build -t provisioning-orchestrator:test . # Run orchestrator container docker -H $connection.docker_socket run -d \ --name orchestrator \ --network provisioning-net \ --ip $service_config.host \ -p $"($service_config.port):($service_config.port)" \ -v /var/run/docker.sock:/var/run/docker.sock \ provisioning-orchestrator:test log info "Orchestrator deployed successfully" } # Deploy CoreDNS service def deploy-coredns [connection: record, config: record] { let test_config = (load-test-config) let service_config = $test_config.services.coredns # Create CoreDNS configuration let coredns_config = $" .:53 { forward . 8.8.8.8 8.8.4.4 log errors cache } local:53 { file /etc/coredns/db.local log errors } " # Write config to temp file $coredns_config | save -f /tmp/Corefile # Run CoreDNS container docker -H $connection.docker_socket run -d \ --name coredns \ --network provisioning-net \ --ip $service_config.host \ -p $"($service_config.port):53/udp" \ -v /tmp/Corefile:/etc/coredns/Corefile \ coredns/coredns:latest log info "CoreDNS deployed successfully" } # Deploy OCI registry (Zot or Harbor) def deploy-oci-registry [connection: record, config: record] { let test_config = (load-test-config) let use_harbor = ($config.use_harbor? | default false) if $use_harbor { deploy-harbor $connection $config } else { deploy-zot $connection $config } } # Deploy Zot OCI registry def deploy-zot [connection: record, config: record] { let test_config = (load-test-config) let service_config = $test_config.services.oci_registry.zot # Zot configuration let zot_config = { storage: { rootDirectory: "/var/lib/registry" } http: { address: "0.0.0.0" port: 5000 } log: { level: "info" } } $zot_config | to json | save -f /tmp/zot-config.json # Run Zot container docker -H $connection.docker_socket run -d \ --name oci-registry \ --network provisioning-net \ --ip $service_config.host \ -p $"($service_config.port):5000" \ -v /tmp/zot-config.json:/etc/zot/config.json \ -v zot-data:/var/lib/registry \ ghcr.io/project-zot/zot:latest log info "Zot OCI registry deployed successfully" } # Deploy Harbor OCI registry def deploy-harbor [connection: record, config: record] { let test_config = (load-test-config) let service_config = $test_config.services.oci_registry.harbor # Harbor requires docker-compose, use Harbor installer log info "Deploying Harbor (enterprise mode)..." # Download Harbor offline installer let harbor_version = "v2.9.0" let harbor_url = $"https://github.com/goharbor/harbor/releases/download/($harbor_version)/harbor-offline-installer-($harbor_version).tgz" # Note: Full Harbor deployment requires docker-compose and is complex # For testing, we'll use a simplified Harbor deployment docker -H $connection.docker_socket run -d \ --name harbor \ --network provisioning-net \ --ip $service_config.host \ -p $"($service_config.port):443" \ -p $"($service_config.ui_port):80" \ goharbor/harbor-core:$harbor_version log info "Harbor OCI registry deployed successfully" } # Deploy Gitea service def deploy-gitea [connection: record, config: record] { let test_config = (load-test-config) let service_config = $test_config.services.gitea let postgres_config = $test_config.services.postgres # Run Gitea container docker -H $connection.docker_socket run -d \ --name gitea \ --network provisioning-net \ --ip $service_config.host \ -p $"($service_config.port):3000" \ -p $"($service_config.ssh_port):22" \ -e USER_UID=1000 \ -e USER_GID=1000 \ -e GITEA__database__DB_TYPE=postgres \ -e $"GITEA__database__HOST=($postgres_config.host):($postgres_config.port)" \ -e GITEA__database__NAME=gitea \ -e GITEA__database__USER=$postgres_config.username \ -e GITEA__database__PASSWD=gitea \ -v gitea-data:/data \ gitea/gitea:latest log info "Gitea deployed successfully" } # Deploy PostgreSQL service def deploy-postgres [connection: record, config: record] { let test_config = (load-test-config) let service_config = $test_config.services.postgres # Run PostgreSQL container docker -H $connection.docker_socket run -d \ --name postgres \ --network provisioning-net \ --ip $service_config.host \ -p $"($service_config.port):5432" \ -e POSTGRES_USER=$service_config.username \ -e POSTGRES_PASSWORD=postgres \ -e POSTGRES_DB=$service_config.database \ -v postgres-data:/var/lib/postgresql/data \ postgres:15-alpine log info "PostgreSQL deployed successfully" } # Deploy Prometheus service def deploy-prometheus [connection: record, config: record] { let test_config = (load-test-config) let service_config = $test_config.services.prometheus # Prometheus configuration let prometheus_config = $" global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: 'orchestrator' static_configs: - targets: ['($test_config.services.orchestrator.host):($test_config.services.orchestrator.port)'] " $prometheus_config | save -f /tmp/prometheus.yml # Run Prometheus container docker -H $connection.docker_socket run -d \ --name prometheus \ --network provisioning-net \ --ip $service_config.host \ -p $"($service_config.port):9090" \ -v /tmp/prometheus.yml:/etc/prometheus/prometheus.yml \ -v prometheus-data:/prometheus \ prom/prometheus:latest log info "Prometheus deployed successfully" } # Deploy Grafana service def deploy-grafana [connection: record, config: record] { let test_config = (load-test-config) let service_config = $test_config.services.grafana # Run Grafana container docker -H $connection.docker_socket run -d \ --name grafana \ --network provisioning-net \ --ip $service_config.host \ -p $"($service_config.port):3000" \ -e GF_SECURITY_ADMIN_PASSWORD=admin \ -v grafana-data:/var/lib/grafana \ grafana/grafana:latest log info "Grafana deployed successfully" } # Create Docker network for services export def orbstack-create-network [] { let connection = (orbstack-connect) let test_config = (load-test-config) # Create custom network docker -H $connection.docker_socket network create \ --subnet $test_config.orbstack.network.subnet \ --gateway $test_config.orbstack.network.gateway \ provisioning-net log info "Docker network 'provisioning-net' created" } # Cleanup OrbStack resources export def orbstack-cleanup [] { let connection = (orbstack-connect) log info "Cleaning up OrbStack resources..." # Stop and remove all containers let containers = [ "orchestrator" "coredns" "oci-registry" "harbor" "gitea" "postgres" "prometheus" "grafana" ] for container in $containers { try { docker -H $connection.docker_socket stop $container docker -H $connection.docker_socket rm $container } catch { # Ignore errors if container doesn't exist } } # Remove network try { docker -H $connection.docker_socket network rm provisioning-net } catch { # Ignore errors if network doesn't exist } log info "OrbStack cleanup completed" } # Get logs from OrbStack container export def orbstack-logs [ container_name: string --tail: int = 100 --follow: bool = false ] { let connection = (orbstack-connect) if $follow { docker -H $connection.docker_socket logs -f --tail $tail $container_name } else { docker -H $connection.docker_socket logs --tail $tail $container_name } } # Helper to load test config (copied from test_helpers.nu to avoid circular dependency) def load-test-config [] { let config_path = $"($env.PWD)/provisioning/tests/integration/test_config.yaml" open $config_path }