railiance-apps/Makefile
tegwick a689270f18
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 13s
WP-0013/0014: warden credential routing, CoulombCore kubeconfig, apps-pg backup dry-run
Document OpenBao/warden paths for the offsite backup lane and flag the sealed
Vault blocker. Point production Makefile targets at CoulombCore, auto-discover
CNPG clusters in backup status, add apps-pg pg_dump dry-run tooling, and
record Core Hub Helm cutover findings (live gitea image, adopt required).
2026-07-10 15:46:02 +02:00

461 lines
26 KiB
Makefile

SHELL := /usr/bin/env bash
.DEFAULT_GOAL := help
VERGABE_RELEASE ?= vergabe-teilnahme
VERGABE_NAMESPACE ?= vergabe-teilnahme
VERGABE_CHART ?= charts/vergabe-teilnahme
VERGABE_VALUES ?= helm/vergabe-teilnahme-values.yaml
VERGABE_INGRESS ?= manifests/vergabe-teilnahme-ingress.yaml
VERGABE_DB_SECRET ?= vergabe-app-credentials
VERGABE_ENV_SECRET ?= vergabe-teilnahme-env
VERGABE_DB_USER ?= vergabe
VERGABE_DB_HOST ?= apps-pg-rw.databases
VERGABE_DB_PORT ?= 5432
VERGABE_DB_NAME ?= vergabe_db
INTER_HUB_RELEASE ?= inter-hub
INTER_HUB_NAMESPACE ?= inter-hub
INTER_HUB_CHART ?= charts/inter-hub
INTER_HUB_VALUES ?= helm/inter-hub-values.yaml
INTER_HUB_IMAGE_REPOSITORY ?= forgejo.coulomb.social/coulomb/inter-hub
INTER_HUB_IMAGE_TAG ?=
INTER_HUB_BASE_URL ?= https://hub.coulomb.social
REUSE_RELEASE ?= reuse
REUSE_NAMESPACE ?= reuse
REUSE_CHART ?= charts/reuse-surface
REUSE_VALUES ?= helm/reuse-surface-values.yaml
REUSE_URL ?= https://reuse.coulomb.social
REUSE_CERTIFICATE ?= reuse-surface-tls
COULOMBCORE_KUBECONFIG ?= $(HOME)/.kube/config
RAILIANCE01_KUBECONFIG ?= $(HOME)/.kube/config-hosteurope
PRODUCTION_KUBECONFIG ?= $(COULOMBCORE_KUBECONFIG)
INTER_HUB_KUBECONFIG ?= $(RAILIANCE01_KUBECONFIG)
REUSE_KUBECONFIG ?= $(RAILIANCE01_KUBECONFIG)
FORGEJO_KUBECONFIG ?= $(RAILIANCE01_KUBECONFIG)
FORGEJO_RELEASE ?= forgejo
FORGEJO_NAMESPACE ?= forgejo
FORGEJO_CHART ?= gitea-charts/gitea
# Forgejo 11.x (Gitea 1.22) lacks `gitea config edit-ini`; chart 12.6+ requires Gitea 1.26+.
FORGEJO_CHART_VERSION ?= 12.5.0
FORGEJO_VALUES ?= helm/forgejo-values.yaml
FORGEJO_REGISTRY_VALUES ?= helm/forgejo-registry-values.yaml
FORGEJO_SECRETS ?= helm/forgejo-secrets.sops.yaml
FORGEJO_INGRESS ?= manifests/forgejo-ingress.yaml
FORGEJO_SSH_NODEPORT ?= manifests/forgejo-ssh-nodeport.yaml
FORGEJO_BASE_URL ?= https://forgejo.coulomb.social
FORGEJO_DB_CLUSTER ?= forgejo-db
FORGEJO_DB_NAMESPACE ?= databases
FORGEJO_RUNNER_MANIFEST ?= manifests/forgejo-runner.yaml
FORGEJO_RUNNER_REGISTRATION_SECRET ?= helm/forgejo-runner-registration.sops.yaml
FORGEJO_MAILER_EXTERNAL_SECRET ?= manifests/forgejo-mailer-externalsecret.yaml
REUSE_RUNTIME_EXTERNAL_SECRET ?= manifests/reuse-surface-runtime-externalsecret.yaml
PLATFORM_REPO ?= $(HOME)/railiance-platform
ESO_CHART_VERSION ?= 0.16.1
INTER_HUB_IMAGE_REF = $(INTER_HUB_IMAGE_REPOSITORY):$(INTER_HUB_IMAGE_TAG)
INTER_HUB_IMAGE_SET_ARG = $(if $(strip $(INTER_HUB_IMAGE_TAG)),--set image.tag=$(INTER_HUB_IMAGE_TAG),)
CORE_HUB_RELEASE ?= core-hub
CORE_HUB_NAMESPACE ?= core-hub
CORE_HUB_CHART ?= charts/core-hub
CORE_HUB_VALUES ?= helm/core-hub-values.yaml
CORE_HUB_STAGING_NAMESPACE ?= core-hub-staging
CORE_HUB_STAGING_VALUES ?= helm/core-hub-staging-values.yaml
CORE_HUB_IMAGE_REPOSITORY ?= forgejo.coulomb.social/coulomb/core-hub
CORE_HUB_IMAGE_TAG ?=
CORE_HUB_BASE_URL ?= https://hub.coulomb.social
CORE_HUB_KUBECONFIG ?= $(PRODUCTION_KUBECONFIG)
VERGABE_KUBECONFIG ?= $(PRODUCTION_KUBECONFIG)
CORE_HUB_IMAGE_REF = $(CORE_HUB_IMAGE_REPOSITORY):$(CORE_HUB_IMAGE_TAG)
CORE_HUB_IMAGE_SET_ARG = $(if $(strip $(CORE_HUB_IMAGE_TAG)),--set image.tag=$(CORE_HUB_IMAGE_TAG),)
SOPS_SENTINEL ?= $(FORGEJO_SECRETS)
DRY_RUN_CREATE_NAMESPACES ?= false
##@ Operator checks
check-tools: ## Check required operator tools and warn about optional diagnostics
tools/check-tools.sh
check-sops: ## Verify the local SOPS age key can decrypt SOPS_SENTINEL
SOPS_SENTINEL="$(SOPS_SENTINEL)" tools/check-sops.sh
k8s-server-dry-run: ## Server-side dry-run rendered Helm and committed manifests
DRY_RUN_CREATE_NAMESPACES=$(DRY_RUN_CREATE_NAMESPACES) tools/k8s-server-dry-run.sh
apps-pg-status: ## Check the shared apps-pg cnpg cluster
@if kubectl cnpg status apps-pg -n databases >/dev/null 2>&1; then \
kubectl cnpg status apps-pg -n databases; \
else \
echo "kubectl cnpg plugin not available; falling back to cnpg resources"; \
kubectl get cluster apps-pg -n databases; \
kubectl get pods -n databases -l cnpg.io/cluster=apps-pg; \
fi
check-railiance01-kubeconfig: ## Verify Railiance01 production kubeconfig exists
@test -r "$(RAILIANCE01_KUBECONFIG)" || { \
echo "Missing Railiance01 kubeconfig: $(RAILIANCE01_KUBECONFIG)" >&2; \
echo "Restore it with:" >&2; \
echo " ssh tegwick@92.205.62.239 'sudo cat /etc/rancher/k3s/k3s.yaml' | sed 's|127.0.0.1|92.205.62.239|' > $(RAILIANCE01_KUBECONFIG)" >&2; \
exit 1; \
}
check-coulombcore-kubeconfig: ## Verify CoulombCore kubeconfig and k3s API tunnel
@test -r "$(COULOMBCORE_KUBECONFIG)" || { \
echo "Missing CoulombCore kubeconfig: $(COULOMBCORE_KUBECONFIG)" >&2; \
echo "Ensure ops-bridge tunnel is up: bridge up k3s-api-coulombcore" >&2; \
exit 1; \
}
@KUBECONFIG="$(COULOMBCORE_KUBECONFIG)" kubectl get --raw=/readyz >/dev/null 2>&1 || { \
echo "CoulombCore API unreachable via $(COULOMBCORE_KUBECONFIG)." >&2; \
echo "Run: bridge up k3s-api-coulombcore" >&2; \
exit 1; \
}
check-production-kubeconfig: check-coulombcore-kubeconfig ## Verify production app cluster API (CoulombCore)
check-inter-hub-image-tag: ## Require an explicit inter-hub image tag for production deploys
@test -n "$(INTER_HUB_IMAGE_TAG)" || { \
echo "Set INTER_HUB_IMAGE_TAG=<sha> for inter-hub production deploys." >&2; \
echo "Example: INTER_HUB_IMAGE_TAG=91037a4 make inter-hub-deploy" >&2; \
exit 1; \
}
check-inter-hub-image: check-inter-hub-image-tag ## Verify the inter-hub OCI image tag exists before deploy
tools/check-oci-image.sh "$(INTER_HUB_IMAGE_REF)"
check-core-hub-image-tag: ## Require an explicit core-hub image tag for production deploys
@test -n "$(CORE_HUB_IMAGE_TAG)" || { \
echo "Set CORE_HUB_IMAGE_TAG=<sha> for core-hub production deploys." >&2; \
echo "Example: CORE_HUB_IMAGE_TAG=59bf1e4 make core-hub-deploy" >&2; \
exit 1; \
}
check-core-hub-image: check-core-hub-image-tag ## Verify the core-hub OCI image tag exists before deploy
tools/check-oci-image.sh "$(CORE_HUB_IMAGE_REF)"
cnpg-backup-status: check-production-kubeconfig ## Report CNPG backup spec and ScheduledBackup coverage
KUBECONFIG="$(PRODUCTION_KUBECONFIG)" tools/cnpg-backup-status.sh
apps-pg-backup-dry-run: check-production-kubeconfig ## Logical pg_dump + age encrypt for vergabe_db (no upload)
chmod +x tools/apps-pg-backup-dry-run.sh
KUBECONFIG="$(PRODUCTION_KUBECONFIG)" PLATFORM_REPO="$(PLATFORM_REPO)" tools/apps-pg-backup-dry-run.sh
##@ Vergabe Teilnahme
vergabe-dry-run: ## helm template render (no apply) for inspection
helm template $(VERGABE_RELEASE) $(VERGABE_CHART) \
--namespace $(VERGABE_NAMESPACE) \
-f $(VERGABE_VALUES)
vergabe-deploy: check-production-kubeconfig ## Deploy / upgrade vergabe-teilnahme Helm release
KUBECONFIG="$(VERGABE_KUBECONFIG)" helm upgrade --install $(VERGABE_RELEASE) $(VERGABE_CHART) \
--namespace $(VERGABE_NAMESPACE) --create-namespace \
-f $(VERGABE_VALUES) --wait --timeout 3m
vergabe-ingress-deploy: ## Apply the vergabe-teilnahme ingress (whywhynot.de)
kubectl apply -f $(VERGABE_INGRESS)
vergabe-status: check-production-kubeconfig ## Show vergabe-teilnahme pod / svc / ingress / cert state
KUBECONFIG="$(VERGABE_KUBECONFIG)" kubectl get pods,svc,ingress,certificate -n $(VERGABE_NAMESPACE) -l app.kubernetes.io/instance=$(VERGABE_RELEASE) --ignore-not-found
vergabe-migrate: ## Run Django migrations against the live deployment
kubectl exec -n $(VERGABE_NAMESPACE) deploy/$(VERGABE_RELEASE) -- python manage.py migrate --noinput
vergabe-seed: ## Run the idempotent seed command
kubectl exec -n $(VERGABE_NAMESPACE) deploy/$(VERGABE_RELEASE) -- python manage.py seed_dev
vergabe-superuser: ## Open an interactive shell for createsuperuser
kubectl exec -it -n $(VERGABE_NAMESPACE) deploy/$(VERGABE_RELEASE) -- python manage.py createsuperuser
vergabe-logs: ## Tail vergabe-teilnahme app logs
kubectl logs -n $(VERGABE_NAMESPACE) -l app.kubernetes.io/instance=$(VERGABE_RELEASE) -f --tail=50
vergabe-db-url-secret: ## Rebuild DATABASE_URL with a URL-encoded cnpg password
APP_NAMESPACE=$(VERGABE_NAMESPACE) \
APP_ENV_SECRET=$(VERGABE_ENV_SECRET) \
APP_DB_SECRET=$(VERGABE_DB_SECRET) \
APP_DB_USER=$(VERGABE_DB_USER) \
APP_DB_HOST=$(VERGABE_DB_HOST) \
APP_DB_PORT=$(VERGABE_DB_PORT) \
APP_DB_NAME=$(VERGABE_DB_NAME) \
tools/build-database-url-secret.sh
##@ Inter-Hub
inter-hub-render-baseline: ## Render checked-in inter-hub values for chart validation only
helm template $(INTER_HUB_RELEASE) $(INTER_HUB_CHART) \
--namespace $(INTER_HUB_NAMESPACE) \
-f $(INTER_HUB_VALUES)
inter-hub-dry-run: check-railiance01-kubeconfig check-inter-hub-image-tag ## helm template render with an explicit production image tag
KUBECONFIG="$(INTER_HUB_KUBECONFIG)" helm template $(INTER_HUB_RELEASE) $(INTER_HUB_CHART) \
--namespace $(INTER_HUB_NAMESPACE) \
-f $(INTER_HUB_VALUES) $(INTER_HUB_IMAGE_SET_ARG)
inter-hub-server-dry-run: check-railiance01-kubeconfig check-inter-hub-image ## Helm server dry-run inter-hub upgrade on Railiance01
KUBECONFIG="$(INTER_HUB_KUBECONFIG)" helm upgrade --install $(INTER_HUB_RELEASE) $(INTER_HUB_CHART) \
--namespace $(INTER_HUB_NAMESPACE) --create-namespace \
-f $(INTER_HUB_VALUES) $(INTER_HUB_IMAGE_SET_ARG) --dry-run=server --timeout 5m
inter-hub-deploy: check-railiance01-kubeconfig check-inter-hub-image ## Deploy / upgrade inter-hub Helm release on Railiance01
KUBECONFIG="$(INTER_HUB_KUBECONFIG)" helm upgrade --install $(INTER_HUB_RELEASE) $(INTER_HUB_CHART) \
--namespace $(INTER_HUB_NAMESPACE) --create-namespace \
-f $(INTER_HUB_VALUES) $(INTER_HUB_IMAGE_SET_ARG) --wait --timeout 5m
inter-hub-status: check-railiance01-kubeconfig ## Show inter-hub pod / svc / ingress / cert state on Railiance01
KUBECONFIG="$(INTER_HUB_KUBECONFIG)" kubectl get pods,svc,ingress,certificate -n $(INTER_HUB_NAMESPACE) -l app=$(INTER_HUB_RELEASE) --ignore-not-found
inter-hub-release-info: check-railiance01-kubeconfig ## Show inter-hub Helm history, values, deployment, and pods
KUBECONFIG="$(INTER_HUB_KUBECONFIG)" helm history $(INTER_HUB_RELEASE) -n $(INTER_HUB_NAMESPACE)
KUBECONFIG="$(INTER_HUB_KUBECONFIG)" helm get values $(INTER_HUB_RELEASE) -n $(INTER_HUB_NAMESPACE)
KUBECONFIG="$(INTER_HUB_KUBECONFIG)" kubectl describe deploy/$(INTER_HUB_RELEASE) -n $(INTER_HUB_NAMESPACE)
KUBECONFIG="$(INTER_HUB_KUBECONFIG)" kubectl get pods -n $(INTER_HUB_NAMESPACE) -o wide
inter-hub-smoke: ## Verify public inter-hub v2 route and OpenAPI surface after rollout
INTER_HUB_BASE_URL="$(INTER_HUB_BASE_URL)" tools/inter-hub-smoke.sh
inter-hub-logs: check-railiance01-kubeconfig ## Tail inter-hub app logs from Railiance01
KUBECONFIG="$(INTER_HUB_KUBECONFIG)" kubectl logs -n $(INTER_HUB_NAMESPACE) -l app=$(INTER_HUB_RELEASE) -f --tail=50
##@ Core Hub
core-hub-render-baseline: ## Render checked-in core-hub values for chart validation only
helm template $(CORE_HUB_RELEASE) $(CORE_HUB_CHART) \
--namespace $(CORE_HUB_NAMESPACE) \
-f $(CORE_HUB_VALUES)
core-hub-dry-run: check-production-kubeconfig check-core-hub-image-tag ## helm template render with an explicit production image tag
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" helm template $(CORE_HUB_RELEASE) $(CORE_HUB_CHART) \
--namespace $(CORE_HUB_NAMESPACE) \
-f $(CORE_HUB_VALUES) $(CORE_HUB_IMAGE_SET_ARG)
core-hub-server-dry-run: check-production-kubeconfig check-core-hub-image ## Helm server dry-run core-hub upgrade on CoulombCore
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" helm upgrade --install $(CORE_HUB_RELEASE) $(CORE_HUB_CHART) \
--namespace $(CORE_HUB_NAMESPACE) --create-namespace \
-f $(CORE_HUB_VALUES) $(CORE_HUB_IMAGE_SET_ARG) --dry-run=server --timeout 5m
core-hub-deploy: check-production-kubeconfig check-core-hub-image ## Deploy / upgrade core-hub Helm release on CoulombCore
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" helm upgrade --install $(CORE_HUB_RELEASE) $(CORE_HUB_CHART) \
--namespace $(CORE_HUB_NAMESPACE) --create-namespace \
-f $(CORE_HUB_VALUES) $(CORE_HUB_IMAGE_SET_ARG) --wait --timeout 5m
core-hub-migrate: check-production-kubeconfig check-core-hub-image ## Run Alembic migrations via a one-off Job
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" kubectl -n $(CORE_HUB_NAMESPACE) delete job $(CORE_HUB_RELEASE)-prod-migrate --ignore-not-found
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" helm template $(CORE_HUB_RELEASE) $(CORE_HUB_CHART) \
--namespace $(CORE_HUB_NAMESPACE) \
-f $(CORE_HUB_VALUES) $(CORE_HUB_IMAGE_SET_ARG) \
--set migration.enabled=true | KUBECONFIG="$(CORE_HUB_KUBECONFIG)" kubectl apply -f -
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" kubectl -n $(CORE_HUB_NAMESPACE) wait --for=condition=complete \
job/$(CORE_HUB_RELEASE)-prod-migrate --timeout=180s
core-hub-status: check-production-kubeconfig ## Show core-hub pod / svc / ingress / cert state on CoulombCore
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" kubectl get pods,svc,ingress,certificate -n $(CORE_HUB_NAMESPACE) \
-l app.kubernetes.io/name=core-hub --ignore-not-found
core-hub-release-info: check-production-kubeconfig ## Show core-hub Helm history, values, deployment, and pods
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" helm history $(CORE_HUB_RELEASE) -n $(CORE_HUB_NAMESPACE)
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" helm get values $(CORE_HUB_RELEASE) -n $(CORE_HUB_NAMESPACE)
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" kubectl describe deploy/$(CORE_HUB_RELEASE)-api -n $(CORE_HUB_NAMESPACE)
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" kubectl get pods -n $(CORE_HUB_NAMESPACE) -o wide
core-hub-smoke: ## Verify public Core Hub health and v2 API surface after rollout
CORE_HUB_BASE_URL="$(CORE_HUB_BASE_URL)" tools/core-hub-smoke.sh
core-hub-logs: check-production-kubeconfig ## Tail core-hub app logs from CoulombCore
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" kubectl logs -n $(CORE_HUB_NAMESPACE) \
-l app.kubernetes.io/name=core-hub,app.kubernetes.io/component=api -f --tail=50
core-hub-staging-dry-run: check-production-kubeconfig check-core-hub-image-tag ## helm template render for core-hub staging
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" helm template $(CORE_HUB_RELEASE) $(CORE_HUB_CHART) \
--namespace $(CORE_HUB_STAGING_NAMESPACE) \
-f $(CORE_HUB_STAGING_VALUES) $(CORE_HUB_IMAGE_SET_ARG)
core-hub-staging-deploy: check-production-kubeconfig check-core-hub-image ## Deploy / upgrade core-hub staging release
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" helm upgrade --install $(CORE_HUB_RELEASE) $(CORE_HUB_CHART) \
--namespace $(CORE_HUB_STAGING_NAMESPACE) --create-namespace \
-f $(CORE_HUB_STAGING_VALUES) $(CORE_HUB_IMAGE_SET_ARG) --wait --timeout 5m
core-hub-staging-migrate: check-production-kubeconfig check-core-hub-image ## Run Alembic migrations for core-hub staging
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" kubectl -n $(CORE_HUB_STAGING_NAMESPACE) delete job $(CORE_HUB_RELEASE)-staging-migrate --ignore-not-found
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" helm template $(CORE_HUB_RELEASE) $(CORE_HUB_CHART) \
--namespace $(CORE_HUB_STAGING_NAMESPACE) \
-f $(CORE_HUB_STAGING_VALUES) $(CORE_HUB_IMAGE_SET_ARG) \
--set migration.enabled=true | KUBECONFIG="$(CORE_HUB_KUBECONFIG)" kubectl apply -f -
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" kubectl -n $(CORE_HUB_STAGING_NAMESPACE) wait --for=condition=complete \
job/$(CORE_HUB_RELEASE)-staging-migrate --timeout=180s
core-hub-staging-status: check-production-kubeconfig ## Show core-hub staging pod / svc state
KUBECONFIG="$(CORE_HUB_KUBECONFIG)" kubectl get pods,svc -n $(CORE_HUB_STAGING_NAMESPACE) \
-l app.kubernetes.io/name=core-hub --ignore-not-found
##@ Forgejo (forgejo.coulomb.social)
eso-deploy: check-railiance01-kubeconfig ## Install External Secrets Operator on railiance01
KUBECONFIG="$(FORGEJO_KUBECONFIG)" helm repo add external-secrets https://charts.external-secrets.io --force-update
KUBECONFIG="$(FORGEJO_KUBECONFIG)" helm upgrade --install external-secrets external-secrets/external-secrets \
--version $(ESO_CHART_VERSION) \
--namespace external-secrets --create-namespace \
--set installCRDs=true \
--set serviceAccount.create=true \
--set serviceAccount.name=external-secrets \
--wait --timeout 5m
forgejo-openbao-eso-token-apply: ## Mint coulombcore OpenBao ESO token + Secret on railiance01 (interactive)
tools/forgejo-openbao-eso-token-apply.sh
forgejo-openbao-store-deploy: check-railiance01-kubeconfig eso-deploy ## Apply openbao-forgejo ClusterSecretStore
test -d "$(PLATFORM_REPO)/argocd/platform-addons/openbao-secretstore"
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl apply -f "$(PLATFORM_REPO)/argocd/platform-addons/openbao-secretstore/openbao-forgejo.clustersecretstore.yaml"
forgejo-mailer-es-deploy: check-railiance01-kubeconfig forgejo-openbao-store-deploy ## Apply Forgejo mailer ExternalSecret
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl apply -f $(FORGEJO_MAILER_EXTERNAL_SECRET)
forgejo-mailer-es-status: check-railiance01-kubeconfig ## Show Forgejo mailer ExternalSecret sync status
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl get externalsecret,secret -n $(FORGEJO_NAMESPACE) forgejo-mailer
forgejo-dry-run: check-railiance01-kubeconfig ## helm template render for Forgejo
KUBECONFIG="$(FORGEJO_KUBECONFIG)" helm template $(FORGEJO_RELEASE) $(FORGEJO_CHART) \
--version $(FORGEJO_CHART_VERSION) \
--namespace $(FORGEJO_NAMESPACE) \
-f $(FORGEJO_VALUES) \
-f $(FORGEJO_REGISTRY_VALUES) \
-f <(KUBECONFIG="$(FORGEJO_KUBECONFIG)" tools/forgejo-helm-secrets.sh)
forgejo-server-dry-run: check-railiance01-kubeconfig ## Helm server dry-run Forgejo upgrade
KUBECONFIG="$(FORGEJO_KUBECONFIG)" helm upgrade --install $(FORGEJO_RELEASE) $(FORGEJO_CHART) \
--version $(FORGEJO_CHART_VERSION) \
--namespace $(FORGEJO_NAMESPACE) --create-namespace \
-f $(FORGEJO_VALUES) \
-f $(FORGEJO_REGISTRY_VALUES) \
-f <(KUBECONFIG="$(FORGEJO_KUBECONFIG)" tools/forgejo-helm-secrets.sh) \
--dry-run=server --timeout 5m
forgejo-deploy: check-railiance01-kubeconfig forgejo-mailer-es-deploy ## Deploy / upgrade Forgejo on railiance01
@test -n "$$(KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl get secret forgejo-mailer -n $(FORGEJO_NAMESPACE) -o name 2>/dev/null)" || { \
echo "Missing secret forgejo-mailer in $(FORGEJO_NAMESPACE)." >&2; \
echo "Ensure ExternalSecret is Ready and OpenBao role external-secrets-forgejo is configured." >&2; \
exit 1; \
}
KUBECONFIG="$(FORGEJO_KUBECONFIG)" helm repo add gitea-charts https://dl.gitea.com/charts/ --force-update
KUBECONFIG="$(FORGEJO_KUBECONFIG)" helm upgrade --install $(FORGEJO_RELEASE) $(FORGEJO_CHART) \
--version $(FORGEJO_CHART_VERSION) \
--namespace $(FORGEJO_NAMESPACE) --create-namespace \
-f $(FORGEJO_VALUES) \
-f $(FORGEJO_REGISTRY_VALUES) \
-f <(KUBECONFIG="$(FORGEJO_KUBECONFIG)" tools/forgejo-helm-secrets.sh) \
--wait --timeout 10m
forgejo-ingress-deploy: check-railiance01-kubeconfig ## Apply Forgejo HTTPS ingress
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl apply -f $(FORGEJO_INGRESS)
forgejo-ssh-nodeport-deploy: check-railiance01-kubeconfig ## Apply Forgejo SSH NodePort (30022)
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl apply -f $(FORGEJO_SSH_NODEPORT)
forgejo-status: check-railiance01-kubeconfig ## Show Forgejo pods, svc, ingress, cert, database
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl get pods,svc,ingress,certificate,pvc -n $(FORGEJO_NAMESPACE) --ignore-not-found
@if KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl cnpg status $(FORGEJO_DB_CLUSTER) -n $(FORGEJO_DB_NAMESPACE) >/dev/null 2>&1; then \
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl cnpg status $(FORGEJO_DB_CLUSTER) -n $(FORGEJO_DB_NAMESPACE); \
else \
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl get cluster $(FORGEJO_DB_CLUSTER) -n $(FORGEJO_DB_NAMESPACE) --ignore-not-found; \
fi
forgejo-smoke: ## Verify Forgejo web and OCI registry challenge
FORGEJO_BASE_URL="$(FORGEJO_BASE_URL)" tools/forgejo-smoke.sh
forgejo-npm-smoke: ## T07 npm install smoke (@coulomb/forgejo-npm-probe)
tools/forgejo-npm-smoke.sh
forgejo-verify: check-railiance01-kubeconfig ## T05 acceptance: smoke, TLS, DB, mailer ESO, SSH operator, SOPS sentinels
FORGEJO_BASE_URL="$(FORGEJO_BASE_URL)" KUBECONFIG="$(FORGEJO_KUBECONFIG)" tools/forgejo-verify.sh
forgejo-operator-bootstrap: ## Idempotent operator user + SSH key bootstrap (no secrets in Git)
FORGEJO_BASE_URL="$(FORGEJO_BASE_URL)" tools/forgejo-operator-bootstrap.sh
forgejo-runner-registration-sops-bootstrap: check-railiance01-kubeconfig ## Capture cluster runner token into SOPS (operator age key)
KUBECONFIG="$(FORGEJO_KUBECONFIG)" tools/forgejo-runner-registration-sops-bootstrap.sh
forgejo-secrets-check: ## Verify Forgejo SOPS sentinels exist and are encrypted
@test -f $(FORGEJO_SECRETS) && grep -q '^sops:' $(FORGEJO_SECRETS) || { echo "Missing encrypted $(FORGEJO_SECRETS)" >&2; exit 1; }
@if [ -f $(FORGEJO_RUNNER_REGISTRATION_SECRET) ]; then \
grep -q '^sops:' $(FORGEJO_RUNNER_REGISTRATION_SECRET) || { echo "Runner registration not SOPS-encrypted" >&2; exit 1; }; \
else \
echo "WARN: $(FORGEJO_RUNNER_REGISTRATION_SECRET) missing — run forgejo-runner-registration-sops-bootstrap on operator host" >&2; \
fi
@echo "ok: Forgejo SOPS sentinels"
forgejo-logs: check-railiance01-kubeconfig ## Tail Forgejo application logs
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl logs -n $(FORGEJO_NAMESPACE) -l app.kubernetes.io/instance=$(FORGEJO_RELEASE) -f --tail=50
forgejo-runner-registration-deploy: check-railiance01-kubeconfig check-sops ## Apply SOPS runner registration secret
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl apply -f <(sops -d $(FORGEJO_RUNNER_REGISTRATION_SECRET))
forgejo-runner-deploy: check-railiance01-kubeconfig ## Deploy in-cluster Forgejo Actions runner (ADR-004)
@test -n "$$(KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl get secret forgejo-runner-registration -n $(FORGEJO_NAMESPACE) -o name 2>/dev/null)" || { \
echo "Missing secret forgejo-runner-registration in $(FORGEJO_NAMESPACE)." >&2; \
echo "Apply helm/forgejo-runner-registration.sops.yaml or bootstrap once:" >&2; \
echo " kubectl create secret generic forgejo-runner-registration -n forgejo --from-literal=token=<token>" >&2; \
exit 1; \
}
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl apply -f $(FORGEJO_RUNNER_MANIFEST)
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl rollout status deployment/forgejo-runner -n $(FORGEJO_NAMESPACE) --timeout=5m
forgejo-runner-status: check-railiance01-kubeconfig ## Show in-cluster runner pod and PVC state
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl get deploy,pods,pvc -n $(FORGEJO_NAMESPACE) -l app.kubernetes.io/name=forgejo-runner --ignore-not-found
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl logs -n $(FORGEJO_NAMESPACE) deploy/forgejo-runner -c runner --tail=20 2>/dev/null || true
forgejo-runner-logs: check-railiance01-kubeconfig ## Tail in-cluster runner logs
KUBECONFIG="$(FORGEJO_KUBECONFIG)" kubectl logs -n $(FORGEJO_NAMESPACE) deploy/forgejo-runner -c runner -f --tail=50
##@ reuse-surface (reuse.coulomb.social)
reuse-dry-run: check-railiance01-kubeconfig ## helm template render (no apply) for reuse-surface
KUBECONFIG="$(REUSE_KUBECONFIG)" helm template $(REUSE_RELEASE) $(REUSE_CHART) \
--namespace $(REUSE_NAMESPACE) \
-f $(REUSE_VALUES)
reuse-deploy: check-railiance01-kubeconfig ## Deploy / upgrade reuse-surface Helm release on Railiance01
KUBECONFIG="$(REUSE_KUBECONFIG)" helm upgrade --install $(REUSE_RELEASE) $(REUSE_CHART) \
--namespace $(REUSE_NAMESPACE) --create-namespace \
-f $(REUSE_VALUES) --wait --timeout 5m
reuse-status: check-railiance01-kubeconfig ## Show reuse-surface pod / svc / ingress / cert state on Railiance01
KUBECONFIG="$(REUSE_KUBECONFIG)" kubectl get pods,svc,ingress,pvc,certificate -n $(REUSE_NAMESPACE) -l app.kubernetes.io/instance=$(REUSE_RELEASE) --ignore-not-found
reuse-smoke: check-railiance01-kubeconfig ## Verify reuse public health, repo list, and TLS certificate readiness
curl -fsS "$(REUSE_URL)/health"
curl -fsS "$(REUSE_URL)/v1/repos"
KUBECONFIG="$(REUSE_KUBECONFIG)" kubectl wait -n $(REUSE_NAMESPACE) --for=condition=Ready certificate/$(REUSE_CERTIFICATE) --timeout=30s
reuse-logs: check-railiance01-kubeconfig ## Tail reuse-surface service logs from Railiance01
KUBECONFIG="$(REUSE_KUBECONFIG)" kubectl logs -n $(REUSE_NAMESPACE) -l app.kubernetes.io/instance=$(REUSE_RELEASE) -f --tail=50
reuse-forgejo-webhook: check-railiance01-kubeconfig ## Idempotent org webhook on Forgejo -> reuse hub (REUSE-WP-0019-T03)
bash tools/reuse-forgejo-webhook.sh
reuse-openbao-eso-token-apply: ## Mint coulombcore OpenBao ESO token + Secret on railiance01 (CCR-2026-0005)
OPENBAO_TOKEN_FILE="$(HOME)/.local/openbao/platform-admin.token" bash tools/reuse-openbao-eso-token-apply.sh
reuse-openbao-store-deploy: check-railiance01-kubeconfig eso-deploy ## Apply openbao-reuse ClusterSecretStore
test -d "$(PLATFORM_REPO)/argocd/platform-addons/openbao-secretstore"
KUBECONFIG="$(REUSE_KUBECONFIG)" kubectl apply -f "$(PLATFORM_REPO)/argocd/platform-addons/openbao-secretstore/openbao-reuse.clustersecretstore.yaml"
reuse-runtime-es-deploy: check-railiance01-kubeconfig reuse-openbao-store-deploy ## Apply reuse-surface runtime ExternalSecret
KUBECONFIG="$(REUSE_KUBECONFIG)" kubectl apply -f $(REUSE_RUNTIME_EXTERNAL_SECRET)
reuse-runtime-es-status: check-railiance01-kubeconfig ## Show reuse-surface runtime ExternalSecret sync status
KUBECONFIG="$(REUSE_KUBECONFIG)" kubectl get externalsecret,secret -n $(REUSE_NAMESPACE) reuse-surface-runtime reuse-surface-env
reuse-webhook-smoke: check-railiance01-kubeconfig ## Webhook + ESO + federated smoke (RAILIANCE-WP-0011-T04)
bash tools/reuse-webhook-smoke.sh
##@ Help
help: ## Show this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} \
/^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } \
/^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) }' $(MAKEFILE_LIST)
.PHONY: check-tools check-sops k8s-server-dry-run apps-pg-status check-railiance01-kubeconfig check-inter-hub-image-tag check-inter-hub-image vergabe-dry-run vergabe-deploy vergabe-ingress-deploy vergabe-status vergabe-migrate vergabe-seed vergabe-superuser vergabe-logs vergabe-db-url-secret eso-deploy forgejo-openbao-eso-token-apply forgejo-openbao-store-deploy forgejo-mailer-es-deploy forgejo-mailer-es-status forgejo-dry-run forgejo-server-dry-run forgejo-deploy forgejo-ingress-deploy forgejo-ssh-nodeport-deploy forgejo-status forgejo-smoke forgejo-npm-smoke forgejo-verify forgejo-operator-bootstrap forgejo-runner-registration-sops-bootstrap forgejo-secrets-check forgejo-logs forgejo-runner-registration-deploy forgejo-runner-deploy forgejo-runner-status forgejo-runner-logs inter-hub-render-baseline inter-hub-dry-run inter-hub-server-dry-run inter-hub-deploy inter-hub-status inter-hub-release-info inter-hub-smoke inter-hub-logs reuse-dry-run reuse-deploy reuse-status reuse-smoke reuse-logs reuse-forgejo-webhook reuse-openbao-eso-token-apply reuse-openbao-store-deploy reuse-runtime-es-deploy reuse-runtime-es-status reuse-webhook-smoke help