#!/usr/bin/env bash set -euo pipefail # ============================================================================= # preflight.sh — Validate everything before running migration phases # Installs nothing. Exits 0 only if ALL checks pass. # ============================================================================= SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "${SCRIPT_DIR}/lib/common.sh" log_info "=== Preflight Checks ===" PASS_COUNT=0 FAIL_COUNT=0 # --------------------------------------------------------------------------- # Check helper — runs a check, tracks pass/fail # --------------------------------------------------------------------------- check() { local num="$1" description="$2" shift 2 if "$@" 2>/dev/null; then log_success "[${num}] ${description}" PASS_COUNT=$((PASS_COUNT + 1)) else log_error "[${num}] FAIL: ${description}" FAIL_COUNT=$((FAIL_COUNT + 1)) fi } # --------------------------------------------------------------------------- # Check 1: .env exists # --------------------------------------------------------------------------- check_env_exists() { [[ -f "${SCRIPT_DIR}/.env" ]] } check 1 ".env file exists" check_env_exists if [[ ! -f "${SCRIPT_DIR}/.env" ]]; then log_error " → .env not found. Copy .env.example to .env and fill in values." log_error " → Or run: setup/configure_env.sh" # Can't continue without .env — run remaining checks but they'll mostly fail fi # --------------------------------------------------------------------------- # Check 2: runners.conf exists # --------------------------------------------------------------------------- check_runners_conf() { [[ -f "${SCRIPT_DIR}/runners.conf" ]] } check 2 "runners.conf file exists" check_runners_conf if [[ ! -f "${SCRIPT_DIR}/runners.conf" ]]; then log_error " → runners.conf not found. Copy runners.conf.example to runners.conf." fi # --------------------------------------------------------------------------- # Load env for remaining checks (may fail if .env missing) # --------------------------------------------------------------------------- if [[ -f "${SCRIPT_DIR}/.env" ]]; then load_env fi # --------------------------------------------------------------------------- # Check 3: Required .env vars # --------------------------------------------------------------------------- REQUIRED_VARS=( UNRAID_IP UNRAID_SSH_USER UNRAID_GITEA_DATA_PATH FEDORA_IP FEDORA_SSH_USER FEDORA_GITEA_DATA_PATH GITEA_ADMIN_USER GITEA_ADMIN_PASSWORD GITEA_ADMIN_EMAIL GITEA_ORG_NAME GITEA_INSTANCE_NAME GITEA_DOMAIN GITEA_INTERNAL_URL GITEA_BACKUP_INTERNAL_URL BACKUP_STORAGE_PATH GITHUB_USERNAME GITHUB_TOKEN REPO_1_NAME REPO_2_NAME REPO_3_NAME GITHUB_MIRROR_TOKEN NGINX_CONTAINER_NAME NGINX_CONF_PATH SSL_EMAIL ) check_required_vars() { local missing=0 for var in "${REQUIRED_VARS[@]}"; do if [[ -z "${!var:-}" ]]; then log_error " → Missing required var: $var" missing=1 fi done return $missing } check 3 "All required .env vars are set" check_required_vars # --------------------------------------------------------------------------- # Check 4: SSH to Unraid # --------------------------------------------------------------------------- check_ssh_unraid() { ssh_check UNRAID } check 4 "SSH to Unraid (${UNRAID_IP:-})" check_ssh_unraid if [[ $FAIL_COUNT -gt 0 ]] && ! ssh_check UNRAID 2>/dev/null; then log_error " → Cannot SSH to Unraid. Run setup/unraid.sh or check SSH config." fi # --------------------------------------------------------------------------- # Check 5: SSH to Fedora # --------------------------------------------------------------------------- check_ssh_fedora() { ssh_check FEDORA } check 5 "SSH to Fedora (${FEDORA_IP:-})" check_ssh_fedora if ! ssh_check FEDORA 2>/dev/null; then log_error " → Cannot SSH to Fedora. Run setup/fedora.sh or check SSH config." fi # --------------------------------------------------------------------------- # Check 6: Docker on Unraid # --------------------------------------------------------------------------- check_docker_unraid() { ssh_exec UNRAID "docker --version" &>/dev/null } check 6 "Docker available on Unraid" check_docker_unraid if ! check_docker_unraid 2>/dev/null; then log_error " → Docker not found on Unraid. Run setup/unraid.sh." fi # --------------------------------------------------------------------------- # Check 7: Docker on Fedora # --------------------------------------------------------------------------- check_docker_fedora() { ssh_exec FEDORA "docker --version" &>/dev/null } check 7 "Docker available on Fedora" check_docker_fedora if ! check_docker_fedora 2>/dev/null; then log_error " → Docker not found on Fedora. Run setup/fedora.sh." fi # --------------------------------------------------------------------------- # Check 8: docker-compose on Unraid # --------------------------------------------------------------------------- check_compose_unraid() { ssh_exec UNRAID "docker compose version" &>/dev/null || ssh_exec UNRAID "docker-compose --version" &>/dev/null } check 8 "docker-compose available on Unraid" check_compose_unraid if ! check_compose_unraid 2>/dev/null; then log_error " → docker-compose not found on Unraid. Run setup/unraid.sh." fi # --------------------------------------------------------------------------- # Check 9: docker-compose on Fedora # --------------------------------------------------------------------------- check_compose_fedora() { ssh_exec FEDORA "docker compose version" &>/dev/null || ssh_exec FEDORA "docker-compose --version" &>/dev/null } check 9 "docker-compose available on Fedora" check_compose_fedora if ! check_compose_fedora 2>/dev/null; then log_error " → docker-compose not found on Fedora. Run setup/fedora.sh." fi # --------------------------------------------------------------------------- # Check 10: Port free on Unraid # --------------------------------------------------------------------------- check_port_unraid() { local port="${UNRAID_GITEA_PORT:-3000}" ! ssh_exec UNRAID "ss -tlnp | grep -q ':${port} '" 2>/dev/null } check 10 "Port ${UNRAID_GITEA_PORT:-3000} free on Unraid" check_port_unraid if ! check_port_unraid 2>/dev/null; then log_error " → Port ${UNRAID_GITEA_PORT:-3000} already in use on Unraid." fi # --------------------------------------------------------------------------- # Check 11: Port free on Fedora # --------------------------------------------------------------------------- check_port_fedora() { local port="${FEDORA_GITEA_PORT:-3000}" ! ssh_exec FEDORA "ss -tlnp | grep -q ':${port} '" 2>/dev/null } check 11 "Port ${FEDORA_GITEA_PORT:-3000} free on Fedora" check_port_fedora if ! check_port_fedora 2>/dev/null; then log_error " → Port ${FEDORA_GITEA_PORT:-3000} already in use on Fedora." fi # --------------------------------------------------------------------------- # Check 12: DNS resolves # --------------------------------------------------------------------------- check_dns() { local resolved resolved=$(dig +short "${GITEA_DOMAIN:-}" 2>/dev/null | head -1) [[ "$resolved" == "${UNRAID_IP:-}" ]] } check 12 "DNS: ${GITEA_DOMAIN:-} resolves to ${UNRAID_IP:-}" check_dns if ! check_dns 2>/dev/null; then log_error " → ${GITEA_DOMAIN:-GITEA_DOMAIN} does not resolve to ${UNRAID_IP:-UNRAID_IP}." fi # --------------------------------------------------------------------------- # Check 13: GitHub token valid # --------------------------------------------------------------------------- check_github_token() { [[ -n "${GITHUB_TOKEN:-}" ]] && curl -sf -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/user -o /dev/null } check 13 "GitHub token valid" check_github_token if ! check_github_token 2>/dev/null; then log_error " → GitHub token invalid. Check GITHUB_TOKEN in .env." fi # --------------------------------------------------------------------------- # Check 14: GitHub repos exist # --------------------------------------------------------------------------- check_github_repos() { local all_ok=0 for var in REPO_1_NAME REPO_2_NAME REPO_3_NAME; do local repo="${!var:-}" if [[ -z "$repo" ]]; then continue fi if ! curl -sf -H "Authorization: token ${GITHUB_TOKEN:-}" "https://api.github.com/repos/${GITHUB_USERNAME:-}/${repo}" -o /dev/null 2>/dev/null; then log_error " → GitHub repo ${repo} not found under ${GITHUB_USERNAME:-}" all_ok=1 fi done return $all_ok } check 14 "All GitHub repos exist" check_github_repos # --------------------------------------------------------------------------- # Check 15: Nginx running on Unraid # --------------------------------------------------------------------------- check_nginx() { local status status=$(ssh_exec UNRAID "docker ps --filter name=${NGINX_CONTAINER_NAME:-nginx} --format '{{.Status}}'" 2>/dev/null) [[ "$status" == *"Up"* ]] } check 15 "Nginx container '${NGINX_CONTAINER_NAME:-}' running on Unraid" check_nginx if ! check_nginx 2>/dev/null; then log_error " → Nginx container '${NGINX_CONTAINER_NAME:-}' not running on Unraid." fi # --------------------------------------------------------------------------- # Check 16: Nginx conf dir writable # --------------------------------------------------------------------------- check_nginx_conf() { ssh_exec UNRAID "test -w '${NGINX_CONF_PATH:-/nonexistent}'" 2>/dev/null } check 16 "Nginx config path writable (${NGINX_CONF_PATH:-})" check_nginx_conf if ! check_nginx_conf 2>/dev/null; then log_error " → Nginx config path ${NGINX_CONF_PATH:-} not writable on Unraid." fi # --------------------------------------------------------------------------- # Summary # --------------------------------------------------------------------------- printf '\n' log_info "Results: ${PASS_COUNT} passed, ${FAIL_COUNT} failed (out of 16 checks)" if [[ $FAIL_COUNT -gt 0 ]]; then log_error "Preflight FAILED — fix the issues above before proceeding." exit 1 else log_success "All preflight checks passed. Ready to run migration phases." exit 0 fi