Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
43abc2f
support agent-sandbox service (#281)
lukefoster11 Apr 30, 2026
8b9582f
[INF-6675] add js executor (#275)
slaminad May 1, 2026
7bb327e
fix jsExecutor image lookup
lukefoster11 May 5, 2026
625173d
fix gvisor seccomp errno ret
lukefoster11 May 6, 2026
414e1fe
Add MCP server support to Retool Helm chart (#285)
arnold-retool May 14, 2026
386c23b
revert accidental version bump (#286)
arnold-retool May 15, 2026
63adf18
[INF-6865] increase js executor mem (#289)
lukefoster11 May 19, 2026
45a04a8
optional agentsandbox postgres secret
lukefoster11 May 19, 2026
9dc36c9
Revert "optional agentsandbox postgres secret"
lukefoster11 May 19, 2026
21a2c40
new agent sandbox secret modularity (#290)
lukefoster11 May 19, 2026
c5ed71f
disable (#292)
lukefoster11 May 20, 2026
c16febe
make retool.fullname prefixed (#291)
lukefoster11 May 20, 2026
180be6f
Revert "make retool.fullname prefixed (#291)" (#293)
lukefoster11 May 20, 2026
4a58e2c
make retool.fullname prefixed (#294)
lukefoster11 May 20, 2026
ef2d5bb
separate deviceplugin use and deployment
lukefoster11 May 21, 2026
70c47c1
minor r2 fixes (#287)
ryanartecona May 21, 2026
710b822
[feat][r2] enable git_server in-process with rrGitServer.enabled + bl…
JatinNanda May 22, 2026
b611145
tune (#297)
lukefoster11 May 22, 2026
be8d372
Add OAUTH_MAIN_DOMAIN for consistent authorization server domain in M…
arnold-retool May 26, 2026
5a2e0a0
Add optional MCP git server URL (#299)
arnold-retool Jun 2, 2026
34bcf51
rr_agent_pubsub_backend (#300)
lukefoster11 Jun 2, 2026
ed33a82
Rename sandbox env vars (#295)
westrik Jun 3, 2026
d83fa5c
add new env vars (#301)
lukefoster11 Jun 3, 2026
09f0045
[fix[R2] Increase the AE proxy timeout to be inline with fix in retoo…
jamie-retool Jun 8, 2026
7da7f86
r2-cleanup → r2: R2 enablement polish (master switch, same-origin pro…
JatinNanda Jun 9, 2026
323d301
[fix][r2] drop mcp from the r2.enabled master switch (#316)
JatinNanda Jun 10, 2026
44e7754
Add controller.scaling.perUserSandboxLimit and sandbox.sandboxGlobalL…
westrik Jun 10, 2026
9398fb7
Sync code-executor nsjail seccomp profile with retool-k8s (#318)
mertbozfakioglu Jun 10, 2026
6d636b1
[fix] [plat] Set appArmorProfile Unconfined for js-executor (#320)
mertbozfakioglu Jun 11, 2026
4e7ac78
[feat][plat-1012] Add opt-in seccomp sandboxing for code-executor (co…
mertbozfakioglu Jun 11, 2026
e983e19
[rr] Restructure into a top-level rr.enabled master switch (#321)
JatinNanda Jun 11, 2026
1bb5740
[agent-sandbox] expose sandboxReadyTimeoutMs -> SANDBOX_READY_TIMEOUT…
JatinNanda Jun 11, 2026
971a1b4
[rr] make legacy-values guard message spell out the fix (#323)
JatinNanda Jun 11, 2026
ef28c2d
[agent-sandbox] fix jwtPublicKey breaking job-template JSON (use toJs…
JatinNanda Jun 11, 2026
1292382
[agent-sandbox] guard device-plugin priorityClassName (fix null opt-o…
JatinNanda Jun 11, 2026
2c6fc90
set chart version to 6.11.0 (#329)
JatinNanda Jun 11, 2026
b052ff4
reduce JSE default CPU request/limit from 6 => 2
ryanartecona Jun 11, 2026
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
4 changes: 2 additions & 2 deletions charts/retool/Chart.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ dependencies:
- name: retool-temporal-services-helm
repository: ""
version: 1.1.5
digest: sha256:6b027cb2d661c436127fe34c4a5e14c820c691d4ec9e0c08609f416e6fe5af21
generated: "2024-03-26T15:39:11.463027-04:00"
digest: sha256:7b9440db4914c56407c98faace390fd00374820b0f87987903912de7ac899ce8
generated: "2026-04-22T17:14:51.109299-07:00"
4 changes: 2 additions & 2 deletions charts/retool/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: v2
name: retool
description: A Helm chart for Kubernetes
type: application
version: 6.10.6
version: 6.11.0
maintainers:
- name: Retool Engineering
email: engineering+helm@retool.com
Expand All @@ -13,4 +13,4 @@ dependencies:
condition: postgresql.enabled
- name: retool-temporal-services-helm
version: 1.1.5
condition: retool-temporal-services-helm.enabled,workflows.enabled
condition: retool-temporal-services-helm.enabled
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
rr:

# Agent Sandbox — device-plugin DaemonSet with priorityClassName opted OUT.
#
# Regression guard for the GKE path documented in values.yaml: GKE doesn't allow
# the `system-node-critical` PriorityClass in user namespaces, so operators set
# rr.agentSandbox.devicePlugin.priorityClassName: null
# to drop it. The DaemonSet template must OMIT the priorityClassName field in that
# case — a bare `{{ ... }}` on a nil value would render the literal `<no value>`,
# producing an invalid manifest that the kubelet rejects (and that kubeconform
# rejects here in CI).
#
# Overlaid on test-install-values.yaml.
agentSandbox:
enabled: true

externalSecret:
name: agent-sandbox-secrets

sandboxNetwork:
enabled: true
devicePlugin: true
deployDaemonSet: true

devicePlugin:
# The GKE opt-out — DaemonSet must render with no priorityClassName field.
priorityClassName: null
79 changes: 79 additions & 0 deletions charts/retool/ci/test-agent-sandbox-enabled-option.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
rr:

# Agent Sandbox — external secret + dedicated proxy domain WITH ingress.
#
# This is the "max surface" scenario: controller + proxy deployments, the
# job-template ConfigMap, RBAC, headless/proxy services, proxy ingress + TLS,
# the image-prepuller + seccomp DaemonSets, the smarter-device-manager device
# plugin DaemonSet, the NetworkPolicies, and both PDBs.
#
# Secret/Postgres sourcing here uses externalSecret.name (Postgres OPTION 4:
# the secret's postgres-url key). The other secret/Postgres precedence paths and
# the same-origin (no-ingress) proxy mode are covered by sibling files:
# - test-agent-sandbox-inline-secrets-option.yaml (inline secrets, plaintext DSN, same-origin/no ingress, hostPath tun)
# - test-agent-sandbox-postgres-fields-option.yaml (assemble DSN from fields + PGPASSWORD secret)
# - test-agent-sandbox-postgres-url-secret-option.yaml (full DSN from an existing secret)
# - test-agent-sandbox-inherit-postgres-option.yaml (zero-config inherit of the backend Postgres)
# Overlaid on test-install-values.yaml.
agentSandbox:
enabled: true

image:
repository: tryretool/agent-sandbox-service
tag: 3.123.4
pullPolicy: IfNotPresent

# Reference a pre-existing K8s Secret (the production-recommended path) rather
# than inlining JWT/encryption material into the chart. With externalSecret.name
# set, secret-backed env vars — including the ones injected into the sandbox
# job-template — resolve via secretKeyRef instead of plaintext.
externalSecret:
name: agent-sandbox-secrets

postgres:
schema: agent_executor
poolMax: 10

sandboxNetwork:
enabled: true
devicePlugin: true
deployDaemonSet: true

snapshotStorage:
s3Bucket: retool-agent-sandbox-snapshots
s3Endpoint: https://s3.us-east-1.amazonaws.com
s3Region: us-east-1
credentialsSecretName: agent-sandbox-s3-credentials

# replicaCount > 1 renders the controller PodDisruptionBudget.
controller:
replicaCount: 2

proxy:
replicaCount: 2
allowedDomains: api.example.com,example.com
backendDomainSuffixes: .example.com
sandboxProxyTimeoutMs: "3600000"
service:
type: ClusterIP
# Dedicated proxy domain → renders the proxy Ingress.
ingress:
enabled: true
ingressClassName: nginx
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
host: sandbox.example.com
tls:
- secretName: agent-sandbox-tls
hosts:
- sandbox.example.com
frontendWsProxyDomain: https://sandbox.example.com

# Restrict sandbox/controller/proxy traffic → renders the NetworkPolicies.
networkPolicy:
enabled: true

# Exercise the proxy PodDisruptionBudget branch.
podDisruptionBudget:
maxUnavailable: 1
22 changes: 22 additions & 0 deletions charts/retool/ci/test-agent-sandbox-inherit-postgres-option.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
rr:

# Agent Sandbox — Postgres sourcing OPTION 5 (default): inherit the backend's
# Postgres connection. With agentSandbox.postgres left entirely unset, the
# controller/proxy reuse config.postgresql / the postgresql subchart (same
# instance and database, separate schema) — the zero-config path for enabling
# the sandbox on an existing deployment. PGPASSWORD mirrors the backend's
# POSTGRES_PASSWORD secretKeyRef, and the DSN is assembled from the postgresql
# helpers. The base test-install-values.yaml enables the postgresql subchart,
# which is what makes inheritance resolve.
#
# Only the (required) JWT secrets are provided; everything else is left default.
agentSandbox:
enabled: true

image:
repository: tryretool/agent-sandbox-service
tag: 3.123.4
pullPolicy: IfNotPresent

jwtPublicKey: '-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEljtqa2nhBwe/PqNhWgPHhj0jv8AI\nY+QUCicYtfv9wLGcEGPQuXoBQtuoIuOwXOdbEWgrQyLdIEb0YjegAW3miA==\n-----END PUBLIC KEY-----'
jwtPrivateKey: '-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMFXLiN/YsJv89D2YkEZ6/Dj5fujghENmYTOilwdChU3oAoGCCqGSM49\nAwEHoUQDQgAEljtqa2nhBwe/PqNhWgPHhj0jv8AIY+QUCicYtfv9wLGcEGPQuXoB\nQtuoIuOwXOdbEWgrQyLdIEb0YjegAW3miA==\n-----END EC PRIVATE KEY-----'
61 changes: 61 additions & 0 deletions charts/retool/ci/test-agent-sandbox-inline-secrets-option.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
rr:

# Agent Sandbox — inline secrets + plaintext DSN + same-origin proxy (no ingress).
#
# Complements test-agent-sandbox-enabled-option.yaml (external secret + dedicated
# proxy ingress). Here we exercise the *other* halves of those branches:
# - Secrets inline (no externalSecret.name) → the chart renders its own Secret
# (jwt-public-key / jwt-private-key / encryption-key / api-secret). jwtPublicKey
# is injected into the sandbox job-template JSON via `toJson`, so a genuine
# multi-line PEM (real newlines, as below) is escaped correctly — no need to
# pre-flatten it to a single `\n`-escaped line.
# - Postgres sourcing OPTION 1: plaintext DSN via postgres.url.
# - Same-origin proxy: no dedicated proxy domain and no proxy ingress — the
# backend reverse-proxies /sandbox/* (frontendWsProxyDomain left empty).
# - sandboxNetwork.devicePlugin=false → sandbox pods get /dev/net/tun via
# hostPath (the non-device-plugin branch), and no device-manager DaemonSet.
# - networkPolicy disabled.
agentSandbox:
enabled: true

image:
repository: tryretool/agent-sandbox-service
tag: 3.123.4
pullPolicy: IfNotPresent

# Real multi-line PEM (block scalar) — exercises the toJson newline escaping in
# the job-template JSON. A raw "{{ . }}" would produce invalid JSON here.
jwtPublicKey: |-
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEljtqa2nhBwe/PqNhWgPHhj0jv8AI
Y+QUCicYtfv9wLGcEGPQuXoBQtuoIuOwXOdbEWgrQyLdIEb0YjegAW3miA==
-----END PUBLIC KEY-----
jwtPrivateKey: |-
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIMFXLiN/YsJv89D2YkEZ6/Dj5fujghENmYTOilwdChU3oAoGCCqGSM49
AwEHoUQDQgAEljtqa2nhBwe/PqNhWgPHhj0jv8AIY+QUCicYtfv9wLGcEGPQuXoB
QtuoIuOwXOdbEWgrQyLdIEb0YjegAW3miA==
-----END EC PRIVATE KEY-----
encryptionKey: a12b01429fe0fe69a80da94e9e837ab2f1e9bda378ed8a25905a238f6fea6b7a
apiSecret: test-agent-sandbox-api-secret

# Option 1: plaintext DSN.
postgres:
url: postgres://retool:retool@agent-sandbox-db.example.internal:5432/agent_sandbox
schema: agent_executor
poolMax: 10

sandboxNetwork:
enabled: true
devicePlugin: false
deployDaemonSet: false

proxy:
# Same-origin: ClusterIP service, no ingress.
service:
type: ClusterIP
ingress:
enabled: false

networkPolicy:
enabled: false
41 changes: 41 additions & 0 deletions charts/retool/ci/test-agent-sandbox-postgres-fields-option.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
rr:

# Agent Sandbox — Postgres sourcing OPTION 2: assemble the DSN from discrete
# fields, with the password supplied via PGPASSWORD from a pre-existing Secret
# (never embedded in the URL, so any password characters are safe).
#
# Also exercises:
# - An Azure-style "user@servername" username, which validateSecrets allows
# (the parser splits userinfo on the last '@').
# - sandboxNetwork with devicePlugin=true but deployDaemonSet=false (a
# smarter-device-manager already runs on the nodes, managed elsewhere) →
# sandbox pods request smarter-devices/net_tun but no DS is rendered.
# - networkPolicy enabled.
agentSandbox:
enabled: true

image:
repository: tryretool/agent-sandbox-service
tag: 3.123.4
pullPolicy: IfNotPresent

jwtPublicKey: '-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEljtqa2nhBwe/PqNhWgPHhj0jv8AI\nY+QUCicYtfv9wLGcEGPQuXoBQtuoIuOwXOdbEWgrQyLdIEb0YjegAW3miA==\n-----END PUBLIC KEY-----'
jwtPrivateKey: '-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMFXLiN/YsJv89D2YkEZ6/Dj5fujghENmYTOilwdChU3oAoGCCqGSM49\nAwEHoUQDQgAEljtqa2nhBwe/PqNhWgPHhj0jv8AIY+QUCicYtfv9wLGcEGPQuXoB\nQtuoIuOwXOdbEWgrQyLdIEb0YjegAW3miA==\n-----END EC PRIVATE KEY-----'

# Option 2: host + user + database, password via PGPASSWORD secretKeyRef.
postgres:
host: agentdb-prod.postgres.database.azure.com
port: 5432
database: agent_sandbox
user: retool@agentdb-prod
passwordSecretName: agent-sandbox-db-password
passwordSecretKey: password
schema: agent_executor

sandboxNetwork:
enabled: true
devicePlugin: true
deployDaemonSet: false

networkPolicy:
enabled: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
rr:

# Agent Sandbox — Postgres sourcing OPTION 3: the full DSN comes from a
# pre-existing Secret (postgres.urlSecretName / urlSecretKey), while the JWT/
# encryption secrets are provided inline. This is the "BYO DB secret, chart-
# managed app secrets" combination.
#
# Also exercises S3 snapshot storage WITHOUT a dedicated credentialsSecretName,
# so the sandbox AWS creds fall back to the default (chart-rendered) Secret.
agentSandbox:
enabled: true

image:
repository: tryretool/agent-sandbox-service
tag: 3.123.4
pullPolicy: IfNotPresent

jwtPublicKey: '-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEljtqa2nhBwe/PqNhWgPHhj0jv8AI\nY+QUCicYtfv9wLGcEGPQuXoBQtuoIuOwXOdbEWgrQyLdIEb0YjegAW3miA==\n-----END PUBLIC KEY-----'
jwtPrivateKey: '-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMFXLiN/YsJv89D2YkEZ6/Dj5fujghENmYTOilwdChU3oAoGCCqGSM49\nAwEHoUQDQgAEljtqa2nhBwe/PqNhWgPHhj0jv8AIY+QUCicYtfv9wLGcEGPQuXoB\nQtuoIuOwXOdbEWgrQyLdIEb0YjegAW3miA==\n-----END EC PRIVATE KEY-----'
encryptionKey: a12b01429fe0fe69a80da94e9e837ab2f1e9bda378ed8a25905a238f6fea6b7a

# Option 3: full DSN from an existing Secret.
postgres:
urlSecretName: agent-sandbox-db-dsn
urlSecretKey: connection-string
schema: agent_executor

snapshotStorage:
s3Bucket: retool-agent-sandbox-snapshots
s3Endpoint: https://s3.us-west-2.amazonaws.com
s3Region: us-west-2
39 changes: 39 additions & 0 deletions charts/retool/ci/test-js-executor-enabled-option.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
rr:

# Exercises the JS executor workload (deployment_js_executor.yaml +
# configmap_js_executor.yaml). Overlaid on top of test-install-values.yaml.
jsExecutor:
enabled: true
replicaCount: 2
image:
repository: tryretool/js-executor-service
tag: 3.123.4
# Deliberately differs from the global image.pullPolicy (IfNotPresent in the
# base values) so the rendered deployment proves the per-workload override is
# honored rather than the global value.
pullPolicy: Always
# JS-executor-specific env (not inherited from top-level .Values.env).
env:
LOG_LEVEL: info
# Exercise the per-workload secretKeyRef branch.
environmentSecrets:
- name: JS_EXECUTOR_TOKEN
secretKeyRef:
name: js-executor-secrets
key: token
environmentVariables:
- name: JS_EXECUTOR_TEST_OPTION
value: "true"
# Memory request and limit are kept equal: JSE rejects requests at 80% of
# its limit, so the request must reserve the full amount.
resources:
limits:
cpu: 4000m
memory: 4Gi
requests:
cpu: 4000m
memory: 4Gi

# Exercise the PDB branch shared by the JS executor deployment.
podDisruptionBudget:
maxUnavailable: 1
19 changes: 19 additions & 0 deletions charts/retool/ci/test-mcp-enabled-option.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
mcp:
enabled: true
replicaCount: 2
config:
oauthMainDomain: https://oauth.example.com
oauthIntrospectionAuthToken: test-oauth-introspection-token
enabledToolsets:
- apps
- resources
maxTransportSessions: 50
sessionIdleTimeoutMs: 600000
environmentVariables:
- name: MCP_TEST_OPTION
value: "true"
service:
internalPort:

httpRoute:
enabled: true
27 changes: 27 additions & 0 deletions charts/retool/ci/test-rr-agent-enabled-option.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
rr:

# Exercises the RR Agent worker (the server-side agent loop worker rendered via
# _workers.tpl as SERVICE_TYPE=R2_AGENT_TEMPORAL_WORKER on healthcheck port 3016).
# Renders a Deployment + Service, plus a PodDisruptionBudget when one is set.
# Overlaid on test-install-values.yaml.
agent:
enabled: true
config:
nodeOptions: "--max_old_space_size=2048"
worker:
replicaCount: 2
resources:
limits:
cpu: 2000m
memory: 4096Mi
requests:
cpu: 1000m
memory: 2048Mi
labels:
test-pod-label: "true"
annotations:
test-pod-annotation: "true"

# Exercise the worker PodDisruptionBudget branch.
podDisruptionBudget:
maxUnavailable: 1
Loading
Loading