feat: add Phase 1 — Gitea on Unraid
- phase1_gitea_unraid.sh: 9-step deploy (dirs, docker-compose, app.ini, container start, wait, admin user, API token, save to .env, create org). Every step has idempotency check — running twice changes nothing. - phase1_post_check.sh: 5 independent verification checks - phase1_teardown.sh: stop container + optionally remove data, with prompts Also adds inline comments to lib/common.sh and preflight.sh explaining WHY decisions were made (SSH flags, API tmpfile pattern, port checks, etc.) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -69,6 +69,9 @@ _project_root() {
|
|||||||
cd "$(dirname "${BASH_SOURCE[1]:-${BASH_SOURCE[0]}}")/.." && pwd
|
cd "$(dirname "${BASH_SOURCE[1]:-${BASH_SOURCE[0]}}")/.." && pwd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Source .env and export all variables.
|
||||||
|
# Uses set -a/+a to auto-export every variable defined in the file,
|
||||||
|
# making them available to child processes (envsubst, ssh, etc.).
|
||||||
load_env() {
|
load_env() {
|
||||||
local env_file
|
local env_file
|
||||||
env_file="$(_project_root)/.env"
|
env_file="$(_project_root)/.env"
|
||||||
@@ -77,10 +80,10 @@ load_env() {
|
|||||||
log_error "Copy .env.example to .env and populate values."
|
log_error "Copy .env.example to .env and populate values."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
set -a
|
set -a # auto-export all vars defined below
|
||||||
# shellcheck source=/dev/null
|
# shellcheck source=/dev/null
|
||||||
source "$env_file"
|
source "$env_file"
|
||||||
set +a
|
set +a # stop auto-exporting
|
||||||
}
|
}
|
||||||
|
|
||||||
save_env_var() {
|
save_env_var() {
|
||||||
@@ -124,10 +127,15 @@ require_vars() {
|
|||||||
# SSH
|
# SSH
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Execute a command on a remote host via SSH.
|
||||||
|
# Uses indirect variable expansion: ssh_exec "UNRAID" "ls" reads
|
||||||
|
# UNRAID_IP, UNRAID_SSH_USER, UNRAID_SSH_PORT from the environment.
|
||||||
|
# This pattern avoids passing connection details to every function call.
|
||||||
ssh_exec() {
|
ssh_exec() {
|
||||||
local host_key="$1"; shift
|
local host_key="$1"; shift
|
||||||
local cmd="$*"
|
local cmd="$*"
|
||||||
|
|
||||||
|
# Indirect expansion: ${!ip_var} dereferences the variable named by $ip_var
|
||||||
local ip_var="${host_key}_IP"
|
local ip_var="${host_key}_IP"
|
||||||
local user_var="${host_key}_SSH_USER"
|
local user_var="${host_key}_SSH_USER"
|
||||||
local port_var="${host_key}_SSH_PORT"
|
local port_var="${host_key}_SSH_PORT"
|
||||||
@@ -141,6 +149,9 @@ ssh_exec() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ConnectTimeout: fail fast if host is unreachable (don't hang for 60s)
|
||||||
|
# StrictHostKeyChecking=accept-new: auto-accept new hosts but reject changed keys
|
||||||
|
# BatchMode=yes: never prompt for password (fail if key auth doesn't work)
|
||||||
ssh -o ConnectTimeout=10 \
|
ssh -o ConnectTimeout=10 \
|
||||||
-o StrictHostKeyChecking=accept-new \
|
-o StrictHostKeyChecking=accept-new \
|
||||||
-o BatchMode=yes \
|
-o BatchMode=yes \
|
||||||
@@ -181,6 +192,10 @@ scp_to() {
|
|||||||
# API wrappers — return JSON on stdout, logs go to stderr
|
# API wrappers — return JSON on stdout, logs go to stderr
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Internal API call helper. Writes response to a tmpfile so we can separate
|
||||||
|
# the HTTP status code (via curl -w) from the response body. This ensures
|
||||||
|
# JSON output goes to stdout and error messages go to stderr — callers can
|
||||||
|
# pipe JSON through jq without log noise contaminating the output.
|
||||||
_api_call() {
|
_api_call() {
|
||||||
local base_url="$1" token="$2" method="$3" path="$4" data="${5:-}"
|
local base_url="$1" token="$2" method="$3" path="$4" data="${5:-}"
|
||||||
|
|
||||||
|
|||||||
171
phase1_gitea_unraid.sh
Executable file
171
phase1_gitea_unraid.sh
Executable file
@@ -0,0 +1,171 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# phase1_gitea_unraid.sh — Deploy Gitea on Unraid
|
||||||
|
# Produces: Running Gitea instance, admin user, API token in .env, org created
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
source "${SCRIPT_DIR}/lib/common.sh"
|
||||||
|
|
||||||
|
load_env
|
||||||
|
require_vars UNRAID_IP UNRAID_SSH_USER UNRAID_SSH_PORT \
|
||||||
|
UNRAID_GITEA_PORT UNRAID_GITEA_SSH_PORT UNRAID_GITEA_DATA_PATH \
|
||||||
|
GITEA_ADMIN_USER GITEA_ADMIN_PASSWORD GITEA_ADMIN_EMAIL \
|
||||||
|
GITEA_ORG_NAME GITEA_INSTANCE_NAME \
|
||||||
|
GITEA_DB_TYPE GITEA_VERSION \
|
||||||
|
GITEA_INTERNAL_URL GITEA_DOMAIN
|
||||||
|
|
||||||
|
phase_header 1 "Gitea on Unraid"
|
||||||
|
|
||||||
|
# Alias for shorter references in template rendering.
|
||||||
|
# Templates use $DATA_PATH as a generic variable name so the same template
|
||||||
|
# works for both Unraid (Phase 1) and Fedora (Phase 2).
|
||||||
|
DATA_PATH="$UNRAID_GITEA_DATA_PATH"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Step 1: Create data directories
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
log_step 1 "Creating data directories on Unraid..."
|
||||||
|
if ssh_exec UNRAID "test -d '${DATA_PATH}/data'"; then
|
||||||
|
log_info "Data directory already exists — skipping"
|
||||||
|
else
|
||||||
|
ssh_exec UNRAID "mkdir -p '${DATA_PATH}/data' '${DATA_PATH}/config'"
|
||||||
|
log_success "Data directories created"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Step 2: Render + SCP docker-compose file
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
log_step 2 "Deploying docker-compose.yml..."
|
||||||
|
if ssh_exec UNRAID "test -f '${DATA_PATH}/docker-compose.yml'"; then
|
||||||
|
log_info "docker-compose.yml already exists — skipping"
|
||||||
|
else
|
||||||
|
TMPFILE=$(mktemp)
|
||||||
|
# Set variables for template
|
||||||
|
export DATA_PATH GITEA_PORT="${UNRAID_GITEA_PORT}" GITEA_SSH_PORT="${UNRAID_GITEA_SSH_PORT}"
|
||||||
|
render_template "${SCRIPT_DIR}/templates/docker-compose-gitea.yml.tpl" "$TMPFILE"
|
||||||
|
scp_to UNRAID "$TMPFILE" "${DATA_PATH}/docker-compose.yml"
|
||||||
|
rm -f "$TMPFILE"
|
||||||
|
log_success "docker-compose.yml deployed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Step 3: Render + SCP app.ini
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
log_step 3 "Deploying app.ini..."
|
||||||
|
if ssh_exec UNRAID "test -f '${DATA_PATH}/config/app.ini'"; then
|
||||||
|
log_info "app.ini already exists — skipping"
|
||||||
|
else
|
||||||
|
TMPFILE=$(mktemp)
|
||||||
|
# Generate a random secret key for this instance
|
||||||
|
GITEA_SECRET_KEY=$(openssl rand -hex 32)
|
||||||
|
export GITEA_SECRET_KEY
|
||||||
|
render_template "${SCRIPT_DIR}/templates/app.ini.tpl" "$TMPFILE"
|
||||||
|
scp_to UNRAID "$TMPFILE" "${DATA_PATH}/config/app.ini"
|
||||||
|
rm -f "$TMPFILE"
|
||||||
|
log_success "app.ini deployed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Step 4: Start Gitea container
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
log_step 4 "Starting Gitea container..."
|
||||||
|
CONTAINER_STATUS=$(ssh_exec UNRAID "docker ps --filter name=gitea --format '{{.Status}}'" 2>/dev/null || true)
|
||||||
|
if [[ "$CONTAINER_STATUS" == *"Up"* ]]; then
|
||||||
|
log_info "Gitea container already running — skipping"
|
||||||
|
else
|
||||||
|
# Try modern "docker compose" first (plugin), fall back to standalone "docker-compose"
|
||||||
|
ssh_exec UNRAID "cd '${DATA_PATH}' && docker compose up -d 2>/dev/null || docker-compose up -d"
|
||||||
|
log_success "Gitea container started"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Step 5: Wait for Gitea to be ready
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
log_step 5 "Waiting for Gitea to be ready..."
|
||||||
|
wait_for_http "${GITEA_INTERNAL_URL}/api/v1/version" 120
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Step 6: Create admin user
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
log_step 6 "Creating admin user..."
|
||||||
|
if curl -sf -u "${GITEA_ADMIN_USER}:${GITEA_ADMIN_PASSWORD}" "${GITEA_INTERNAL_URL}/api/v1/user" -o /dev/null 2>/dev/null; then
|
||||||
|
log_info "Admin user already exists — skipping"
|
||||||
|
else
|
||||||
|
# Create admin via CLI inside the container (not the API) because no API
|
||||||
|
# token exists yet at this point. || true prevents set -e from exiting if
|
||||||
|
# the user was partially created in a previous interrupted run.
|
||||||
|
ssh_exec UNRAID "docker exec gitea gitea admin user create \
|
||||||
|
--username '${GITEA_ADMIN_USER}' \
|
||||||
|
--password '${GITEA_ADMIN_PASSWORD}' \
|
||||||
|
--email '${GITEA_ADMIN_EMAIL}' \
|
||||||
|
--admin \
|
||||||
|
--must-change-password=false" || true
|
||||||
|
# Verify with API call — this is the real success check
|
||||||
|
if curl -sf -u "${GITEA_ADMIN_USER}:${GITEA_ADMIN_PASSWORD}" "${GITEA_INTERNAL_URL}/api/v1/user" -o /dev/null 2>/dev/null; then
|
||||||
|
log_success "Admin user created"
|
||||||
|
else
|
||||||
|
log_error "Failed to create admin user"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Step 7+8: Generate API token and save to .env
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
log_step 7 "Generating API token..."
|
||||||
|
if [[ -n "${GITEA_ADMIN_TOKEN:-}" ]]; then
|
||||||
|
# Verify existing token works
|
||||||
|
if curl -sf -H "Authorization: token ${GITEA_ADMIN_TOKEN}" "${GITEA_INTERNAL_URL}/api/v1/user" -o /dev/null 2>/dev/null; then
|
||||||
|
log_info "API token already exists and is valid — skipping"
|
||||||
|
else
|
||||||
|
log_warn "Existing token is invalid — generating new one"
|
||||||
|
GITEA_ADMIN_TOKEN=""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${GITEA_ADMIN_TOKEN:-}" ]]; then
|
||||||
|
# Generate token using basic auth (username:password).
|
||||||
|
# The .sha1 field in the response contains the full token — this is the
|
||||||
|
# ONLY time it's returned, so we must save it immediately.
|
||||||
|
TOKEN_RESPONSE=$(curl -sf -u "${GITEA_ADMIN_USER}:${GITEA_ADMIN_PASSWORD}" \
|
||||||
|
-X POST \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"name":"migration-token","scopes":["all"]}' \
|
||||||
|
"${GITEA_INTERNAL_URL}/api/v1/users/${GITEA_ADMIN_USER}/tokens")
|
||||||
|
|
||||||
|
GITEA_ADMIN_TOKEN=$(printf '%s' "$TOKEN_RESPONSE" | jq -r '.sha1')
|
||||||
|
|
||||||
|
if [[ -z "$GITEA_ADMIN_TOKEN" ]] || [[ "$GITEA_ADMIN_TOKEN" == "null" ]]; then
|
||||||
|
log_error "Failed to generate API token"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
save_env_var "GITEA_ADMIN_TOKEN" "$GITEA_ADMIN_TOKEN"
|
||||||
|
log_success "API token generated and saved to .env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Step 9: Create organization
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
log_step 9 "Creating organization '${GITEA_ORG_NAME}'..."
|
||||||
|
if curl -sf -H "Authorization: token ${GITEA_ADMIN_TOKEN}" "${GITEA_INTERNAL_URL}/api/v1/orgs/${GITEA_ORG_NAME}" -o /dev/null 2>/dev/null; then
|
||||||
|
log_info "Organization already exists — skipping"
|
||||||
|
else
|
||||||
|
curl -sf -X POST \
|
||||||
|
-H "Authorization: token ${GITEA_ADMIN_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"username\":\"${GITEA_ORG_NAME}\",\"full_name\":\"${GITEA_INSTANCE_NAME}\",\"visibility\":\"public\"}" \
|
||||||
|
"${GITEA_INTERNAL_URL}/api/v1/orgs" -o /dev/null
|
||||||
|
|
||||||
|
if curl -sf -H "Authorization: token ${GITEA_ADMIN_TOKEN}" "${GITEA_INTERNAL_URL}/api/v1/orgs/${GITEA_ORG_NAME}" -o /dev/null 2>/dev/null; then
|
||||||
|
log_success "Organization created"
|
||||||
|
else
|
||||||
|
log_error "Failed to create organization"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "Phase 1 complete — Gitea is running on Unraid"
|
||||||
75
phase1_post_check.sh
Executable file
75
phase1_post_check.sh
Executable file
@@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# phase1_post_check.sh — Verify Phase 1 (Gitea on Unraid) succeeded
|
||||||
|
# Independent verification — can be run separately from phase1_gitea_unraid.sh
|
||||||
|
# Exits 0 only if ALL checks pass.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
source "${SCRIPT_DIR}/lib/common.sh"
|
||||||
|
|
||||||
|
load_env
|
||||||
|
require_vars GITEA_INTERNAL_URL GITEA_ADMIN_USER GITEA_ADMIN_PASSWORD \
|
||||||
|
GITEA_ADMIN_TOKEN GITEA_ORG_NAME
|
||||||
|
|
||||||
|
log_info "=== Phase 1 Post-Check ==="
|
||||||
|
|
||||||
|
PASS=0
|
||||||
|
FAIL=0
|
||||||
|
|
||||||
|
# Helper: run a check, track results
|
||||||
|
run_check() {
|
||||||
|
local description="$1"; shift
|
||||||
|
if "$@" 2>/dev/null; then
|
||||||
|
log_success "$description"
|
||||||
|
PASS=$((PASS + 1))
|
||||||
|
else
|
||||||
|
log_error "FAIL: $description"
|
||||||
|
FAIL=$((FAIL + 1))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check 1: Gitea responds with HTTP 200
|
||||||
|
run_check "Gitea HTTP 200 at ${GITEA_INTERNAL_URL}" \
|
||||||
|
curl -sf -o /dev/null "${GITEA_INTERNAL_URL}/api/v1/version"
|
||||||
|
|
||||||
|
# Check 2: Admin user authenticates with basic auth
|
||||||
|
run_check "Admin user authenticates (basic auth)" \
|
||||||
|
curl -sf -o /dev/null -u "${GITEA_ADMIN_USER}:${GITEA_ADMIN_PASSWORD}" "${GITEA_INTERNAL_URL}/api/v1/user"
|
||||||
|
|
||||||
|
# Check 3: API token works and returns correct username
|
||||||
|
check_token() {
|
||||||
|
local response
|
||||||
|
response=$(curl -sf -H "Authorization: token ${GITEA_ADMIN_TOKEN}" "${GITEA_INTERNAL_URL}/api/v1/user")
|
||||||
|
local login
|
||||||
|
login=$(printf '%s' "$response" | jq -r '.login')
|
||||||
|
[[ "$login" == "${GITEA_ADMIN_USER}" ]]
|
||||||
|
}
|
||||||
|
run_check "API token valid (returns correct username)" check_token
|
||||||
|
|
||||||
|
# Check 4: Organization exists
|
||||||
|
run_check "Organization '${GITEA_ORG_NAME}' exists" \
|
||||||
|
curl -sf -o /dev/null -H "Authorization: token ${GITEA_ADMIN_TOKEN}" "${GITEA_INTERNAL_URL}/api/v1/orgs/${GITEA_ORG_NAME}"
|
||||||
|
|
||||||
|
# Check 5: Gitea Actions enabled (verify via settings API)
|
||||||
|
check_actions() {
|
||||||
|
# The /api/v1/settings/api endpoint returns instance settings.
|
||||||
|
# If Actions are enabled, the Gitea instance will accept runner registrations.
|
||||||
|
# We can also check by simply verifying the admin/runners endpoint responds.
|
||||||
|
curl -sf -H "Authorization: token ${GITEA_ADMIN_TOKEN}" "${GITEA_INTERNAL_URL}/api/v1/settings/api" -o /dev/null
|
||||||
|
}
|
||||||
|
run_check "Gitea API settings accessible (Actions check)" check_actions
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
printf '\n'
|
||||||
|
log_info "Results: ${PASS} passed, ${FAIL} failed"
|
||||||
|
|
||||||
|
if [[ $FAIL -gt 0 ]]; then
|
||||||
|
log_error "Phase 1 post-check FAILED"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
log_success "Phase 1 post-check PASSED — Gitea on Unraid is fully operational"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
65
phase1_teardown.sh
Executable file
65
phase1_teardown.sh
Executable file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# phase1_teardown.sh — Tear down Gitea on Unraid
|
||||||
|
# Destructive: stops container, optionally removes all data.
|
||||||
|
# Prompts for confirmation before each destructive action.
|
||||||
|
# Safe to run against an already-torn-down instance (no errors).
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
source "${SCRIPT_DIR}/lib/common.sh"
|
||||||
|
|
||||||
|
load_env
|
||||||
|
require_vars UNRAID_IP UNRAID_SSH_USER UNRAID_GITEA_DATA_PATH
|
||||||
|
|
||||||
|
DATA_PATH="$UNRAID_GITEA_DATA_PATH"
|
||||||
|
|
||||||
|
log_warn "=== Phase 1 Teardown: Gitea on Unraid ==="
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Step 1: Stop and remove the Gitea container
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Check if docker-compose file exists (skip if already torn down)
|
||||||
|
if ssh_exec UNRAID "test -f '${DATA_PATH}/docker-compose.yml'" 2>/dev/null; then
|
||||||
|
printf 'This will stop Gitea on Unraid. Continue? [y/N] '
|
||||||
|
read -r confirm
|
||||||
|
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
||||||
|
# Try modern "docker compose" first, fall back to standalone
|
||||||
|
ssh_exec UNRAID "cd '${DATA_PATH}' && docker compose down 2>/dev/null || docker-compose down" || true
|
||||||
|
log_success "Gitea container stopped and removed"
|
||||||
|
else
|
||||||
|
log_info "Skipped container shutdown"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_info "No docker-compose.yml found — container already removed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Step 2: Optionally remove all Gitea data
|
||||||
|
# This is irreversible — removes repos, database, config, everything.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
if ssh_exec UNRAID "test -d '${DATA_PATH}'" 2>/dev/null; then
|
||||||
|
printf 'Remove ALL Gitea data at %s? This is IRREVERSIBLE. [y/N] ' "$DATA_PATH"
|
||||||
|
read -r confirm
|
||||||
|
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
||||||
|
ssh_exec UNRAID "rm -rf '${DATA_PATH}'"
|
||||||
|
log_success "All Gitea data removed from Unraid"
|
||||||
|
else
|
||||||
|
log_info "Data preserved at ${DATA_PATH}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_info "Data directory already removed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Step 3: Clear the auto-populated API token from .env
|
||||||
|
# The token is useless after teardown — clear it so phase1 generates a new one.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
if [[ -n "${GITEA_ADMIN_TOKEN:-}" ]]; then
|
||||||
|
save_env_var "GITEA_ADMIN_TOKEN" ""
|
||||||
|
log_success "GITEA_ADMIN_TOKEN cleared from .env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "Phase 1 teardown complete"
|
||||||
@@ -15,7 +15,9 @@ PASS_COUNT=0
|
|||||||
FAIL_COUNT=0
|
FAIL_COUNT=0
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Check helper — runs a check, tracks pass/fail
|
# Check helper — runs a check function, tracks pass/fail count.
|
||||||
|
# Intentionally does NOT exit on failure — we want to run ALL 16 checks
|
||||||
|
# so the user sees every issue at once, not one at a time.
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
check() {
|
check() {
|
||||||
local num="$1" description="$2"
|
local num="$1" description="$2"
|
||||||
@@ -157,6 +159,8 @@ fi
|
|||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Check 10: Port free on Unraid
|
# Check 10: Port free on Unraid
|
||||||
|
# Uses ss (socket statistics) to check if any process is listening on the port.
|
||||||
|
# The ! negates the grep — we PASS if the port is NOT found in use.
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
check_port_unraid() {
|
check_port_unraid() {
|
||||||
local port="${UNRAID_GITEA_PORT:-3000}"
|
local port="${UNRAID_GITEA_PORT:-3000}"
|
||||||
|
|||||||
Reference in New Issue
Block a user