Codify host firewall + Gitea bootstrap as IaC (hands-off rebuild)

Per operator: the firewalld rule (VM->host:3000 for the Flux<-Gitea source) must be
IaC, not a manual command (R-ENV-01, R-PLAT-04).
- infra/ansible/playbooks/host-prereqs.yml: idempotent firewalld open on the libvirt
  zone (localhost play, become; no extra collection).
- bootstrap/gitea/bootstrap-gitea.sh: now fully automates admin + public repo + push
  (was manual instructions) — idempotent; creds stay 0600 on host, never committed.
Applying host-prereqs still needs host sudo (I lack non-interactive sudo); with
passwordless become a destroy/rebuild is fully unattended.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
jakman85andClaude Opus 4.8 committed 2026-08-16 14:52:08 -05:00
1 parent 4f39bb8d45
commit 3df5071bd1
3 files changed
+84 -17

No files matched your search

+39 -14
View File
@@ -38,20 +38,45 @@ else
"$GITEA_IMAGE"
fi
# --- automated, idempotent setup (admin + PUBLIC repo + push) — NO manual steps (R-ENV-01) ---
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
ADMIN_CRED_FILE="${GITEA_ADMIN_CRED_FILE:-${HOME}/.config/home-k3s-bootstrap-gitea-admin.txt}"
BASE="http://localhost:${HTTP_PORT}" # host-side mgmt via localhost; the cluster uses HOST_NAT_IP
echo "Waiting for Gitea to be healthy..."
curl -fsS --retry 40 --retry-delay 2 --retry-all-errors "${BASE}/api/healthz" >/dev/null
# Admin credentials: generated once, stored 0600 on the host (never committed, never printed).
if [ ! -s "$ADMIN_CRED_FILE" ]; then
mkdir -p "$(dirname "$ADMIN_CRED_FILE")"
printf 'user=gitops\npass=%s\n' "$(openssl rand -base64 18 | tr -dc 'A-Za-z0-9' | head -c 22)" > "$ADMIN_CRED_FILE"
chmod 600 "$ADMIN_CRED_FILE"
fi
ADMIN_USER="$(sed -n 's/^user=//p' "$ADMIN_CRED_FILE")"
ADMIN_PW="$(sed -n 's/^pass=//p' "$ADMIN_CRED_FILE")"
# Create the admin user if missing (idempotent).
if ! "$ENGINE" exec -u git "$NAME" gitea admin user list 2>/dev/null | grep -qw "$ADMIN_USER"; then
"$ENGINE" exec -u git "$NAME" gitea admin user create \
--username "$ADMIN_USER" --password "$ADMIN_PW" --email "${ADMIN_USER}@home.local" \
--admin --must-change-password=false
fi
# Org + PUBLIC repo (idempotent — 'already exists' is fine; public => Flux needs no git creds).
curl -fsS -u "${ADMIN_USER}:${ADMIN_PW}" -H 'Content-Type: application/json' -X POST \
"${BASE}/api/v1/orgs" -d "{\"username\":\"${ORG}\"}" -o /dev/null 2>/dev/null || true
curl -fsS -u "${ADMIN_USER}:${ADMIN_PW}" -H 'Content-Type: application/json' -X POST \
"${BASE}/api/v1/orgs/${ORG}/repos" -d "{\"name\":\"${REPO}\",\"private\":false}" -o /dev/null 2>/dev/null || true
# Push current HEAD -> the bootstrap source's main.
git -C "$REPO_ROOT" push "http://${ADMIN_USER}:${ADMIN_PW}@localhost:${HTTP_PORT}/${ORG}/${REPO}.git" HEAD:main
cat <<EOF
Gitea (bootstrap source) at http://${HOST_NAT_IP}:${HTTP_PORT}/ data: ${DATA_DIR}
One-time setup (manual — keeps creds out of this script):
1. Create an admin user:
${ENGINE} exec -u git ${NAME} gitea admin user create \\
--username <admin> --password <pw> --email <you@example> --admin
2. In the UI (or API) create org '${ORG}' and a **PUBLIC** repo '${REPO}'
(public => Flux needs no git credentials; this Gitea is NAT-only, not internet-exposed).
3. Push this repo up:
git remote add bootstrap http://<admin>:<pw>@${HOST_NAT_IP}:${HTTP_PORT}/${ORG}/${REPO}.git
git push bootstrap main
Flux's flux-system GitRepository url is already wired to:
http://${HOST_NAT_IP}:${HTTP_PORT}/${ORG}/${REPO}.git (clusters/dev)
Gitea bootstrap source ready (${DATA_DIR}).
UI (host): ${BASE}/${ORG}/${REPO}
Flux GitRepository (cluster): http://${HOST_NAT_IP}:${HTTP_PORT}/${ORG}/${REPO}.git (clusters/dev)
Admin creds (host, 0600): ${ADMIN_CRED_FILE}
Prerequisite: firewalld must allow VM->host:${HTTP_PORT} —
ansible-playbook infra/ansible/playbooks/host-prereqs.yml --ask-become-pass
EOF