From 9b6c18aeffe5f78fd0241f31f65b08a98c350455 Mon Sep 17 00:00:00 2001 From: lukefoster11 Date: Thu, 13 Aug 2026 15:46:50 -0700 Subject: [PATCH 1/8] opt in hpa for jse --- .../ci/test-js-executor-hpa-option.yaml | 39 ++++++++++++++++ .../templates/deployment_js_executor.yaml | 44 +++++++++++++++++++ charts/retool/values.yaml | 14 ++++++ values.yaml | 14 ++++++ 4 files changed, 111 insertions(+) create mode 100644 charts/retool/ci/test-js-executor-hpa-option.yaml diff --git a/charts/retool/ci/test-js-executor-hpa-option.yaml b/charts/retool/ci/test-js-executor-hpa-option.yaml new file mode 100644 index 00000000..f7c2f71c --- /dev/null +++ b/charts/retool/ci/test-js-executor-hpa-option.yaml @@ -0,0 +1,39 @@ +rr: + + # Exercises the JS executor HPA (opt-in via rr.jsExecutor.autoscaling). + # Overlaid on top of test-install-values.yaml. Covers CPU, memory, extra + # metrics, and scale behavior branches; replicaCount must be omitted from + # the Deployment when the HPA is enabled. + jsExecutor: + enabled: true + replicaCount: 3 + image: + repository: tryretool/js-executor-service + tag: 3.123.4 + autoscaling: + enabled: true + minReplicas: 2 + maxReplicas: 8 + targetCPUUtilizationPercentage: 70 + targetMemoryUtilizationPercentage: 80 + metrics: + - type: Pods + pods: + metric: + name: packets-per-second + target: + type: AverageValue + averageValue: 1k + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + policies: + - type: Percent + value: 50 + periodSeconds: 60 + scaleUp: + stabilizationWindowSeconds: 0 + policies: + - type: Percent + value: 100 + periodSeconds: 15 diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml index 2e005bf6..a97d2935 100644 --- a/charts/retool/templates/deployment_js_executor.yaml +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -15,7 +15,9 @@ metadata: {{ toYaml .Values.deployment.annotations | indent 4 }} {{- end }} spec: + {{- if not ((.Values.rr.jsExecutor.autoscaling).enabled) }} replicas: {{ .Values.rr.jsExecutor.replicaCount }} + {{- end }} selector: matchLabels: {{- include "retool.jsExecutor.selectorLabels" . | nindent 6 }} @@ -258,4 +260,46 @@ spec: matchLabels: {{- include "retool.jsExecutor.selectorLabels" . | nindent 6 }} {{- end }} +{{- if (.Values.rr.jsExecutor.autoscaling).enabled }} +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ template "retool.jsExecutor.name" . }} + labels: + {{- include "retool.jsExecutor.selectorLabels" . | nindent 4 }} + {{- include "retool.jsExecutor.labels" . | nindent 4 }} + {{- include "retool.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "retool.jsExecutor.name" . }} + minReplicas: {{ .Values.rr.jsExecutor.autoscaling.minReplicas }} + maxReplicas: {{ .Values.rr.jsExecutor.autoscaling.maxReplicas }} + metrics: + {{- if .Values.rr.jsExecutor.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.rr.jsExecutor.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.rr.jsExecutor.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.rr.jsExecutor.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} + {{- with .Values.rr.jsExecutor.autoscaling.metrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.rr.jsExecutor.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} {{- end }} diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index 27d2c1b5..412ac0dc 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -864,6 +864,20 @@ rr: replicaCount: 1 + # Horizontal Pod Autoscaler for the JS executor. Disabled by default; + # set enabled: true to opt in. When enabled, replicaCount is ignored + # and the HPA controls the replica count. + autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 10 + targetCPUUtilizationPercentage: 70 + targetMemoryUtilizationPercentage: 70 + # Additional HPA metrics (Pods, Object, External, or extra Resource). + # metrics: [] + # Scaling behavior (stabilization windows and policies). + # behavior: {} + seccompLocalhostProfile: profiles/nsjail-seccomp.json # JS-executor-specific environment; not inherited from the top-level diff --git a/values.yaml b/values.yaml index 27d2c1b5..412ac0dc 100644 --- a/values.yaml +++ b/values.yaml @@ -864,6 +864,20 @@ rr: replicaCount: 1 + # Horizontal Pod Autoscaler for the JS executor. Disabled by default; + # set enabled: true to opt in. When enabled, replicaCount is ignored + # and the HPA controls the replica count. + autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 10 + targetCPUUtilizationPercentage: 70 + targetMemoryUtilizationPercentage: 70 + # Additional HPA metrics (Pods, Object, External, or extra Resource). + # metrics: [] + # Scaling behavior (stabilization windows and policies). + # behavior: {} + seccompLocalhostProfile: profiles/nsjail-seccomp.json # JS-executor-specific environment; not inherited from the top-level From 9aeae79fed146c0e001c9cec560a9d26115b780f Mon Sep 17 00:00:00 2001 From: lukefoster11 Date: Fri, 14 Aug 2026 15:40:39 -0700 Subject: [PATCH 2/8] address greptile --- charts/retool/templates/deployment_js_executor.yaml | 8 ++++++++ charts/retool/values.yaml | 7 +++++++ values.yaml | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml index a97d2935..e1b8b9fa 100644 --- a/charts/retool/templates/deployment_js_executor.yaml +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -261,6 +261,14 @@ spec: {{- include "retool.jsExecutor.selectorLabels" . | nindent 6 }} {{- end }} {{- if (.Values.rr.jsExecutor.autoscaling).enabled }} +{{- $hpa := .Values.rr.jsExecutor.autoscaling }} +{{- $requests := ((.Values.rr.jsExecutor.resources).requests | default dict) }} +{{- if and $hpa.targetCPUUtilizationPercentage (not $requests.cpu) }} +{{- fail "rr.jsExecutor.autoscaling.targetCPUUtilizationPercentage requires rr.jsExecutor.resources.requests.cpu. CPU utilization is unavailable without a CPU request, so the HPA cannot scale on CPU. Set a CPU request or unset targetCPUUtilizationPercentage." }} +{{- end }} +{{- if and $hpa.targetMemoryUtilizationPercentage (not $requests.memory) }} +{{- fail "rr.jsExecutor.autoscaling.targetMemoryUtilizationPercentage requires rr.jsExecutor.resources.requests.memory. Memory utilization is unavailable without a memory request, so the HPA cannot scale on memory. Set a memory request or unset targetMemoryUtilizationPercentage." }} +{{- end }} --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index 412ac0dc..7b04b443 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -867,6 +867,11 @@ rr: # Horizontal Pod Autoscaler for the JS executor. Disabled by default; # set enabled: true to opt in. When enabled, replicaCount is ignored # and the HPA controls the replica count. + # + # CPU and memory Utilization targets require a matching container + # request (resources.requests.cpu / resources.requests.memory). A + # limits-only or partial resources override leaves those metrics + # unavailable and the HPA will not scale on the affected resource. autoscaling: enabled: false minReplicas: 1 @@ -901,6 +906,8 @@ rr: # Resources for the JS executor. Memory request and limit are kept equal: # JSE reads its memory limit and rejects requests at 80% of it, so the # request must reserve the full amount to avoid premature rejections. + # HPA Utilization metrics (see autoscaling above) also require these + # requests; do not drop them if autoscaling is enabled. resources: limits: cpu: '2' diff --git a/values.yaml b/values.yaml index 412ac0dc..7b04b443 100644 --- a/values.yaml +++ b/values.yaml @@ -867,6 +867,11 @@ rr: # Horizontal Pod Autoscaler for the JS executor. Disabled by default; # set enabled: true to opt in. When enabled, replicaCount is ignored # and the HPA controls the replica count. + # + # CPU and memory Utilization targets require a matching container + # request (resources.requests.cpu / resources.requests.memory). A + # limits-only or partial resources override leaves those metrics + # unavailable and the HPA will not scale on the affected resource. autoscaling: enabled: false minReplicas: 1 @@ -901,6 +906,8 @@ rr: # Resources for the JS executor. Memory request and limit are kept equal: # JSE reads its memory limit and rejects requests at 80% of it, so the # request must reserve the full amount to avoid premature rejections. + # HPA Utilization metrics (see autoscaling above) also require these + # requests; do not drop them if autoscaling is enabled. resources: limits: cpu: '2' From 51f378a533d9800977e6fd5f5895a2ebff7bf529 Mon Sep 17 00:00:00 2001 From: lukefoster11 Date: Fri, 14 Aug 2026 15:57:52 -0700 Subject: [PATCH 3/8] fix --- .../retool/templates/deployment_js_executor.yaml | 15 +++++++++++++++ charts/retool/values.yaml | 7 +++++-- values.yaml | 7 +++++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml index e1b8b9fa..c161eaa0 100644 --- a/charts/retool/templates/deployment_js_executor.yaml +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -269,6 +269,21 @@ spec: {{- if and $hpa.targetMemoryUtilizationPercentage (not $requests.memory) }} {{- fail "rr.jsExecutor.autoscaling.targetMemoryUtilizationPercentage requires rr.jsExecutor.resources.requests.memory. Memory utilization is unavailable without a memory request, so the HPA cannot scale on memory. Set a memory request or unset targetMemoryUtilizationPercentage." }} {{- end }} +{{- range $hpa.metrics }} +{{- if eq (toString .type) "Resource" }} +{{- $name := (.resource).name | default "" }} +{{- $targetType := ((.resource).target).type | default "" }} +{{- if and (eq $targetType "Utilization") $name (not (index $requests $name)) }} +{{- fail (printf "rr.jsExecutor.autoscaling.metrics Resource Utilization target %q requires rr.jsExecutor.resources.requests.%s. Utilization is unavailable without that request, so the HPA cannot scale on it. Set the request or use an AverageValue target instead." $name $name) }} +{{- end }} +{{- else if eq (toString .type) "ContainerResource" }} +{{- $name := (.containerResource).name | default "" }} +{{- $targetType := ((.containerResource).target).type | default "" }} +{{- if and (eq $targetType "Utilization") $name (not (index $requests $name)) }} +{{- fail (printf "rr.jsExecutor.autoscaling.metrics ContainerResource Utilization target %q requires rr.jsExecutor.resources.requests.%s. Utilization is unavailable without that request, so the HPA cannot scale on it. Set the request or use an AverageValue target instead." $name $name) }} +{{- end }} +{{- end }} +{{- end }} --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index 7b04b443..b579c890 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -868,8 +868,9 @@ rr: # set enabled: true to opt in. When enabled, replicaCount is ignored # and the HPA controls the replica count. # - # CPU and memory Utilization targets require a matching container - # request (resources.requests.cpu / resources.requests.memory). A + # CPU and memory Utilization targets (the shortcuts below, and any + # Resource / ContainerResource Utilization metric in autoscaling.metrics) + # require a matching container request (resources.requests.). A # limits-only or partial resources override leaves those metrics # unavailable and the HPA will not scale on the affected resource. autoscaling: @@ -879,6 +880,8 @@ rr: targetCPUUtilizationPercentage: 70 targetMemoryUtilizationPercentage: 70 # Additional HPA metrics (Pods, Object, External, or extra Resource). + # Resource Utilization metrics here have the same request requirement + # as the CPU/memory shortcuts above. # metrics: [] # Scaling behavior (stabilization windows and policies). # behavior: {} diff --git a/values.yaml b/values.yaml index 7b04b443..b579c890 100644 --- a/values.yaml +++ b/values.yaml @@ -868,8 +868,9 @@ rr: # set enabled: true to opt in. When enabled, replicaCount is ignored # and the HPA controls the replica count. # - # CPU and memory Utilization targets require a matching container - # request (resources.requests.cpu / resources.requests.memory). A + # CPU and memory Utilization targets (the shortcuts below, and any + # Resource / ContainerResource Utilization metric in autoscaling.metrics) + # require a matching container request (resources.requests.). A # limits-only or partial resources override leaves those metrics # unavailable and the HPA will not scale on the affected resource. autoscaling: @@ -879,6 +880,8 @@ rr: targetCPUUtilizationPercentage: 70 targetMemoryUtilizationPercentage: 70 # Additional HPA metrics (Pods, Object, External, or extra Resource). + # Resource Utilization metrics here have the same request requirement + # as the CPU/memory shortcuts above. # metrics: [] # Scaling behavior (stabilization windows and policies). # behavior: {} From d2776ad19962ab50b579788a2ee624104a601c16 Mon Sep 17 00:00:00 2001 From: lukefoster11 Date: Fri, 14 Aug 2026 16:12:09 -0700 Subject: [PATCH 4/8] version bump --- charts/retool/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/retool/Chart.yaml b/charts/retool/Chart.yaml index 853effcf..79a41372 100644 --- a/charts/retool/Chart.yaml +++ b/charts/retool/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: retool description: A Helm chart for Kubernetes type: application -version: 6.11.18 +version: 6.11.19 maintainers: - name: Retool Engineering email: engineering+helm@retool.com From b27fc53bd24cfcf4ab98251d09490fc7460aff87 Mon Sep 17 00:00:00 2001 From: lukefoster11 Date: Mon, 17 Aug 2026 12:54:51 -0700 Subject: [PATCH 5/8] fix greptile --- charts/retool/templates/_helpers.tpl | 44 +++++++++++++++++++ .../templates/deployment_js_executor.yaml | 8 +++- charts/retool/values.yaml | 4 +- values.yaml | 4 +- 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/charts/retool/templates/_helpers.tpl b/charts/retool/templates/_helpers.tpl index e2a90e83..166edbee 100644 --- a/charts/retool/templates/_helpers.tpl +++ b/charts/retool/templates/_helpers.tpl @@ -255,6 +255,50 @@ app.kubernetes.io/instance: {{ .Release.Name }} telemetry.retool.com/service-name: js-executor {{- end }} +{{/* +Resource requests for a named container on the JS executor pod. +js-executor uses rr.jsExecutor.resources.requests; any other name is looked +up in extraContainers. Fails if the container is not part of the pod. +Usage: include "retool.jsExecutor.containerRequests" (dict "root" $ "container" "js-executor") +*/}} +{{- define "retool.jsExecutor.containerRequests" -}} +{{- $root := .root -}} +{{- $name := .container | default "" -}} +{{- if not $name -}} +{{- fail "rr.jsExecutor.autoscaling.metrics ContainerResource metric requires containerResource.container." -}} +{{- end -}} +{{- if eq $name "js-executor" -}} +{{- toYaml ((($root.Values.rr.jsExecutor).resources).requests | default dict) -}} +{{- else -}} +{{- $found := false -}} +{{- $requests := dict -}} +{{- $extra := $root.Values.extraContainers -}} +{{- $containers := list -}} +{{- if kindIs "string" $extra -}} +{{- $rendered := tpl $extra $root -}} +{{- if trim $rendered -}} +{{- $doc := fromYaml (printf "items:%s" ($rendered | nindent 2)) -}} +{{- if $doc.Error -}} +{{- fail (printf "rr.jsExecutor.autoscaling could not parse extraContainers while validating a ContainerResource metric: %s" $doc.Error) -}} +{{- end -}} +{{- $containers = $doc.items | default list -}} +{{- end -}} +{{- else if kindIs "slice" $extra -}} +{{- $containers = $extra -}} +{{- end -}} +{{- range $containers -}} +{{- if eq (toString .name) $name -}} +{{- $found = true -}} +{{- $requests = ((.resources).requests | default dict) -}} +{{- end -}} +{{- end -}} +{{- if not $found -}} +{{- fail (printf "rr.jsExecutor.autoscaling.metrics ContainerResource metric targets container %q, which is not the js-executor container and was not found in extraContainers." $name) -}} +{{- end -}} +{{- toYaml $requests -}} +{{- end -}} +{{- end -}} + {{/* Selector labels for agent worker. Note changes here will require manual deployment recreation and incur downtime, so should be avoided. diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml index c161eaa0..f3f87cd4 100644 --- a/charts/retool/templates/deployment_js_executor.yaml +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -278,9 +278,13 @@ spec: {{- end }} {{- else if eq (toString .type) "ContainerResource" }} {{- $name := (.containerResource).name | default "" }} +{{- $containerName := (.containerResource).container | default "" }} {{- $targetType := ((.containerResource).target).type | default "" }} -{{- if and (eq $targetType "Utilization") $name (not (index $requests $name)) }} -{{- fail (printf "rr.jsExecutor.autoscaling.metrics ContainerResource Utilization target %q requires rr.jsExecutor.resources.requests.%s. Utilization is unavailable without that request, so the HPA cannot scale on it. Set the request or use an AverageValue target instead." $name $name) }} +{{- if and (eq $targetType "Utilization") $name }} +{{- $containerRequests := fromYaml (include "retool.jsExecutor.containerRequests" (dict "root" $ "container" $containerName)) }} +{{- if not (index $containerRequests $name) }} +{{- fail (printf "rr.jsExecutor.autoscaling.metrics ContainerResource Utilization target %q on container %q requires a matching request on that container. Utilization is unavailable without it, so the HPA cannot scale on it. Set resources.requests.%s on %q (rr.jsExecutor.resources for js-executor, or the extraContainers entry) or use an AverageValue target instead." $name $containerName $name $containerName) }} +{{- end }} {{- end }} {{- end }} {{- end }} diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index b579c890..30307a1b 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -870,7 +870,9 @@ rr: # # CPU and memory Utilization targets (the shortcuts below, and any # Resource / ContainerResource Utilization metric in autoscaling.metrics) - # require a matching container request (resources.requests.). A + # require a matching container request. Resource metrics use + # rr.jsExecutor.resources.requests.; ContainerResource metrics use + # the named container (js-executor or an extraContainers entry). A # limits-only or partial resources override leaves those metrics # unavailable and the HPA will not scale on the affected resource. autoscaling: diff --git a/values.yaml b/values.yaml index b579c890..30307a1b 100644 --- a/values.yaml +++ b/values.yaml @@ -870,7 +870,9 @@ rr: # # CPU and memory Utilization targets (the shortcuts below, and any # Resource / ContainerResource Utilization metric in autoscaling.metrics) - # require a matching container request (resources.requests.). A + # require a matching container request. Resource metrics use + # rr.jsExecutor.resources.requests.; ContainerResource metrics use + # the named container (js-executor or an extraContainers entry). A # limits-only or partial resources override leaves those metrics # unavailable and the HPA will not scale on the affected resource. autoscaling: From 186f6ccdb2462c76fa4ed3696d95059544a96f08 Mon Sep 17 00:00:00 2001 From: lukefoster11 Date: Tue, 18 Aug 2026 11:36:23 -0700 Subject: [PATCH 6/8] make more strict --- charts/retool/templates/_helpers.tpl | 44 ------------------- .../templates/deployment_js_executor.yaml | 10 +---- charts/retool/values.yaml | 6 +-- values.yaml | 6 +-- 4 files changed, 5 insertions(+), 61 deletions(-) diff --git a/charts/retool/templates/_helpers.tpl b/charts/retool/templates/_helpers.tpl index 23e2f013..ef831ed0 100644 --- a/charts/retool/templates/_helpers.tpl +++ b/charts/retool/templates/_helpers.tpl @@ -255,50 +255,6 @@ app.kubernetes.io/instance: {{ .Release.Name }} telemetry.retool.com/service-name: js-executor {{- end }} -{{/* -Resource requests for a named container on the JS executor pod. -js-executor uses rr.jsExecutor.resources.requests; any other name is looked -up in extraContainers. Fails if the container is not part of the pod. -Usage: include "retool.jsExecutor.containerRequests" (dict "root" $ "container" "js-executor") -*/}} -{{- define "retool.jsExecutor.containerRequests" -}} -{{- $root := .root -}} -{{- $name := .container | default "" -}} -{{- if not $name -}} -{{- fail "rr.jsExecutor.autoscaling.metrics ContainerResource metric requires containerResource.container." -}} -{{- end -}} -{{- if eq $name "js-executor" -}} -{{- toYaml ((($root.Values.rr.jsExecutor).resources).requests | default dict) -}} -{{- else -}} -{{- $found := false -}} -{{- $requests := dict -}} -{{- $extra := $root.Values.extraContainers -}} -{{- $containers := list -}} -{{- if kindIs "string" $extra -}} -{{- $rendered := tpl $extra $root -}} -{{- if trim $rendered -}} -{{- $doc := fromYaml (printf "items:%s" ($rendered | nindent 2)) -}} -{{- if $doc.Error -}} -{{- fail (printf "rr.jsExecutor.autoscaling could not parse extraContainers while validating a ContainerResource metric: %s" $doc.Error) -}} -{{- end -}} -{{- $containers = $doc.items | default list -}} -{{- end -}} -{{- else if kindIs "slice" $extra -}} -{{- $containers = $extra -}} -{{- end -}} -{{- range $containers -}} -{{- if eq (toString .name) $name -}} -{{- $found = true -}} -{{- $requests = ((.resources).requests | default dict) -}} -{{- end -}} -{{- end -}} -{{- if not $found -}} -{{- fail (printf "rr.jsExecutor.autoscaling.metrics ContainerResource metric targets container %q, which is not the js-executor container and was not found in extraContainers." $name) -}} -{{- end -}} -{{- toYaml $requests -}} -{{- end -}} -{{- end -}} - {{/* Selector labels for agent worker. Note changes here will require manual deployment recreation and incur downtime, so should be avoided. diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml index f3f87cd4..7098dc84 100644 --- a/charts/retool/templates/deployment_js_executor.yaml +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -277,15 +277,7 @@ spec: {{- fail (printf "rr.jsExecutor.autoscaling.metrics Resource Utilization target %q requires rr.jsExecutor.resources.requests.%s. Utilization is unavailable without that request, so the HPA cannot scale on it. Set the request or use an AverageValue target instead." $name $name) }} {{- end }} {{- else if eq (toString .type) "ContainerResource" }} -{{- $name := (.containerResource).name | default "" }} -{{- $containerName := (.containerResource).container | default "" }} -{{- $targetType := ((.containerResource).target).type | default "" }} -{{- if and (eq $targetType "Utilization") $name }} -{{- $containerRequests := fromYaml (include "retool.jsExecutor.containerRequests" (dict "root" $ "container" $containerName)) }} -{{- if not (index $containerRequests $name) }} -{{- fail (printf "rr.jsExecutor.autoscaling.metrics ContainerResource Utilization target %q on container %q requires a matching request on that container. Utilization is unavailable without it, so the HPA cannot scale on it. Set resources.requests.%s on %q (rr.jsExecutor.resources for js-executor, or the extraContainers entry) or use an AverageValue target instead." $name $containerName $name $containerName) }} -{{- end }} -{{- end }} +{{- fail "rr.jsExecutor.autoscaling.metrics does not support ContainerResource metrics. Use targetCPUUtilizationPercentage / targetMemoryUtilizationPercentage, or a Resource metric, to scale on the JS executor pod." }} {{- end }} {{- end }} --- diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index 603efa7d..cd5c1c67 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -873,10 +873,8 @@ rr: # and the HPA controls the replica count. # # CPU and memory Utilization targets (the shortcuts below, and any - # Resource / ContainerResource Utilization metric in autoscaling.metrics) - # require a matching container request. Resource metrics use - # rr.jsExecutor.resources.requests.; ContainerResource metrics use - # the named container (js-executor or an extraContainers entry). A + # Resource Utilization metric in autoscaling.metrics) require a matching + # container request (rr.jsExecutor.resources.requests.). A # limits-only or partial resources override leaves those metrics # unavailable and the HPA will not scale on the affected resource. autoscaling: diff --git a/values.yaml b/values.yaml index 603efa7d..cd5c1c67 100644 --- a/values.yaml +++ b/values.yaml @@ -873,10 +873,8 @@ rr: # and the HPA controls the replica count. # # CPU and memory Utilization targets (the shortcuts below, and any - # Resource / ContainerResource Utilization metric in autoscaling.metrics) - # require a matching container request. Resource metrics use - # rr.jsExecutor.resources.requests.; ContainerResource metrics use - # the named container (js-executor or an extraContainers entry). A + # Resource Utilization metric in autoscaling.metrics) require a matching + # container request (rr.jsExecutor.resources.requests.). A # limits-only or partial resources override leaves those metrics # unavailable and the HPA will not scale on the affected resource. autoscaling: From 70ad4b9804a6bfdb1386d4d4dd30bc1342d3bc48 Mon Sep 17 00:00:00 2001 From: lukefoster11 Date: Tue, 18 Aug 2026 11:52:11 -0700 Subject: [PATCH 7/8] simplify --- .../retool/ci/test-js-executor-hpa-option.yaml | 14 +++----------- .../retool/templates/deployment_js_executor.yaml | 15 ++------------- charts/retool/values.yaml | 16 ++++++---------- values.yaml | 16 ++++++---------- 4 files changed, 17 insertions(+), 44 deletions(-) diff --git a/charts/retool/ci/test-js-executor-hpa-option.yaml b/charts/retool/ci/test-js-executor-hpa-option.yaml index f7c2f71c..9ec2a183 100644 --- a/charts/retool/ci/test-js-executor-hpa-option.yaml +++ b/charts/retool/ci/test-js-executor-hpa-option.yaml @@ -1,8 +1,8 @@ rr: # Exercises the JS executor HPA (opt-in via rr.jsExecutor.autoscaling). - # Overlaid on top of test-install-values.yaml. Covers CPU, memory, extra - # metrics, and scale behavior branches; replicaCount must be omitted from + # Overlaid on top of test-install-values.yaml. Covers CPU and memory + # Utilization plus scale behavior; replicaCount must be omitted from # the Deployment when the HPA is enabled. jsExecutor: enabled: true @@ -15,15 +15,7 @@ rr: minReplicas: 2 maxReplicas: 8 targetCPUUtilizationPercentage: 70 - targetMemoryUtilizationPercentage: 80 - metrics: - - type: Pods - pods: - metric: - name: packets-per-second - target: - type: AverageValue - averageValue: 1k + targetMemoryUtilizationPercentage: 70 behavior: scaleDown: stabilizationWindowSeconds: 300 diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml index 7098dc84..3d1b5e70 100644 --- a/charts/retool/templates/deployment_js_executor.yaml +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -269,16 +269,8 @@ spec: {{- if and $hpa.targetMemoryUtilizationPercentage (not $requests.memory) }} {{- fail "rr.jsExecutor.autoscaling.targetMemoryUtilizationPercentage requires rr.jsExecutor.resources.requests.memory. Memory utilization is unavailable without a memory request, so the HPA cannot scale on memory. Set a memory request or unset targetMemoryUtilizationPercentage." }} {{- end }} -{{- range $hpa.metrics }} -{{- if eq (toString .type) "Resource" }} -{{- $name := (.resource).name | default "" }} -{{- $targetType := ((.resource).target).type | default "" }} -{{- if and (eq $targetType "Utilization") $name (not (index $requests $name)) }} -{{- fail (printf "rr.jsExecutor.autoscaling.metrics Resource Utilization target %q requires rr.jsExecutor.resources.requests.%s. Utilization is unavailable without that request, so the HPA cannot scale on it. Set the request or use an AverageValue target instead." $name $name) }} -{{- end }} -{{- else if eq (toString .type) "ContainerResource" }} -{{- fail "rr.jsExecutor.autoscaling.metrics does not support ContainerResource metrics. Use targetCPUUtilizationPercentage / targetMemoryUtilizationPercentage, or a Resource metric, to scale on the JS executor pod." }} -{{- end }} +{{- with $hpa.metrics }} +{{- fail "rr.jsExecutor.autoscaling.metrics is not supported. The JS executor HPA scales only on CPU and memory via targetCPUUtilizationPercentage and targetMemoryUtilizationPercentage." }} {{- end }} --- apiVersion: autoscaling/v2 @@ -313,9 +305,6 @@ spec: type: Utilization averageUtilization: {{ .Values.rr.jsExecutor.autoscaling.targetMemoryUtilizationPercentage }} {{- end }} - {{- with .Values.rr.jsExecutor.autoscaling.metrics }} - {{- toYaml . | nindent 4 }} - {{- end }} {{- with .Values.rr.jsExecutor.autoscaling.behavior }} behavior: {{- toYaml . | nindent 4 }} diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index cd5c1c67..cf3a662a 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -870,23 +870,19 @@ rr: # Horizontal Pod Autoscaler for the JS executor. Disabled by default; # set enabled: true to opt in. When enabled, replicaCount is ignored - # and the HPA controls the replica count. + # and the HPA controls the replica count. Scales on CPU and memory + # Utilization only. # - # CPU and memory Utilization targets (the shortcuts below, and any - # Resource Utilization metric in autoscaling.metrics) require a matching - # container request (rr.jsExecutor.resources.requests.). A - # limits-only or partial resources override leaves those metrics - # unavailable and the HPA will not scale on the affected resource. + # Each Utilization target requires a matching container request + # (rr.jsExecutor.resources.requests.cpu / .memory). A limits-only or + # partial resources override leaves those metrics unavailable and the + # HPA will not scale on the affected resource. autoscaling: enabled: false minReplicas: 1 maxReplicas: 10 targetCPUUtilizationPercentage: 70 targetMemoryUtilizationPercentage: 70 - # Additional HPA metrics (Pods, Object, External, or extra Resource). - # Resource Utilization metrics here have the same request requirement - # as the CPU/memory shortcuts above. - # metrics: [] # Scaling behavior (stabilization windows and policies). # behavior: {} diff --git a/values.yaml b/values.yaml index cd5c1c67..cf3a662a 100644 --- a/values.yaml +++ b/values.yaml @@ -870,23 +870,19 @@ rr: # Horizontal Pod Autoscaler for the JS executor. Disabled by default; # set enabled: true to opt in. When enabled, replicaCount is ignored - # and the HPA controls the replica count. + # and the HPA controls the replica count. Scales on CPU and memory + # Utilization only. # - # CPU and memory Utilization targets (the shortcuts below, and any - # Resource Utilization metric in autoscaling.metrics) require a matching - # container request (rr.jsExecutor.resources.requests.). A - # limits-only or partial resources override leaves those metrics - # unavailable and the HPA will not scale on the affected resource. + # Each Utilization target requires a matching container request + # (rr.jsExecutor.resources.requests.cpu / .memory). A limits-only or + # partial resources override leaves those metrics unavailable and the + # HPA will not scale on the affected resource. autoscaling: enabled: false minReplicas: 1 maxReplicas: 10 targetCPUUtilizationPercentage: 70 targetMemoryUtilizationPercentage: 70 - # Additional HPA metrics (Pods, Object, External, or extra Resource). - # Resource Utilization metrics here have the same request requirement - # as the CPU/memory shortcuts above. - # metrics: [] # Scaling behavior (stabilization windows and policies). # behavior: {} From 8dc09b0e97071805ff85944a6605725e0fee7fee Mon Sep 17 00:00:00 2001 From: lukefoster11 Date: Mon, 24 Aug 2026 11:25:06 -0700 Subject: [PATCH 8/8] metrics-server note --- charts/retool/templates/NOTES.txt | 11 +++++++++++ charts/retool/values.yaml | 4 ++++ values.yaml | 4 ++++ 3 files changed, 19 insertions(+) diff --git a/charts/retool/templates/NOTES.txt b/charts/retool/templates/NOTES.txt index 1fac551d..bafa98bb 100644 --- a/charts/retool/templates/NOTES.txt +++ b/charts/retool/templates/NOTES.txt @@ -60,3 +60,14 @@ FROM 169.254.169.254 and will FAIL. In that case set: networkPolicy.blockCloudMetadataEgress: false *************************************************************************** {{- end }} +{{- if and (eq (include "retool.rr.componentEnabled" (dict "root" . "component" "jsExecutor")) "1") ((.Values.rr.jsExecutor).autoscaling).enabled }} + +*************************************************************************** +NOTE: JS executor autoscaling is enabled (rr.jsExecutor.autoscaling). The HPA +scales on CPU and memory Utilization and needs a cluster metrics-server (or +another metrics.k8s.io implementation). This chart does not install it. + +If kubectl top pod fails in this namespace, the HPA is created but will not +scale until metrics-server is enabled on the cluster. +*************************************************************************** +{{- end }} diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index cf3a662a..ee37dde6 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -873,6 +873,10 @@ rr: # and the HPA controls the replica count. Scales on CPU and memory # Utilization only. # + # Scaling requires a cluster metrics-server (or another metrics.k8s.io + # implementation). This chart does not install it. If kubectl top pod + # fails in the namespace, the HPA is created but does not scale. + # # Each Utilization target requires a matching container request # (rr.jsExecutor.resources.requests.cpu / .memory). A limits-only or # partial resources override leaves those metrics unavailable and the diff --git a/values.yaml b/values.yaml index cf3a662a..ee37dde6 100644 --- a/values.yaml +++ b/values.yaml @@ -873,6 +873,10 @@ rr: # and the HPA controls the replica count. Scales on CPU and memory # Utilization only. # + # Scaling requires a cluster metrics-server (or another metrics.k8s.io + # implementation). This chart does not install it. If kubectl top pod + # fails in the namespace, the HPA is created but does not scale. + # # Each Utilization target requires a matching container request # (rr.jsExecutor.resources.requests.cpu / .memory). A limits-only or # partial resources override leaves those metrics unavailable and the