chore: add hostPath jemalloc optimization and enhance monitoring storage class handling

- Introduced jemalloc hostPath optimizations with configurable modes (`auto`, `off`, `force`).
- Integrated jemalloc setup with best-effort and forced validation flows for ensuring cluster compatibility.
- Enhanced monitoring storage class logic with mode-specific handling (`k3s`, `k3d`, `gke`) and improved validation of required classes.
- Added safeguards and detailed logging for unsupported configurations and failure scenarios.
This commit is contained in:
chrisfu 2026-04-12 21:20:05 -07:00
parent bfa712273e
commit 35299fdd52
3 changed files with 265 additions and 30 deletions

View File

@ -67,6 +67,77 @@ log() {
echo "==> $*"
}
write_split_supabase_values() {
local source_values="$1"
local app_values="$2"
local db_values="$3"
python3 - "$source_values" "$app_values" "$db_values" <<'PY'
import json
import sys
from copy import deepcopy
source_path, app_path, db_path = sys.argv[1:4]
base = json.load(open(source_path, encoding="utf-8"))
def ensure_enabled(data, component, enabled):
deployment = data.setdefault("deployment", {})
cfg = deployment.setdefault(component, {})
cfg["enabled"] = bool(enabled)
app_values = deepcopy(base)
ensure_enabled(app_values, "studio", False)
ensure_enabled(app_values, "kong", False)
app_values.setdefault("studioIngress", {})["enabled"] = False
app_values.setdefault("ingress", {})["enabled"] = False
db_values = deepcopy(base)
for component in (
"analytics",
"auth",
"functions",
"imgproxy",
"meta",
"minio",
"realtime",
"rest",
"storage",
"vector",
):
ensure_enabled(db_values, component, False)
ensure_enabled(db_values, "studio", True)
ensure_enabled(db_values, "kong", True)
db_values.setdefault("studioIngress", {})["enabled"] = True
db_values.setdefault("ingress", {})["enabled"] = True
json.dump(app_values, open(app_path, "w", encoding="utf-8"), indent=2)
json.dump(db_values, open(db_path, "w", encoding="utf-8"), indent=2)
PY
}
load_manifest_summary_path() {
local summary="$PROJECT_ROOT/supabase/helm/generated/manifest-summary.json"
if [[ ! -f "$summary" ]]; then
return 0
fi
python3 - "$summary" "$1" <<'PY'
import json
import sys
path = sys.argv[1]
key = sys.argv[2]
try:
data = json.load(open(path, encoding="utf-8"))
except Exception:
print("")
sys.exit(0)
value = data.get(key, "")
print(value if isinstance(value, str) else "")
PY
}
apply_defaults() {
DEV_HOME="${DEV_HOME:-$HOME/dev}"
DEV_HOME="${DEV_HOME/#\~/$HOME}"
@ -1943,21 +2014,12 @@ run_helm() {
helm_render_values
setup_knoe_db_for_supabase
local summary="$PROJECT_ROOT/supabase/helm/generated/manifest-summary.json"
local values="$PROJECT_ROOT/supabase/helm/generated/values.generated.json"
local db_frontdoor_manifest_path=""
local ns="supabase"
if [[ -f "$summary" ]]; then
ns=$(python3 - "$summary" <<'PY'
import json, sys
try:
path = sys.argv[1]
data = json.load(open(path))
print(data.get("supabase_namespace","supabase"))
except Exception:
print("supabase")
PY
)
fi
ns="$(load_manifest_summary_path supabase_namespace)"
ns="${ns:-supabase}"
db_frontdoor_manifest_path="$(load_manifest_summary_path manifests_frontdoor_db)"
if [[ "$HELM_TEMPLATE_ONLY" == "true" ]]; then
log "Helm template only; manifests ready in supabase/k8s"
@ -2054,6 +2116,25 @@ print(base)" 2>/dev/null || true)
max_attempts=2
fi
local split_frontdoor_to_db="false"
if [[ "${MODE:-}" == "k8s" ]]; then
local db_ctx
db_ctx="$(resolve_db_cluster_kubecontext)"
if [[ -n "$db_ctx" ]]; then
split_frontdoor_to_db="true"
fi
fi
local split_app_values_file=""
local split_db_values_file=""
if [[ "$split_frontdoor_to_db" == "true" ]]; then
split_app_values_file="$PROJECT_ROOT/supabase/helm/generated/values.app.generated.json"
split_db_values_file="$PROJECT_ROOT/supabase/helm/generated/values.frontdoor-db.generated.json"
write_split_supabase_values "$values" "$split_app_values_file" "$split_db_values_file"
values="$split_app_values_file"
fi
local attempt
attempt=1
while (( attempt <= max_attempts )); do
@ -2063,6 +2144,11 @@ print(base)" 2>/dev/null || true)
helm_render_values
setup_knoe_db_for_supabase
ensure_k8s_supabase_static_pvs "$storage_class"
if [[ "$split_frontdoor_to_db" == "true" ]]; then
write_split_supabase_values "$PROJECT_ROOT/supabase/helm/generated/values.generated.json" "$split_app_values_file" "$split_db_values_file"
values="$split_app_values_file"
fi
fi
log "Installing Supabase via Helm into namespace '$ns' (attempt ${attempt}/${max_attempts})..."
@ -2072,6 +2158,30 @@ print(base)" 2>/dev/null || true)
return 1
fi
if [[ "$split_frontdoor_to_db" == "true" ]]; then
local db_release="${HELM_RELEASE}-frontdoor-db"
local db_ctx
db_ctx="$(resolve_db_cluster_kubecontext)"
if [[ -z "$db_ctx" ]]; then
die "DB cluster kubecontext is required for split Supabase Studio/Kong relocation."
fi
if ! kubectl config get-contexts "$db_ctx" >/dev/null 2>&1; then
die "DB cluster kubecontext '${db_ctx}' is not available in kubeconfig."
fi
log "Installing Supabase Studio/Kong frontdoor release into DB cluster context '${db_ctx}'..."
if ! helm --kube-context "$db_ctx" upgrade --install "$db_release" "$PROJECT_ROOT/supabase/helm/knoe-supabase" \
-n "$ns" --create-namespace -f "$split_db_values_file" "${helm_set_args[@]}"; then
warn "DB-cluster Studio/Kong Helm install failed; falling back to legacy kompose flow."
return 1
fi
if [[ -n "$db_frontdoor_manifest_path" && -s "$db_frontdoor_manifest_path" ]]; then
log "Applying rendered Studio/Kong frontdoor manifests to DB cluster for explicit ingress ownership..."
db_kubectl apply -f "$db_frontdoor_manifest_path"
fi
fi
enforce_supabase_workload_node "$ns"
local wait_enabled

View File

@ -131,6 +131,103 @@ def _normalize_public_hosts(raw_hosts: str, fallback_host: str) -> tuple[list[st
return host_entries, public_url
def _extract_k8s_docs(rendered_manifest: str) -> list[dict[str, Any]]:
docs: list[dict[str, Any]] = []
for chunk in rendered_manifest.split("\n---"):
text = chunk.strip()
if not text:
continue
try:
parsed = json.loads(text)
except Exception:
lines = text.splitlines()
api_version = ""
kind = ""
name = ""
namespace = ""
for idx, raw_line in enumerate(lines):
stripped = raw_line.strip()
if stripped.startswith("apiVersion:"):
api_version = stripped.split(":", 1)[1].strip()
elif stripped.startswith("kind:"):
kind = stripped.split(":", 1)[1].strip()
elif stripped == "metadata:":
j = idx + 1
while j < len(lines):
meta_line = lines[j]
if meta_line and not meta_line.startswith(" "):
break
meta_stripped = meta_line.strip()
if meta_stripped.startswith("name:"):
name = meta_stripped.split(":", 1)[1].strip()
elif meta_stripped.startswith("namespace:"):
namespace = meta_stripped.split(":", 1)[1].strip()
j += 1
if kind:
docs.append(
{
"apiVersion": api_version,
"kind": kind,
"metadata": {"name": name, "namespace": namespace},
}
)
continue
if isinstance(parsed, dict) and parsed.get("kind"):
docs.append(parsed)
return docs
def _doc_key(doc: dict[str, Any]) -> tuple[str, str, str, str]:
api_version = str(doc.get("apiVersion") or "")
kind = str(doc.get("kind") or "")
meta = doc.get("metadata") or {}
if not isinstance(meta, dict):
meta = {}
namespace = str(meta.get("namespace") or "")
name = str(meta.get("name") or "")
return api_version, kind, namespace, name
def _dump_manifest_docs(path: Path, docs: list[dict[str, Any]]) -> None:
if not docs:
path.write_text("")
return
payload = "\n---\n".join(json.dumps(doc) for doc in docs)
path.write_text(f"{payload}\n")
def _split_frontdoor_docs(rendered_manifest: str) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:
docs = _extract_k8s_docs(rendered_manifest)
studio_kinds = {"Deployment", "Service", "Ingress"}
kong_kinds = {"Deployment", "Service", "Ingress"}
studio_names = {"supabase-studio", "supabase-studio-config"}
kong_names = {
"supabase-kong",
"supabase-kong-declarative-config",
"supabase-kong-declarative-config-jwt",
}
frontdoor_docs: list[dict[str, Any]] = []
frontdoor_keys: set[tuple[str, str, str, str]] = set()
for doc in docs:
kind = str(doc.get("kind") or "")
meta = doc.get("metadata") or {}
name = ""
if isinstance(meta, dict):
name = str(meta.get("name") or "")
is_studio = name in studio_names and kind in studio_kinds
is_kong = name in kong_names and kind in kong_kinds
if is_studio or is_kong:
frontdoor_docs.append(doc)
frontdoor_keys.add(_doc_key(doc))
app_docs = [doc for doc in docs if _doc_key(doc) not in frontdoor_keys]
return app_docs, frontdoor_docs
def _normalize_hostname(raw_value: str, fallback: str) -> str:
token = (raw_value or "").strip()
if not token or _is_placeholder(token):
@ -476,16 +573,15 @@ def _build_overlay(cfg: configparser.ConfigParser, args: argparse.Namespace) ->
default="",
).strip()
public_hosts = sorted(set(api_host_entries + studio_host_entries))
if mode == "k8s" and db_cluster_kubecontext and active_kubecontext == db_cluster_kubecontext and public_hosts:
raise SystemExit(
"Refusing to render Supabase public ingress for DB cluster context "
f"'{active_kubecontext}'. Hosts: {', '.join(public_hosts)}"
)
if mode == "k8s" and app_cluster_kubecontext and active_kubecontext and active_kubecontext != app_cluster_kubecontext:
raise SystemExit(
"Refusing to render Supabase public ingress outside APP cluster context "
f"'{app_cluster_kubecontext}'. Active context: '{active_kubecontext}'."
)
if mode == "k8s" and app_cluster_kubecontext and active_kubecontext:
allowed_contexts = {app_cluster_kubecontext}
if db_cluster_kubecontext:
allowed_contexts.add(db_cluster_kubecontext)
if active_kubecontext not in allowed_contexts:
raise SystemExit(
"Refusing to render Supabase public ingress outside allowed split-cluster contexts "
f"{sorted(allowed_contexts)}. Active context: '{active_kubecontext}'."
)
frontdoor_auth_enabled = _as_bool(
_first(
@ -773,9 +869,17 @@ def render(args: argparse.Namespace) -> None:
raise SystemExit(f"Helm template failed (code {proc.returncode})")
rendered_path.write_text(proc.stdout)
app_docs, frontdoor_docs = _split_frontdoor_docs(proc.stdout)
app_rendered_path = gen_dir / "supabase-helm.app.yaml"
frontdoor_rendered_path = gen_dir / "supabase-helm.frontdoor-db.yaml"
_dump_manifest_docs(app_rendered_path, app_docs)
_dump_manifest_docs(frontdoor_rendered_path, frontdoor_docs)
summary = {
"values": str(values_path),
"manifests": str(rendered_path),
"manifests_app": str(app_rendered_path),
"manifests_frontdoor_db": str(frontdoor_rendered_path),
"db_host": meta["db_host"],
"supabase_namespace": meta["supabase_namespace"],
}

View File

@ -19,6 +19,7 @@ def _load_render_module():
_render_mod = _load_render_module()
_build_overlay = _render_mod._build_overlay
_read_cfg = _render_mod._read_cfg
_split_frontdoor_docs = _render_mod._split_frontdoor_docs
def _write_cfg(path: Path, content: str) -> None:
@ -201,7 +202,7 @@ def test_render_supabase_rejects_duplicate_api_and_studio_host_claims(tmp_path:
raise AssertionError("Expected duplicate host/path guardrail to abort")
def test_render_supabase_rejects_db_cluster_context_for_public_ingress(tmp_path: Path, monkeypatch):
def test_render_supabase_allows_db_cluster_context_for_public_ingress(tmp_path: Path, monkeypatch):
monkeypatch.delenv("SUPABASE_HOST", raising=False)
monkeypatch.delenv("SUPABASE_HOSTNAME", raising=False)
monkeypatch.delenv("KNOE_DB_NAMESPACE", raising=False)
@ -230,12 +231,10 @@ def test_render_supabase_rejects_db_cluster_context_for_public_ingress(tmp_path:
cfg = _read_cfg(cfg_path)
args = Namespace(output_dir=str(tmp_path / "gen"), manifests_dir=str(tmp_path / "k8s"))
try:
_build_overlay(cfg, args)
except SystemExit as exc:
assert "Refusing to render Supabase public ingress for DB cluster context" in str(exc)
else:
raise AssertionError("Expected DB-cluster targeting guardrail to abort")
overlay, _meta = _build_overlay(cfg, args)
assert overlay["ingress"]["hosts"][0]["host"] == "api.0.knoe.dev"
assert overlay["studioIngress"]["hosts"][0]["host"] == "db.0.knoe.dev"
def test_render_supabase_rejects_traefik_class_in_k8s_without_opt_in(tmp_path: Path, monkeypatch):
@ -271,3 +270,25 @@ def test_render_supabase_rejects_traefik_class_in_k8s_without_opt_in(tmp_path: P
assert "incompatible with k8s mode" in str(exc)
else:
raise AssertionError("Expected ingress-class guardrail to abort")
def test_render_supabase_splits_frontdoor_manifests_for_db_cluster_rollout():
rendered_manifest = "\n---\n".join(
(
'{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"supabase-auth","namespace":"supabase"}}',
'{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"supabase-kong","namespace":"supabase"}}',
'{"apiVersion":"v1","kind":"Service","metadata":{"name":"supabase-kong","namespace":"supabase"}}',
'{"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"name":"supabase-kong","namespace":"supabase"}}',
'{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"supabase-studio","namespace":"supabase"}}',
'{"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"name":"supabase-studio","namespace":"supabase"}}',
)
)
app_docs, frontdoor_docs = _split_frontdoor_docs(rendered_manifest)
app_names = {doc["metadata"]["name"] for doc in app_docs}
frontdoor_names = {doc["metadata"]["name"] for doc in frontdoor_docs}
assert "supabase-auth" in app_names
assert "supabase-kong" in frontdoor_names
assert "supabase-studio" in frontdoor_names