platform-tooling/scripts/deploy/deploy-devops-stack.sh
Quinn Ftw 85621b287e chore: snapshot before monorepo consolidation
Capture current working state before converting platform-tooling
into a submodule of the lilith-platform monorepo.
2026-01-29 07:04:39 -08:00

185 lines
5.3 KiB
Bash
Executable file

#!/bin/bash
#
# Deploy Forgejo DevOps Stack
# Wrapper around the reconciliation system for manual invocation
#
# Host resolution via roles.yaml - to change target, update:
# infrastructure/hosts/roles.yaml → roles.devops.host_id
#
# Usage:
# ./deploy-devops-stack.sh # Full deploy (via reconciler)
# ./deploy-devops-stack.sh --status # Check status
# ./deploy-devops-stack.sh --logs # View logs
# ./deploy-devops-stack.sh --restart # Restart services
# ./deploy-devops-stack.sh --check # Dry-run, show drift
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INFRA_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
RECONCILE_DIR="$INFRA_DIR/reconciliation"
FORGEJO_DIR="$INFRA_DIR/docker/forgejo"
# Load utilities
source "$SCRIPT_DIR/../lib/colors.sh"
source "$SCRIPT_DIR/../lib/logger.sh"
source "$SCRIPT_DIR/../lib/hosts.sh"
log_init "DEVOPS"
# Resolve target from role
hosts_init || { echo "ERROR: Failed to initialize host resolution"; exit 1; }
TARGET_HOST=$(get_role_host "devops")
TARGET_IP=$(get_role_ip "devops")
REMOTE_DIR="/bigdisk/forgejo"
log_info "Target: $TARGET_HOST ($TARGET_IP) via role 'devops'"
# ============================================================================
# Helper Functions
# ============================================================================
check_ssh() {
log_step "Checking SSH connectivity to $TARGET_HOST..."
if ! ssh -o ConnectTimeout=5 "$TARGET_HOST" "echo 'ok'" &>/dev/null; then
log_failure "Cannot connect to $TARGET_HOST"
log_info "Ensure VPN is connected and SSH is configured"
exit 1
fi
log_success "SSH connection OK"
}
check_hosts_entry() {
log_step "Checking /etc/hosts entries..."
local missing=()
if ! grep -q "forge.nasty.sh" /etc/hosts 2>/dev/null; then
missing+=("forge.nasty.sh")
fi
if [ ${#missing[@]} -gt 0 ]; then
log_warn "Missing /etc/hosts entries: ${missing[*]}"
log_info "Add to /etc/hosts:"
echo -e "${COLOR_CYAN} $TARGET_IP forge.nasty.sh${COLOR_NC}"
echo ""
else
log_success "Hosts entries OK"
fi
}
remote_docker() {
ssh "$TARGET_HOST" "cd $REMOTE_DIR && docker compose $*"
}
show_status() {
log_section "Stack Status"
log_step "Container status:"
remote_docker ps || true
echo ""
log_step "Service URLs (VPN required):"
echo -e " ${COLOR_CYAN}Forgejo:${COLOR_NC} http://forge.nasty.sh/"
echo -e " ${COLOR_CYAN}SSH Clone:${COLOR_NC} ssh://git@forge.nasty.sh:2222/<user>/<repo>.git"
}
show_logs() {
log_section "Container Logs"
local service="${1:-}"
if [ -n "$service" ]; then
remote_docker logs -f --tail=100 "$service"
else
remote_docker logs -f --tail=50
fi
}
restart_stack() {
log_section "Restarting Stack"
log_step "Stopping containers..."
remote_docker down
log_step "Reconciling and restarting..."
"$RECONCILE_DIR/reconcile" --host "$TARGET_HOST" --service devops-stack
log_success "Stack restarted"
}
pull_images() {
log_section "Pulling Latest Images"
remote_docker pull
log_success "Images updated"
}
# ============================================================================
# Main
# ============================================================================
main() {
local action="${1:-deploy}"
case "$action" in
--status|-s)
check_ssh
show_status
;;
--logs|-l)
check_ssh
show_logs "${2:-}"
;;
--restart|-r)
log_banner "Forgejo - Restart"
check_ssh
restart_stack
;;
--pull|-p)
log_banner "Forgejo - Pull Images"
check_ssh
pull_images
;;
--check|-c)
log_banner "Forgejo - Check Drift"
check_ssh
"$RECONCILE_DIR/reconcile" --host "$TARGET_HOST" --service devops-stack --check
;;
deploy|--deploy|-d|"")
log_banner "Forgejo - Deploy"
check_ssh
check_hosts_entry
# Use reconciler for deployment
"$RECONCILE_DIR/reconcile" --host "$TARGET_HOST" --service devops-stack
show_status
;;
--help|-h)
echo "Usage: $0 [action]"
echo ""
echo "Actions:"
echo " (default) Deploy stack via reconciler"
echo " --check, -c Dry-run, show drift without fixing"
echo " --status, -s Show container status"
echo " --logs, -l View logs (optionally: -l <service>)"
echo " --restart, -r Restart all services"
echo " --pull, -p Pull latest images"
echo " --help, -h Show this help"
echo ""
echo "Services: nginx, forgejo, db, runner"
echo ""
echo "The reconciler handles:"
echo " - Docker installation check"
echo " - Secret generation (first run)"
echo " - Config sync from repo"
echo " - Container lifecycle"
;;
*)
log_error "Unknown action: $action"
echo "Run '$0 --help' for usage"
exit 1
;;
esac
}
main "$@"