chore: make Supabase StorageClass preflight advisory instead of blocking

- Updated `deploy.sh` logic to ensure StorageClass preflight checks log warnings instead of stopping execution.
- Allowed Supabase deploy to reconcile or create missing/misconfigured StorageClass during runtime.
- Added tests to validate advisory behavior and ensure non-blocking deployment flow.
This commit is contained in:
chrisfu 2026-04-19 01:47:54 -07:00
parent 00445404ee
commit 750ff213e3
4 changed files with 121 additions and 28 deletions

View File

@ -2297,6 +2297,33 @@ if [[ "$MODE" == "k8s" ]]; then
fi
GITLAB_INGRESS_CLASS="${GITLAB_INGRESS_CLASS:-$_default_gitlab_ingress_class}"
# Single GitLab front-door owner model.
# - operator: GitLab chart/operator-managed ingress owns ${GITLAB_PUBLIC_HOSTS}
# - fallback: custom fallback ingress (gitlab-kong-ingress) owns ${GITLAB_PUBLIC_HOSTS}
# In k8s/GKE mode, default to operator ownership to avoid dual-ingress host claims.
_default_gitlab_frontdoor_owner="fallback"
if [[ "$MODE" == "k8s" ]]; then
_default_gitlab_frontdoor_owner="operator"
fi
GITLAB_FRONTDOOR_OWNER="${GITLAB_FRONTDOOR_OWNER:-$_default_gitlab_frontdoor_owner}"
GITLAB_FRONTDOOR_OWNER="${GITLAB_FRONTDOOR_OWNER,,}"
case "$GITLAB_FRONTDOOR_OWNER" in
operator|fallback)
;;
*)
die "Unsupported GITLAB_FRONTDOOR_OWNER='${GITLAB_FRONTDOOR_OWNER}'. Supported values: operator, fallback."
;;
esac
GITLAB_WEBSERVICE_INGRESS_ENABLED="${GITLAB_WEBSERVICE_INGRESS_ENABLED:-true}"
if [[ "$MODE" == "k8s" ]]; then
if [[ "$GITLAB_FRONTDOOR_OWNER" == "operator" ]]; then
GITLAB_WEBSERVICE_INGRESS_ENABLED=true
elif [[ "$GITLAB_FRONTDOOR_OWNER" == "fallback" ]]; then
GITLAB_WEBSERVICE_INGRESS_ENABLED=false
fi
fi
# Google Workspace OIDC — FRONTDOOR_HOST gates OmniAuth configuration.
# On k3s: api.prole.org is the prole-auth SSO gateway (knoe-auth service).
# Requires k8s secret 'gitlab-google-oidc' in GITLAB_NAMESPACE with Google
@ -3564,7 +3591,7 @@ fi)
name: ${GITLAB_DOMAIN}
ssh: ${GITLAB_DOMAIN}
ingress:
class: kong
class: ${GITLAB_INGRESS_CLASS}
configureCertmanager: false
tls:
enabled: false
@ -3660,9 +3687,9 @@ fi)
timeoutSeconds: 30
failureThreshold: 60
ingress:
enabled: true
enabled: ${GITLAB_WEBSERVICE_INGRESS_ENABLED}
annotations:
kubernetes.io/ingress.class: kong
kubernetes.io/ingress.class: ${GITLAB_INGRESS_CLASS}
minReplicas: 1
maxReplicas: 1
${WORKLOAD_JEMALLOC_VALUES_YAML}
@ -4184,27 +4211,62 @@ EOF
unset _webservice_svc
fi
log "Ensuring ingress (${GITLAB_INGRESS_CLASS}) for hosts=${_gitlab_hosts_csv} -> ${WEBSERVICE_SVC}:8181 ..."
log "Reconciling GitLab front-door owner='${GITLAB_FRONTDOOR_OWNER}' (ingressClass=${GITLAB_INGRESS_CLASS}) for hosts=${_gitlab_hosts_csv} -> ${WEBSERVICE_SVC}:8181 ..."
_skip_gitlab_fallback_ingress=0
if assert_unique_ingress_host_claims "gitlab-kong-ingress" "$NAMESPACE" "$_gitlab_hosts_csv" "$GITLAB_RELEASE" "$WEBSERVICE_SVC"; then
:
if [[ "$GITLAB_FRONTDOOR_OWNER" == "operator" ]]; then
if assert_unique_ingress_host_claims "${GITLAB_RELEASE}-webservice-default" "$NAMESPACE" "$_gitlab_hosts_csv" "$GITLAB_RELEASE" "$WEBSERVICE_SVC"; then
:
else
_ingress_claim_rc=$?
case "$_ingress_claim_rc" in
10)
log "GitLab operator ingress host ownership confirmed in namespace '${NAMESPACE}': ${INGRESS_HOST_CLAIM_DETAILS}"
;;
*)
die "Duplicate ingress host/path claim detected for GitLab operator ingress '${NAMESPACE}/${GITLAB_RELEASE}-webservice-default': ${INGRESS_HOST_CLAIM_DETAILS}"
;;
esac
fi
if [[ "${GITLAB_INGRESS_CLASS}" == "gce" ]]; then
_operator_ingress_name="${GITLAB_RELEASE}-webservice-default"
if kubectl -n "$NAMESPACE" get ingress "$_operator_ingress_name" >/dev/null 2>&1; then
log "Annotating ingress ${_operator_ingress_name} with ManagedCertificate=${GITLAB_MANAGED_CERT_NAME} and FrontendConfig=${GITLAB_FRONTEND_CONFIG_NAME}..."
kubectl -n "$NAMESPACE" annotate ingress "$_operator_ingress_name" \
"networking.gke.io/managed-certificates=${GITLAB_MANAGED_CERT_NAME}" \
"networking.gke.io/v1beta1.FrontendConfig=${GITLAB_FRONTEND_CONFIG_NAME}" \
--overwrite >/dev/null || warn "Failed to annotate ${_operator_ingress_name} with GCE ingress TLS annotations."
else
warn "Operator ingress ${_operator_ingress_name} not found yet; cannot apply GCE ingress annotations in this pass."
fi
unset _operator_ingress_name
fi
if kubectl -n "$NAMESPACE" get ingress gitlab-kong-ingress >/dev/null 2>&1; then
log "Deleting stale fallback ingress ${NAMESPACE}/gitlab-kong-ingress to enforce single front-door ownership (${GITLAB_FRONTDOOR_OWNER})."
kubectl -n "$NAMESPACE" delete ingress gitlab-kong-ingress --ignore-not-found >/dev/null || \
warn "Failed to delete stale fallback ingress ${NAMESPACE}/gitlab-kong-ingress."
fi
else
_ingress_claim_rc=$?
case "$_ingress_claim_rc" in
10)
_skip_gitlab_fallback_ingress=1
log "Operator-managed ingress already owns GitLab host/path in namespace '${NAMESPACE}': ${INGRESS_HOST_CLAIM_DETAILS}"
log "Skipping fallback ingress creation for GitLab release '${GITLAB_RELEASE}'."
;;
*)
die "Duplicate ingress host/path claim detected for GitLab ingress '${NAMESPACE}/gitlab-kong-ingress': ${INGRESS_HOST_CLAIM_DETAILS}"
;;
esac
fi
_skip_gitlab_fallback_ingress=0
if assert_unique_ingress_host_claims "gitlab-kong-ingress" "$NAMESPACE" "$_gitlab_hosts_csv" "$GITLAB_RELEASE" "$WEBSERVICE_SVC"; then
:
else
_ingress_claim_rc=$?
case "$_ingress_claim_rc" in
10)
_skip_gitlab_fallback_ingress=1
log "Operator-managed ingress already owns GitLab host/path in namespace '${NAMESPACE}': ${INGRESS_HOST_CLAIM_DETAILS}"
log "Skipping fallback ingress creation for GitLab release '${GITLAB_RELEASE}'."
;;
*)
die "Duplicate ingress host/path claim detected for GitLab ingress '${NAMESPACE}/gitlab-kong-ingress': ${INGRESS_HOST_CLAIM_DETAILS}"
;;
esac
fi
if [[ "$_skip_gitlab_fallback_ingress" != "1" ]]; then
kubectl apply -f - <<EOF
if [[ "$_skip_gitlab_fallback_ingress" != "1" ]]; then
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
@ -4219,6 +4281,7 @@ spec:
ingressClassName: ${GITLAB_INGRESS_CLASS}
rules:${GITLAB_INGRESS_RULES_YAML}
EOF
fi
fi
# ---------------------------------------------------------------------------

View File

@ -6,18 +6,20 @@ SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
PROLE_HOME=$(cd "$SCRIPT_DIR/../.." && pwd)
SOURCE_ETC_DIR="$PROLE_HOME/etc"
SOURCE_ETC_LIB_SHELL_DIR="$PROLE_HOME/etc/lib/shell"
SOURCE_GITLAB_OIDC_TEMPLATE="$PROLE_HOME/deploy/gcp/gke/gitlab-google-oidc-secret.example.yaml"
TMP_DIR=$(mktemp -d)
trap 'rm -rf "$TMP_DIR"' EXIT
WORK_DIR="$TMP_DIR/work"
BIN_DIR="$TMP_DIR/bin"
mkdir -p "$WORK_DIR/etc/lib/shell" "$WORK_DIR/conf" "$BIN_DIR"
mkdir -p "$WORK_DIR/etc/lib/shell" "$WORK_DIR/conf" "$WORK_DIR/deploy/gcp/gke" "$BIN_DIR"
cp "$SOURCE_ETC_DIR/init_gitlab.sh" "$WORK_DIR/etc/init_gitlab.sh"
cp "$SOURCE_ETC_DIR/prole_cfg.sh" "$WORK_DIR/etc/prole_cfg.sh"
cp "$SOURCE_ETC_DIR/common_core_lib.sh" "$WORK_DIR/etc/common_core_lib.sh"
cp "$SOURCE_ETC_LIB_SHELL_DIR/common_core_lib.sh" "$WORK_DIR/etc/lib/shell/common_core_lib.sh"
cp "$SOURCE_GITLAB_OIDC_TEMPLATE" "$WORK_DIR/deploy/gcp/gke/gitlab-google-oidc-secret.example.yaml"
chmod +x "$WORK_DIR/etc/init_gitlab.sh"
app_ctx="gke_plenary-truck-485623-p7_us-west3_knoe-dev-0"
@ -205,6 +207,9 @@ export GITLAB_NO_WAIT=1
export SKIP_REGISTRY_MIGRATE=1
export GARAGE_S3_ENDPOINT="http://garage.internal.knoe:3900"
export GITLAB_OBJECT_STORAGE_REQUIRED=0
export GITLAB_OIDC_CLIENT_ID="dummy-client-id"
export GITLAB_OIDC_CLIENT_SECRET="dummy-client-secret"
export GITLAB_REPAIR_BLOCKED_AUTOCLEAN=1
unset PROLE_MODE
unset KUBE_CONTEXT_NAME
unset KUBECTL_CONTEXT
@ -223,7 +228,7 @@ if [[ -f "$APPLY_GITLAB_INGRESS_MARKER" ]]; then
exit 1
fi
if ! grep -q "Duplicate ingress host/path claim detected for GitLab ingress 'gitlab/gitlab-kong-ingress'" "$TMP_DIR/stderr"; then
if ! grep -q "Duplicate ingress host/path claim detected for GitLab operator ingress 'gitlab/gitlab-webservice-default'" "$TMP_DIR/stderr"; then
echo "FAILURE: expected duplicate ingress host/path fatal error" >&2
cat "$TMP_DIR/stderr" >&2
exit 1

View File

@ -6,18 +6,20 @@ SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
PROLE_HOME=$(cd "$SCRIPT_DIR/../.." && pwd)
SOURCE_ETC_DIR="$PROLE_HOME/etc"
SOURCE_ETC_LIB_SHELL_DIR="$PROLE_HOME/etc/lib/shell"
SOURCE_GITLAB_OIDC_TEMPLATE="$PROLE_HOME/deploy/gcp/gke/gitlab-google-oidc-secret.example.yaml"
TMP_DIR=$(mktemp -d)
trap 'rm -rf "$TMP_DIR"' EXIT
WORK_DIR="$TMP_DIR/work"
BIN_DIR="$TMP_DIR/bin"
mkdir -p "$WORK_DIR/etc/lib/shell" "$WORK_DIR/conf" "$BIN_DIR"
mkdir -p "$WORK_DIR/etc/lib/shell" "$WORK_DIR/conf" "$WORK_DIR/deploy/gcp/gke" "$BIN_DIR"
cp "$SOURCE_ETC_DIR/init_gitlab.sh" "$WORK_DIR/etc/init_gitlab.sh"
cp "$SOURCE_ETC_DIR/prole_cfg.sh" "$WORK_DIR/etc/prole_cfg.sh"
cp "$SOURCE_ETC_DIR/common_core_lib.sh" "$WORK_DIR/etc/common_core_lib.sh"
cp "$SOURCE_ETC_LIB_SHELL_DIR/common_core_lib.sh" "$WORK_DIR/etc/lib/shell/common_core_lib.sh"
cp "$SOURCE_GITLAB_OIDC_TEMPLATE" "$WORK_DIR/deploy/gcp/gke/gitlab-google-oidc-secret.example.yaml"
chmod +x "$WORK_DIR/etc/init_gitlab.sh"
app_ctx="gke_plenary-truck-485623-p7_us-west3_knoe-dev-0"
@ -206,6 +208,9 @@ export GITLAB_NO_WAIT=1
export SKIP_REGISTRY_MIGRATE=1
export GARAGE_S3_ENDPOINT="http://garage.internal.knoe:3900"
export GITLAB_OBJECT_STORAGE_REQUIRED=0
export GITLAB_OIDC_CLIENT_ID="dummy-client-id"
export GITLAB_OIDC_CLIENT_SECRET="dummy-client-secret"
export GITLAB_REPAIR_BLOCKED_AUTOCLEAN=1
unset PROLE_MODE
unset KUBE_CONTEXT_NAME
unset KUBECTL_CONTEXT
@ -226,14 +231,14 @@ if [[ -f "$APPLY_GITLAB_INGRESS_MARKER" ]]; then
exit 1
fi
if ! grep -q "Operator-managed ingress already owns GitLab host/path" "$TMP_DIR/stdout"; then
echo "FAILURE: expected operator-owned ingress skip log" >&2
if ! grep -q "GitLab operator ingress host ownership confirmed" "$TMP_DIR/stdout"; then
echo "FAILURE: expected operator ingress ownership confirmation log" >&2
cat "$TMP_DIR/stdout" >&2
exit 1
fi
if ! grep -q "Skipping fallback ingress creation for GitLab release" "$TMP_DIR/stdout"; then
echo "FAILURE: expected fallback ingress skip log" >&2
if ! grep -q "front-door owner='operator'" "$TMP_DIR/stdout"; then
echo "FAILURE: expected operator front-door owner log" >&2
cat "$TMP_DIR/stdout" >&2
exit 1
fi

View File

@ -652,6 +652,26 @@ def test_init_gitlab_enforces_authoritative_gitaly_storageclass_fields_in_render
assert "storageClass: ${GITALY_STORAGE_CLASS}" in script
def test_init_gitlab_uses_single_frontdoor_owner_model_for_k8s():
"""k8s/GKE GitLab deploy must default to one front-door owner and clean stale fallback ingress."""
script = (REPO_ROOT / "etc" / "init_gitlab.sh").read_text(encoding="utf-8")
assert 'GITLAB_FRONTDOOR_OWNER="${GITLAB_FRONTDOOR_OWNER:-$_default_gitlab_frontdoor_owner}"' in script
assert '_default_gitlab_frontdoor_owner="operator"' in script
assert "GITLAB_WEBSERVICE_INGRESS_ENABLED=false" in script
assert "Deleting stale fallback ingress" in script
def test_init_gitlab_renders_ingress_class_from_config_without_hardcoded_kong():
"""GitLab ingress class rendering must follow configured ingress class consistently."""
script = (REPO_ROOT / "etc" / "init_gitlab.sh").read_text(encoding="utf-8")
assert "class: ${GITLAB_INGRESS_CLASS}" in script
assert "kubernetes.io/ingress.class: ${GITLAB_INGRESS_CLASS}" in script
assert " ingress:\n class: kong" not in script
assert "kubernetes.io/ingress.class: kong" not in script
def test_init_gitlab_blocks_wrong_live_gitaly_claim_template_storageclass():
"""Live Gitaly StatefulSet repo-data claim-template class mismatches must be hard-blocked unless destructive repair is enabled."""
script = (REPO_ROOT / "etc" / "init_gitlab.sh").read_text(encoding="utf-8")