From 9f20dcae0528e3d27862314f9ace954ab79bc922 Mon Sep 17 00:00:00 2001 From: oskar Date: Mon, 18 May 2026 21:34:57 +0200 Subject: [PATCH] Add control plane deploy script and fix UI healthcheck --- docs/vps-control-plane.md | 37 +++++++++------- scripts/deploy/deploy-control-plane.sh | 23 ++++++++++ services/control-plane/deploy-local.sh | 53 +++++++++++++++++++++++ services/control-plane/docker-compose.yml | 2 +- 4 files changed, 98 insertions(+), 17 deletions(-) create mode 100755 scripts/deploy/deploy-control-plane.sh create mode 100755 services/control-plane/deploy-local.sh diff --git a/docs/vps-control-plane.md b/docs/vps-control-plane.md index 59f7376..1507c5c 100644 --- a/docs/vps-control-plane.md +++ b/docs/vps-control-plane.md @@ -20,19 +20,22 @@ All services adhere to **filesystem-first** semantics, using `/opt/homelab/` as - Repository cloned to `/home/oskar/homelab-codex-ws`. ### 2. Bootstrap -Run the bootstrap script to initialize the runtime filesystem and start the stack: - -```bash -./scripts/bootstrap/vps-control-plane.sh -``` - -### 3. Verification -Verify the stack is healthy: +Run the local deployment script on the VPS to initialize the runtime filesystem and start the stack: ```bash cd services/control-plane -docker compose ps -curl http://localhost:8080/summary +bash deploy-local.sh +``` + +### 3. Verification +Verify the stack is healthy using the deployment script or check container status on the VPS: + +```bash +# Check status via deploy script +./scripts/deploy/deploy-control-plane.sh --ssh + +# Manual status check on VPS +docker ps --filter "name=control-plane" ``` ## Operational Workflows @@ -45,14 +48,16 @@ curl http://localhost:8080/summary ### Recovery Flow In case of control plane failure: -1. Check logs: `docker compose logs -f`. -2. Restart stack: `docker compose restart`. -3. Rebuild world state: Delete `/opt/homelab/state/observer_checkpoint.json` and restart the observer service. +1. Check logs using `docker logs`. +2. Restart stack using the local deployment script: `bash deploy-local.sh`. +3. Rebuild world state: Delete `/opt/homelab/state/observer_checkpoint.json` and redeploy. ### Upgrade Flow -1. Pull latest changes from git. -2. Run bootstrap script again: `./scripts/bootstrap/vps-control-plane.sh`. - - This will rebuild images and restart containers with new code. +To deploy updates from the SOLARIA/control host: + +```bash +./scripts/deploy/deploy-control-plane.sh --ssh +``` ### Rollback Semantics Since the runtime is filesystem-first and append-only: diff --git a/scripts/deploy/deploy-control-plane.sh b/scripts/deploy/deploy-control-plane.sh new file mode 100755 index 0000000..889f8e4 --- /dev/null +++ b/scripts/deploy/deploy-control-plane.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# scripts/deploy/deploy-control-plane.sh +set -e + +VPS_IP="100.95.58.48" +USER="oskar" +REMOTE_REPO_PATH="/home/oskar/homelab-codex-ws" + +MODE=$1 + +case "$MODE" in + "--ssh") + echo "Deploying to VPS ($VPS_IP) via SSH..." + ssh "$USER@$VPS_IP" "cd $REMOTE_REPO_PATH && git pull origin master && cd services/control-plane && bash deploy-local.sh" + ;; + "--print") + echo "ssh $USER@$VPS_IP \"cd $REMOTE_REPO_PATH && git pull origin master && cd services/control-plane && bash deploy-local.sh\"" + ;; + *) + echo "Usage: $0 [--ssh|--print]" + exit 1 + ;; +esac diff --git a/services/control-plane/deploy-local.sh b/services/control-plane/deploy-local.sh new file mode 100755 index 0000000..784d027 --- /dev/null +++ b/services/control-plane/deploy-local.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# services/control-plane/deploy-local.sh +set -e + +# 1. Validate it is deploying control-plane +if [[ ! $(pwd) == *"/services/control-plane" ]]; then + echo "Error: Script must be run from services/control-plane directory" + exit 1 +fi + +if [[ ! -f "docker-compose.yml" ]]; then + echo "Error: docker-compose.yml not found" + exit 1 +fi + +echo "--- Preparing Control Plane Directories ---" +# 2. Prepare required dirs +# /opt/homelab/config +# /opt/homelab/actions/{pending,approved,rejected,running,completed,failed} +# /opt/homelab/world +# /opt/homelab/state + +DIRS=( + "/opt/homelab/config" + "/opt/homelab/actions/pending" + "/opt/homelab/actions/approved" + "/opt/homelab/actions/rejected" + "/opt/homelab/actions/running" + "/opt/homelab/actions/completed" + "/opt/homelab/actions/failed" + "/opt/homelab/world" + "/opt/homelab/state" +) + +for dir in "${DIRS[@]}"; do + if [ ! -d "$dir" ]; then + echo "Creating $dir" + sudo mkdir -p "$dir" + fi +done + +# 3. chown/chmod for UID 1000 +echo "Setting permissions for UID 1000 on /opt/homelab..." +sudo chown -R 1000:1000 /opt/homelab +sudo chmod -R 775 /opt/homelab + +# 4. Run docker compose up -d --build --force-recreate +echo "--- Starting Control Plane Services ---" +docker compose up -d --build --force-recreate + +# 5. Print docker ps for control-plane containers +echo "--- Deployment Status ---" +docker ps --filter "name=control-plane" diff --git a/services/control-plane/docker-compose.yml b/services/control-plane/docker-compose.yml index b396c70..7234bfa 100644 --- a/services/control-plane/docker-compose.yml +++ b/services/control-plane/docker-compose.yml @@ -10,7 +10,7 @@ services: - /opt/homelab:/opt/homelab restart: unless-stopped healthcheck: - test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/summary', timeout=3).read()"] + test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/', timeout=3).read()"] interval: 30s timeout: 10s retries: 3