mirror of
https://github.com/dredx/prole.git
synced 2026-09-24 18:44:33 +00:00
Migrate Supabase to pi.prole.org, fix supabase_enabled override, monitoring PV vars
Memory pressure on merlin (95% OOM with monitoring + CNPG replica + Supabase) resolved by moving Supabase workload to pi.prole.org which has headroom (49% memory, 2 pods). - conf/service/prole.cfg: set SUPABASE_PV_NODE, SUPABASE_PRIMARY_NODE=pi.prole.org, SUPABASE_STORAGE_CLASS=pi-local-iscsi, SUPABASE_PV_BASE_DIR for rancher local-path - supabase/helm/render_supabase.py: resolve SUPABASE_STORAGE_CLASS from env/cfg, apply pi-local-iscsi to storage/analytics PVCs, resolve DATABASE_NAMESPACE for correct db_host, DB_PASSWORD env override takes priority for live cluster password - supabase/deploy.sh: default SUPABASE_PV_NODE to pi.prole.org, default base dir to /var/lib/rancher/k3s/storage/supabase, add idempotent ALTER ROLE password sync, live DB_PASSWORD resolution in helm_render_values from knoe-db-superuser secret - knoe/core/actions.py: stop overriding init_cluster.supabase_enabled to False in silent mode so prole.cfg value is honored end-to-end - etc/init_monitoring.sh: derive pv_prom/pv_am/pv_graf inline before Released-PV loop to fix unbound variable error on idempotent monitoring installs Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
parent
5e7c03324e
commit
498a7f0412
@ -1,5 +1,5 @@
|
||||
; Prole Master Configuration File
|
||||
; Generated by install.py on 2026-03-24 00:02:11
|
||||
; Generated by install.py on 2026-03-24 01:08:31
|
||||
; This file is used as input for Ansible deployment and k8s cluster creation.
|
||||
|
||||
[User]
|
||||
@ -51,7 +51,7 @@ init_cluster.cluster_env = service
|
||||
init_cluster.deployment_target = prole-service-cluster
|
||||
init_cluster.gitops_enabled = false
|
||||
init_cluster.k3s_server_url = https://myrddin.prole.org:6443
|
||||
init_cluster.k3s_token = ${PROLE_SECRET:v1:ivIwpFaAjYf6RQ07:8F5FGTOZvIgkH3S6ts0nNMWLZSHu4T80nBpj7LO9l_5Q0QuJq9yvqaiSz7VS8H_5fQ5-EfWcRzddp8n2uzC0QPtdLA_xw93lx6DKXhU4sIpKTTQ5AvFDFZ8GKPrjActqZrGJA5k1OicdpBSVX4lJ_FTLQ1HdaEoFhYpM8Q==}
|
||||
init_cluster.k3s_token = ${PROLE_SECRET:v1:U0Rfgq70bBLBqhg9:pr_3Fr_vf1KjX-j9p7QEbwmoEAp7T5ozvBBCLDyPW0F5sE8nWZIGvCNSgi_41UfqyvFMM_qgImBvM6zk9yrobEYhXuUrk8r7qU13qMGDmCtHqel3n-lyw3bBWxAzS3mKOzRiYtGcpkUndC6Y8TxHFt0d0FAngBO8VssX2g==}
|
||||
init_cluster.kerberos_enabled = true
|
||||
init_cluster.mode = k3s
|
||||
init_cluster.start_cluster = true
|
||||
@ -62,8 +62,8 @@ init_db_build.run_build = true
|
||||
init_password.cluster_name = ${CLUSTER_NAME}
|
||||
init_password.db_host_port = 5432
|
||||
init_password.db_namespace = ${DATABASE_NAMESPACE}
|
||||
init_password.db_password = ${PROLE_SECRET:v1:t3Nx6z7T3bq-taI2:ZTyGOC8o84rKIucb8sLAtiXelAuCla2X}
|
||||
init_password.db_password_confirm = ${PROLE_SECRET:v1:t3Nx6z7T3bq-taI2:ZTyGOC8o84rKIucb8sLAtiXelAuCla2X}
|
||||
init_password.db_password = ${PROLE_SECRET:v1:j9YGAlAsEMEyRtoe:-ZyezLZApNHLSxsFMg-8qe9fcIgT0_5C}
|
||||
init_password.db_password_confirm = ${PROLE_SECRET:v1:j9YGAlAsEMEyRtoe:-ZyezLZApNHLSxsFMg-8qe9fcIgT0_5C}
|
||||
init_password.db_username = root
|
||||
init_password.generate_ssh_key = true
|
||||
init_scripts.run_scripts = true
|
||||
@ -105,8 +105,10 @@ PROLE_K3S_TOKEN = K107c8c6000488eca4a067d8a73119bbae2f07b4ea1bac7d8d3dc9c500cbb8
|
||||
PROLE_OPENTOFU_URL = http://127.0.0.1:8080
|
||||
REGISTRY_NAMESPACE = knoe-system
|
||||
SERVICE_NAMESPACE = knoe-system
|
||||
SUPABASE_PV_BASE_DIR = /synology/d002/supabase
|
||||
SUPABASE_PV_NODE = merlin.prole.org
|
||||
SUPABASE_PV_BASE_DIR = /var/lib/rancher/k3s/storage/supabase
|
||||
SUPABASE_PV_NODE = pi.prole.org
|
||||
SUPABASE_PRIMARY_NODE = pi.prole.org
|
||||
SUPABASE_STORAGE_CLASS = pi-local-iscsi
|
||||
SYNOLOGY_ROOTS = /synology/d001,/synology/d002,/synology/d003,/synology/d004
|
||||
|
||||
[Welcome]
|
||||
@ -188,7 +190,7 @@ MODE = k3d
|
||||
CLUSTER_ENV = prole-service-cluster
|
||||
DISPLAY_NAME = prole-service-cluster
|
||||
K3S_SERVER_URL = https://myrddin.prole.org:6443
|
||||
K3S_TOKEN = ${PROLE_SECRET:v1:If9U8gIX4OlvXvfr:EaQRFTq_wZyKCA-HBT8869bIrZKZJMKW9fe0-KSinJtoLRVFw4zk2q2cigosI58Gbk4utguq90oH6EZ2FDZ17HGt1b9ISen7fzGGKaaQJ_MGWJUxIOBAZSaPTIT5bPkvHiNyKjDT0phyYaVzU8wm5N49KQnc__5Q-yyDKw==}
|
||||
K3S_TOKEN = ${PROLE_SECRET:v1:q_KpNe3tVe2F2vj1:la27bQosKigefxuHA7wPN9bhXRNjER541nKPsgzF3LOZuUNPLm1eDpIajogCELrZy6SgorXDuq2O6Rz6FHwXmui-WMaQS7PbY4gTJN7SdF7CAst_yclW_gjEhz8pRhkrTifmARtT9AKJWcGnnXqw88_NqB8IzXPkCVm9tg==}
|
||||
MODE = k3s
|
||||
PIPELINE_URL = http://myrddin.prole.org:8080
|
||||
|
||||
|
||||
@ -1106,6 +1106,14 @@ setup_knoe_db_for_supabase() {
|
||||
DO \$\$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname='supabase_functions_admin') THEN CREATE ROLE supabase_functions_admin LOGIN PASSWORD '${pg_password}' NOINHERIT; END IF; END \$\$;
|
||||
DO \$\$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname='supabase_read_only_user') THEN CREATE ROLE supabase_read_only_user NOLOGIN; END IF; END \$\$;
|
||||
|
||||
-- Always sync service role passwords to current postgres password (idempotent)
|
||||
ALTER ROLE authenticator PASSWORD '${pg_password}';
|
||||
ALTER ROLE pgbouncer PASSWORD '${pg_password}';
|
||||
ALTER ROLE supabase_admin PASSWORD '${pg_password}';
|
||||
ALTER ROLE supabase_auth_admin PASSWORD '${pg_password}';
|
||||
ALTER ROLE supabase_storage_admin PASSWORD '${pg_password}';
|
||||
ALTER ROLE supabase_functions_admin PASSWORD '${pg_password}';
|
||||
|
||||
-- Grant membership
|
||||
GRANT anon TO authenticator;
|
||||
GRANT authenticated TO authenticator;
|
||||
@ -1208,6 +1216,17 @@ helm_render_values() {
|
||||
cfg_arg=("-c" "$PROLE_CFG_PATH")
|
||||
fi
|
||||
|
||||
# Resolve the live postgres password from the CNPG secret so the renderer
|
||||
# always uses the actual cluster password rather than the (potentially stale)
|
||||
# value stored in prole.cfg.
|
||||
local _live_pg_pw
|
||||
_live_pg_pw=$(kubectl get secret knoe-db-superuser \
|
||||
-n "${DATABASE_NAMESPACE:-knoe-db}" \
|
||||
-o jsonpath='{.data.password}' 2>/dev/null | base64 --decode 2>/dev/null || true)
|
||||
if [[ -n "$_live_pg_pw" ]]; then
|
||||
export DB_PASSWORD="$_live_pg_pw"
|
||||
fi
|
||||
|
||||
log "Rendering Supabase Helm values/manifests..."
|
||||
python3 "$renderer" "${cfg_arg[@]}" \
|
||||
--output-dir "$PROJECT_ROOT/supabase/helm/generated" \
|
||||
@ -1226,8 +1245,8 @@ ensure_k8s_supabase_static_pvs() {
|
||||
require_cmd kubectl
|
||||
|
||||
local node base parent base_name
|
||||
node="${SUPABASE_PV_NODE:-merlin.prole.org}"
|
||||
base="${SUPABASE_PV_BASE_DIR:-/synology/d002/supabase}"
|
||||
node="${SUPABASE_PV_NODE:-pi.prole.org}"
|
||||
base="${SUPABASE_PV_BASE_DIR:-/var/lib/rancher/k3s/storage/supabase}"
|
||||
base="${base%/}"
|
||||
parent="$(dirname "$base")"
|
||||
base_name="$(basename "$base")"
|
||||
|
||||
@ -111,6 +111,8 @@ def _build_overlay(cfg: configparser.ConfigParser, args: argparse.Namespace) ->
|
||||
|
||||
db_ns = _first(
|
||||
os.environ.get("KNOE_DB_NAMESPACE", ""),
|
||||
os.environ.get("DATABASE_NAMESPACE", ""),
|
||||
_cfg_get(cfg, "Global", "DATABASE_NAMESPACE"),
|
||||
_cfg_get(cfg, "Global", "NAMESPACE"),
|
||||
os.environ.get("NAMESPACE", ""),
|
||||
default="",
|
||||
@ -139,9 +141,9 @@ def _build_overlay(cfg: configparser.ConfigParser, args: argparse.Namespace) ->
|
||||
"postgres",
|
||||
)
|
||||
db_password = _first(
|
||||
os.environ.get("DB_PASSWORD", ""), # live secret override takes highest priority
|
||||
_cfg_get(cfg, "Inputs", "init_password.db_password"),
|
||||
_cfg_get(cfg, "Global", "DB_PASSWORD"),
|
||||
os.environ.get("DB_PASSWORD", ""),
|
||||
)
|
||||
if not db_password:
|
||||
raise SystemExit("Database password is required (init_password.db_password or DB_PASSWORD).")
|
||||
@ -187,8 +189,7 @@ def _build_overlay(cfg: configparser.ConfigParser, args: argparse.Namespace) ->
|
||||
else:
|
||||
public_url = f"https://{ingress_host}"
|
||||
|
||||
# Placement: in k3s we run Supabase on the monitoring/service node (merlin) and keep it
|
||||
# off the control-plane/db node.
|
||||
# Placement: pin Supabase pods to the configured primary node (default: pi.prole.org)
|
||||
mode = _first(
|
||||
os.environ.get("PROLE_MODE", ""),
|
||||
_cfg_get(cfg, "Global", "DEPLOYMENT_MODE"),
|
||||
@ -197,14 +198,23 @@ def _build_overlay(cfg: configparser.ConfigParser, args: argparse.Namespace) ->
|
||||
).strip().lower()
|
||||
supabase_primary_node = _first(
|
||||
os.environ.get("SUPABASE_PRIMARY_NODE", ""),
|
||||
_cfg_get(cfg, "Global", "SUPABASE_PRIMARY_NODE"),
|
||||
_cfg_get(cfg, "Supabase", "PRIMARY_NODE"),
|
||||
default="merlin.prole.org",
|
||||
default="pi.prole.org",
|
||||
).strip()
|
||||
if _is_placeholder(supabase_primary_node):
|
||||
supabase_primary_node = ""
|
||||
supabase_node_selector = (
|
||||
{"kubernetes.io/hostname": supabase_primary_node} if supabase_primary_node else {}
|
||||
)
|
||||
supabase_storage_class = _first(
|
||||
os.environ.get("SUPABASE_STORAGE_CLASS", ""),
|
||||
_cfg_get(cfg, "Global", "SUPABASE_STORAGE_CLASS"),
|
||||
_cfg_get(cfg, "Supabase", "STORAGE_CLASS"),
|
||||
default="pi-local-iscsi",
|
||||
).strip()
|
||||
if _is_placeholder(supabase_storage_class):
|
||||
supabase_storage_class = "pi-local-iscsi"
|
||||
|
||||
overlay: dict[str, Any] = {
|
||||
"nameOverride": "supabase",
|
||||
@ -248,6 +258,11 @@ def _build_overlay(cfg: configparser.ConfigParser, args: argparse.Namespace) ->
|
||||
},
|
||||
}
|
||||
|
||||
if mode == "k3s" and supabase_storage_class:
|
||||
# Apply storage class to components that need persistent volumes
|
||||
for sc_component in ("storage", "analytics"):
|
||||
overlay.setdefault("deployment", {}).setdefault(sc_component, {})["storageClass"] = supabase_storage_class
|
||||
|
||||
if mode == "k3s" and supabase_node_selector:
|
||||
deployment = overlay.setdefault("deployment", {})
|
||||
for component in (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user