clear old assets, new ci/cd flow
This commit is contained in:
252
scripts/setup-pan.sh
Executable file
252
scripts/setup-pan.sh
Executable file
@@ -0,0 +1,252 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# ─── Kordant Scheduler — Pan Server Setup ─────────────────────
|
||||
# Usage:
|
||||
# bash scripts/setup-pan.sh # interactively
|
||||
# bash scripts/setup-pan.sh user@pan # interactively, remote
|
||||
# bash scripts/setup-pan.sh -u <url> -d <url> ...
|
||||
#
|
||||
# Flags:
|
||||
# -u, --gitea-url URL Gitea clone URL (skip prompt)
|
||||
# -d, --db-url URL Turso database URL (skip prompt)
|
||||
# -t, --db-token TOKEN Turso auth token (skip prompt)
|
||||
# -k, --hooks-dir DIR Gitea hooks directory (skip prompt; empty=skip hook)
|
||||
# --host HOST SSH host (default: pan)
|
||||
# -y, --non-interactive Skip all prompts (requires -u, -d, -t)
|
||||
# -h, --help Show this message
|
||||
|
||||
# ─── Defaults ───────────────────────────────────────────────────
|
||||
|
||||
PAN_HOST=""
|
||||
GITEA_URL=""
|
||||
DB_URL=""
|
||||
DB_TOKEN=""
|
||||
HOOKS_DIR=""
|
||||
NON_INTERACTIVE=false
|
||||
REPO_DIR="/opt/kordant"
|
||||
|
||||
# ─── Help ───────────────────────────────────────────────────────
|
||||
|
||||
usage() {
|
||||
sed -n 's/^# //p; s/^#$//p' "$0"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ─── Parse flags ────────────────────────────────────────────────
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-u|--gitea-url) GITEA_URL="$2"; shift 2 ;;
|
||||
-d|--db-url) DB_URL="$2"; shift 2 ;;
|
||||
-t|--db-token) DB_TOKEN="$2"; shift 2 ;;
|
||||
-k|--hooks-dir) HOOKS_DIR="$2"; shift 2 ;;
|
||||
--host) PAN_HOST="$2"; shift 2 ;;
|
||||
-y|--non-interactive) NON_INTERACTIVE=true; shift ;;
|
||||
-h|--help) usage ;;
|
||||
-*)
|
||||
echo "Unknown option: $1"
|
||||
usage
|
||||
;;
|
||||
*) PAN_HOST="${PAN_HOST:-$1}"; shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
PAN_HOST="${PAN_HOST:-pan}"
|
||||
|
||||
# ─── Remote detection ───────────────────────────────────────────
|
||||
|
||||
if [ "$(hostname)" != "pan" ] && [ "$(hostname -s 2>/dev/null)" != "pan" ]; then
|
||||
if [ -n "${SSH_CONNECTION:-}" ]; then
|
||||
echo "Already connected to pan via SSH."
|
||||
else
|
||||
echo "Not on pan. Connecting to $PAN_HOST via SSH..."
|
||||
# Rebuild the flag string to pass through
|
||||
FLAGS=""
|
||||
[ -n "$GITEA_URL" ] && FLAGS="$FLAGS -u '$GITEA_URL'"
|
||||
[ -n "$DB_URL" ] && FLAGS="$FLAGS -d '$DB_URL'"
|
||||
[ -n "$DB_TOKEN" ] && FLAGS="$FLAGS -t '$DB_TOKEN'"
|
||||
[ -n "$HOOKS_DIR" ] && FLAGS="$FLAGS -k '$HOOKS_DIR'"
|
||||
$NON_INTERACTIVE && FLAGS="$FLAGS -y"
|
||||
scp "$0" "${PAN_HOST}:/tmp/kordant-setup.sh"
|
||||
ssh -t "$PAN_HOST" "sudo bash /tmp/kordant-setup.sh $FLAGS && rm /tmp/kordant-setup.sh"
|
||||
exit $?
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "=== Kordant Scheduler Setup (running on pan) ==="
|
||||
|
||||
# ─── Step 1: Install prerequisites ─────────────────────────────
|
||||
|
||||
echo "--- Step 1: Checking prerequisites ---"
|
||||
|
||||
if ! command -v docker &>/dev/null; then
|
||||
echo "Installing Docker..."
|
||||
curl -fsSL https://get.docker.com | bash
|
||||
systemctl enable --now docker
|
||||
else
|
||||
echo "Docker already installed."
|
||||
fi
|
||||
|
||||
if ! docker compose version &>/dev/null; then
|
||||
echo "Installing Docker Compose plugin..."
|
||||
apt-get update && apt-get install -y docker-compose-plugin
|
||||
else
|
||||
echo "Docker Compose plugin already installed."
|
||||
fi
|
||||
|
||||
if ! command -v git &>/dev/null; then
|
||||
echo "Installing git..."
|
||||
apt-get update && apt-get install -y git
|
||||
else
|
||||
echo "Git already installed."
|
||||
fi
|
||||
|
||||
# ─── Step 2: Clone or pull the repo ────────────────────────────
|
||||
|
||||
echo "--- Step 2: Setting up repo at $REPO_DIR ---"
|
||||
|
||||
if [ ! -d "$REPO_DIR/.git" ]; then
|
||||
if [ -z "$GITEA_URL" ]; then
|
||||
if $NON_INTERACTIVE; then
|
||||
echo "❌ --gitea-url is required in non-interactive mode"
|
||||
exit 1
|
||||
fi
|
||||
while [ -z "$GITEA_URL" ]; do
|
||||
read -rp "Gitea clone URL (e.g. http://localhost:3000/kordant/kordant.git): " GITEA_URL
|
||||
done
|
||||
fi
|
||||
echo "Cloning $GITEA_URL ..."
|
||||
git clone "$GITEA_URL" "$REPO_DIR"
|
||||
cd "$REPO_DIR"
|
||||
else
|
||||
echo "Repo exists. Pulling latest..."
|
||||
cd "$REPO_DIR"
|
||||
git pull
|
||||
fi
|
||||
|
||||
# ─── Step 3: Create .env with credentials ──────────────────────
|
||||
|
||||
echo "--- Step 3: Environment file ---"
|
||||
|
||||
if [ ! -f "$REPO_DIR/.env" ]; then
|
||||
if [ -z "$DB_URL" ]; then
|
||||
if $NON_INTERACTIVE; then
|
||||
echo "❌ --db-url is required in non-interactive mode"
|
||||
exit 1
|
||||
fi
|
||||
read -rp " DATABASE_URL (e.g. libsql://kordant.turso.io): " DB_URL
|
||||
fi
|
||||
if [ -z "$DB_TOKEN" ]; then
|
||||
if $NON_INTERACTIVE; then
|
||||
echo "❌ --db-token is required in non-interactive mode"
|
||||
exit 1
|
||||
fi
|
||||
read -rsp " DATABASE_AUTH_TOKEN: " DB_TOKEN
|
||||
echo ""
|
||||
fi
|
||||
|
||||
cat > "$REPO_DIR/.env" << ENVEOF
|
||||
# ─── Kordant Scheduler Environment ─────────────────────────────
|
||||
# Turso database
|
||||
DATABASE_URL="${DB_URL}"
|
||||
DATABASE_AUTH_TOKEN="${DB_TOKEN}"
|
||||
|
||||
# Job queue (local Redis container)
|
||||
REDIS_URL="redis://redis:6379"
|
||||
|
||||
# Node environment
|
||||
NODE_ENV=production
|
||||
JOB_WORKER=true
|
||||
JOB_PRIMARY=true
|
||||
ENVEOF
|
||||
chmod 600 "$REPO_DIR/.env"
|
||||
echo "✅ Created $REPO_DIR/.env"
|
||||
else
|
||||
echo "$REPO_DIR/.env already exists, keeping it."
|
||||
fi
|
||||
|
||||
# ─── Step 4: Gitea post-receive hook ────────────────────────────
|
||||
|
||||
echo "--- Step 4: Gitea post-receive hook ---"
|
||||
|
||||
if [ -z "$HOOKS_DIR" ] && ! $NON_INTERACTIVE; then
|
||||
read -rp "Gitea repo hooks directory (or leave blank to skip): " HOOKS_DIR
|
||||
fi
|
||||
|
||||
if [ -n "$HOOKS_DIR" ]; then
|
||||
if [ ! -d "$HOOKS_DIR" ]; then
|
||||
echo " Directory not found: $HOOKS_DIR"
|
||||
if $NON_INTERACTIVE; then
|
||||
echo "❌ hooks-dir does not exist"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
HOOK_FILE="$HOOKS_DIR/post-receive"
|
||||
cat > "$HOOK_FILE" << 'HOOKEOF'
|
||||
#!/bin/bash
|
||||
cd /opt/kordant
|
||||
git pull origin main
|
||||
docker compose -f scheduler/docker-compose.yml up -d --build
|
||||
HOOKEOF
|
||||
chmod +x "$HOOK_FILE"
|
||||
echo "✅ Post-receive hook installed at $HOOK_FILE"
|
||||
fi
|
||||
else
|
||||
echo "Skipping post-receive hook."
|
||||
fi
|
||||
|
||||
# ─── Step 5: Create systemd service ────────────────────────────
|
||||
|
||||
echo "--- Step 5: Systemd service ---"
|
||||
|
||||
SERVICE_NAME="kordant-scheduler"
|
||||
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
|
||||
|
||||
if [ ! -f "$SERVICE_FILE" ]; then
|
||||
echo "Creating $SERVICE_FILE..."
|
||||
cat > "$SERVICE_FILE" << SERVICEEOF
|
||||
[Unit]
|
||||
Description=Kordant Background Job Scheduler
|
||||
After=docker.service network-online.target
|
||||
Wants=docker.service network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
WorkingDirectory=$REPO_DIR
|
||||
ExecStart=docker compose -f scheduler/docker-compose.yml up -d --build
|
||||
ExecStop=docker compose -f scheduler/docker-compose.yml down
|
||||
ExecReload=docker compose -f scheduler/docker-compose.yml pull && docker compose -f scheduler/docker-compose.yml up -d --build
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SERVICEEOF
|
||||
systemctl daemon-reload
|
||||
else
|
||||
echo "$SERVICE_FILE already exists."
|
||||
fi
|
||||
|
||||
# ─── Step 6: Start / restart the scheduler ─────────────────────
|
||||
|
||||
echo "--- Step 6: Starting scheduler ---"
|
||||
|
||||
systemctl enable "$SERVICE_NAME" 2>/dev/null || true
|
||||
|
||||
cd "$REPO_DIR"
|
||||
docker compose -f scheduler/docker-compose.yml pull 2>/dev/null || true
|
||||
docker compose -f scheduler/docker-compose.yml up -d --build
|
||||
|
||||
echo ""
|
||||
echo "=== Scheduler status ==="
|
||||
sleep 3
|
||||
docker compose -f scheduler/docker-compose.yml ps
|
||||
|
||||
echo ""
|
||||
echo "=== Kordant scheduler setup complete ==="
|
||||
echo " Repo: $REPO_DIR"
|
||||
echo " Logs: journalctl -u kordant-scheduler -f"
|
||||
echo " Shell: cd $REPO_DIR && docker compose -f scheduler/docker-compose.yml logs -f"
|
||||
echo " .env: $REPO_DIR/.env"
|
||||
Reference in New Issue
Block a user