Commit Graph

44 Commits

Author SHA1 Message Date
Will Anderson b0f2b7533f fix(mudcraft): grant voicechat permissions to mortal tier 2026-03-29 21:59:30 -05:00
MUDCraft CI d741fa5d0c deploy(mudcraft): update plugin image to 10abb0f6f66e134efd81d787df249a9a738403b9 2026-03-30 02:56:57 +00:00
Will Anderson 0a3be2b40d feat(mudcraft): grant voicechat.mute to Angel tier 2026-03-29 21:55:41 -05:00
Will Anderson da6faf918a feat(mudcraft): auto-bootstrap LuckPerms tiers on every pod start
Adds postStart lifecycle hook that waits for RCON then applies the full
permission structure idempotently on every deploy. Tiers:

  Mortals:   mortal → hero → metamortal
  Immortals: angel → god

Permission structure is now git-managed in configmap-luckperms-bootstrap.yaml
— edit that file to change the permission hierarchy.
2026-03-29 21:55:29 -05:00
Will Anderson c2336dc9fc chore(mudcraft): set difficulty to normal 2026-03-29 21:39:58 -05:00
MUDCraft CI c4fbfb79ac deploy(mudcraft): update plugin image to 54f38f924ef38789a02d1316a3605137b6193d71 2026-03-30 02:38:36 +00:00
Will Anderson 574faa0279 fix(mudcraft): set voice_host so clients connect to correct UDP endpoint
Simple Voice Chat was advertising a blank voice_host, causing clients to
try connecting to the pod's internal IP over UDP. Explicitly set
voice_host=mudcraft.nook.family:24454 via ConfigMap + initContainer.
2026-03-29 21:22:03 -05:00
MUDCraft CI 1313886912 deploy(mudcraft): update plugin image to 7d3a8132bd9f9790101c214ee4d5776f53b63137 2026-03-30 02:15:41 +00:00
Will Anderson 1a27f2ad79 feat(mudcraft): whitelist random_guy789 2026-03-29 20:47:12 -05:00
Will Anderson 63d54d9ea0 fix(mudcraft): substitute LP_PASSWORD in LuckPerms config at init time
LuckPerms reads config.yml as a literal string — ${LP_PASSWORD} was
never being substituted, causing auth failures against PostgreSQL.
initContainer now has the secret injected as an env var and uses sed
to write the real password into the config before LuckPerms reads it.

Also adds faultexception to WHITELIST so they can connect.
2026-03-29 20:41:39 -05:00
Will Anderson 8588def1ab fix(mudcraft): add fsGroup 1000 so PVC dirs are writable by server process
Existing /data/plugins/LuckPerms/ dir on PVC was created by root, so
UID 1000 couldn't create subdirs (libs/, etc.). fsGroup:1000 tells k8s
to chown all volume mounts to group 1000 at pod startup, fixing access.
2026-03-29 20:37:44 -05:00
MUDCraft CI a86e9f892f deploy(mudcraft): update plugin image to d2528281d4d304a8ae62e0f73ba6aed034113d34 2026-03-30 01:36:19 +00:00
Will Anderson e79424e6e1 fix(mudcraft): run initContainer as UID 1000 so plugin dirs are writable
LuckPerms was failing with AccessDeniedException on /data/plugins/LuckPerms/libs
because the initContainer was creating directories as root. Main container runs
as UID 1000 and couldn't write inside them. Running initContainer as matching
UID 1000 fixes ownership.
2026-03-29 20:34:14 -05:00
Will Anderson e482059a03 fix(mudcraft): fix LuckPerms init by removing subPath mounts
SubPath mounts into plugin directories were causing k8s to create those
directories owned by root before the server process could write to them.
LuckPerms was failing with "Unable to create libs directory" as a result.

Move config injection to the initContainer: it now cleans stale JARs
(rm *.jar), copies fresh JARs from the plugins image, and pre-creates
the LuckPerms and PurpurExtras directories with configs copied from
ConfigMaps. Main container no longer mounts configs via subPath.

Also fixes stale JAR accumulation — initContainer now clears old JARs
before copying, preventing broken old versions from loading.
2026-03-29 20:30:50 -05:00
Will Anderson 50aa2d2828 Force pod restart — pick up corrected plugin image SHA 2026-03-29 20:20:49 -05:00
Will Anderson 77b94fa946 Fix mudcraft plugin image tag — point to valid SHA from run 225 2026-03-29 20:18:46 -05:00
MUDCraft CI 3d702f644f deploy(mudcraft): update plugin image to 2026-03-30 01:14:38 +00:00
Will Anderson 8d3e72da17 Pin mudcraft plugin image to SHA (CI will update this on every build) 2026-03-29 20:07:16 -05:00
Will Anderson 31363d2631 Configure LuckPerms with PostgreSQL backend for persistent permissions
- LuckPerms stores all permissions/groups in Postgres (not ephemeral ops.json)
- Mount luckperms config.yml from ConfigMap with DB connection details
- LP_PASSWORD injected from same secret as DB_PASSWORD
- OPS env var kept as bootstrap until LuckPerms admin group is configured
2026-03-29 19:59:34 -05:00
Will Anderson 222ddf044d Persist faultexception as op via OPS env var (survives pod restarts) 2026-03-29 19:58:42 -05:00
Will Anderson 27623af8f9 Add Simple Voice Chat UDP routing for mudcraft
- Expose UDP 24454 on mudcraft pod and Service (Simple Voice Chat)
- Add Traefik voicechat UDP entrypoint on port 24454
- Add IngressRouteUDP to route external UDP 24454 → mudcraft service
2026-03-29 19:42:16 -05:00
Will Anderson bb8748d426 feat(registry): daily GC cronjob — keep last 10 SHA tags per repo, prune layers 2026-03-29 19:26:14 -05:00
Will Anderson 70e69e1283 MUDCraft: initContainer plugin pattern + PurpurExtras ConfigMap 2026-03-29 19:07:58 -05:00
Will Anderson c7ef04b37e Update Purpur to 1.21.11 (latest) 2026-03-29 18:38:10 -05:00
Will Anderson df216e74f9 Reduce mudcraft heap to 4G, lower resource requests 2026-03-29 18:33:16 -05:00
Will Anderson a94aca0e01 Accept Minecraft EULA 2026-03-29 18:19:06 -05:00
Will Anderson 1cf47477d3 Add MUDCraft Minecraft server infrastructure
- Purpur 1.21.4 server via itzg/docker-minecraft-server (java21)
- StatefulSet with 3 PVCs: worlds (20Gi), plugins (5Gi), logs (5Gi)
- Aikar G1GC JVM flags, 6GB heap (sized for Legion's 15GB RAM)
- Postgres: mudcraft database + user in existing platform/postgres
- RCON secret + DB password via ExternalSecret → Vault
- Traefik TCP entrypoint on port 25565 for mudcraft.nook.family
- mudcraft namespace via Terraform
- Argo CD app watching k8s/mudcraft/
2026-03-29 18:17:48 -05:00
Will Anderson 2cb89b715f ci: copy forgejo-runner binary from correct path 2026-03-26 13:00:42 -05:00
Will Anderson 23131ef04f ci: use data.forgejo.org for runner image 2026-03-26 13:00:01 -05:00
Will Anderson e4db8bbda5 ci: switch to Forgejo runner for proper DEFAULT_ACTIONS_URL support 2026-03-26 12:58:22 -05:00
Will Anderson c9bee67e67 feat: make ci-base equivalent to ubuntu-latest
Comprehensive runner image with Python, Node.js 20, Ruby, Go 1.22,
Docker CLI, kubectl, Helm, yq, gh, make, jq, rsync, zstd, and all
standard tools. Mirrors GitHub ubuntu-24.04 hosted runner so workflows
are swappable between Gitea and GitHub with no friction.
2026-03-26 12:11:38 -05:00
Will Anderson 798cf8611d feat: make ci-base a comprehensive runner image like ubuntu-latest
Add Node.js 20 LTS (required for all Forgejo JS actions), Python 3.12,
Ruby, Go 1.22, Docker CLI, kubectl, Helm, yq, gh, zstd, and common
build/system tools. Mirrors GitHub ubuntu-24.04 hosted runner capability
so jobs work without needing container: overrides for standard tasks.
2026-03-26 12:08:16 -05:00
Will Anderson 978639601c fix: correct act_runner binary path in ci-base Dockerfile 2026-03-26 11:35:37 -05:00
Will Anderson 9595a18f3a refactor: rebase CI runner on Ubuntu 24.04, rename to ci-base
Replace Alpine-based legion-runner with a minimal Ubuntu 24.04 image.
The act_runner binary is copied from the official image via multi-stage
build. Job-specific tooling (Ruby, Node, Python, etc.) belongs in
per-job container images specified via container: in workflows, not
in the base runner image.

Rename: legion-runner → ci-base
2026-03-26 11:32:52 -05:00
Will Anderson d163a92ec6 fix: replace registry Ingress+Buffering with IngressRoute for streaming
The Buffering middleware was causing 413 on large Docker layer pushes
by spooling entire request bodies to disk before forwarding. Docker's
chunked blob upload protocol (PATCH/PUT with Content-Range) requires
streaming, not buffering.

Replace with IngressRoute CRDs + Certificate resources for direct
streaming passthrough. responseForwarding.flushInterval=100ms ensures
prompt chunk delivery to the registry backend.
2026-03-26 11:13:25 -05:00
Will Anderson ce45384f81 feat: add Ruby and bundler to legion-runner image
Required for Jekyll-based doc builds in CI.
2026-03-26 10:59:36 -05:00
Will Anderson f3477ac102 ci: fix gitea runner URL and set DEFAULT_ACTIONS_URL
- external-secrets.yaml: GITEA_INSTANCE_URL changed from cluster-internal
  URL to https://git.neuralplatform.ai so runner can register externally
- gitea.yaml: add GITEA__actions__DEFAULT_ACTIONS_URL=gitea so all
  actions/* references resolve from gitea.com, not github.com
- Dockerfile: track runner image (Python 3.12 + build deps) in repo
2026-03-26 10:35:13 -05:00
Will Anderson d5c5d753c7 ci: use custom pantheon-ci image; fix registry 413 with Traefik buffering middleware 2026-03-25 20:36:20 -05:00
Will Anderson 9904bce343 gitea-runner: use internal cluster URL to avoid CF tunnel timeouts on runner long-polling 2026-03-25 20:29:23 -05:00
Will Anderson 371e60d3bc fix: add admin-user key to grafana-admin-secret ExternalSecret 2026-03-25 10:52:10 -05:00
Will Anderson 3737ff0bcb fix: pin PVCs to existing PVs; fix kube-prometheus-stack grafana auth
PVC manifests: add volumeName to bind new PVCs to existing PVs whose
old PVCs were accidentally deleted during Terraform->ArgoCD migration.
All PVs patched to Retain to prevent data loss on pod restart.

kube-prometheus-stack: replace invalid adminPassword.valueFrom.secretKeyRef
(Helm values don't support k8s secretKeyRef syntax) with correct
admin.existingSecret + admin.passwordKey pattern.
2026-03-25 10:48:10 -05:00
Will Anderson f1fc1fafea Fix ddclient image: use linuxserver/ddclient (correct image) 2026-03-25 10:36:23 -05:00
Will Anderson 6c073029a3 Fix gitea-runner ExternalSecret: use template for static GITEA_INSTANCE_URL 2026-03-25 10:34:11 -05:00
Will Anderson 4d0cfb1bbf Migrate k8s config from Terraform to Argo CD + ESO
Phase 1: Install External Secrets Operator via Argo CD app
- apps/external-secrets.yaml — ESO Helm chart install
- apps/external-secrets-config.yaml — ClusterSecretStore deployment
- k8s/external-secrets/cluster-secret-store.yaml — Vault backend using vault-token Secret

Phase 2: Create k8s manifests for all services
- k8s/neuron/ — PVC, ConfigMap, ExternalSecrets (neuron-secrets, cloudflared-secret), Ingress
- k8s/gitea/ — PVC, ConfigMap (custom CSS), ExternalSecret (gitea-db), Ingress
- k8s/github-runner/ — ExternalSecret (github-runner-secret)
- k8s/gitea-runner/ — ExternalSecret (gitea-runner-secret)
- k8s/monitoring/ — ExternalSecrets (grafana, slack), Alloy OTLP service+middleware, datasources ConfigMap, Ingress
- k8s/postgres/ — ExternalSecret (postgres-passwords)
- k8s/vault/ — ExternalSecret (vault-gcp-sa from Vault)
- k8s/adguard/ — PVCs, ConfigMap, Certificate, Ingress, ddclient Deployment+ExternalSecret
- k8s/ollama/ — PVC, Ingress
- k8s/headscale/ — PVC
- k8s/packages/ — PVCs, ConfigMap, Ingresses
- k8s/registry/ — PVC, Ingresses
- k8s/backup/ — CronJob, ExternalSecret (backup-credentials)

New Argo CD apps for Helm releases:
- apps/kube-prometheus-stack.yaml, loki.yaml, tempo.yaml, alloy.yaml
- apps/postgres.yaml, redis.yaml, vault.yaml

New Argo CD apps for k8s config paths:
- apps/neuron-config, gitea-config, ci-config, gitea-runner-config
- apps/monitoring-config, adguard-config, ollama-config, headscale-config
- apps/packages-config, registry-config, postgres-config, vault-config, backup

Phase 3: Strip Terraform to infrastructure-only
- All kubernetes_* and helm_release resources removed from service .tf files
- Each service .tf now contains only kubernetes_namespace (bootstrap dependency)
- variables.tf stripped to only cloudflare_api_key, cloudflare_email, gitea_api_token
- namespaces.tf gains external-secrets namespace
- ingress.tf, backup.tf, ddclient.tf emptied (resources in k8s/)
- cert-manager.tf, argocd.tf, traefik.tf unchanged (bootstrap)
2026-03-25 10:29:14 -05:00