Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions deploy/helm/codex-lb/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,13 @@ Image string — resolves registry/repository:tag with optional digest override
{{- printf "%s/%s:%s" $registry $repository $tag }}
{{- end }}
{{- end }}

{{/*
Merged nodeSelector: global.nodeSelector + local nodeSelector (local wins).
*/}}
{{- define "codex-lb.nodeSelector" -}}
{{- $merged := mustMerge (.Values.nodeSelector | default dict) (.Values.global.nodeSelector | default dict) -}}
{{- if $merged }}
{{- toYaml $merged }}
{{- end }}
{{- end -}}
8 changes: 4 additions & 4 deletions deploy/helm/codex-lb/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ spec:
topologySpreadConstraints:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with (include "codex-lb.nodeSelector" .) }}
nodeSelector:
{{- . | nindent 8 }}
Comment on lines +93 to +94
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Align deployment nodeSelector with pod-spec indentation

This nodeSelector key is indented one space deeper than sibling pod-spec fields, so when nodeSelector/global.nodeSelector is set and this block renders, Helm emits invalid YAML for the Deployment and install/template fails with a parse error. The key needs to align with other fields under spec.template.spec.

Useful? React with 👍 / 👎.

{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
Expand Down
57 changes: 57 additions & 0 deletions deploy/helm/codex-lb/templates/hooks/db-init-job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{{- if and .Values.dbInit.enabled (not .Values.postgresql.enabled) }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ printf "%s-db-init" (include "codex-lb.fullname" . | trunc 52 | trimSuffix "-") }}
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "codex-lb.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": pre-install
"helm.sh/hook-weight": "-10"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
template:
spec:
restartPolicy: OnFailure
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
Comment on lines +17 to +19
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply merged nodeSelector helper in db-init hook

The new db-init Job reads only .Values.nodeSelector, so global.nodeSelector is ignored for this hook while other pods were switched to the merged helper. In clusters relying on global selectors for placement/network access, db-init can run on unintended nodes or fail scheduling; this hook should use the same merged selector logic as deployment/migration/test pods.

Useful? React with 👍 / 👎.

{{- end }}
containers:
- name: db-init
image: {{ printf "%s/bitnami/postgresql:16" (.Values.global.imageRegistry | default "docker.io") }}
command: ["sh", "-ec"]
args:
- |
PGPASSWORD="$ADMIN_PASSWORD" psql \
-h "$DB_HOST" -p "$DB_PORT" -U "$ADMIN_USER" -d postgres <<'SQL'
{{- range .Values.dbInit.databases }}
DO $$ BEGIN
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '{{ .user }}') THEN
CREATE ROLE {{ .user }} WITH LOGIN PASSWORD '{{ .password }}';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Escape db-init SQL identifiers and literals

This statement injects Helm values directly into SQL without identifier/literal escaping, so valid inputs like a username containing - or a password containing ' will break the hook (and can alter SQL semantics). Use SQL-safe quoting (%I/%L, quote_ident, quote_literal) for role/database names and passwords before executing.

Useful? React with 👍 / 👎.

END IF;
END $$;
SELECT format('CREATE DATABASE %I OWNER %I', '{{ .name }}', '{{ .user }}')
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '{{ .name }}')\gexec
GRANT ALL PRIVILEGES ON DATABASE {{ .name }} TO {{ .user }};
{{- end }}
SQL
env:
- name: DB_HOST
value: {{ .Values.dbInit.host | quote }}
- name: DB_PORT
value: {{ .Values.dbInit.port | default "5432" | quote }}
- name: ADMIN_USER
value: {{ .Values.dbInit.adminUser | quote }}
- name: ADMIN_PASSWORD
{{- if .Values.dbInit.adminPasswordSecret }}
valueFrom:
secretKeyRef:
name: {{ .Values.dbInit.adminPasswordSecret.name }}
key: {{ .Values.dbInit.adminPasswordSecret.key }}
{{- else }}
value: {{ .Values.dbInit.adminPassword | quote }}
{{- end }}
backoffLimit: 3
{{- end }}
8 changes: 6 additions & 2 deletions deploy/helm/codex-lb/templates/hooks/migration-job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,12 @@ spec:
{{- range $pullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}
{{- if .Values.postgresql.enabled }}
{{- end }}
{{- with (include "codex-lb.nodeSelector" .) }}
nodeSelector:
{{- . | nindent 8 }}
Comment on lines +39 to +41
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Align migration hook nodeSelector indentation

The migration Job has the same over-indented nodeSelector block, which renders invalid YAML whenever a node selector is configured; because migration.enabled defaults to true, this can break installs/upgrades in common configurations that set node selectors. The nodeSelector key must be aligned with other fields under spec.template.spec.

Useful? React with 👍 / 👎.

{{- end }}
{{- if .Values.postgresql.enabled }}
initContainers:
- name: wait-for-db
image: postgres:16-alpine
Expand Down
4 changes: 4 additions & 0 deletions deploy/helm/codex-lb/templates/tests/test-connection.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ spec:
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
{{- with (include "codex-lb.nodeSelector" .) }}
nodeSelector:
{{- . | nindent 4 }}
{{- end }}
containers:
- name: test-connection
image: busybox:1.37
Expand Down
33 changes: 33 additions & 0 deletions deploy/helm/codex-lb/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ global:
imagePullSecrets: []
# @param global.storageClass Global storage class for PVCs
storageClass: ""
# @param global.nodeSelector Node selector labels applied to ALL pods (deployment, jobs, tests)
nodeSelector: {}

# @section Common parameters
# @param nameOverride Override the chart name
Expand Down Expand Up @@ -295,6 +297,13 @@ metrics:
port: 9090
serviceMonitor:
# @param metrics.serviceMonitor.enabled Create a ServiceMonitor for Prometheus Operator
# Defaults to false because it requires the Prometheus Operator CRDs to be installed.
# Enable this when running kube-prometheus-stack or standalone Prometheus Operator.
# Without ServiceMonitor, configure prometheus.io annotations for scraping:
# commonAnnotations:
# prometheus.io/scrape: "true"
# prometheus.io/port: "9090"
# prometheus.io/path: "/metrics"
enabled: false
# @param metrics.serviceMonitor.interval Metrics scrape interval
interval: 30s
Expand All @@ -306,6 +315,8 @@ metrics:
relabelings: []
prometheusRule:
# @param metrics.prometheusRule.enabled Create PrometheusRule for alerting
# Requires Prometheus Operator. Includes alerts for: high error rate, circuit breaker open,
# all accounts exhausted, high request latency. See templates/prometheusrule.yaml for details.
enabled: false
# @param metrics.prometheusRule.additionalLabels Additional labels for PrometheusRule
additionalLabels: {}
Expand Down Expand Up @@ -355,6 +366,28 @@ externalDatabase:
# @param externalDatabase.existingSecret Secret containing external DB credentials
existingSecret: ""

# @section Database initialization parameters
dbInit:
# @param dbInit.enabled Enable pre-install Job to create databases/users on external PostgreSQL
enabled: false
# @param dbInit.host External PostgreSQL host
host: ""
# @param dbInit.port External PostgreSQL port
port: "5432"
# @param dbInit.adminUser Admin username for creating databases/users
adminUser: "adminuser"
# @param dbInit.adminPassword Admin password (use adminPasswordSecret for production)
adminPassword: ""
# @param dbInit.adminPasswordSecret Reference to existing Secret for admin password
adminPasswordSecret: {}
# name: pg-admin-secret
# key: password
# @param dbInit.databases List of databases and users to create
databases:
- name: codexlb
user: codexlb
password: changeme

# @section Migration parameters
migration:
# @param migration.enabled Run database migration Job on install/upgrade
Expand Down
Loading