From 6cf1d89278ca7e17f8c7a46282aa943fb4ec8ddc Mon Sep 17 00:00:00 2001 From: Scooby Husky Date: Sat, 22 Aug 2026 13:54:43 -0500 Subject: [PATCH] GitLab cross-site replication Phase 2a (corrected): ignoreDifferences approach The CONFIG_TEMPLATE_DIRECTORY redirect from the previous commit doesn't work - confirmed live that extraVolumes is a dead values key for the Praefect subchart specifically (its statefulset.yaml never calls the gitlab.extraVolumes helper in its volumes: list, only volumeMounts calls the corresponding helper - a real chart limitation, not a config mistake). A dangling volumeMount with no matching volume would have failed to schedule. Real fix: ignoreDifferences on ConfigMap gitlab-praefect's data field (argocd-apps/apps/gitlab.yaml) lets Helm create the object normally while ArgoCD stops reconciling its content afterward - the actual config gets kubectl-patched onto the live object directly. praefect-ha-configmap.yaml is now a git-tracked reference/documentation copy (deployed under its own harmless name) rather than something Helm/ArgoCD wires in on its own. Co-Authored-By: Claude Sonnet 5 --- .../manifests/praefect-ha-configmap.yaml | 46 +++++++++++------- apps/gitlab/values.yaml | 47 +++++++++---------- argocd-apps/apps/gitlab.yaml | 13 +++++ 3 files changed, 64 insertions(+), 42 deletions(-) diff --git a/apps/gitlab/manifests/praefect-ha-configmap.yaml b/apps/gitlab/manifests/praefect-ha-configmap.yaml index 77fd0f3..4e2d48e 100644 --- a/apps/gitlab/manifests/praefect-ha-configmap.yaml +++ b/apps/gitlab/manifests/praefect-ha-configmap.yaml @@ -1,4 +1,4 @@ -# GitLab cross-site replication Phase 2a (see +# GitLab cross-site replication (see # /home/scooby/.claude/plans/jiggly-snacking-iverson.md) - the chart has # no support for registering an externally-hosted Gitaly node into an # existing Praefect virtual storage (confirmed live: no @@ -6,24 +6,34 @@ # gitalyReplicas just counts StatefulSet ordinals). Overriding Praefect's # rendered config.toml is the only way to add one. # -# The chart's own gitlab-praefect ConfigMap (auto-rendered from -# global.praefect.virtualStorages) is mounted at /etc/gitaly/templates, -# which CONFIG_TEMPLATE_DIRECTORY already points at - can't just add data -# to that SAME ConfigMap (ArgoCD/Helm fully owns and would revert it), -# and can't mount a second volume at the SAME path/name (Kubernetes -# rejects duplicate volume names). So this ConfigMap mounts at a -# DIFFERENT path (values.yaml's gitlab.praefect.extraVolumes), and -# CONFIG_TEMPLATE_DIRECTORY gets overridden via extraEnv to point at it -# instead - env var duplicate-key "last wins" IS legitimate documented -# Kubernetes behavior for a container's env: list, unlike volumes. +# A values-only CONFIG_TEMPLATE_DIRECTORY redirect (extraEnv + +# extraVolumes/extraVolumeMounts) was tried first and confirmed NOT to +# work: charts/gitlab/charts/praefect/templates/statefulset.yaml's own +# volumes: list never calls the gitlab.extraVolumes helper (only +# volumeMounts does) - a chart limitation specific to this subchart, no +# values-only fix exists. # -# Phase 2a content is intentionally byte-identical to the chart's own -# current rendering (confirmed live via `kubectl -n gitlab get cm -# gitlab-praefect -o jsonpath='{.data.config\.toml\.tpl}'`) - this -# commit only proves the override mechanism itself doesn't break -# anything, before Phase 2b switches addressing to floating hostnames -# and adds the VPS as a 4th node (no reason to change addressing scheme -# before there's an actual cross-site node that needs it). +# THIS ConfigMap (praefect-ha-config) is deployed as a harmless, +# otherwise-unused object - it exists purely as a git-tracked reference +# copy of the content that actually matters. The REAL live config lives +# on the chart's own gitlab-praefect ConfigMap, which +# argocd-apps/apps/gitlab.yaml's ignoreDifferences now exempts from +# ArgoCD's normal drift-reconciliation (its `data` field specifically) - +# apply this file's content to it directly: +# kubectl -n gitlab patch configmap gitlab-praefect --type merge \ +# -p "{\"data\":{\"config.toml.tpl\":\"$(kubectl -n gitlab get cm \ +# praefect-ha-config -o jsonpath='{.data.config\.toml\.tpl}' | \ +# python3 -c 'import sys,json; print(json.dumps(sys.stdin.read())[1:-1])')\"}}" +# (or simpler: kubectl -n gitlab get cm praefect-ha-config -o +# jsonpath='{.data}' | kubectl -n gitlab patch cm gitlab-praefect --type +# merge -p "{\"data\":$(cat -)}") +# +# Content below is intentionally byte-identical to the chart's own +# current rendering for the first pass (confirmed live via `kubectl -n +# gitlab get cm gitlab-praefect -o jsonpath='{.data.config\.toml\.tpl}'`) +# - proves the ignoreDifferences + manual-patch mechanism itself doesn't +# break anything, before a follow-up switches addressing to floating +# hostnames and adds the VPS as a 4th node. apiVersion: v1 kind: ConfigMap metadata: diff --git a/apps/gitlab/values.yaml b/apps/gitlab/values.yaml index 2e63db1..75846d9 100644 --- a/apps/gitlab/values.yaml +++ b/apps/gitlab/values.yaml @@ -308,30 +308,29 @@ gitlab: # this one, so gitalyReplicas: 3 up there always won regardless of # what this said. See global.praefect.virtualStorages above for the # real config.) - - # GitLab cross-site replication Phase 2a (see - # /home/scooby/.claude/plans/jiggly-snacking-iverson.md) - redirects - # Praefect's config template source so a hand-written config.toml.tpl - # (praefect-ha-configmap.yaml) can add a VPS-hosted Gitaly node the - # chart itself has no mechanism to register. The chart's own - # gitlab-praefect ConfigMap is already mounted at - # /etc/gitaly/templates (which CONFIG_TEMPLATE_DIRECTORY points at by - # default) - can't add a second volume at that same path/name - # (Kubernetes rejects duplicate volume names), so this mounts the - # override at a different path and points CONFIG_TEMPLATE_DIRECTORY - # there instead. Duplicate env var names in a container's env: list - # resolve last-wins (documented Kubernetes behavior) - this entry - # renders after the chart's own, so it's the one that takes effect. - extraEnv: - CONFIG_TEMPLATE_DIRECTORY: /etc/gitaly/templates-ha - extraVolumes: - - name: praefect-ha-config - configMap: - name: praefect-ha-config - extraVolumeMounts: - - name: praefect-ha-config - mountPath: /etc/gitaly/templates-ha - readOnly: true + # + # GitLab cross-site replication (see + # /home/scooby/.claude/plans/jiggly-snacking-iverson.md): tried a + # values-only CONFIG_TEMPLATE_DIRECTORY redirect (extraEnv + + # extraVolumes/extraVolumeMounts) to add a VPS-hosted Gitaly node the + # chart has no mechanism to register - confirmed live this doesn't + # work: extraVolumeMounts and extraEnv both render correctly, but + # extraVolumes is a dead values key for THIS subchart specifically - + # charts/gitlab/charts/praefect/templates/statefulset.yaml's own + # volumes: list never calls the gitlab.extraVolumes helper at all + # (only volumeMounts does), so the mount has nothing to mount and the + # pod would fail to schedule. No values-only fix exists. + # + # Real fix: argocd-apps/apps/gitlab.yaml's ignoreDifferences now + # covers ConfigMap gitlab-praefect's `data` field, so Helm creates + # the object (with its own 3-node content) but ArgoCD stops + # reconciling its content afterward. The actual multi-node content + # lives in apps/gitlab/manifests/praefect-ha-configmap.yaml as a + # git-tracked reference/documentation copy (deployed under its own + # name, praefect-ha-config, harmless and otherwise unused) - the + # live gitlab-praefect ConfigMap gets kubectl-patched with that same + # content directly, same "documented but manually-applied" + # convention as every other cross-cluster secret in this plan. # GitLab Exporter for Prometheus metrics gitlab-exporter: diff --git a/argocd-apps/apps/gitlab.yaml b/argocd-apps/apps/gitlab.yaml index 31fd4bc..f00a063 100644 --- a/argocd-apps/apps/gitlab.yaml +++ b/argocd-apps/apps/gitlab.yaml @@ -33,6 +33,19 @@ spec: jsonPointers: - /spec/ports - /spec/selector + # GitLab cross-site replication (see + # /home/scooby/.claude/plans/jiggly-snacking-iverson.md) - the chart + # has no mechanism to register an externally-hosted (VPS) Gitaly node + # into Praefect's virtual storage. Lets the live ConfigMap's `data` + # be kubectl-patched directly (see apps/gitlab/manifests/ + # praefect-ha-configmap.yaml for the content + patch command) without + # ArgoCD reverting it on the next sync - Helm still creates the + # object and everything else about it stays normally managed. + - group: "" + kind: ConfigMap + name: gitlab-praefect + jsonPointers: + - /data syncPolicy: automated: prune: true