From deb1272b006d62a692722f37334f0a9912a1ef5c Mon Sep 17 00:00:00 2001 From: youngkermit8-coder <263626606+youngkermit8-coder@users.noreply.github.com> Date: Mon, 19 Oct 2026 15:15:57 +0800 Subject: [PATCH] fix(helm): honor database Pod scheduling constraints --- .../helm_charts/templates/statefulset.yaml | 12 ++++++ tests/test_helm_scheduling.py | 41 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/test_helm_scheduling.py diff --git a/k8s-cluster/ha-cluster/helm_charts/templates/statefulset.yaml b/k8s-cluster/ha-cluster/helm_charts/templates/statefulset.yaml index ffa96a4..840e17f 100644 --- a/k8s-cluster/ha-cluster/helm_charts/templates/statefulset.yaml +++ b/k8s-cluster/ha-cluster/helm_charts/templates/statefulset.yaml @@ -147,6 +147,18 @@ spec: - name: secret secret: secretName: {{ .Values.clusterName }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} terminationGracePeriodSeconds: 0 volumeClaimTemplates: - metadata: diff --git a/tests/test_helm_scheduling.py b/tests/test_helm_scheduling.py new file mode 100644 index 0000000..d632b00 --- /dev/null +++ b/tests/test_helm_scheduling.py @@ -0,0 +1,41 @@ +"""Render regression tests. Requires Helm 3 and PyYAML (pip install pyyaml).""" +import json +import os +from pathlib import Path +import subprocess +import unittest + +CHART = Path(__file__).resolve().parents[1] / 'k8s-cluster/ha-cluster/helm_charts' + +def render(overrides=None): + command = [os.environ.get('HELM', 'helm'), 'template', 'test', str(CHART)] + if overrides: + command += ['--values', '-'] + result = subprocess.run(command, input=json.dumps(overrides or {}), + text=True, encoding='utf-8', capture_output=True, check=True) + import yaml + return list(yaml.safe_load_all(result.stdout)) + +def statefulset(documents): + return next(doc for doc in documents if doc and doc['kind'] == 'StatefulSet') + +class SchedulingTest(unittest.TestCase): + def test_defaults_omit_constraints(self): + pod = statefulset(render())['spec']['template']['spec'] + for key in ('nodeSelector', 'affinity', 'tolerations'): + self.assertNotIn(key, pod) + + def test_scheduling_constraints(self): + settings = { + 'nodeSelector': {'disktype': 'ssd'}, + 'tolerations': [{'key': 'database', 'operator': 'Equal', 'value': 'ivorysql', 'effect': 'NoSchedule'}], + 'affinity': {'podAntiAffinity': {'requiredDuringSchedulingIgnoredDuringExecution': [ + {'labelSelector': {'matchLabels': {'application': 'ivyhac'}}, + 'topologyKey': 'kubernetes.io/hostname'}]}}, + } + pod = statefulset(render(settings))['spec']['template']['spec'] + for key, value in settings.items(): + self.assertEqual(pod.get(key), value, key) + +if __name__ == '__main__': + unittest.main()