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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion charts/rstudio-connect/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: rstudio-connect
description: Official Helm chart for Posit Connect
version: 0.8.30
version: 0.8.31
apiVersion: v2
appVersion: 2026.02.0
icon: https://raw.githubusercontent.com/rstudio/helm/main/images/posit-icon-fullcolor.svg
Expand Down
4 changes: 4 additions & 0 deletions charts/rstudio-connect/NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.8.31

- Add `executionEnvironments` value for declarative management of execution environments. Unlike `launcher.customRuntimeYaml`, changes take effect on every `helm upgrade` without requiring a pod restart or database reset.

## 0.8.30

- Fix connect-version-check in CI
Expand Down
42 changes: 39 additions & 3 deletions charts/rstudio-connect/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Posit Connect

![Version: 0.8.30](https://img.shields.io/badge/Version-0.8.30-informational?style=flat-square) ![AppVersion: 2026.02.0](https://img.shields.io/badge/AppVersion-2026.02.0-informational?style=flat-square)
![Version: 0.8.31](https://img.shields.io/badge/Version-0.8.31-informational?style=flat-square) ![AppVersion: 2026.02.0](https://img.shields.io/badge/AppVersion-2026.02.0-informational?style=flat-square)

#### _Official Helm chart for Posit Connect_

Expand Down Expand Up @@ -30,11 +30,11 @@ To ensure reproducibility in your environment and insulate yourself from future

## Installing the chart

To install the chart with the release name `my-release` at version 0.8.30:
To install the chart with the release name `my-release` at version 0.8.31:

```{.bash}
helm repo add rstudio https://helm.rstudio.com
helm upgrade --install my-release rstudio/rstudio-connect --version=0.8.30
helm upgrade --install my-release rstudio/rstudio-connect --version=0.8.31
```

To explore other chart versions, look at:
Expand Down Expand Up @@ -191,6 +191,41 @@ the API key unset for the Chronicle agent, deploy the chart, create an administr
secret with the API key. Once the secret is created, the value of `chronicleAgent.connectApiKey.secretKeyRef`
can be set and the release can be upgraded to include the new value.

## Execution Environments

This chart supports declarative management of execution environments via
`ExecutionEnvironments.ConfigFilePath`. Unlike the legacy `launcher.customRuntimeYaml`,
changes to `executionEnvironments` take effect on every `helm upgrade` without requiring
a pod restart or database reset.

When `executionEnvironments` is set, the chart:

1. Renders the list into a dedicated ConfigMap.
2. Mounts the ConfigMap as a volume at `/etc/rstudio-connect/execution-environments/environments.yaml`.
3. Sets `ExecutionEnvironments.ConfigFilePath` in the Connect configuration.

The ConfigMap is deliberately not included in the pod's checksum annotations, so changes
do not trigger a pod restart. The kubelet updates the mounted file automatically when the
ConfigMap changes (typically within 60-120 seconds), and Connect detects the update via
file polling.

Example `values.yaml`:

```yaml
executionEnvironments:
- name: ghcr.io/my-org/connect-runtime:ubuntu22
title: "Default Runtime"
matching: any
python:
installations:
- version: "3.11.3"
path: /opt/python/3.11.3/bin/python3
r:
installations:
- version: "4.4.0"
path: /opt/R/4.4.0/bin/R
```

## General principles

- In most places, we opt to pass Helm values over configmaps. We translate these into the valid `.gcfg` file format
Expand Down Expand Up @@ -234,6 +269,7 @@ The Helm `config` values are converted into the `rstudio-connect.gcfg` service c
| chronicleAgent.volumeMounts | list | `[]` | Verbatim volumeMounts to attach to the Chronicle agent container |
| command | list | `[]` | The pod's run command. By default, it uses the container's default |
| config | object | [Posit Connect Configuration Reference](https://docs.posit.co/connect/admin/appendix/off-host/helm-reference/) | A nested map of maps that generates the rstudio-connect.gcfg file |
| executionEnvironments | list | `[]` (disabled) | Optional list of execution environments to manage declaratively. When set, the chart renders these into a ConfigMap, mounts it into the Connect pod, and sets ExecutionEnvironments.ConfigFilePath in the Connect configuration. Unlike launcher.customRuntimeYaml, changes take effect on every helm upgrade without requiring a pod restart or database reset. |
| extraObjects | list | `[]` | Extra objects to deploy (value evaluated as a template) |
| fullnameOverride | string | `""` | The full name of the release (can be overridden) |
| image | object | `{"imagePullPolicy":"IfNotPresent","imagePullSecrets":[],"repository":"ghcr.io/rstudio/rstudio-connect","tag":"","tagPrefix":"ubuntu2204-"}` | Defines the Posit Connect image to deploy |
Expand Down
35 changes: 35 additions & 0 deletions charts/rstudio-connect/README.md.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,41 @@ the API key unset for the Chronicle agent, deploy the chart, create an administr
secret with the API key. Once the secret is created, the value of `chronicleAgent.connectApiKey.secretKeyRef`
can be set and the release can be upgraded to include the new value.

## Execution Environments

This chart supports declarative management of execution environments via
`ExecutionEnvironments.ConfigFilePath`. Unlike the legacy `launcher.customRuntimeYaml`,
changes to `executionEnvironments` take effect on every `helm upgrade` without requiring
a pod restart or database reset.

When `executionEnvironments` is set, the chart:

1. Renders the list into a dedicated ConfigMap.
2. Mounts the ConfigMap as a volume at `/etc/rstudio-connect/execution-environments/environments.yaml`.
3. Sets `ExecutionEnvironments.ConfigFilePath` in the Connect configuration.

The ConfigMap is deliberately not included in the pod's checksum annotations, so changes
do not trigger a pod restart. The kubelet updates the mounted file automatically when the
ConfigMap changes (typically within 60-120 seconds), and Connect detects the update via
file polling.

Example `values.yaml`:

```yaml
executionEnvironments:
- name: ghcr.io/my-org/connect-runtime:ubuntu22
title: "Default Runtime"
matching: any
python:
installations:
- version: "3.11.3"
path: /opt/python/3.11.3/bin/python3
r:
installations:
- version: "4.4.0"
path: /opt/R/4.4.0/bin/R
```

## General principles

- In most places, we opt to pass Helm values over configmaps. We translate these into the valid `.gcfg` file format
Expand Down
12 changes: 12 additions & 0 deletions charts/rstudio-connect/lint/execution-environments-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
executionEnvironments:
- name: ghcr.io/rstudio/content-base:r4.4.0-py3.11.3-jammy
title: "Test Runtime"
matching: any
python:
installations:
- version: "3.11.3"
path: /opt/python/3.11.3/bin/python3
r:
installations:
- version: "4.4.0"
path: /opt/R/4.4.0/bin/R
5 changes: 5 additions & 0 deletions charts/rstudio-connect/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ app.kubernetes.io/instance: {{ .Release.Name }}
{{- $launcherDict := dict "Launcher" ( $launcherSettingsDict ) }}
{{- $defaultConfig = merge $defaultConfig $launcherDict }}
{{- end }}
{{- /* declarative execution environments configuration */}}
{{- if .Values.executionEnvironments }}
{{- $eeDict := dict "ExecutionEnvironments" (dict "ConfigFilePath" "/etc/rstudio-connect/execution-environments/environments.yaml") }}
{{- $defaultConfig = merge $defaultConfig $eeDict }}
{{- end }}
{{- /* default licensing configuration */}}
{{- if .Values.license.server }}
{{- $licenseDict := dict "Licensing" ( dict "LicenseType" ("Remote") ) }}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
{{- if .Values.executionEnvironments }}
{{- range $i, $env := .Values.executionEnvironments }}
{{- if not $env.name }}
{{- fail (printf "executionEnvironments[%d].name is required" $i) }}
{{- end }}
{{- end }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "rstudio-connect.fullname" . }}-execution-environments
namespace: {{ $.Release.Namespace }}
labels:
{{- include "rstudio-connect.labels" . | nindent 4 }}
data:
environments.yaml: |
{{- toYaml .Values.executionEnvironments | nindent 4 }}
{{- end }}
10 changes: 10 additions & 0 deletions charts/rstudio-connect/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ spec:
subPath: "libnss_connect.conf"
readOnly: true
{{- end }}
{{- if .Values.executionEnvironments }}
- name: execution-environments
mountPath: "/etc/rstudio-connect/execution-environments"
readOnly: true
{{- end }}
{{- if .Values.pod.volumeMounts }}
{{- toYaml .Values.pod.volumeMounts | nindent 10 }}
{{- end }}
Expand Down Expand Up @@ -304,6 +309,11 @@ spec:
- key: libnss_connect.conf
path: libnss_connect.conf
{{- end }}
{{- if .Values.executionEnvironments }}
- name: execution-environments
configMap:
name: {{ include "rstudio-connect.fullname" . }}-execution-environments
{{- end }}
{{- if .Values.launcher.enabled }}
{{- if .Values.launcher.useTemplates }}
- name: rstudio-connect-templates
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{{- if .Values.executionEnvironments }}
apiVersion: v1
kind: Pod
metadata:
name: {{ include "rstudio-connect.fullname" . }}-test-execution-environments
namespace: {{ $.Release.Namespace }}
labels:
{{- include "rstudio-connect.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
"helm.sh/hook-delete-policy": before-hook-creation
spec:
restartPolicy: Never
activeDeadlineSeconds: 300
containers:
- name: test-execution-environments
image: alpine:3
command: ["sh", "-c"]
args:
- |
apk add --no-cache curl jq

CONNECT_URL="http://{{ include "rstudio-connect.fullname" . }}:{{ .Values.service.port }}"
API_KEY=$(printf "admin" | md5sum | cut -d' ' -f1)

# Wait for Connect to be ready
echo "Waiting for Connect to be ready..."
MAX_RETRIES=60
RETRY=0
until curl -sf "$CONNECT_URL/__ping__"; do
RETRY=$((RETRY + 1))
if [ "$RETRY" -ge "$MAX_RETRIES" ]; then
echo "FAIL: Connect not ready after $MAX_RETRIES attempts"
exit 1
fi
sleep 5
done
echo "Connect is ready."

# Check that at least one execution environment exists with managed_by: config
echo "Checking for managed execution environments..."
response=$(curl -sf -H "Authorization: Key $API_KEY" "$CONNECT_URL/v1/environments")
echo "$response" | jq .

managed_count=$(echo "$response" | jq '[.results[] | select(.managed_by == "config")] | length')
if [ "$managed_count" -gt 0 ]; then
echo "PASS: Found $managed_count execution environment(s) with managed_by: config"
exit 0
else
echo "FAIL: No execution environment found with managed_by: config"
exit 1
fi
{{- end }}
Loading
Loading