diff --git a/chart/templates/backend-deployment.yaml b/chart/templates/backend-deployment.yaml index 0913650..aee363d 100644 --- a/chart/templates/backend-deployment.yaml +++ b/chart/templates/backend-deployment.yaml @@ -144,16 +144,30 @@ spec: {{- include "lightrun-backend-crons.environmentVariables" . | nindent 12 }} - name: SPRING_PROFILES_ACTIVE value: "prod,swagger,cluster" - {{- if .Values.deployments.backend.extraEnvs }} - {{- toYaml .Values.deployments.backend.extraEnvs | nindent 12 }} - {{- if not (include "list-of-maps-contains" (list .Values.deployments.backend.extraEnvs "_JAVA_OPTIONS") ) }} - - name: "_JAVA_OPTIONS" - value: {{- toYaml (include "calculate-heap-size" .Values.deployments.backend) | nindent 21 }} - {{- end }} - {{- else }} - - name: "_JAVA_OPTIONS" - value: {{- toYaml (include "calculate-heap-size" .Values.deployments.backend) | nindent 21 }} - {{- end }} +{{- $envs := .Values.deployments.backend.extraEnvs | default (list) -}} +{{- $memMi := include "mem-to-mi" (.Values.deployments.backend.resources.memory | default "") | int -}} +{{- $javaVal := (include "get-env" (list $envs "_JAVA_OPTIONS") | trim) -}} +{{- /* start with user extraEnvs, but drop _JAVA_OPTIONS */ -}} +{{- $rendered := list -}} +{{- range $e := $envs -}} + {{- $name := $e.name | default "" -}} + {{- if ne $name "_JAVA_OPTIONS" -}} + {{- $rendered = append $rendered $e -}} + {{- end -}} +{{- end -}} + +{{- /* add enhanced _JAVA_OPTIONS calculation */ -}} +{{- $enhancedJavaOpts := include "calculate-enhanced-java-options" (dict "deployment" .Values.deployments.backend "existingJavaOpts" $javaVal) -}} +{{- if ne $enhancedJavaOpts "" -}} + {{- $rendered = append $rendered (dict "name" "_JAVA_OPTIONS" "value" $enhancedJavaOpts) -}} +{{- else if eq $javaVal "" -}} + {{- $rendered = append $rendered (dict "name" "_JAVA_OPTIONS" "value" "") -}} +{{- end -}} + +{{- if $rendered }} +{{ toYaml $rendered | nindent 12 }} +{{- end }} +{{- /* >>> END updated env-emitting block <<< */}} # waiting for mysql, rabbitmq and keycloak initialization initContainers: diff --git a/chart/templates/crons/deployment.yaml b/chart/templates/crons/deployment.yaml index b0c8225..3fc0d29 100644 --- a/chart/templates/crons/deployment.yaml +++ b/chart/templates/crons/deployment.yaml @@ -136,13 +136,50 @@ spec: {{- include "lightrun-backend-crons.environmentVariables" . | nindent 12 }} - name: SPRING_PROFILES_ACTIVE value: "prod,swagger,cluster,cron" - {{- $mergedExtraEnvs := include "lightrun-crons.mergedExtraEnvs" . }} - {{- if $mergedExtraEnvs }} -{{ $mergedExtraEnvs | nindent 12 }} - {{- end }} - {{- if and (not (include "list-of-maps-contains" (list .Values.deployments.crons.extraEnvs "_JAVA_OPTIONS"))) (not (include "list-of-maps-contains" (list .Values.deployments.backend.extraEnvs "_JAVA_OPTIONS"))) }} - - name: "_JAVA_OPTIONS" - value: {{- toYaml (include "calculate-heap-size" (list .Values.deployments.crons 1 3)) | nindent 21 }} + {{- /* Enhanced _JAVA_OPTIONS logic for crons */ -}} + {{- $backendExtraEnvs := .Values.deployments.backend.extraEnvs | default list -}} + {{- $cronsExtraEnvs := .Values.deployments.crons.extraEnvs | default list -}} + {{- $mergedEnvs := list -}} + {{- $javaVal := "" -}} + {{- /* First, add all backend extraEnvs except _JAVA_OPTIONS */ -}} + {{- range $backendExtraEnvs -}} + {{- $backendEnv := . -}} + {{- $isOverridden := false -}} + {{- if eq $backendEnv.name "_JAVA_OPTIONS" -}} + {{- $javaVal = (printf "%v" $backendEnv.value) -}} + {{- else -}} + {{- /* Check if this env var is overridden in crons */ -}} + {{- range $cronsExtraEnvs -}} + {{- if eq .name $backendEnv.name -}} + {{- $isOverridden = true -}} + {{- end -}} + {{- end -}} + {{- /* Only add backend env if not overridden by crons */ -}} + {{- if not $isOverridden -}} + {{- $mergedEnvs = append $mergedEnvs $backendEnv -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- /* Then, add all crons extraEnvs except _JAVA_OPTIONS */ -}} + {{- range $cronsExtraEnvs -}} + {{- if eq .name "_JAVA_OPTIONS" -}} + {{- $javaVal = (printf "%v" .value) -}} + {{- else -}} + {{- $mergedEnvs = append $mergedEnvs . -}} + {{- end -}} + {{- end -}} + + {{- /* Add enhanced _JAVA_OPTIONS calculation */ -}} + {{- $enhancedJavaOpts := include "calculate-enhanced-java-options" (dict "deployment" .Values.deployments.crons "existingJavaOpts" $javaVal) -}} + {{- if ne $enhancedJavaOpts "" -}} + {{- $mergedEnvs = append $mergedEnvs (dict "name" "_JAVA_OPTIONS" "value" $enhancedJavaOpts) -}} + {{- else if eq $javaVal "" -}} + {{- $mergedEnvs = append $mergedEnvs (dict "name" "_JAVA_OPTIONS" "value" "") -}} + {{- end -}} + + {{- if $mergedEnvs }} +{{ toYaml $mergedEnvs | nindent 12 }} {{- end }} # waiting for mysql, rabbitmq and keycloak initialization diff --git a/chart/templates/helpers/_helpers.tpl b/chart/templates/helpers/_helpers.tpl index 9e6ae47..8943add 100644 --- a/chart/templates/helpers/_helpers.tpl +++ b/chart/templates/helpers/_helpers.tpl @@ -539,48 +539,170 @@ false ##################### */}} +{{- /* Convert a memory string like "1024Mi" or "2Gi" to Mi (int). Unknown/empty -> 0 */ -}} +{{- define "mem-to-mi" -}} +{{- $m := . | default "" -}} +{{- if $m | hasSuffix "Gi" -}} +{{- mul (trimSuffix "Gi" $m | int) 1024 -}} +{{- else if $m | hasSuffix "Mi" -}} +{{- trimSuffix "Mi" $m | int -}} +{{- else -}} +0 +{{- end -}} +{{- end -}} + +{{- define "get-env" -}} +{{- $list := index . 0 -}} +{{- $name := index . 1 -}} +{{- $out := "" -}} +{{- range $list -}} + {{- if and (hasKey . "name") (eq .name $name) -}} + {{- if hasKey . "value" -}} + {{- $out = (printf "%v" .value) -}} + {{- else -}} + {{- $out = "" -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- $out -}} +{{- end -}} + {{- define "calculate-heap-size" -}} {{- $deployment := . -}} {{- $xmsRatio := 1 -}} {{- $xmxRatio := 1 -}} -{{- $heap:= "" -}} -{{- $xms:= "" -}} -{{/* Check if called with parameters: deployment, xmsRatio, xmxRatio */}} {{- if kindIs "slice" . -}} - {{- $deployment = index . 0 -}} - {{- if ge (len .) 2 -}} - {{- $xmsRatio = index . 1 | int -}} + {{- $deployment = index . 0 -}} + {{- if ge (len .) 2 -}}{{- $xmsRatio = index . 1 | int -}}{{- end -}} + {{- if ge (len .) 3 -}}{{- $xmxRatio = index . 2 | int -}}{{- end -}} +{{- end -}} +{{- if ne $xmsRatio 1 -}}{{- fail "calculate-heap-size: xmsRatio must be 1 (supported: 1:1..1:5)" -}}{{- end -}} +{{- if or (lt $xmxRatio 1) (gt $xmxRatio 5) -}}{{- fail "calculate-heap-size: xmxRatio must be 1..5 (supported: 1:1..1:5)" -}}{{- end -}} + +{{- $memMi := include "mem-to-mi" ($deployment.resources.memory | default "") | int -}} +{{- if le $memMi 0 -}} +{{- "" -}} +{{- else -}} + {{- $xmx := div (mul $memMi 75) 100 -}} {{/* 75% of container memory */}} + {{- $xms := div $xmx $xmxRatio -}} {{/* Xms = Xmx / xmxRatio */}} + {{- printf "-Xmx%vm -Xms%vm" $xmx $xms -}} +{{- end -}} +{{- end -}} + +{{- /* Parse existing _JAVA_OPTIONS to extract Xms and Xmx values */ -}} +{{- define "parse-java-options" -}} +{{- $javaOpts := . | default "" -}} +{{- $xms := "" -}} +{{- $xmx := "" -}} +{{- $otherOpts := "" -}} +{{- if ne $javaOpts "" -}} + {{- $parts := split " " $javaOpts -}} + {{- range $parts -}} + {{- $part := . | trim -}} + {{- if hasPrefix "-Xms" $part -}} + {{- $xms = $part -}} + {{- else if hasPrefix "-Xmx" $part -}} + {{- $xmx = $part -}} + {{- else if ne $part "" -}} + {{- if eq $otherOpts "" -}} + {{- $otherOpts = $part -}} + {{- else -}} + {{- $otherOpts = printf "%s %s" $otherOpts $part -}} + {{- end -}} {{- end -}} - {{- if ge (len .) 3 -}} - {{- $xmxRatio = index . 2 | int -}} + {{- end -}} +{{- end -}} +{{- printf "%s|%s|%s" $xms $xmx $otherOpts -}} +{{- end -}} + +{{- /* Calculate enhanced _JAVA_OPTIONS based on existing options and memory */ -}} +{{- define "calculate-enhanced-java-options" -}} +{{- $deployment := .deployment -}} +{{- $existingJavaOpts := .existingJavaOpts | default "" -}} +{{- $memMi := include "mem-to-mi" ($deployment.resources.memory | default "") | int -}} + +{{- $hasXms := false -}} +{{- $hasXmx := false -}} +{{- $existingXms := "" -}} +{{- $existingXmx := "" -}} +{{- $otherOpts := "" -}} + +{{- /* Parse existing options */ -}} +{{- if ne $existingJavaOpts "" -}} + {{- $parts := split " " $existingJavaOpts -}} + {{- range $parts -}} + {{- $part := . | trim -}} + {{- if or (hasPrefix "-Xms" $part) (hasPrefix "Xms" $part) -}} + {{- $hasXms = true -}} + {{- if hasPrefix "-Xms" $part -}} + {{- $existingXms = $part -}} + {{- else -}} + {{- $existingXms = printf "-%s" $part -}} + {{- end -}} + {{- else if or (hasPrefix "-Xmx" $part) (hasPrefix "Xmx" $part) -}} + {{- $hasXmx = true -}} + {{- if hasPrefix "-Xmx" $part -}} + {{- $existingXmx = $part -}} + {{- else -}} + {{- $existingXmx = printf "-%s" $part -}} + {{- end -}} + {{- else if ne $part "" -}} + {{- if eq $otherOpts "" -}} + {{- $otherOpts = $part -}} + {{- else -}} + {{- $otherOpts = printf "%s %s" $otherOpts $part -}} + {{- end -}} {{- end -}} + {{- end -}} {{- end -}} -{{/* Validate ratios - only allow sensible ratios like 1:1, 1:2, 1:3, 1:4, 1:5 */}} -{{- if ne $xmsRatio 1 -}} - {{- fail "calculate-heap-size: xmsRatio must be 1. Only ratios like 1:1, 1:2, 1:3, 1:4, 1:5 are supported." -}} + +{{- $result := "" -}} +{{- $xms := "" -}} +{{- $xmx := "" -}} + +{{- /* Calculate Xms and Xmx only if memory > 0 AND neither Xms nor Xmx is provided by user */ -}} +{{- if and (gt $memMi 0) (not $hasXms) (not $hasXmx) -}} + {{- $calculatedXmx := div (mul $memMi 75) 100 -}} + {{- $calculatedXms := $calculatedXmx -}} + {{- $xms = printf "-Xms%vm" $calculatedXms -}} + {{- $xmx = printf "-Xmx%vm" $calculatedXmx -}} +{{- else -}} + {{- /* Use existing values if provided, do not calculate missing ones */ -}} + {{- if $hasXms -}}{{- $xms = $existingXms -}}{{- end -}} + {{- if $hasXmx -}}{{- $xmx = $existingXmx -}}{{- end -}} +{{- end -}} + +{{- /* Build the final result */ -}} +{{- if ne $xms "" -}} + {{- $result = $xms -}} +{{- end -}} +{{- if ne $xmx "" -}} + {{- if ne $result "" -}} + {{- $result = printf "%s %s" $result $xmx -}} + {{- else -}} + {{- $result = $xmx -}} + {{- end -}} {{- end -}} -{{- if or (lt $xmxRatio 1) (gt $xmxRatio 5) -}} - {{- fail "calculate-heap-size: xmxRatio must be between 1 and 5. Only ratios like 1:1, 1:2, 1:3, 1:4, 1:5 are supported." -}} +{{- if ne $otherOpts "" -}} + {{- if ne $result "" -}} + {{- $result = printf "%s %s" $result $otherOpts -}} + {{- else -}} + {{- $result = $otherOpts -}} + {{- end -}} {{- end -}} -{{- if contains "Gi" $deployment.resources.memory -}} - {{- $heap = div ($deployment.resources.memory | replace "Gi" "" | int | mul 1024 | mul 75 ) 100 -}} -{{- else if contains "Mi" $deployment.resources.memory -}} - {{- $heap = div ($deployment.resources.memory | replace "Mi" "" | int | mul 75) 100 -}} + +{{- $result -}} {{- end -}} -{{/* Calculate Xms = Xmx / xmxRatio */}} -{{- $xms = div $heap $xmxRatio -}} -{{- printf "-Xmx%vm -Xms%vm" $heap $xms -}} + +{{- /* Unchanged: check if a list of {name,value} maps contains a given name */ -}} +{{- define "list-of-maps-contains" -}} + {{- $arg1 := index . 0 -}} + {{- $arg2 := index . 1 -}} + {{- range $arg1 -}} + {{- if eq .name $arg2 -}}true{{- end -}} + {{- end -}} {{- end -}} -{{- define "list-of-maps-contains" }} - {{- $arg1 := index . 0 }} - {{- $arg2 := index . 1 }} - {{- range $arg1 }} - {{- if eq .name $arg2 }} - true - {{- end }} - {{- end }} -{{- end }} {{/* diff --git a/chart/templates/keycloak-statefulset.yaml b/chart/templates/keycloak-statefulset.yaml index c31fec8..e3247a4 100644 --- a/chart/templates/keycloak-statefulset.yaml +++ b/chart/templates/keycloak-statefulset.yaml @@ -11,7 +11,7 @@ metadata: {{- end }} spec: serviceName: {{ include "lightrun-keycloak.name" . }} - updateStrategy: + updateStrategy: type: RollingUpdate # For clusters with more than 3 pods, consider changing the number of "owner nodes" as described in # https://www.keycloak.org/server/caching#_configuring_caches -> Configuring caches for availability @@ -30,7 +30,6 @@ spec: annotations: {{- end }} {{- with .Values.deployments.keycloak.annotations }} - {{/* deprecated if favor of podAnnotations */}} {{ toYaml . | nindent 8 }} {{- end }} {{- with .Values.deployments.keycloak.podAnnotations }} @@ -55,7 +54,6 @@ spec: {{- toYaml .Values.deployments.keycloak.podSecurityContext | nindent 8 }} {{- end }} containers: - {{- include "lightrun-keycloak.container.persist-async-profiler-output-files" . | indent 8 }} - name: {{ include "lightrun-keycloak.name" . }} securityContext: {{- include "lightrun-keycloak.containerSecurityContext" . | indent 12 }} @@ -71,7 +69,7 @@ spec: ports: - name: mgmt containerPort: 9000 - protocol: TCP + protocol: TCP - name: http containerPort: 9080 protocol: TCP @@ -214,15 +212,15 @@ spec: secretKeyRef: name: {{ include "secrets.backend.name" . }} key: SPRING_RABBITMQ_PASSWORD - {{- end }} + {{- end }} - name: INFO_DEPLOYMENT - {{ if eq .Values.general.deployment_type "saas" }} + {{- if eq .Values.general.deployment_type "saas" }} value: "SaaS" - {{ else if eq .Values.general.deployment_type "single-tenant" }} + {{- else if eq .Values.general.deployment_type "single-tenant" }} value: "single-tenant" - {{ else }} + {{- else }} value: "on-prem" - {{ end }} + {{- end }} - name: KC_PROXY_HEADERS value: "xforwarded" - name: KC_BOOTSTRAP_ADMIN_USERNAME @@ -235,12 +233,12 @@ spec: secretKeyRef: name: {{ include "secrets.keycloak.name" . }} key: KEYCLOAK_PASSWORD - {{ if .Values.general.internal_tls.enabled }} + {{- if .Values.general.internal_tls.enabled }} - name: KC_HTTPS_CERTIFICATE_FILE value: /etc/x509/https/tls.crt - name: KC_HTTPS_CERTIFICATE_KEY_FILE value: /etc/x509/https/tls.key - {{- if and .Values.deployments.keycloak.clusterMode (eq .Values.general.internal_tls.certificates.source "existing_certificates") }} + {{- if and .Values.deployments.keycloak.clusterMode (eq .Values.general.internal_tls.certificates.source "existing_certificates") }} - name: KC_CACHE_EMBEDDED_MTLS_ENABLED value: "true" - name: KC_CACHE_EMBEDDED_MTLS_KEY_STORE_FILE @@ -258,12 +256,12 @@ spec: name: {{ include "secrets.backend.name" . }} key: KEYSTORE_PASSWORD {{- end }} - {{ else }} + {{- else }} - name: KC_HTTPS_CERTIFICATE_FILE - name: KC_HTTPS_CERTIFICATE_KEY_FILE - name: KC_HTTP_ENABLED value: "true" - {{ end }} + {{- end }} - name: KC_DB value: mysql - name: KC_DB_URL @@ -300,32 +298,45 @@ spec: {{- end }} - name: JAVASCRIPT_FILES value: js/keycloak.js - {{- if .Values.deployments.keycloak.extraEnvs }} - {{- toYaml .Values.deployments.keycloak.extraEnvs | nindent 12 }} - {{- if not (include "list-of-maps-contains" (list .Values.deployments.keycloak.extraEnvs "_JAVA_OPTIONS") ) }} - - name: "_JAVA_OPTIONS" - value: {{- toYaml (include "calculate-heap-size" .Values.deployments.keycloak) | nindent 21 }} - {{- end }} - {{- if not (include "list-of-maps-contains" (list .Values.deployments.keycloak.extraEnvs "KC_HOSTNAME") ) }} - {{- if semverCompare ">=1.38.0" $version }} - - name: KC_HOSTNAME - value: 'https://{{ .Values.general.lightrun_endpoint }}/auth' - {{- else }} - - name: KC_HOSTNAME_URL - value: 'https://{{ .Values.general.lightrun_endpoint }}/auth' - {{- end }} - {{- end }} - {{- else }} - - name: "_JAVA_OPTIONS" - value: {{- toYaml (include "calculate-heap-size" .Values.deployments.keycloak) | nindent 21 }} - {{- if semverCompare ">=1.38.0" $version }} - - name: KC_HOSTNAME - value: 'https://{{ .Values.general.lightrun_endpoint }}/auth' - {{- else }} - - name: KC_HOSTNAME_URL - value: 'https://{{ .Values.general.lightrun_endpoint }}/auth' - {{- end }} + + # ---- extra envs (with computed _JAVA_OPTIONS when empty) ---- + {{- $envs := .Values.deployments.keycloak.extraEnvs | default (list) -}} + {{- $memMi := include "mem-to-mi" (.Values.deployments.keycloak.resources.memory | default "") | int -}} + {{- $javaVal := (include "get-env" (list $envs "_JAVA_OPTIONS") | trim) -}} + + {{- /* start with user extraEnvs, but drop an empty _JAVA_OPTIONS */ -}} + {{- $rendered := list -}} + {{- range $e := $envs -}} + {{- $name := $e.name | default "" -}} + {{- $val := "" -}} + {{- if hasKey $e "value" -}}{{- $val = (printf "%v" $e.value) -}}{{- end -}} + {{- if ne $name "_JAVA_OPTIONS" -}} + {{- $rendered = append $rendered $e -}} + {{- end -}} + {{- end -}} + + {{- /* add enhanced _JAVA_OPTIONS calculation */ -}} + {{- $enhancedJavaOpts := include "calculate-enhanced-java-options" (dict "deployment" .Values.deployments.keycloak "existingJavaOpts" $javaVal) -}} + {{- if ne $enhancedJavaOpts "" -}} + {{- $rendered = append $rendered (dict "name" "_JAVA_OPTIONS" "value" $enhancedJavaOpts) -}} + {{- else if eq $javaVal "" -}} + {{- $rendered = append $rendered (dict "name" "_JAVA_OPTIONS" "value" "") -}} + {{- end -}} + + {{- /* ensure KC_HOSTNAME (or KC_HOSTNAME_URL) exists if user didn’t supply one */ -}} + {{- if not (include "list-of-maps-contains" (list $envs "KC_HOSTNAME")) -}} + {{- if semverCompare ">=1.38.0" $version -}} + {{- $rendered = append $rendered (dict "name" "KC_HOSTNAME" "value" (printf "https://%s/auth" .Values.general.lightrun_endpoint)) -}} + {{- else -}} + {{- $rendered = append $rendered (dict "name" "KC_HOSTNAME_URL" "value" (printf "https://%s/auth" .Values.general.lightrun_endpoint)) -}} + {{- end -}} + {{- end -}} + + {{- if $rendered }} + {{ toYaml $rendered | nindent 12 }} {{- end }} + + {{- if or .Values.general.readOnlyRootFilesystem .Values.general.db_local .Values.general.internal_tls.enabled @@ -333,9 +344,9 @@ spec: }} initContainers: {{- include "lightrun-keycloak.initContainer.download-async-profiler" . | nindent 6 }} - {{ if .Values.general.mq.enabled }} + {{- if .Values.general.mq.enabled }} {{- include "lightrun-mq.initContainer.wait-for-rabbitmq" (merge (dict "imageConfig" .Values.deployments.keycloak.initContainers.wait_for_rabbitmq "securityContext" "lightrun-keycloak.containerSecurityContext") .) | nindent 6 }} - {{- end }} + {{- end }} {{- end -}} {{- if .Values.general.readOnlyRootFilesystem }} {{- include "lightrun-keycloak.initContainer.read-only-rootfs" . }} @@ -389,17 +400,12 @@ spec: {{- else if eq .Values.general.internal_tls.certificates.source "existing_certificates" }} secretName: {{ .Values.general.internal_tls.certificates.existing_certificates.keycloak }} {{- end }} - {{- if and .Values.deployments.keycloak.clusterMode (eq .Values.general.internal_tls.certificates.source "existing_certificates") }} + {{- if and .Values.deployments.keycloak.clusterMode (eq .Values.general.internal_tls.certificates.source "existing_certificates") }} - name: cluster-cert secret: defaultMode: 444 - # Secret should create the following files: ca.crt, tls.key, tls.crt secretName: {{ .Values.general.internal_tls.certificates.existing_certificates.keycloak_cluster }} - name: p12 emptyDir: {} {{- end }} {{- end }} - {{- if .Values.deployments.keycloak.extraVolumes }} - {{- range .Values.deployments.keycloak.extraVolumes }} - {{- end }} - {{- end }}