Files

156 lines
5.2 KiB
Bash
Raw Permalink Normal View History

#!/usr/bin/env bash
# RemoteRig — Pi-side deploy script
# Deploys a new binary with backup, health-check, and automatic rollback.
#
# Usage:
# sudo ./deploy.sh [BINARY_PATH] [DEPLOY_PATH] [SERVICE_NAME]
#
# Defaults:
# BINARY_PATH = ./remoterig (new binary to deploy)
# DEPLOY_PATH = /opt/remoterig/remoterig
# SERVICE_NAME = remoterig
#
# Examples:
# # Deploy locally-built binary with defaults
# sudo ./deploy.sh ./remoterig
#
# # Custom paths
# sudo ./deploy.sh /tmp/remoterig-arm64 /opt/remoterig/remoterig remoterig
set -euo pipefail
# ---------------------------------------------------------------------------
# Args
# ---------------------------------------------------------------------------
BINARY="${1:-remoterig}"
DEPLOY_PATH="${2:-/opt/remoterig/remoterig}"
SERVICE="${3:-remoterig}"
TIMESTAMP="$(date +%Y%m%d%H%M%S)"
BACKUP="${DEPLOY_PATH}.${TIMESTAMP}.bak"
MAX_BACKUPS=3
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
info() { echo "[INFO] $*"; }
ok() { echo "[OK] $*"; }
fail() { echo "[FAIL] $*" >&2; }
# ---------------------------------------------------------------------------
# Pre-flight checks
# ---------------------------------------------------------------------------
if [ "$(id -u)" -ne 0 ]; then
echo "ERROR: must run as root (sudo ./deploy.sh ...)" >&2
exit 1
fi
if [ ! -f "${BINARY}" ]; then
fail "Binary not found: ${BINARY}"
exit 1
fi
echo "=============================================="
echo " RemoteRig Deploy"
echo " Binary: ${BINARY}"
echo " Deploy path: ${DEPLOY_PATH}"
echo " Service: ${SERVICE}"
echo " Timestamp: ${TIMESTAMP}"
echo "=============================================="
# ---------------------------------------------------------------------------
# 1. Backup existing binary
# ---------------------------------------------------------------------------
info "Backing up current binary..."
if [ -f "${DEPLOY_PATH}" ]; then
cp "${DEPLOY_PATH}" "${BACKUP}"
ok "Backed up to ${BACKUP}"
else
info "No existing binary at ${DEPLOY_PATH} — fresh install"
fi
# ---------------------------------------------------------------------------
# 2. Deploy new binary
# ---------------------------------------------------------------------------
info "Deploying new binary..."
cp "${BINARY}" "${DEPLOY_PATH}"
chmod +x "${DEPLOY_PATH}"
ok "Binary installed at ${DEPLOY_PATH}"
# ---------------------------------------------------------------------------
# 3. Reload systemd and restart service
# ---------------------------------------------------------------------------
info "Reloading systemd and restarting ${SERVICE}..."
systemctl daemon-reload
# Restart (or start if not running)
if systemctl is-active --quiet "${SERVICE}" 2>/dev/null; then
systemctl restart "${SERVICE}"
else
systemctl start "${SERVICE}"
fi
ok "Service restart issued"
# ---------------------------------------------------------------------------
# 4. Health check
# ---------------------------------------------------------------------------
info "Waiting 3s for service to stabilize..."
sleep 3
if systemctl is-active --quiet "${SERVICE}"; then
ok "${SERVICE} is active — deploy successful"
# Optional: curl health endpoint
if command -v curl >/dev/null 2>&1; then
HEALTH_URL="http://localhost:8080/health"
if curl -sf --max-time 3 "${HEALTH_URL}" >/dev/null 2>&1; then
ok "Health check passed: ${HEALTH_URL}"
else
info "Health endpoint not reachable (may need more startup time)"
fi
fi
else
fail "${SERVICE} is NOT active — rolling back"
# -----------------------------------------------------------------------
# 5. Rollback on failure
# -----------------------------------------------------------------------
if [ -f "${BACKUP}" ]; then
info "Restoring backup: ${BACKUP}"
cp "${BACKUP}" "${DEPLOY_PATH}"
chmod +x "${DEPLOY_PATH}"
systemctl restart "${SERVICE}" 2>/dev/null || true
sleep 2
if systemctl is-active --quiet "${SERVICE}"; then
ok "Rollback successful — previous binary restored and service is active"
else
fail "Rollback failed — service still not active"
echo "Check logs: journalctl -u ${SERVICE} -n 50" >&2
exit 1
fi
else
fail "No backup available — cannot roll back"
echo "Check logs: journalctl -u ${SERVICE} -n 50" >&2
exit 1
fi
fi
# ---------------------------------------------------------------------------
# 6. Cleanup old backups (keep last N)
# ---------------------------------------------------------------------------
info "Cleaning up old backups (keeping last ${MAX_BACKUPS})..."
DEPLOY_DIR="$(dirname "${DEPLOY_PATH}")"
BASE_NAME="$(basename "${DEPLOY_PATH}")"
# List backups, skip current, keep last MAX_BACKUPS, delete the rest
ls -1t "${DEPLOY_DIR}/${BASE_NAME}."*.bak 2>/dev/null | \
tail -n +$((MAX_BACKUPS + 1)) | \
while IFS= read -r old_backup; do
rm -f "${old_backup}"
info "Removed old backup: $(basename "${old_backup}")"
done
ok "Deploy complete — ${MAX_BACKUPS} backups retained"
echo ""