fix(deploy): inventory-aware orchestration and correct override paths
- orchestrate-deploy.sh: read nodes from inventory/topology.yaml instead of hardcoded list - orchestrate-deploy.sh: LTE nodes (chelsty-infra, chelsty-ha) use ConnectTimeout=30, non-fatal on failure - deploy-node.sh: service discovery falls back to services.yaml if no services.txt - deploy-node.sh: override path corrected to hosts/<node>/runtime/<service>/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
dc483ae31a
commit
b02c8bb50e
|
|
@ -8,6 +8,7 @@ set -e
|
||||||
REPO_PATH="${HOME}/homelab-codex-ws"
|
REPO_PATH="${HOME}/homelab-codex-ws"
|
||||||
RUNTIME_PATH="/opt/homelab"
|
RUNTIME_PATH="/opt/homelab"
|
||||||
HOSTNAME=$(hostname | tr '[:lower:]' '[:upper:]')
|
HOSTNAME=$(hostname | tr '[:lower:]' '[:upper:]')
|
||||||
|
HOST_DIR="${REPO_PATH}/hosts/$(hostname | tr '[:upper:]' '[:lower:]')"
|
||||||
|
|
||||||
echo "--- Starting Deployment on ${HOSTNAME} ---"
|
echo "--- Starting Deployment on ${HOSTNAME} ---"
|
||||||
|
|
||||||
|
|
@ -22,20 +23,33 @@ echo "Pulling latest changes..."
|
||||||
git pull
|
git pull
|
||||||
|
|
||||||
# 2. Identify Services
|
# 2. Identify Services
|
||||||
# Based on our convention, we look for services assigned to this host
|
SERVICES=()
|
||||||
# For now, we'll check if a 'services.txt' exists in the host folder
|
if [ -f "${HOST_DIR}/services.txt" ]; then
|
||||||
SERVICE_LIST="${REPO_PATH}/hosts/$(hostname | tr '[:upper:]' '[:lower:]')/services.txt"
|
mapfile -t SERVICES < <(grep -v '^\s*#' "${HOST_DIR}/services.txt" | grep -v '^\s*$')
|
||||||
|
elif [ -f "${HOST_DIR}/services.yaml" ]; then
|
||||||
|
SERVICES=($(python3 -c "
|
||||||
|
import yaml, sys
|
||||||
|
try:
|
||||||
|
with open('${HOST_DIR}/services.yaml', 'r') as f:
|
||||||
|
data = yaml.safe_load(f)
|
||||||
|
if data and 'services' in data:
|
||||||
|
if isinstance(data['services'], dict):
|
||||||
|
print(' '.join(data['services'].keys()))
|
||||||
|
elif isinstance(data['services'], list):
|
||||||
|
print(' '.join(data['services']))
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Error parsing YAML: {e}', file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
"))
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -f "$SERVICE_LIST" ]; then
|
if [ ${#SERVICES[@]} -eq 0 ]; then
|
||||||
echo "No services.txt found for ${HOSTNAME}. Skipping service deployment."
|
echo "No services found for ${HOSTNAME}. Skipping service deployment."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 3. Deploy Services
|
# 3. Deploy Services
|
||||||
while IFS= read -r service || [ -n "$service" ]; do
|
for service in "${SERVICES[@]}"; do
|
||||||
[[ "$service" =~ ^#.*$ ]] && continue # Skip comments
|
|
||||||
[[ -z "$service" ]] && continue # Skip empty lines
|
|
||||||
|
|
||||||
echo "Deploying service: ${service}..."
|
echo "Deploying service: ${service}..."
|
||||||
|
|
||||||
COMPOSE_FILE="${REPO_PATH}/services/${service}/docker-compose.yml"
|
COMPOSE_FILE="${REPO_PATH}/services/${service}/docker-compose.yml"
|
||||||
|
|
@ -45,13 +59,10 @@ while IFS= read -r service || [ -n "$service" ]; do
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Target directory in runtime
|
|
||||||
TARGET_DIR="${RUNTIME_PATH}/services/${service}"
|
TARGET_DIR="${RUNTIME_PATH}/services/${service}"
|
||||||
mkdir -p "$TARGET_DIR"
|
mkdir -p "$TARGET_DIR"
|
||||||
|
|
||||||
# We use the compose file from the repo directly
|
OVERRIDE_FILE="${HOST_DIR}/runtime/${service}/docker-compose.override.yml"
|
||||||
# but we can also handle overrides here
|
|
||||||
OVERRIDE_FILE="${RUNTIME_PATH}/config/${service}/docker-compose.override.yml"
|
|
||||||
|
|
||||||
COMPOSE_CMD="docker compose -f ${COMPOSE_FILE}"
|
COMPOSE_CMD="docker compose -f ${COMPOSE_FILE}"
|
||||||
if [ -f "$OVERRIDE_FILE" ]; then
|
if [ -f "$OVERRIDE_FILE" ]; then
|
||||||
|
|
@ -60,7 +71,6 @@ while IFS= read -r service || [ -n "$service" ]; do
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$COMPOSE_CMD up -d --remove-orphans
|
$COMPOSE_CMD up -d --remove-orphans
|
||||||
|
done
|
||||||
done < "$SERVICE_LIST"
|
|
||||||
|
|
||||||
echo "--- Deployment Complete ---"
|
echo "--- Deployment Complete ---"
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,30 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# orchestrate-deploy.sh - To be run on SATURN
|
# orchestrate-deploy.sh - To be run on SATURN
|
||||||
# Triggers deployment on remote execution nodes.
|
# Triggers deployment on remote execution nodes via inventory.
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
HOSTS=("solaria" "piha" "vps")
|
REPO_PATH="${HOME}/homelab-codex-ws"
|
||||||
USER="oskar" # Default user
|
USER="oskar"
|
||||||
|
|
||||||
for HOST in "${HOSTS[@]}"; do
|
while IFS=' ' read -r HOST TAG; do
|
||||||
echo ">>> Triggering deployment on ${HOST}..."
|
echo ">>> Triggering deployment on ${HOST}..."
|
||||||
ssh "${USER}@${HOST}" "bash ~/homelab-codex-ws/scripts/deploy/deploy-node.sh"
|
if [[ "$TAG" == "lte" ]]; then
|
||||||
done
|
ssh -o ConnectTimeout=30 "${USER}@${HOST}" "bash ~/homelab-codex-ws/scripts/deploy/deploy-node.sh" || \
|
||||||
|
echo "WARNING: Deployment on ${HOST} failed or timed out (LTE/intermittent node, skipping)"
|
||||||
|
else
|
||||||
|
ssh "${USER}@${HOST}" "bash ~/homelab-codex-ws/scripts/deploy/deploy-node.sh"
|
||||||
|
fi
|
||||||
|
done < <(python3 -c "
|
||||||
|
import yaml, sys
|
||||||
|
with open('${REPO_PATH}/inventory/topology.yaml') as f:
|
||||||
|
data = yaml.safe_load(f)
|
||||||
|
skip = {'saturn', 'solaria'}
|
||||||
|
for name, info in (data.get('nodes') or {}).items():
|
||||||
|
if name in skip:
|
||||||
|
continue
|
||||||
|
uplink = ((info or {}).get('connectivity') or {}).get('uplink', '')
|
||||||
|
print(name, 'lte' if uplink == 'lte' else 'standard')
|
||||||
|
")
|
||||||
|
|
||||||
echo ">>> All deployments triggered."
|
echo ">>> All deployments triggered."
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue