From 6ad3730ac109fe3b0d49dd6a6eb2865a99b0625d Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Tue, 21 Apr 2026 17:09:40 -0700 Subject: [PATCH 01/15] initial commit --- charts/retool/files/nsjail-seccomp.json | 692 ++++++++++++++++++ charts/retool/templates/_helpers.tpl | 24 + .../templates/configmap_js_executor.yaml | 9 + .../templates/daemonset_js_executor.yaml | 63 ++ .../retool/templates/deployment_backend.yaml | 4 + .../templates/deployment_js_executor.yaml | 189 +++++ .../templates/deployment_workflows.yaml | 4 + charts/retool/values.yaml | 45 ++ values.yaml | 45 ++ 9 files changed, 1075 insertions(+) create mode 100644 charts/retool/files/nsjail-seccomp.json create mode 100644 charts/retool/templates/configmap_js_executor.yaml create mode 100644 charts/retool/templates/daemonset_js_executor.yaml create mode 100644 charts/retool/templates/deployment_js_executor.yaml diff --git a/charts/retool/files/nsjail-seccomp.json b/charts/retool/files/nsjail-seccomp.json new file mode 100644 index 0000000..42c9c5c --- /dev/null +++ b/charts/retool/files/nsjail-seccomp.json @@ -0,0 +1,692 @@ +{ + "defaultAction": "SCMP_ACT_ERRNO", + "defaultErrnoRet": 1, + "archMap": [ + { + "architecture": "SCMP_ARCH_X86_64", + "subArchitectures": ["SCMP_ARCH_X86", "SCMP_ARCH_X32"] + }, + { + "architecture": "SCMP_ARCH_AARCH64", + "subArchitectures": ["SCMP_ARCH_ARM"] + }, + { + "architecture": "SCMP_ARCH_MIPS64", + "subArchitectures": ["SCMP_ARCH_MIPS", "SCMP_ARCH_MIPS64N32"] + }, + { + "architecture": "SCMP_ARCH_MIPS64N32", + "subArchitectures": ["SCMP_ARCH_MIPS", "SCMP_ARCH_MIPS64"] + }, + { + "architecture": "SCMP_ARCH_MIPSEL64", + "subArchitectures": ["SCMP_ARCH_MIPSEL", "SCMP_ARCH_MIPSEL64N32"] + }, + { + "architecture": "SCMP_ARCH_MIPSEL64N32", + "subArchitectures": ["SCMP_ARCH_MIPSEL", "SCMP_ARCH_MIPSEL64"] + }, + { + "architecture": "SCMP_ARCH_S390X", + "subArchitectures": ["SCMP_ARCH_S390"] + }, + { + "architecture": "SCMP_ARCH_RISCV64", + "subArchitectures": null + } + ], + "syscalls": [ + { + "names": [ + "accept", + "accept4", + "access", + "adjtimex", + "alarm", + "bind", + "brk", + "cachestat", + "capget", + "capset", + "chdir", + "chmod", + "chown", + "chown32", + "clock_adjtime", + "clock_adjtime64", + "clock_getres", + "clock_getres_time64", + "clock_gettime", + "clock_gettime64", + "clock_nanosleep", + "clock_nanosleep_time64", + "close", + "close_range", + "connect", + "copy_file_range", + "creat", + "dup", + "dup2", + "dup3", + "epoll_create", + "epoll_create1", + "epoll_ctl", + "epoll_ctl_old", + "epoll_pwait", + "epoll_pwait2", + "epoll_wait", + "epoll_wait_old", + "eventfd", + "eventfd2", + "execve", + "execveat", + "exit", + "exit_group", + "faccessat", + "faccessat2", + "fadvise64", + "fadvise64_64", + "fallocate", + "fanotify_mark", + "fchdir", + "fchmod", + "fchmodat", + "fchmodat2", + "fchown", + "fchown32", + "fchownat", + "fcntl", + "fcntl64", + "fdatasync", + "fgetxattr", + "flistxattr", + "flock", + "fork", + "fremovexattr", + "fsetxattr", + "fstat", + "fstat64", + "fstatat64", + "fstatfs", + "fstatfs64", + "fsync", + "ftruncate", + "ftruncate64", + "futex", + "futex_requeue", + "futex_time64", + "futex_wait", + "futex_waitv", + "futex_wake", + "futimesat", + "getcpu", + "getcwd", + "getdents", + "getdents64", + "getegid", + "getegid32", + "geteuid", + "geteuid32", + "getgid", + "getgid32", + "getgroups", + "getgroups32", + "getitimer", + "getpeername", + "getpgid", + "getpgrp", + "getpid", + "getppid", + "getpriority", + "getrandom", + "getresgid", + "getresgid32", + "getresuid", + "getresuid32", + "getrlimit", + "get_robust_list", + "getrusage", + "getsid", + "getsockname", + "getsockopt", + "get_thread_area", + "gettid", + "gettimeofday", + "getuid", + "getuid32", + "getxattr", + "getxattrat", + "inotify_add_watch", + "inotify_init", + "inotify_init1", + "inotify_rm_watch", + "io_cancel", + "ioctl", + "io_destroy", + "io_getevents", + "io_pgetevents", + "io_pgetevents_time64", + "ioprio_get", + "ioprio_set", + "io_setup", + "io_submit", + "ipc", + "kill", + "landlock_add_rule", + "landlock_create_ruleset", + "landlock_restrict_self", + "lchown", + "lchown32", + "lgetxattr", + "link", + "linkat", + "listen", + "listmount", + "listxattr", + "listxattrat", + "llistxattr", + "_llseek", + "lremovexattr", + "lseek", + "lsetxattr", + "lstat", + "lstat64", + "madvise", + "map_shadow_stack", + "membarrier", + "memfd_create", + "memfd_secret", + "mincore", + "mkdir", + "mkdirat", + "mknod", + "mknodat", + "mlock", + "mlock2", + "mlockall", + "mmap", + "mmap2", + "mprotect", + "mq_getsetattr", + "mq_notify", + "mq_open", + "mq_timedreceive", + "mq_timedreceive_time64", + "mq_timedsend", + "mq_timedsend_time64", + "mq_unlink", + "mremap", + "mseal", + "msgctl", + "msgget", + "msgrcv", + "msgsnd", + "msync", + "munlock", + "munlockall", + "munmap", + "name_to_handle_at", + "nanosleep", + "newfstatat", + "_newselect", + "open", + "openat", + "openat2", + "pause", + "pidfd_open", + "pidfd_send_signal", + "pipe", + "pipe2", + "pkey_alloc", + "pkey_free", + "pkey_mprotect", + "poll", + "ppoll", + "ppoll_time64", + "prctl", + "pread64", + "preadv", + "preadv2", + "prlimit64", + "process_mrelease", + "pselect6", + "pselect6_time64", + "pwrite64", + "pwritev", + "pwritev2", + "read", + "readahead", + "readlink", + "readlinkat", + "readv", + "recv", + "recvfrom", + "recvmmsg", + "recvmmsg_time64", + "recvmsg", + "remap_file_pages", + "removexattr", + "removexattrat", + "rename", + "renameat", + "renameat2", + "restart_syscall", + "riscv_hwprobe", + "rmdir", + "rseq", + "rt_sigaction", + "rt_sigpending", + "rt_sigprocmask", + "rt_sigqueueinfo", + "rt_sigreturn", + "rt_sigsuspend", + "rt_sigtimedwait", + "rt_sigtimedwait_time64", + "rt_tgsigqueueinfo", + "sched_getaffinity", + "sched_getattr", + "sched_getparam", + "sched_get_priority_max", + "sched_get_priority_min", + "sched_getscheduler", + "sched_rr_get_interval", + "sched_rr_get_interval_time64", + "sched_setaffinity", + "sched_setattr", + "sched_setparam", + "sched_setscheduler", + "sched_yield", + "seccomp", + "select", + "semctl", + "semget", + "semop", + "semtimedop", + "semtimedop_time64", + "send", + "sendfile", + "sendfile64", + "sendmmsg", + "sendmsg", + "sendto", + "setfsgid", + "setfsgid32", + "setfsuid", + "setfsuid32", + "setgid", + "setgid32", + "setgroups", + "setgroups32", + "setitimer", + "setpgid", + "setpriority", + "setregid", + "setregid32", + "setresgid", + "setresgid32", + "setresuid", + "setresuid32", + "setreuid", + "setreuid32", + "setrlimit", + "set_robust_list", + "setsid", + "setsockopt", + "set_thread_area", + "set_tid_address", + "setuid", + "setuid32", + "setxattr", + "setxattrat", + "shmat", + "shmctl", + "shmdt", + "shmget", + "shutdown", + "sigaltstack", + "signalfd", + "signalfd4", + "sigprocmask", + "sigreturn", + "socketcall", + "socketpair", + "splice", + "stat", + "stat64", + "statfs", + "statfs64", + "statmount", + "statx", + "symlink", + "symlinkat", + "sync", + "sync_file_range", + "syncfs", + "sysinfo", + "tee", + "tgkill", + "time", + "timer_create", + "timer_delete", + "timer_getoverrun", + "timer_gettime", + "timer_gettime64", + "timer_settime", + "timer_settime64", + "timerfd_create", + "timerfd_gettime", + "timerfd_gettime64", + "timerfd_settime", + "timerfd_settime64", + "times", + "tkill", + "truncate", + "truncate64", + "ugetrlimit", + "umask", + "uname", + "unlink", + "unlinkat", + "uretprobe", + "utime", + "utimensat", + "utimensat_time64", + "utimes", + "vfork", + "vmsplice", + "wait4", + "waitid", + "waitpid", + "write", + "writev" + ], + "action": "SCMP_ACT_ALLOW" + }, + { + "names": ["process_vm_readv", "process_vm_writev", "ptrace"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "minKernel": "4.8" + } + }, + { + "names": ["socket"], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 40, + "op": "SCMP_CMP_NE" + } + ] + }, + { + "names": ["personality"], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 0, + "op": "SCMP_CMP_EQ" + } + ] + }, + { + "names": ["personality"], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 8, + "op": "SCMP_CMP_EQ" + } + ] + }, + { + "names": ["personality"], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 131072, + "op": "SCMP_CMP_EQ" + } + ] + }, + { + "names": ["personality"], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 131080, + "op": "SCMP_CMP_EQ" + } + ] + }, + { + "names": ["personality"], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 4294967295, + "op": "SCMP_CMP_EQ" + } + ] + }, + { + "names": ["sync_file_range2", "swapcontext"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "arches": ["ppc64le"] + } + }, + { + "names": ["arm_fadvise64_64", "arm_sync_file_range", "sync_file_range2", "breakpoint", "cacheflush", "set_tls"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "arches": ["arm", "arm64"] + } + }, + { + "names": ["arch_prctl"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "arches": ["amd64", "x32"] + } + }, + { + "names": ["modify_ldt"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "arches": ["amd64", "x32", "x86"] + } + }, + { + "names": ["s390_pci_mmio_read", "s390_pci_mmio_write", "s390_runtime_instr"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "arches": ["s390", "s390x"] + } + }, + { + "names": ["riscv_flush_icache"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "arches": ["riscv64"] + } + }, + { + "names": ["open_by_handle_at"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_DAC_READ_SEARCH"] + } + }, + { + "names": ["clone", "clone2", "mount", "pivot_root", "sethostname", "umount2"], + "action": "SCMP_ACT_ALLOW", + "comment": "Retool specific syscalls to enable nsjail sandboxing" + }, + { + "names": [ + "bpf", + "clone", + "clone3", + "fanotify_init", + "fsconfig", + "fsmount", + "fsopen", + "fspick", + "lookup_dcookie", + "lsm_get_self_attr", + "lsm_list_modules", + "lsm_set_self_attr", + "mount", + "mount_setattr", + "move_mount", + "open_tree", + "perf_event_open", + "quotactl", + "quotactl_fd", + "setdomainname", + "sethostname", + "setns", + "syslog", + "umount", + "umount2", + "unshare" + ], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYS_ADMIN"] + } + }, + { + "names": ["clone"], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 0, + "value": 2114060288, + "op": "SCMP_CMP_MASKED_EQ" + } + ], + "excludes": { + "caps": ["CAP_SYS_ADMIN"], + "arches": ["s390", "s390x"] + } + }, + { + "names": ["clone"], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 1, + "value": 2114060288, + "op": "SCMP_CMP_MASKED_EQ" + } + ], + "comment": "s390 parameter ordering for clone is different", + "includes": { + "arches": ["s390", "s390x"] + }, + "excludes": { + "caps": ["CAP_SYS_ADMIN"] + } + }, + { + "names": ["clone3"], + "action": "SCMP_ACT_ERRNO", + "errnoRet": 38, + "excludes": { + "caps": ["CAP_SYS_ADMIN"] + } + }, + { + "names": ["reboot"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYS_BOOT"] + } + }, + { + "names": ["chroot"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYS_CHROOT"] + } + }, + { + "names": ["delete_module", "init_module", "finit_module"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYS_MODULE"] + } + }, + { + "names": ["acct"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYS_PACCT"] + } + }, + { + "names": ["kcmp", "pidfd_getfd", "process_madvise", "process_vm_readv", "process_vm_writev", "ptrace"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYS_PTRACE"] + } + }, + { + "names": ["iopl", "ioperm"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYS_RAWIO"] + } + }, + { + "names": ["settimeofday", "stime", "clock_settime", "clock_settime64"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYS_TIME"] + } + }, + { + "names": ["vhangup"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYS_TTY_CONFIG"] + } + }, + { + "names": ["get_mempolicy", "mbind", "set_mempolicy", "set_mempolicy_home_node"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYS_NICE"] + } + }, + { + "names": ["syslog"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYSLOG"] + } + }, + { + "names": ["bpf"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_BPF"] + } + }, + { + "names": ["perf_event_open"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_PERFMON"] + } + } + ] +} diff --git a/charts/retool/templates/_helpers.tpl b/charts/retool/templates/_helpers.tpl index fde306d..28acf78 100644 --- a/charts/retool/templates/_helpers.tpl +++ b/charts/retool/templates/_helpers.tpl @@ -125,6 +125,23 @@ app.kubernetes.io/instance: {{ .Release.Name }} telemetry.retool.com/service-name: code-executor {{- end }} +{{/* +Selector labels for js executor. Note changes here will require manual +deployment recreation and incur downtime, so should be avoided. +*/}} +{{- define "retool.jsExecutor.selectorLabels" -}} +retoolService: {{ include "retool.jsExecutor.name" . }} +{{- end }} + +{{/* +Extra (non-selector) labels for js executor. +*/}} +{{- define "retool.jsExecutor.labels" -}} +app.kubernetes.io/name: {{ include "retool.jsExecutor.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +telemetry.retool.com/service-name: js-executor +{{- end }} + {{/* Selector labels for agent worker. Note changes here will require manual deployment recreation and incur downtime, so should be avoided. @@ -358,6 +375,13 @@ Set code executor service name {{ template "retool.fullname" . }}-code-executor {{- end -}} +{{/* +Set JS executor service name +*/}} +{{- define "retool.jsExecutor.name" -}} +{{ template "retool.fullname" . }}-js-executor +{{- end -}} + {{/* Set multiplayer service name */}} diff --git a/charts/retool/templates/configmap_js_executor.yaml b/charts/retool/templates/configmap_js_executor.yaml new file mode 100644 index 0000000..accacb6 --- /dev/null +++ b/charts/retool/templates/configmap_js_executor.yaml @@ -0,0 +1,9 @@ +{{- if $.Values.jsExecutorDefault.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: js-executor-seccomp +data: + nsjail-seccomp.json: | + {{- .Files.Get "files/nsjail-seccomp.json" | nindent 4 }} +{{- end }} diff --git a/charts/retool/templates/daemonset_js_executor.yaml b/charts/retool/templates/daemonset_js_executor.yaml new file mode 100644 index 0000000..e4ee856 --- /dev/null +++ b/charts/retool/templates/daemonset_js_executor.yaml @@ -0,0 +1,63 @@ +{{- if $.Values.jsExecutor.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: js-executor-seccomp-node-installer +spec: + selector: + matchLabels: + app: js-executor-seccomp-node-installer + template: + metadata: + labels: + app: js-executor-seccomp-node-installer + annotations: + checksum/seccomp: {{ include (print $.Template.BasePath "/js-executor-seccomp-configmap.yaml") . | sha256sum }} + spec: + automountServiceAccountToken: false + initContainers: + - name: install + image: busybox:1.37.0@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + command: + - /bin/sh + - -c + - | + DEST="/host-seccomp/profiles/nsjail-seccomp.json" + mkdir -p "$(dirname "$DEST")" + cp /seccomp-profile/nsjail-seccomp.json "$DEST" + echo "seccomp profile installed at $DEST" + volumeMounts: + - name: seccomp-profile + mountPath: /seccomp-profile + - name: host-seccomp + mountPath: /host-seccomp + containers: + - name: pause + image: busybox:1.37.0@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f + command: ["sleep", "infinity"] + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + resources: + requests: + cpu: 1m + memory: 4Mi + limits: + cpu: 10m + memory: 16Mi + volumes: + - name: seccomp-profile + configMap: + name: js-executor-seccomp + - name: host-seccomp + hostPath: + path: /var/lib/kubelet/seccomp + type: DirectoryOrCreate +{{- end }} diff --git a/charts/retool/templates/deployment_backend.yaml b/charts/retool/templates/deployment_backend.yaml index 57206e5..ca6e5fb 100644 --- a/charts/retool/templates/deployment_backend.yaml +++ b/charts/retool/templates/deployment_backend.yaml @@ -179,6 +179,10 @@ spec: {{- end }} {{- end }} {{- end }} + {{- if .Values.jsExecutor.enabled }} + - name: JS_EXECUTOR_INGRESS_DOMAIN + value: http://{{ template "retool.jsExecutor.name" . }} + {{- end }} {{- include "retool.telemetry.includeEnvVars" . | nindent 10 }} diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml new file mode 100644 index 0000000..0b042a2 --- /dev/null +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -0,0 +1,189 @@ +{{- if include "retool.workflows.enabled" . }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "retool.jsExecutor.name" . }} + labels: + {{- include "retool.jsExecutor.selectorLabels" . | nindent 4 }} + {{- include "retool.jsExecutor.labels" . | nindent 4 }} + {{- include "retool.labels" . | nindent 4 }} +{{- if .Values.deployment.labels }} +{{ toYaml .Values.deployment.labels | indent 4 }} +{{- end }} +{{- if .Values.deployment.annotations }} + annotations: +{{ toYaml .Values.deployment.annotations | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.jsExecutor.replicaCount }} + selector: + matchLabels: + {{- include "retool.jsExecutor.selectorLabels" . | nindent 6 }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + template: + metadata: + annotations: +{{- if .Values.podAnnotations }} +{{ toYaml .Values.podAnnotations | indent 8 }} +{{- end }} +{{- if .Values.jsExecutor.annotations }} +{{ toYaml .Values.jsExecutor.annotations | indent 8 }} +{{- end }} + labels: + {{- include "retool.jsExecutor.selectorLabels" . | nindent 8 }} + {{- include "retool.jsExecutor.labels" . | nindent 8 }} + {{- include "retool.labels" . | nindent 8 }} +{{- if .Values.podLabels }} +{{ toYaml .Values.podLabels | indent 8 }} +{{- end }} +{{- if .Values.jsExecutor.labels }} +{{ toYaml .Values.jsExecutor.labels | indent 8 }} +{{- end }} + spec: + serviceAccountName: {{ template "retool.serviceAccountName" . }} + {{- if .Values.priorityClassName }} + priorityClassName: "{{ .Values.priorityClassName }}" + {{- end }} +{{- if .Values.initContainers }} + initContainers: +{{- range $key, $value := .Values.initContainers }} + - name: "{{ $key }}" +{{ toYaml $value | indent 8 }} +{{- end }} +{{- end }} + containers: + - name: js-executor + image: "{{ .Values.jsExecutor.image.repository }}:{{ include "retool.jsExecutor.image.tag" . }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + {{ if .Values.jsExecutor.securityContext }} +{{ toYaml .Values.jsExecutor.securityContext | indent 10 }} + {{ else }} + privileged: true + {{ end }} + {{- if .Values.securityContext.extraContainerSecurityContext }} +{{ toYaml .Values.securityContext.extraContainerSecurityContext | indent 10 }} + {{- end }} + env: + - name: DEPLOYMENT_TEMPLATE_TYPE + value: {{ template "retool.deploymentTemplateType" . }} + - name: DEPLOYMENT_TEMPLATE_VERSION + value: {{ template "retool.deploymentTemplateVersion" . }} + - name: NODE_ENV + value: production + - name: NODE_OPTIONS + value: {{(.Values.jsExecutor.config).nodeOptions | default "--max_old_space_size=1024" }} + + {{- include "retool.telemetry.includeEnvVars" . | nindent 10 }} + + {{- range $key, $value := .Values.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- range .Values.environmentSecrets }} + - name: {{ .name }} + valueFrom: + secretKeyRef: + name: {{ .secretKeyRef.name }} + key: {{ .secretKeyRef.key }} + {{- end }} + {{- with .Values.environmentVariables }} +{{ toYaml . | indent 10 }} + {{- end }} + ports: + - containerPort: 3004 + name: http-server + protocol: TCP +{{- if .Values.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.livenessProbe.path }} + port: 3004 + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} +{{- end }} +{{- if .Values.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.readinessProbe.path }} + port: 3004 + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} +{{- end }} + resources: +{{ toYaml .Values.jsExecutor.resources | indent 10 }} + volumeMounts: +{{- if .Values.jsExecutor.volumeMounts }} +{{ toYaml .Values.jsExecutor.volumeMounts | indent 10 }} +{{- end }} +{{- if .Values.extraVolumeMounts }} +{{ toYaml .Values.extraVolumeMounts | indent 10 }} +{{- end }} +{{- range .Values.extraConfigMapMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} +{{- end }} +{{- with .Values.extraContainers }} +{{ tpl . $ | indent 6 }} +{{- end }} + volumes: +{{- if .Values.jsExecutor.volumes }} +{{ toYaml .Values.jsExecutor.volumes | indent 8 }} +{{- end }} +{{- range .Values.extraConfigMapMounts }} + - name: {{ .name }} + configMap: + name: {{ .configMap }} +{{- end }} +{{- if .Values.extraVolumes }} +{{ toYaml .Values.extraVolumes | indent 8 }} +{{- end }} +{{- if .Values.image.pullSecrets }} + imagePullSecrets: +{{ toYaml .Values.image.pullSecrets | indent 8 }} +{{- end }} +{{- if .Values.jsExecutor.affinity }} + affinity: +{{ toYaml .Values.jsExecutor.affinity | indent 8 }} +{{- end }} +{{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} +{{- end }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "retool.jsExecutor.name" . }} +spec: + selector: + {{- include "retool.jsExecutor.selectorLabels" . | nindent 4 }} + ports: + - protocol: TCP + port: 80 + targetPort: 3004 + name: http-server +--- +{{- if .Values.podDisruptionBudget }} +{{- if semverCompare ">=1.21-0" .Capabilities.KubeVersion.Version -}} +apiVersion: policy/v1 +{{- else -}} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ template "retool.jsExecutor.name" . }} +spec: + {{- toYaml .Values.podDisruptionBudget | nindent 2 }} + selector: + matchLabels: + {{- include "retool.jsExecutor.selectorLabels" . | nindent 6 }} +{{- end }} +--- +{{- end }} diff --git a/charts/retool/templates/deployment_workflows.yaml b/charts/retool/templates/deployment_workflows.yaml index a03f741..74b9fa0 100644 --- a/charts/retool/templates/deployment_workflows.yaml +++ b/charts/retool/templates/deployment_workflows.yaml @@ -153,6 +153,10 @@ spec: {{- end }} {{- end }} {{- end }} + {{- if .Values.jsExecutor.enabled }} + - name: JS_EXECUTOR_INGRESS_DOMAIN + value: http://{{ template "retool.jsExecutor.name" . }} + {{- end }} {{- include "retool.telemetry.includeEnvVars" . | nindent 10 }} diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index 1c925d2..be44de1 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -606,6 +606,51 @@ codeExecutor: securityContext: privileged: true +# JS Executor +jsExecutor: + # dcm - is it optional? + enabled: true + # dcm - does this need to always align with the backend/CE image + image: + repository: tryretool/js-executor-service + pullPolicy: IfNotPresent + + replicaCount: 1 + + # Annotations for code executor pods + annotations: {} + + # Labels for code executor pods + labels: {} + + # Config for code executor. Node heap size limits can be overridden here + config: {} + # config: { + # nodeOptions: --max_old_space_size=1024 + # } + volumes: {} + volumeMounts: {} + + # Config affinity and anti-affinity rules for the code executor pods + affinity: {} + + # Resources for the JS executor. Most common issues will be seen with CPU usage as this will + # most likely be CPU bound. Adjust the CPU if latency increases under load. + resources: + limits: + cpu: 2000m + memory: 2048Mi + requests: + cpu: 1000m + memory: 1024Mi + + #dcm - should this be configurable? + # code executor uses nsjail to sandbox code execution. nsjail requires privileged container access. + # If your deployment does not support privileged access, you can set `privileged` to false to not + # use nsjail. Without nsjail, all code is run without sandboxing within your deployment. + securityContext: + privileged: true + agents: # Enable AI Agents enabled: false diff --git a/values.yaml b/values.yaml index 1c925d2..be44de1 100644 --- a/values.yaml +++ b/values.yaml @@ -606,6 +606,51 @@ codeExecutor: securityContext: privileged: true +# JS Executor +jsExecutor: + # dcm - is it optional? + enabled: true + # dcm - does this need to always align with the backend/CE image + image: + repository: tryretool/js-executor-service + pullPolicy: IfNotPresent + + replicaCount: 1 + + # Annotations for code executor pods + annotations: {} + + # Labels for code executor pods + labels: {} + + # Config for code executor. Node heap size limits can be overridden here + config: {} + # config: { + # nodeOptions: --max_old_space_size=1024 + # } + volumes: {} + volumeMounts: {} + + # Config affinity and anti-affinity rules for the code executor pods + affinity: {} + + # Resources for the JS executor. Most common issues will be seen with CPU usage as this will + # most likely be CPU bound. Adjust the CPU if latency increases under load. + resources: + limits: + cpu: 2000m + memory: 2048Mi + requests: + cpu: 1000m + memory: 1024Mi + + #dcm - should this be configurable? + # code executor uses nsjail to sandbox code execution. nsjail requires privileged container access. + # If your deployment does not support privileged access, you can set `privileged` to false to not + # use nsjail. Without nsjail, all code is run without sandboxing within your deployment. + securityContext: + privileged: true + agents: # Enable AI Agents enabled: false From 156bdf805ed3f86d3320c52fad7e57da762570ea Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Wed, 22 Apr 2026 17:04:21 -0700 Subject: [PATCH 02/15] fixes --- charts/retool/values.yaml | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index be44de1..6488e2c 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -608,8 +608,6 @@ codeExecutor: # JS Executor jsExecutor: - # dcm - is it optional? - enabled: true # dcm - does this need to always align with the backend/CE image image: repository: tryretool/js-executor-service @@ -617,21 +615,16 @@ jsExecutor: replicaCount: 1 - # Annotations for code executor pods + # Annotations for JS executor pods annotations: {} - # Labels for code executor pods + # Labels for JS executor pods labels: {} - # Config for code executor. Node heap size limits can be overridden here - config: {} - # config: { - # nodeOptions: --max_old_space_size=1024 - # } volumes: {} volumeMounts: {} - # Config affinity and anti-affinity rules for the code executor pods + # Config affinity and anti-affinity rules for the JS executor pods affinity: {} # Resources for the JS executor. Most common issues will be seen with CPU usage as this will @@ -645,9 +638,9 @@ jsExecutor: memory: 1024Mi #dcm - should this be configurable? - # code executor uses nsjail to sandbox code execution. nsjail requires privileged container access. + # JS executor uses nsjail to sandbox JS execution. nsjail requires privileged container access. # If your deployment does not support privileged access, you can set `privileged` to false to not - # use nsjail. Without nsjail, all code is run without sandboxing within your deployment. + # use nsjail. Without nsjail, all JS is run without sandboxing within your deployment. securityContext: privileged: true From e7bcde0b40fe5235b135274ebe97b6177424795e Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Wed, 22 Apr 2026 17:05:57 -0700 Subject: [PATCH 03/15] remove securitycontext from values --- charts/retool/values.yaml | 7 ------- values.yaml | 20 +++----------------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index 6488e2c..0603af4 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -637,13 +637,6 @@ jsExecutor: cpu: 1000m memory: 1024Mi - #dcm - should this be configurable? - # JS executor uses nsjail to sandbox JS execution. nsjail requires privileged container access. - # If your deployment does not support privileged access, you can set `privileged` to false to not - # use nsjail. Without nsjail, all JS is run without sandboxing within your deployment. - securityContext: - privileged: true - agents: # Enable AI Agents enabled: false diff --git a/values.yaml b/values.yaml index be44de1..0603af4 100644 --- a/values.yaml +++ b/values.yaml @@ -608,8 +608,6 @@ codeExecutor: # JS Executor jsExecutor: - # dcm - is it optional? - enabled: true # dcm - does this need to always align with the backend/CE image image: repository: tryretool/js-executor-service @@ -617,21 +615,16 @@ jsExecutor: replicaCount: 1 - # Annotations for code executor pods + # Annotations for JS executor pods annotations: {} - # Labels for code executor pods + # Labels for JS executor pods labels: {} - # Config for code executor. Node heap size limits can be overridden here - config: {} - # config: { - # nodeOptions: --max_old_space_size=1024 - # } volumes: {} volumeMounts: {} - # Config affinity and anti-affinity rules for the code executor pods + # Config affinity and anti-affinity rules for the JS executor pods affinity: {} # Resources for the JS executor. Most common issues will be seen with CPU usage as this will @@ -644,13 +637,6 @@ jsExecutor: cpu: 1000m memory: 1024Mi - #dcm - should this be configurable? - # code executor uses nsjail to sandbox code execution. nsjail requires privileged container access. - # If your deployment does not support privileged access, you can set `privileged` to false to not - # use nsjail. Without nsjail, all code is run without sandboxing within your deployment. - securityContext: - privileged: true - agents: # Enable AI Agents enabled: false From a13ddc3686d247ae073f04c45cc340cc12baf282 Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Thu, 23 Apr 2026 13:54:03 -0700 Subject: [PATCH 04/15] more fixes --- charts/retool/dcm-dev.yaml | 40 +++++++++++ charts/retool/templates/_helpers.tpl | 19 ++++++ .../templates/configmap_js_executor.yaml | 2 - .../templates/daemonset_js_executor.yaml | 63 ------------------ .../templates/deployment_js_executor.yaml | 66 +++++++++++++------ charts/retool/values.yaml | 5 +- 6 files changed, 108 insertions(+), 87 deletions(-) create mode 100644 charts/retool/dcm-dev.yaml delete mode 100644 charts/retool/templates/daemonset_js_executor.yaml diff --git a/charts/retool/dcm-dev.yaml b/charts/retool/dcm-dev.yaml new file mode 100644 index 0000000..fa37dce --- /dev/null +++ b/charts/retool/dcm-dev.yaml @@ -0,0 +1,40 @@ +codeExecutor: + enabled: true + replicaCount: 2 +config: + encryptionKeySecretName: encryption-key + jwtSecretSecretName: jwt-secret + postgresql: + db: retool + host: dcm-dev-main.cncxzczgbouo.us-west-2.rds.amazonaws.com + passwordSecretKey: password + passwordSecretName: db-credentials + port: 5432 + ssl_enabled: true + user: retool + useInsecureCookies: true +dbconnector: + enabled: true + replicas: 2 +env: + BASE_DOMAIN: http://dcm-dev.blessed-dev.retool-hosted.com + IGNORE_CODE_EXECUTOR_STARTUP_CHECK: "true" +externalSecrets: + enabled: true + includeConfigSecrets: true + name: extra-env-vars +image: + tag: 3.334.0-stable +ingress: + enabled: false +podDisruptionBudget: + maxUnavailable: 1 +postgresql: + enabled: false +replicaCount: 2 +workflows: + backend: + replicaCount: 2 + enabled: true + worker: + replicaCount: 2 diff --git a/charts/retool/templates/_helpers.tpl b/charts/retool/templates/_helpers.tpl index 28acf78..1657832 100644 --- a/charts/retool/templates/_helpers.tpl +++ b/charts/retool/templates/_helpers.tpl @@ -422,6 +422,25 @@ Usage: (template "retool.codeExecutor.image.tag" .) {{- end -}} {{- end -}} +{{/* +Set JS executor image tag +Usage: (template "retool.jsExecutor.image.tag" .) +*/}} +{{- define "retool.jsExecutor.image.tag" -}} +{{- if .Values.image.tag -}} + {{- $valid_retool_version_regexp := "([0-9]+\\.[0-9]+(\\.[0-9]+)?(-[a-zA-Z0-9]+)?)" }} + {{- $semver_version_regexp := "[0-9]+\\.[0-9]+(\\.[0-9]+)?" }} + {{- $retool_version_with_ce := ( and ( regexMatch $valid_retool_version_regexp $.Values.image.tag ) ( semverCompare ">= 3.20.15-0" ( regexFind $semver_version_regexp $.Values.image.tag ) ) ) }} + {{- if $retool_version_with_ce -}} + {{- .Values.image.tag -}} + {{- else -}} + {{- "1.1.0" -}} + {{- end -}} +{{- else -}} + {{- fail "Please set a value for .Values.image.tag" }} +{{- end -}} +{{- end -}} + {{- define "retool_version_with_java_dbconnector_opt_out" -}} {{- $output := "" -}} {{- $valid_retool_version_regexp := "([0-9]+\\.[0-9]+(\\.[0-9]+)?(-[a-zA-Z0-9]+)?)" }} diff --git a/charts/retool/templates/configmap_js_executor.yaml b/charts/retool/templates/configmap_js_executor.yaml index accacb6..60c45c8 100644 --- a/charts/retool/templates/configmap_js_executor.yaml +++ b/charts/retool/templates/configmap_js_executor.yaml @@ -1,4 +1,3 @@ -{{- if $.Values.jsExecutorDefault.enabled }} apiVersion: v1 kind: ConfigMap metadata: @@ -6,4 +5,3 @@ metadata: data: nsjail-seccomp.json: | {{- .Files.Get "files/nsjail-seccomp.json" | nindent 4 }} -{{- end }} diff --git a/charts/retool/templates/daemonset_js_executor.yaml b/charts/retool/templates/daemonset_js_executor.yaml deleted file mode 100644 index e4ee856..0000000 --- a/charts/retool/templates/daemonset_js_executor.yaml +++ /dev/null @@ -1,63 +0,0 @@ -{{- if $.Values.jsExecutor.enabled }} -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: js-executor-seccomp-node-installer -spec: - selector: - matchLabels: - app: js-executor-seccomp-node-installer - template: - metadata: - labels: - app: js-executor-seccomp-node-installer - annotations: - checksum/seccomp: {{ include (print $.Template.BasePath "/js-executor-seccomp-configmap.yaml") . | sha256sum }} - spec: - automountServiceAccountToken: false - initContainers: - - name: install - image: busybox:1.37.0@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: ["ALL"] - command: - - /bin/sh - - -c - - | - DEST="/host-seccomp/profiles/nsjail-seccomp.json" - mkdir -p "$(dirname "$DEST")" - cp /seccomp-profile/nsjail-seccomp.json "$DEST" - echo "seccomp profile installed at $DEST" - volumeMounts: - - name: seccomp-profile - mountPath: /seccomp-profile - - name: host-seccomp - mountPath: /host-seccomp - containers: - - name: pause - image: busybox:1.37.0@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f - command: ["sleep", "infinity"] - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - capabilities: - drop: ["ALL"] - resources: - requests: - cpu: 1m - memory: 4Mi - limits: - cpu: 10m - memory: 16Mi - volumes: - - name: seccomp-profile - configMap: - name: js-executor-seccomp - - name: host-seccomp - hostPath: - path: /var/lib/kubelet/seccomp - type: DirectoryOrCreate -{{- end }} diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml index 0b042a2..6aa97c8 100644 --- a/charts/retool/templates/deployment_js_executor.yaml +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -1,4 +1,3 @@ -{{- if include "retool.workflows.enabled" . }} apiVersion: apps/v1 kind: Deployment metadata: @@ -23,6 +22,7 @@ spec: template: metadata: annotations: + checksum/seccomp: {{ .Files.Get "files/nsjail-seccomp.json" | sha256sum }} {{- if .Values.podAnnotations }} {{ toYaml .Values.podAnnotations | indent 8 }} {{- end }} @@ -44,11 +44,38 @@ spec: {{- if .Values.priorityClassName }} priorityClassName: "{{ .Values.priorityClassName }}" {{- end }} -{{- if .Values.initContainers }} initContainers: + - name: install-seccomp + image: busybox:1.37.0@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + resources: + requests: + cpu: 1m + memory: 4Mi + limits: + cpu: 10m + memory: 16Mi + command: + - /bin/sh + - -c + - | + DEST="/host-seccomp/{{ .Values.jsExecutor.seccompLocalhostProfile }}" + mkdir -p "$(dirname "$DEST")" + cp /seccomp-profile/nsjail-seccomp.json "$DEST" + echo "seccomp profile installed at $DEST" + volumeMounts: + - name: seccomp-profile + mountPath: /seccomp-profile + - name: host-seccomp + mountPath: /host-seccomp +{{- if .Values.initContainers }} {{- range $key, $value := .Values.initContainers }} - name: "{{ $key }}" -{{ toYaml $value | indent 8 }} +{{ toYaml $value | indent 10 }} {{- end }} {{- end }} containers: @@ -56,14 +83,11 @@ spec: image: "{{ .Values.jsExecutor.image.repository }}:{{ include "retool.jsExecutor.image.tag" . }}" imagePullPolicy: {{ .Values.image.pullPolicy }} securityContext: - {{ if .Values.jsExecutor.securityContext }} -{{ toYaml .Values.jsExecutor.securityContext | indent 10 }} - {{ else }} - privileged: true - {{ end }} - {{- if .Values.securityContext.extraContainerSecurityContext }} -{{ toYaml .Values.securityContext.extraContainerSecurityContext | indent 10 }} - {{- end }} + capabilities: + add: ["NET_ADMIN"] + seccompProfile: + type: Localhost + localhostProfile: {{ .Values.jsExecutor.seccompLocalhostProfile }} env: - name: DEPLOYMENT_TEMPLATE_TYPE value: {{ template "retool.deploymentTemplateType" . }} @@ -94,25 +118,21 @@ spec: - containerPort: 3004 name: http-server protocol: TCP -{{- if .Values.livenessProbe.enabled }} livenessProbe: httpGet: - path: {{ .Values.livenessProbe.path }} - port: 3004 + path: /api/readiness + port: 3000 initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} failureThreshold: {{ .Values.livenessProbe.failureThreshold }} -{{- end }} -{{- if .Values.readinessProbe.enabled }} readinessProbe: httpGet: - path: {{ .Values.readinessProbe.path }} - port: 3004 + path: /api/health + port: 3000 initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} successThreshold: {{ .Values.readinessProbe.successThreshold }} periodSeconds: {{ .Values.readinessProbe.periodSeconds }} -{{- end }} resources: {{ toYaml .Values.jsExecutor.resources | indent 10 }} volumeMounts: @@ -131,6 +151,13 @@ spec: {{ tpl . $ | indent 6 }} {{- end }} volumes: + - name: seccomp-profile + configMap: + name: "js-executor-seccomp" + - name: host-seccomp + hostPath: + path: /var/lib/kubelet/seccomp + type: DirectoryOrCreate {{- if .Values.jsExecutor.volumes }} {{ toYaml .Values.jsExecutor.volumes | indent 8 }} {{- end }} @@ -186,4 +213,3 @@ spec: {{- include "retool.jsExecutor.selectorLabels" . | nindent 6 }} {{- end }} --- -{{- end }} diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index 0603af4..e2a9fd4 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -615,6 +615,8 @@ jsExecutor: replicaCount: 1 + seccompLocalhostProfile: profiles/nsjail-seccomp.json + # Annotations for JS executor pods annotations: {} @@ -627,8 +629,7 @@ jsExecutor: # Config affinity and anti-affinity rules for the JS executor pods affinity: {} - # Resources for the JS executor. Most common issues will be seen with CPU usage as this will - # most likely be CPU bound. Adjust the CPU if latency increases under load. + # Resources for the JS executor resources: limits: cpu: 2000m From 1a6d4be82829d9cf65c8d221aadf4d987dffcc9f Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Thu, 23 Apr 2026 13:54:58 -0700 Subject: [PATCH 05/15] align --- values.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/values.yaml b/values.yaml index 0603af4..e2a9fd4 100644 --- a/values.yaml +++ b/values.yaml @@ -615,6 +615,8 @@ jsExecutor: replicaCount: 1 + seccompLocalhostProfile: profiles/nsjail-seccomp.json + # Annotations for JS executor pods annotations: {} @@ -627,8 +629,7 @@ jsExecutor: # Config affinity and anti-affinity rules for the JS executor pods affinity: {} - # Resources for the JS executor. Most common issues will be seen with CPU usage as this will - # most likely be CPU bound. Adjust the CPU if latency increases under load. + # Resources for the JS executor resources: limits: cpu: 2000m From 90b555cda9fe64e96984dc1cd3292fcf2b303c71 Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Thu, 23 Apr 2026 13:55:31 -0700 Subject: [PATCH 06/15] test --- charts/retool/dcm-dev.yaml | 40 -------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 charts/retool/dcm-dev.yaml diff --git a/charts/retool/dcm-dev.yaml b/charts/retool/dcm-dev.yaml deleted file mode 100644 index fa37dce..0000000 --- a/charts/retool/dcm-dev.yaml +++ /dev/null @@ -1,40 +0,0 @@ -codeExecutor: - enabled: true - replicaCount: 2 -config: - encryptionKeySecretName: encryption-key - jwtSecretSecretName: jwt-secret - postgresql: - db: retool - host: dcm-dev-main.cncxzczgbouo.us-west-2.rds.amazonaws.com - passwordSecretKey: password - passwordSecretName: db-credentials - port: 5432 - ssl_enabled: true - user: retool - useInsecureCookies: true -dbconnector: - enabled: true - replicas: 2 -env: - BASE_DOMAIN: http://dcm-dev.blessed-dev.retool-hosted.com - IGNORE_CODE_EXECUTOR_STARTUP_CHECK: "true" -externalSecrets: - enabled: true - includeConfigSecrets: true - name: extra-env-vars -image: - tag: 3.334.0-stable -ingress: - enabled: false -podDisruptionBudget: - maxUnavailable: 1 -postgresql: - enabled: false -replicaCount: 2 -workflows: - backend: - replicaCount: 2 - enabled: true - worker: - replicaCount: 2 From 8c2b369e9057a80063c4d21f0ee18eae18a79de5 Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Thu, 23 Apr 2026 16:54:56 -0700 Subject: [PATCH 07/15] temp --- charts/retool/templates/deployment_js_executor.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml index 6aa97c8..534645a 100644 --- a/charts/retool/templates/deployment_js_executor.yaml +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -80,7 +80,8 @@ spec: {{- end }} containers: - name: js-executor - image: "{{ .Values.jsExecutor.image.repository }}:{{ include "retool.jsExecutor.image.tag" . }}" + image: "753800337063.dkr.ecr.us-west-2.amazonaws.com/js-executor-service:dev-3.376.0-1580847" + #image: "{{ .Values.jsExecutor.image.repository }}:{{ include "retool.jsExecutor.image.tag" . }}" imagePullPolicy: {{ .Values.image.pullPolicy }} securityContext: capabilities: From 85d01164f9637c39fc4bb95bd2799854388ee609 Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Tue, 28 Apr 2026 13:43:41 -0700 Subject: [PATCH 08/15] add jsexec to workers.tpl --- charts/retool/templates/_workers.tpl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/charts/retool/templates/_workers.tpl b/charts/retool/templates/_workers.tpl index 2202691..f7e2ebb 100644 --- a/charts/retool/templates/_workers.tpl +++ b/charts/retool/templates/_workers.tpl @@ -200,6 +200,9 @@ spec: value: {{ template "retool.postgresql.ssl_enabled" $ }} - name: CODE_EXECUTOR_INGRESS_DOMAIN value: http://{{ template "retool.codeExecutor.name" $ }} + - name: JS_EXECUTOR_INGRESS_DOMAIN + value: http://{{ template "retool.jsExecutor.name" $ }} + {{- include "retool.agentSandbox.backendEnvVars" $ | nindent 10 }} {{- include "retool.telemetry.includeEnvVars" $ | nindent 10 }} From 133bafd0fc4f8d1d8016b11f01e81fc0240f2d15 Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Tue, 28 Apr 2026 13:47:37 -0700 Subject: [PATCH 09/15] test --- charts/retool/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index e2a9fd4..fa5f55c 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -613,7 +613,7 @@ jsExecutor: repository: tryretool/js-executor-service pullPolicy: IfNotPresent - replicaCount: 1 + replicaCount: 2 seccompLocalhostProfile: profiles/nsjail-seccomp.json From 3fc97cd5c527db8c72cc471add02ca99b5c67d77 Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Tue, 28 Apr 2026 13:49:24 -0700 Subject: [PATCH 10/15] test --- values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/values.yaml b/values.yaml index e2a9fd4..fa5f55c 100644 --- a/values.yaml +++ b/values.yaml @@ -613,7 +613,7 @@ jsExecutor: repository: tryretool/js-executor-service pullPolicy: IfNotPresent - replicaCount: 1 + replicaCount: 2 seccompLocalhostProfile: profiles/nsjail-seccomp.json From c3851671e8563c025300512d42fa3acb2c261651 Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Tue, 28 Apr 2026 14:48:31 -0700 Subject: [PATCH 11/15] fix ports, probes --- charts/retool/templates/deployment_js_executor.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml index 534645a..df1425c 100644 --- a/charts/retool/templates/deployment_js_executor.yaml +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -116,19 +116,19 @@ spec: {{ toYaml . | indent 10 }} {{- end }} ports: - - containerPort: 3004 + - containerPort: 3000 name: http-server protocol: TCP livenessProbe: httpGet: - path: /api/readiness + path: /api/health port: 3000 initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} failureThreshold: {{ .Values.livenessProbe.failureThreshold }} readinessProbe: httpGet: - path: /api/health + path: /api/readiness port: 3000 initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} @@ -195,7 +195,7 @@ spec: ports: - protocol: TCP port: 80 - targetPort: 3004 + targetPort: 3000 name: http-server --- {{- if .Values.podDisruptionBudget }} From 05d973f7182d2724e07985467de06a1a74dec124 Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Thu, 30 Apr 2026 10:11:01 -0700 Subject: [PATCH 12/15] updates --- charts/retool/templates/deployment_js_executor.yaml | 7 +------ charts/retool/values.yaml | 3 +-- values.yaml | 3 +-- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml index df1425c..3cb47ad 100644 --- a/charts/retool/templates/deployment_js_executor.yaml +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -80,8 +80,7 @@ spec: {{- end }} containers: - name: js-executor - image: "753800337063.dkr.ecr.us-west-2.amazonaws.com/js-executor-service:dev-3.376.0-1580847" - #image: "{{ .Values.jsExecutor.image.repository }}:{{ include "retool.jsExecutor.image.tag" . }}" + image: "{{ .Values.jsExecutor.image.repository }}:{{ include "retool.jsExecutor.image.tag" . }}" imagePullPolicy: {{ .Values.image.pullPolicy }} securityContext: capabilities: @@ -96,11 +95,7 @@ spec: value: {{ template "retool.deploymentTemplateVersion" . }} - name: NODE_ENV value: production - - name: NODE_OPTIONS - value: {{(.Values.jsExecutor.config).nodeOptions | default "--max_old_space_size=1024" }} - {{- include "retool.telemetry.includeEnvVars" . | nindent 10 }} - {{- range $key, $value := .Values.env }} - name: "{{ $key }}" value: "{{ $value }}" diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index fa5f55c..6d2577a 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -608,7 +608,6 @@ codeExecutor: # JS Executor jsExecutor: - # dcm - does this need to always align with the backend/CE image image: repository: tryretool/js-executor-service pullPolicy: IfNotPresent @@ -633,7 +632,7 @@ jsExecutor: resources: limits: cpu: 2000m - memory: 2048Mi + memory: 4096Mi requests: cpu: 1000m memory: 1024Mi diff --git a/values.yaml b/values.yaml index fa5f55c..6d2577a 100644 --- a/values.yaml +++ b/values.yaml @@ -608,7 +608,6 @@ codeExecutor: # JS Executor jsExecutor: - # dcm - does this need to always align with the backend/CE image image: repository: tryretool/js-executor-service pullPolicy: IfNotPresent @@ -633,7 +632,7 @@ jsExecutor: resources: limits: cpu: 2000m - memory: 2048Mi + memory: 4096Mi requests: cpu: 1000m memory: 1024Mi From 3a077e0ea23dac73a2b7d312ba2c31ecbb8442d3 Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Thu, 30 Apr 2026 14:23:42 -0700 Subject: [PATCH 13/15] minor --- charts/retool/templates/deployment_backend.yaml | 2 -- charts/retool/templates/deployment_js_executor.yaml | 2 +- charts/retool/templates/deployment_workflows.yaml | 2 -- charts/retool/values.yaml | 4 ++-- values.yaml | 4 ++-- 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/charts/retool/templates/deployment_backend.yaml b/charts/retool/templates/deployment_backend.yaml index ca6e5fb..f36cfb7 100644 --- a/charts/retool/templates/deployment_backend.yaml +++ b/charts/retool/templates/deployment_backend.yaml @@ -179,10 +179,8 @@ spec: {{- end }} {{- end }} {{- end }} - {{- if .Values.jsExecutor.enabled }} - name: JS_EXECUTOR_INGRESS_DOMAIN value: http://{{ template "retool.jsExecutor.name" . }} - {{- end }} {{- include "retool.telemetry.includeEnvVars" . | nindent 10 }} diff --git a/charts/retool/templates/deployment_js_executor.yaml b/charts/retool/templates/deployment_js_executor.yaml index 3cb47ad..b432b0f 100644 --- a/charts/retool/templates/deployment_js_executor.yaml +++ b/charts/retool/templates/deployment_js_executor.yaml @@ -74,7 +74,7 @@ spec: mountPath: /host-seccomp {{- if .Values.initContainers }} {{- range $key, $value := .Values.initContainers }} - - name: "{{ $key }}" + - name: "{{ $key }}" {{ toYaml $value | indent 10 }} {{- end }} {{- end }} diff --git a/charts/retool/templates/deployment_workflows.yaml b/charts/retool/templates/deployment_workflows.yaml index 74b9fa0..38aa2f7 100644 --- a/charts/retool/templates/deployment_workflows.yaml +++ b/charts/retool/templates/deployment_workflows.yaml @@ -153,10 +153,8 @@ spec: {{- end }} {{- end }} {{- end }} - {{- if .Values.jsExecutor.enabled }} - name: JS_EXECUTOR_INGRESS_DOMAIN value: http://{{ template "retool.jsExecutor.name" . }} - {{- end }} {{- include "retool.telemetry.includeEnvVars" . | nindent 10 }} diff --git a/charts/retool/values.yaml b/charts/retool/values.yaml index 6d2577a..42aa7a8 100644 --- a/charts/retool/values.yaml +++ b/charts/retool/values.yaml @@ -612,7 +612,7 @@ jsExecutor: repository: tryretool/js-executor-service pullPolicy: IfNotPresent - replicaCount: 2 + replicaCount: 1 seccompLocalhostProfile: profiles/nsjail-seccomp.json @@ -632,7 +632,7 @@ jsExecutor: resources: limits: cpu: 2000m - memory: 4096Mi + memory: 2048Mi requests: cpu: 1000m memory: 1024Mi diff --git a/values.yaml b/values.yaml index 6d2577a..42aa7a8 100644 --- a/values.yaml +++ b/values.yaml @@ -612,7 +612,7 @@ jsExecutor: repository: tryretool/js-executor-service pullPolicy: IfNotPresent - replicaCount: 2 + replicaCount: 1 seccompLocalhostProfile: profiles/nsjail-seccomp.json @@ -632,7 +632,7 @@ jsExecutor: resources: limits: cpu: 2000m - memory: 4096Mi + memory: 2048Mi requests: cpu: 1000m memory: 1024Mi From 819f33faad85fc65f07b81b9b263001b5dc2a89e Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Thu, 30 Apr 2026 14:45:01 -0700 Subject: [PATCH 14/15] update chart version --- 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 2ac23c9..50dd0ff 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.10.3 +version: 6.11.0 maintainers: - name: Retool Engineering email: engineering+helm@retool.com From 2b2a98afcadbdb738c44a47c72084d6354529654 Mon Sep 17 00:00:00 2001 From: Dan Merino Date: Thu, 30 Apr 2026 14:48:03 -0700 Subject: [PATCH 15/15] gtfo --- charts/retool/templates/_workers.tpl | 1 - 1 file changed, 1 deletion(-) diff --git a/charts/retool/templates/_workers.tpl b/charts/retool/templates/_workers.tpl index f7e2ebb..2893b9b 100644 --- a/charts/retool/templates/_workers.tpl +++ b/charts/retool/templates/_workers.tpl @@ -202,7 +202,6 @@ spec: value: http://{{ template "retool.codeExecutor.name" $ }} - name: JS_EXECUTOR_INGRESS_DOMAIN value: http://{{ template "retool.jsExecutor.name" $ }} - {{- include "retool.agentSandbox.backendEnvVars" $ | nindent 10 }} {{- include "retool.telemetry.includeEnvVars" $ | nindent 10 }}