Skip to content

Commit 7a7e0e6

Browse files
eamonnmoloneyclaude
andcommitted
fix(8.10): back Web Modeler restapi /tmp with a per-pod ephemeral volume
The restapi persistence PVC backs only the pod-local /tmp scratch directory. Backing disposable per-pod scratch with a shared chart-managed ReadWriteOnce PVC was the root cause of the install Pending (claimName casing mismatch, SUPPORT-30069) and the helm-upgrade Multi-Attach deadlock. Switch the chart-managed path to a generic ephemeral volume (per-pod PVC), remove the standalone persistentvolumeclaim-restapi.yaml, and add the component-persistence (cprst) CI scenario that exercises it. emptyDir default and existingClaim paths are unchanged. Requires Kubernetes 1.23+ / OpenShift 4.10+ (generic ephemeral volumes GA). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 13e5438 commit 7a7e0e6

11 files changed

Lines changed: 114 additions & 63 deletions

File tree

charts/camunda-platform-8.10/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,7 @@ Please see the corresponding [release guide](../../docs/release.md) to find out
927927
| `webModeler.persistence.existingClaim` | can be used to specify an existing PVC instead of creating a new one | `""` |
928928
| `webModeler.persistence.annotations` | can be used to define annotations to add to the persistent volume claim | `{}` |
929929
| `webModeler.persistence.selector` | can be used to define a label selector for the persistent volume claim | `{}` |
930-
| `webModeler.persistence.deploymentStrategy` | update strategy for the restapi Deployment. Defaults to RollingUpdate (zero-downtime), which only works when the PVC supports concurrent attach (RWX storage, or accessModes including ReadWriteMany). For chart-managed PVCs on RWO storage, set to "Recreate" to avoid Multi-Attach deadlocks during helm upgrade (introduces brief downtime per upgrade). | `RollingUpdate` |
930+
| `webModeler.persistence.deploymentStrategy` | update strategy for the restapi Deployment. Defaults to RollingUpdate, which is always safe because the default chart-managed persistence path uses a per-pod ephemeral volume (no concurrent-attach contention). Set to "Recreate" only when using existingClaim with a ReadWriteOnce volume that cannot tolerate concurrent attach during a rollout (introduces brief downtime per upgrade). | `RollingUpdate` |
931931
| `webModeler.serviceAccount` | configuration for the service account the WebModeler pods are assigned to | |
932932

933933
### Connectors Parameters

charts/camunda-platform-8.10/templates/web-modeler/deployment-restapi.yaml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{{- fail "webModeler.persistence.deploymentStrategy value must be one of 'RollingUpdate', 'Recreate'" -}}
55
{{- end -}}
66
{{- if and (eq $deploymentStrategy "Recreate") (not (or .Values.camundaHub.webModeler.persistence.enabled .Values.webModeler.persistence.enabled)) -}}
7-
{{- fail "webModeler.persistence.deploymentStrategy: Recreate requires webModeler.persistence.enabled: true (it avoids a Multi-Attach deadlock on the chart-managed RWO PVC; without persistence it only adds upgrade downtime)" -}}
7+
{{- fail "webModeler.persistence.deploymentStrategy: Recreate requires webModeler.persistence.enabled: true. The default chart-managed path uses a per-pod ephemeral volume with no Multi-Attach contention, so Recreate is only useful when existingClaim points to a ReadWriteOnce volume; without persistence it only adds upgrade downtime" -}}
88
{{- end -}}
99
apiVersion: apps/v1
1010
kind: Deployment
@@ -189,8 +189,23 @@ spec:
189189
persistentVolumeClaim:
190190
claimName: {{ (or .Values.camundaHub.webModeler.persistence.existingClaim .Values.webModeler.persistence.existingClaim) }}
191191
{{- else if (or .Values.camundaHub.webModeler.persistence.enabled .Values.webModeler.persistence.enabled) }}
192-
persistentVolumeClaim:
193-
claimName: {{ include "camundaPlatform.fullname" . }}-webmodeler-data
192+
ephemeral:
193+
volumeClaimTemplate:
194+
{{- with (or .Values.camundaHub.webModeler.persistence.annotations .Values.webModeler.persistence.annotations) }}
195+
metadata:
196+
annotations: {{- toYaml . | nindent 18 }}
197+
{{- end }}
198+
spec:
199+
accessModes: {{ (or .Values.camundaHub.webModeler.persistence.accessModes .Values.webModeler.persistence.accessModes) | default (list "ReadWriteOnce") | toYaml | nindent 18 }}
200+
{{- with (or .Values.camundaHub.webModeler.persistence.storageClassName .Values.webModeler.persistence.storageClassName) }}
201+
storageClassName: {{ . | quote }}
202+
{{- end }}
203+
{{- with (or .Values.camundaHub.webModeler.persistence.selector .Values.webModeler.persistence.selector) }}
204+
selector: {{- toYaml . | nindent 18 }}
205+
{{- end }}
206+
resources:
207+
requests:
208+
storage: {{ (or .Values.camundaHub.webModeler.persistence.size .Values.webModeler.persistence.size) | default "1Gi" | quote }}
194209
{{- else }}
195210
emptyDir: {}
196211
{{- end }}

charts/camunda-platform-8.10/templates/web-modeler/persistentvolumeclaim-restapi.yaml

Lines changed: 0 additions & 21 deletions
This file was deleted.

charts/camunda-platform-8.10/test/ci/registry-snapshot.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,37 @@ integration:
603603
env-vars:
604604
- RDBMS_POSTGRESQL_USERNAME
605605
- RDBMS_POSTGRESQL_PASSWORD
606+
- name: component-persistence
607+
enabled: true
608+
shortname: cprst
609+
auth: keycloak
610+
flow: install,upgrade-minor
611+
platforms:
612+
- gke
613+
exclude: []
614+
tier: 2
615+
infra-type:
616+
gke: distroci
617+
identity: keycloak
618+
persistence: elasticsearch
619+
features:
620+
- persistence
621+
dependencies:
622+
- chart: charts/internal-keycloak-26
623+
release-name: keycloak
624+
values-file: test/integration/companion-values/keycloak.yaml
625+
- chart: elastic/elasticsearch
626+
version: 8.5.1
627+
release-name: elasticsearch
628+
values-file: test/integration/companion-values/elasticsearch.yaml
629+
repo-name: elastic
630+
repo-url: https://helm.elastic.co
631+
- chart: charts/internal-postgresql
632+
release-name: postgresql
633+
values-file: test/integration/companion-values/postgresql.yaml
634+
env-vars:
635+
- RDBMS_POSTGRESQL_USERNAME
636+
- RDBMS_POSTGRESQL_PASSWORD
606637
- name: hub-legacy
607638
enabled: true
608639
shortname: huble

charts/camunda-platform-8.10/test/ci/registry/manifest.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ integration:
8383
shortname: rdbms
8484
tier: 2
8585
enabled: true
86+
- id: component-persistence
87+
shortname: cprst
88+
tier: 2
89+
enabled: true
8690
- id: hub-legacy-install
8791
shortname: huble
8892
tier: 2
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: component-persistence
2+
auth: keycloak
3+
flows:
4+
- install,upgrade-minor
5+
identity: keycloak
6+
persistence: elasticsearch
7+
features:
8+
- persistence
9+
platforms:
10+
- gke
11+
infra-type:
12+
gke: distroci
13+
dependencies:
14+
- keycloak
15+
- elasticsearch
16+
- postgresql
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# =============================================================================
2+
# Component Persistence Feature
3+
# =============================================================================
4+
# Layer 4: Optional feature - exercises persistent volume configuration on
5+
# Camunda components so the chart's PVC/StatefulSet templates are covered by
6+
# nightly CI. Tracks the regressions reported in:
7+
# SUPPORT-30042 (Optimize PVC pending)
8+
# SUPPORT-30069 (web-modeler PVC pending / install failure)
9+
# SUPPORT-30094 (orchestration extraVolumeClaimTemplates rejected)
10+
# Used with: TEST_VALUES_FEATURES containing "persistence"
11+
# =============================================================================
12+
13+
optimize:
14+
enabled: true
15+
persistence:
16+
enabled: true
17+
size: 1Gi
18+
19+
webModeler:
20+
persistence:
21+
enabled: true
22+
size: 1Gi
23+
24+
orchestration:
25+
extraVolumeClaimTemplates:
26+
- metadata:
27+
name: extra-data
28+
spec:
29+
accessModes: ["ReadWriteOnce"]
30+
resources:
31+
requests:
32+
storage: 1Gi

charts/camunda-platform-8.10/test/unit/web-modeler/persistence_test.go

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,12 @@ func (s *PersistenceTemplateTest) TestPersistenceConfiguration() {
109109

110110
// then
111111
s.Require().NotNil(tmpVolume, "tmp volume should exist")
112-
s.Require().NotNil(tmpVolume.PersistentVolumeClaim, "should use PVC when persistence is enabled")
112+
s.Require().NotNil(tmpVolume.Ephemeral, "should use a per-pod ephemeral volume when persistence is enabled")
113113
s.Require().Nil(tmpVolume.EmptyDir, "should not use emptyDir when persistence is enabled")
114-
s.Require().Equal("camunda-platform-test-webmodeler-data", tmpVolume.PersistentVolumeClaim.ClaimName)
114+
s.Require().Nil(tmpVolume.PersistentVolumeClaim, "should not reference a shared PVC when persistence is enabled")
115+
spec := tmpVolume.Ephemeral.VolumeClaimTemplate.Spec
116+
s.Require().Equal("5Gi", spec.Resources.Requests.Storage().String())
117+
s.Require().Equal(corev1.ReadWriteOnce, spec.AccessModes[0])
115118
},
116119
},
117120
{
@@ -182,39 +185,10 @@ func (s *PersistenceTemplateTest) TestPersistenceConfiguration() {
182185
}
183186
}
184187

185-
func TestPVCManifestCreated(t *testing.T) {
186-
t.Parallel()
187-
188-
chartPath, err := filepath.Abs("../../../")
189-
require.NoError(t, err)
190-
191-
testCase := testhelpers.TestCase{
192-
Name: "TestPVCManifestCreated",
193-
Values: map[string]string{
194-
"identity.enabled": "true",
195-
"webModeler.enabled": "true",
196-
"camundaHub.webModeler.restapi.mail.fromAddress": "test@test.com",
197-
"camundaHub.webModeler.persistence.enabled": "true",
198-
"camundaHub.webModeler.persistence.size": "5Gi",
199-
"camundaHub.webModeler.persistence.accessModes[0]": "ReadWriteOnce",
200-
},
201-
Verifier: func(t *testing.T, output string, err error) {
202-
var pvc corev1.PersistentVolumeClaim
203-
helm.UnmarshalK8SYaml(t, output, &pvc)
204-
require.Equal(t, "camunda-platform-test-webmodeler-data", pvc.Name)
205-
require.Equal(t, "5Gi", pvc.Spec.Resources.Requests.Storage().String())
206-
require.Equal(t, corev1.ReadWriteOnce, pvc.Spec.AccessModes[0])
207-
},
208-
}
209-
210-
testhelpers.RunTestCasesE(t, chartPath, "camunda-platform-test", "camunda-platform-webmodeler", []string{"templates/web-modeler/persistentvolumeclaim-restapi.yaml"}, []testhelpers.TestCase{testCase})
211-
}
212-
213188
// TestDeploymentStrategyDefaultsToRollingUpdate asserts the default strategy
214-
// is RollingUpdate (preserves zero-downtime upgrade for users with RWX/
215-
// existingClaim setups). Users with chart-managed RWO PVCs hit a Multi-Attach
216-
// deadlock with RollingUpdate and must opt into "Recreate" — see
217-
// TestDeploymentStrategyRecreateOptIn.
189+
// is RollingUpdate. The restapi /tmp volume is a per-pod ephemeral volume, so
190+
// rollouts never contend for a shared RWO volume and zero-downtime RollingUpdate
191+
// is always safe.
218192
func TestDeploymentStrategyDefaultsToRollingUpdate(t *testing.T) {
219193
t.Parallel()
220194
chartPath, err := filepath.Abs("../../../")

charts/camunda-platform-8.10/values.schema.extra.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@
10261026
"RollingUpdate",
10271027
"Recreate"
10281028
],
1029-
"description": "update strategy for the restapi Deployment. Defaults to RollingUpdate (zero-downtime), which only works when the PVC supports concurrent attach (RWX storage, or accessModes including ReadWriteMany). For chart-managed PVCs on RWO storage, set to \"Recreate\" to avoid Multi-Attach deadlocks during helm upgrade (introduces brief downtime per upgrade).",
1029+
"description": "update strategy for the restapi Deployment. Defaults to RollingUpdate, which is always safe because the default chart-managed persistence path uses a per-pod ephemeral volume (no concurrent-attach contention). Set to \"Recreate\" only when using existingClaim with a ReadWriteOnce volume that cannot tolerate concurrent attach during a rollout (introduces brief downtime per upgrade).",
10301030
"default": "RollingUpdate"
10311031
}
10321032
}

charts/camunda-platform-8.10/values.schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,7 +2506,7 @@
25062506
"RollingUpdate",
25072507
"Recreate"
25082508
],
2509-
"description": "update strategy for the restapi Deployment. Defaults to RollingUpdate (zero-downtime), which only works when the PVC supports concurrent attach (RWX storage, or accessModes including ReadWriteMany). For chart-managed PVCs on RWO storage, set to \"Recreate\" to avoid Multi-Attach deadlocks during helm upgrade (introduces brief downtime per upgrade).",
2509+
"description": "update strategy for the restapi Deployment. Defaults to RollingUpdate, which is always safe because the default chart-managed persistence path uses a per-pod ephemeral volume (no concurrent-attach contention). Set to \"Recreate\" only when using existingClaim with a ReadWriteOnce volume that cannot tolerate concurrent attach during a rollout (introduces brief downtime per upgrade).",
25102510
"default": "RollingUpdate"
25112511
}
25122512
}
@@ -3577,7 +3577,7 @@
35773577
},
35783578
"deploymentStrategy": {
35793579
"type": "string",
3580-
"description": "update strategy for the restapi Deployment. Defaults to RollingUpdate (zero-downtime), which only works when the PVC supports concurrent attach (RWX storage, or accessModes including ReadWriteMany). For chart-managed PVCs on RWO storage, set to \"Recreate\" to avoid Multi-Attach deadlocks during helm upgrade (introduces brief downtime per upgrade).",
3580+
"description": "update strategy for the restapi Deployment. Defaults to RollingUpdate, which is always safe because the default chart-managed persistence path uses a per-pod ephemeral volume (no concurrent-attach contention). Set to \"Recreate\" only when using existingClaim with a ReadWriteOnce volume that cannot tolerate concurrent attach during a rollout (introduces brief downtime per upgrade).",
35813581
"default": "RollingUpdate",
35823582
"enum": [
35833583
"RollingUpdate",

0 commit comments

Comments
 (0)