Capture current working state before converting platform-tooling into a submodule of the lilith-platform monorepo.
185 lines
5.3 KiB
Bash
Executable file
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 "$@"
|