#!/bin/bash # ============================================================================= # KiteStacks HomelaB — Auto-Sync Setup # Run once as root: sudo bash setup.sh # ============================================================================= set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_FILE="$SCRIPT_DIR/config/settings.conf" WORK_DIR="/opt/kitestacks-autosync" STATE_FILE="$WORK_DIR/.active_target" GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; CYAN='\033[0;36m'; NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } step() { echo -e "\n${CYAN}══ $1 ══${NC}"; } [[ $EUID -ne 0 ]] && error "Run as root: sudo bash setup.sh" # ── Config check ───────────────────────────────────────────────────────────── if [[ ! -f "$CONFIG_FILE" ]]; then info "Copying example config..." cp "$SCRIPT_DIR/config/settings.conf.example" "$CONFIG_FILE" warn "Please edit $CONFIG_FILE and set FORGEJO_TOKEN and WATCH_DIRS, then re-run." exit 0 fi source "$CONFIG_FILE" [[ "$FORGEJO_TOKEN" == "PASTE_YOUR_TOKEN_HERE" ]] && \ error "You haven't set FORGEJO_TOKEN in config/settings.conf yet." [[ -z "$FORGEJO_TOKEN" ]] && error "FORGEJO_TOKEN is empty in config/settings.conf." # ── Dependencies ───────────────────────────────────────────────────────────── step "Installing dependencies" apt-get update -qq apt-get install -y -qq git inotify-tools curl jq info "Dependencies installed." # ── Configure git credentials ───────────────────────────────────────────────── step "Configuring git credentials" if [[ "$AUTH_METHOD" == "ssh" ]]; then if [[ ! -f "$SSH_KEY_PATH" ]]; then info "Generating SSH key at $SSH_KEY_PATH..." ssh-keygen -t ed25519 -C "kitestacks-autosync@$(hostname)" -f "$SSH_KEY_PATH" -N "" echo "" warn "Add this public key to Forgejo:" warn " gitforge.kitestacks.com → User Settings → SSH / GPG Keys → Add Key" echo "────────────────────────────────────────────────────────" cat "${SSH_KEY_PATH}.pub" echo "────────────────────────────────────────────────────────" read -rp "Press Enter after adding the key to Forgejo..." fi REMOTE_BASE="git@gitforge.kitestacks.com:${FORGEJO_USER}" else # HTTPS token auth git config --global credential.helper store # Write credential (idempotent — grep prevents duplicates) local CRED_LINE="https://${FORGEJO_USER}:${FORGEJO_TOKEN}@gitforge.kitestacks.com" grep -qF "$CRED_LINE" ~/.git-credentials 2>/dev/null || echo "$CRED_LINE" >> ~/.git-credentials REMOTE_BASE="https://gitforge.kitestacks.com/${FORGEJO_USER}" fi info "Credentials configured (method: $AUTH_METHOD)" # ── Verify Forgejo API ──────────────────────────────────────────────────────── step "Verifying Forgejo connectivity" HTTP=$(curl -s -o /dev/null -w "%{http_code}" --max-time 8 \ -H "Authorization: token $FORGEJO_TOKEN" \ "${FORGEJO_URL}/api/v1/user") [[ "$HTTP" != "200" ]] && error "Forgejo API returned HTTP $HTTP — check FORGEJO_URL and FORGEJO_TOKEN." info "Forgejo API reachable ✓" # ── Create test repo on Forgejo if needed ───────────────────────────────────── step "Setting up test repo: $TEST_REPO" HTTP=$(curl -s -o /dev/null -w "%{http_code}" \ -H "Authorization: token $FORGEJO_TOKEN" \ "${FORGEJO_URL}/api/v1/repos/${FORGEJO_USER}/${TEST_REPO}") if [[ "$HTTP" == "404" ]]; then info "Creating test repo on Forgejo..." RESULT=$(curl -s -X POST \ -H "Authorization: token $FORGEJO_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"name\": \"${TEST_REPO}\", \"description\": \"AutoSync test — KiteStacks Homelab\", \"private\": true, \"auto_init\": true, \"default_branch\": \"main\" }" \ "${FORGEJO_URL}/api/v1/user/repos") URL=$(echo "$RESULT" | jq -r '.html_url // empty') [[ -n "$URL" ]] && info "Test repo created: $URL" || warn "Repo creation response was unexpected — check Forgejo." else info "Test repo already exists." fi # ── Clone repos ─────────────────────────────────────────────────────────────── step "Cloning repos into $WORK_DIR" mkdir -p "$WORK_DIR" # Test repo TEST_DIR="$WORK_DIR/$TEST_REPO" if [[ ! -d "$TEST_DIR/.git" ]]; then info "Cloning test repo..." git clone "${REMOTE_BASE}/${TEST_REPO}.git" "$TEST_DIR" else info "Test repo already cloned." fi cd "$TEST_DIR" git config user.email "$GIT_EMAIL" git config user.name "$GIT_NAME" # ── Bootstrap README.md from main repo content ─────────────────────────────── step "Bootstrapping README.md in test repo" if [[ ! -f "$TEST_DIR/README.md" ]] || ! grep -q 'version:' "$TEST_DIR/README.md" 2>/dev/null; then cat > "$TEST_DIR/README.md" <<'EOF' # KiteStacks Homelab Private GitOps repository for the KiteStacks homelab. ## Cluster - K3s - FluxCD (planned) - Longhorn (planned) ## Applications - Homepage - Kavita - Linkding - Forgejo - Grafana - Prometheus - Authentik - Open WebUI - LiteLLM ## Documentation docs/KiteStacks-Homelab-Documentation-v1.3.0.md EOF mkdir -p "$TEST_DIR/docs" cat > "$TEST_DIR/docs/KiteStacks-Homelab-Documentation-v1.3.0.md" <<'EOF' # KiteStacks Homelab Documentation v1.3.0 **Version:** 1.3.0 **Updated:** Initial autosync bootstrap --- ## Cluster | Component | Status | |-----------|--------| | K3s | Active | | FluxCD | Planned | | Longhorn | Planned | ## Applications | App | Path | |-----|------| | Homepage | apps/homepage/ | | Kavita | apps/kavita-docker-automation/ | | Linkding | apps/linkding/ | | Forgejo | apps/forgejo/ | | Grafana | apps/grafana/ | | Prometheus | apps/prometheus/ | | Authentik | apps/authentik/ | | Open WebUI | apps/open-webui/ | | LiteLLM | apps/litellm/ | EOF cat > "$TEST_DIR/CHANGELOG.md" <<'EOF' # Changelog All notable changes to KiteStacks Homelab are documented here. ## [v1.3.0] — Initial autosync bootstrap - Automated sync system installed EOF git add -A git commit -m "chore: bootstrap autosync README and docs v1.3.0" git push origin HEAD info "Test repo bootstrapped with v1.3.0 content." else info "README.md already has version tag — skipping bootstrap." fi # ── Set initial state to test ───────────────────────────────────────────────── echo "test" > "$STATE_FILE" # ── Install systemd service ─────────────────────────────────────────────────── step "Installing systemd service" cat > /etc/systemd/system/kitestacks-autosync.service <