#!/bin/bash # Auto-deploy script for LXC 106 (cinny) # Handles: cinny/config.json, cinny/nginx.conf, cinny/upstream-check.sh, # cinny/lotus-build.sh, cinny/lotus_deploy.sh, # deploy/hooks-lxc106.json, systemd/cinny-upstream-check.cron # Triggered by: Gitea webhook on push to main → http://10.10.10.6:9001/hooks/matrix-deploy # (webhook-lotus; the :9000 listener is bound to 127.0.0.1 and unreachable). set -euo pipefail REPO_DIR="/opt/matrix-config" LOG="/var/log/matrix-deploy.log" CLONE_URL="https://code.lotusguild.org/LotusGuild/matrix.git" exec >> "$LOG" 2>&1 echo "=== $(date) === LXC106 deploy triggered ===" if [ ! -d "$REPO_DIR/.git" ]; then git clone "$CLONE_URL" "$REPO_DIR" CHANGED="cinny/config.json cinny/nginx.conf cinny/upstream-check.sh cinny/lotus-build.sh cinny/lotus_deploy.sh deploy/hooks-lxc106.json systemd/cinny-upstream-check.cron" else cd "$REPO_DIR" git fetch --all PREV=$(git rev-parse HEAD) git reset --hard origin/main NEW=$(git rev-parse HEAD) CHANGED=$(git diff --name-only "$PREV" "$NEW") echo "Changed files: $CHANGED" fi if echo "$CHANGED" | grep -q '^cinny/config.json'; then echo "Deploying cinny config.json (merged: keeps server-only values)..." # The live file carries values injected on the server that are empty in git # (gifApiKey, set by lotus_deploy.sh from GIPHY_API_KEY). A plain copy would # blank them, so repo keys win except where the repo value is empty and the # live one isn't. Backup outside the web root; on any error the live file # is left untouched. mkdir -p /root/config-backups cp -p /var/www/html/config.json "/root/config-backups/config.json.$(date +%Y%m%d%H%M%S)" 2>/dev/null || true if python3 - "$REPO_DIR/cinny/config.json" /var/www/html/config.json <<'PY' import json, os, sys, tempfile repo_path, live_path = sys.argv[1], sys.argv[2] repo = json.load(open(repo_path)) live = json.load(open(live_path)) if os.path.exists(live_path) else {} merged = dict(repo) kept = [] for key, value in live.items(): if key in repo and repo[key] in ("", None) and value not in ("", None): merged[key] = value kept.append(key) fd, tmp = tempfile.mkstemp(dir=os.path.dirname(live_path)) with os.fdopen(fd, "w") as f: json.dump(merged, f, indent=2) f.write("\n") json.load(open(tmp)) os.chmod(tmp, 0o644) os.replace(tmp, live_path) print("kept server values for: " + (", ".join(kept) or "none")) PY then echo "✓ config.json deployed" else echo "✗ config.json merge FAILED — live file left unchanged" fi fi if echo "$CHANGED" | grep -q '^cinny/nginx.conf'; then echo "Deploying cinny nginx site config..." # Back up the live config, swap in the repo copy, and validate before # reloading. If `nginx -t` fails, restore the backup and skip the reload so # a bad config can never take the site down. BACKUP="/etc/nginx/sites-available/cinny.bak-$(date +%Y%m%d%H%M%S)" cp /etc/nginx/sites-available/cinny "$BACKUP" cp "$REPO_DIR/cinny/nginx.conf" /etc/nginx/sites-available/cinny if nginx -t; then systemctl reload nginx echo "✓ nginx site config deployed + reloaded" else echo "✗ nginx -t FAILED — restoring previous config, skipping reload" cp "$BACKUP" /etc/nginx/sites-available/cinny fi fi if echo "$CHANGED" | grep -q '^cinny/upstream-check.sh'; then echo "Deploying upstream-check.sh..." cp "$REPO_DIR/cinny/upstream-check.sh" /usr/local/bin/cinny-upstream-check.sh chmod +x /usr/local/bin/cinny-upstream-check.sh echo "✓ upstream-check.sh deployed" fi if echo "$CHANGED" | grep -q '^cinny/lotus-build.sh'; then echo "Deploying lotus-build.sh..." cp "$REPO_DIR/cinny/lotus-build.sh" /usr/local/bin/cinny-build.sh chmod +x /usr/local/bin/cinny-build.sh echo "✓ lotus-build.sh deployed" fi if echo "$CHANGED" | grep -q '^cinny/lotus_deploy.sh'; then echo "Deploying lotus_deploy.sh (webhook CI-gated web deploy)..." # The `lotus-deploy` webhook hook executes /usr/local/bin/lotus_deploy.sh. # Validate syntax before swapping so a broken script can never wedge deploys. if bash -n "$REPO_DIR/cinny/lotus_deploy.sh"; then cp "$REPO_DIR/cinny/lotus_deploy.sh" /usr/local/bin/lotus_deploy.sh chmod +x /usr/local/bin/lotus_deploy.sh echo "✓ lotus_deploy.sh deployed" else echo "✗ bash -n FAILED on lotus_deploy.sh — skipping install" fi fi if echo "$CHANGED" | grep -q '^deploy/hooks-lxc106.json'; then echo "Deploying hooks-lxc106.json..." cp "$REPO_DIR/deploy/hooks-lxc106.json" /etc/webhook/hooks.json systemctl restart webhook # webhook-lotus (:9001) serves the same hooks and is the one running THIS # script (Gitea posts matrix-deploy there), so restarting it now would kill # this deploy mid-run: restart it shortly after we exit instead. systemd-run --on-active=15s --unit="webhook-lotus-reload-$(date +%s)" systemctl restart webhook-lotus echo "✓ hooks.json deployed, webhook restarted (webhook-lotus in 15s)" fi if echo "$CHANGED" | grep -q '^systemd/cinny-upstream-check.cron'; then echo "Deploying cinny-upstream-check.cron..." cp "$REPO_DIR/systemd/cinny-upstream-check.cron" /etc/cron.d/cinny-upstream-check chmod 644 /etc/cron.d/cinny-upstream-check echo "✓ cron deployed" fi # Keep the installed copy of this script in step with the repo (the webhook # runs /usr/local/bin/matrix-deploy.sh, not the repo file). Checked with bash -n # first; takes effect from the next deploy. if echo "$CHANGED" | grep -q '^deploy/lxc106-cinny.sh'; then if bash -n "$REPO_DIR/deploy/lxc106-cinny.sh"; then cp "$REPO_DIR/deploy/lxc106-cinny.sh" /usr/local/bin/matrix-deploy.sh chmod +x /usr/local/bin/matrix-deploy.sh echo "✓ matrix-deploy.sh updated" else echo "✗ bash -n FAILED on lxc106-cinny.sh — keeping the installed copy" fi fi echo "=== $(date) === LXC106 deploy complete ==="