This is an automated email from the ASF dual-hosted git repository.

jscheffl pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 8e5bc6f2171 Allow custom volumeClaimTemplates when 
logs.persistence.enabled is true (#60118)
8e5bc6f2171 is described below

commit 8e5bc6f2171f90d0316c1f4b99c295587b616f7b
Author: Arjav Patel <[email protected]>
AuthorDate: Tue Jan 6 00:30:53 2026 +0530

    Allow custom volumeClaimTemplates when logs.persistence.enabled is true 
(#60118)
    
    * Update worker-deployment.yaml to conditionally include 
volumeClaimTemplates based on persistence settings
    
    * Add tests for volumeClaimTemplates behavior with logs persistence enabled
---
 chart/templates/workers/worker-deployment.yaml     |   5 +-
 .../tests/helm_tests/airflow_core/test_worker.py   | 176 +++++++++++++++++++++
 2 files changed, 180 insertions(+), 1 deletion(-)

diff --git a/chart/templates/workers/worker-deployment.yaml 
b/chart/templates/workers/worker-deployment.yaml
index 5af194eb790..a2fb246c329 100644
--- a/chart/templates/workers/worker-deployment.yaml
+++ b/chart/templates/workers/worker-deployment.yaml
@@ -461,8 +461,10 @@ spec:
   {{- else if not $persistence }}
         - name: logs
           emptyDir: {{- toYaml (default (dict) .Values.logs.emptyDirConfig) | 
nindent 12 }}
-  {{- else }}
+  {{- end }}
+  {{- if and $persistence (or (not .Values.logs.persistence.enabled) 
.Values.workers.volumeClaimTemplates) }}
   volumeClaimTemplates:
+    {{- if not .Values.logs.persistence.enabled }}
     - apiVersion: v1
       kind: PersistentVolumeClaim
       metadata:
@@ -478,6 +480,7 @@ spec:
         resources:
           requests:
             storage: {{ .Values.workers.persistence.size }}
+    {{- end }}
     {{- with .Values.workers.volumeClaimTemplates }}
       {{- toYaml . | nindent 4 }}
     {{- end }}
diff --git a/helm-tests/tests/helm_tests/airflow_core/test_worker.py 
b/helm-tests/tests/helm_tests/airflow_core/test_worker.py
index 970b43eb326..dd228b75df6 100644
--- a/helm-tests/tests/helm_tests/airflow_core/test_worker.py
+++ b/helm-tests/tests/helm_tests/airflow_core/test_worker.py
@@ -1060,6 +1060,182 @@ class TestWorker:
             
jmespath.search("spec.volumeClaimTemplates[2].spec.resources.requests.storage", 
docs[0]) == "20Gi"
         )
 
+    def 
test_should_add_extra_volume_claim_templates_with_logs_persistence_enabled(self):
+        """
+        Test that custom volumeClaimTemplates are created even when 
logs.persistence.enabled is true.
+
+        This test verifies the fix for the bug where custom 
volumeClaimTemplates were ignored
+        when logs.persistence.enabled was true, because the 
volumeClaimTemplates section
+        was only rendered in the else block that executed when 
logs.persistence.enabled was false.
+        """
+        docs = render_chart(
+            values={
+                "executor": "CeleryExecutor",
+                "workers": {
+                    "persistence": {"enabled": True},
+                    "volumeClaimTemplates": [
+                        {
+                            "metadata": {"name": "data"},
+                            "spec": {
+                                "storageClassName": "longhorn",
+                                "accessModes": ["ReadWriteOnce"],
+                                "resources": {"requests": {"storage": "10Gi"}},
+                            },
+                        },
+                    ],
+                },
+                "logs": {
+                    "persistence": {"enabled": True},  # This is the key: logs 
persistence enabled
+                },
+            },
+            show_only=["templates/workers/worker-deployment.yaml"],
+        )
+
+        # Verify StatefulSet is created
+        assert jmespath.search("kind", docs[0]) == "StatefulSet"
+
+        # Verify logs volume is created as regular PVC (not as 
volumeClaimTemplate)
+        volumes = jmespath.search("spec.template.spec.volumes", docs[0])
+        logs_volume = next((v for v in volumes if v.get("name") == "logs"), 
None)
+        assert logs_volume is not None
+        assert "persistentVolumeClaim" in logs_volume
+        assert logs_volume["persistentVolumeClaim"]["claimName"] == 
"release-name-logs"
+
+        # Verify volumeClaimTemplates section exists (this was the bug - it 
was missing before)
+        volume_claim_templates = jmespath.search("spec.volumeClaimTemplates", 
docs[0])
+        assert volume_claim_templates is not None
+        assert len(volume_claim_templates) > 0
+
+        # Verify custom volumeClaimTemplate is present
+        data_template = next(
+            (t for t in volume_claim_templates if t.get("metadata", 
{}).get("name") == "data"),
+            None,
+        )
+        assert data_template is not None
+        assert data_template["spec"]["storageClassName"] == "longhorn"
+        assert data_template["spec"]["accessModes"] == ["ReadWriteOnce"]
+        assert data_template["spec"]["resources"]["requests"]["storage"] == 
"10Gi"
+
+        # Verify logs is NOT in volumeClaimTemplates (it should be a regular 
PVC)
+        logs_template = next(
+            (t for t in volume_claim_templates if t.get("metadata", 
{}).get("name") == "logs"),
+            None,
+        )
+        assert logs_template is None, (
+            "Logs should not be in volumeClaimTemplates when 
logs.persistence.enabled is true"
+        )
+
+    @pytest.mark.parametrize(
+        (
+            "logs_persistence_enabled",
+            "workers_persistence_enabled",
+            "custom_templates",
+            "should_have_volume_claim_templates",
+        ),
+        [
+            # Test case 1: logs.persistence=false, workers.persistence=true, 
no custom templates
+            # Should have volumeClaimTemplates with logs template
+            (False, True, [], True),
+            # Test case 2: logs.persistence=true, workers.persistence=true, 
custom templates provided
+            # Should have volumeClaimTemplates with custom templates (this is 
the fix!)
+            (
+                True,
+                True,
+                [
+                    {
+                        "metadata": {"name": "data"},
+                        "spec": {
+                            "accessModes": ["ReadWriteOnce"],
+                            "resources": {"requests": {"storage": "10Gi"}},
+                        },
+                    }
+                ],
+                True,
+            ),
+            # Test case 3: logs.persistence=true, workers.persistence=true, no 
custom templates
+            # Should NOT have volumeClaimTemplates
+            (True, True, [], False),
+            # Test case 4: logs.persistence=false, workers.persistence=false 
(Deployment)
+            # Should NOT have volumeClaimTemplates (Deployments don't support 
it)
+            (
+                False,
+                False,
+                [
+                    {
+                        "metadata": {"name": "data"},
+                        "spec": {
+                            "accessModes": ["ReadWriteOnce"],
+                            "resources": {"requests": {"storage": "10Gi"}},
+                        },
+                    }
+                ],
+                False,
+            ),
+        ],
+    )
+    def test_volume_claim_templates_conditional_logic(
+        self,
+        logs_persistence_enabled,
+        workers_persistence_enabled,
+        custom_templates,
+        should_have_volume_claim_templates,
+    ):
+        """
+        Test the conditional logic for volumeClaimTemplates creation.
+
+        This test verifies that volumeClaimTemplates are created correctly 
based on:
+        - workers.persistence.enabled (must be true for StatefulSet)
+        - logs.persistence.enabled (affects whether logs is a template or 
regular PVC)
+        - Custom volumeClaimTemplates provided (should always create section 
if provided)
+        """
+        docs = render_chart(
+            values={
+                "executor": "CeleryExecutor",
+                "workers": {
+                    "persistence": {"enabled": workers_persistence_enabled},
+                    "volumeClaimTemplates": custom_templates,
+                },
+                "logs": {
+                    "persistence": {"enabled": logs_persistence_enabled},
+                },
+            },
+            show_only=["templates/workers/worker-deployment.yaml"],
+        )
+
+        volume_claim_templates = jmespath.search("spec.volumeClaimTemplates", 
docs[0])
+
+        if should_have_volume_claim_templates:
+            assert volume_claim_templates is not None
+            assert len(volume_claim_templates) > 0
+
+            # If logs.persistence is false, logs should be in 
volumeClaimTemplates
+            if not logs_persistence_enabled:
+                logs_template = next(
+                    (t for t in volume_claim_templates if t.get("metadata", 
{}).get("name") == "logs"),
+                    None,
+                )
+                assert logs_template is not None, (
+                    "Logs should be in volumeClaimTemplates when 
logs.persistence.enabled is false"
+                )
+
+            # If custom templates provided, they should be in 
volumeClaimTemplates
+            if custom_templates:
+                for template in custom_templates:
+                    template_name = template["metadata"]["name"]
+                    found_template = next(
+                        (
+                            t
+                            for t in volume_claim_templates
+                            if t.get("metadata", {}).get("name") == 
template_name
+                        ),
+                        None,
+                    )
+                    assert found_template is not None, (
+                        f"Custom template '{template_name}' should be in 
volumeClaimTemplates"
+                    )
+        else:
+            assert volume_claim_templates is None or 
len(volume_claim_templates) == 0
+
     @pytest.mark.parametrize(
         ("globalScope", "localScope", "precedence"),
         [

Reply via email to