From 9498127b5441b612da6f8388d4ab01f0a210f46d Mon Sep 17 00:00:00 2001 From: Amartya Sinha Date: Wed, 4 Nov 2026 19:46:18 +0530 Subject: [PATCH] Add dumb-init to service containers When a pod is deleted before the service is ready to handle SIGTERM, the service can keep running until terminationGracePeriodSeconds expires, delaying pod termination. Run the service under dumb-init so SIGTERM is handled and forwarded even during early startup. Wrap Heat API, CFN API, and engine processes with dumb-init to forward SIGTERM to the service process. Add functional assertions and update KUTTL expectations for the wrapped commands. Assisted-by: Codex Signed-off-by: Amartya Sinha --- internal/heatapi/deployment.go | 7 ++++++- internal/heatcfnapi/deployment.go | 7 ++++++- internal/heatengine/deployment.go | 5 +++++ test/functional/heat_controller_test.go | 19 +++++++++++++++++++ test/kuttl/tests/heat_tls/01-assert.yaml | 14 ++++++++++++-- 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/internal/heatapi/deployment.go b/internal/heatapi/deployment.go index 3cc13683..7977dec5 100644 --- a/internal/heatapi/deployment.go +++ b/internal/heatapi/deployment.go @@ -118,9 +118,14 @@ func Deployment( { Name: heat.ServiceName + "-" + heat.APIComponent, Command: []string{ + "/usr/bin/dumb-init", + }, + Args: []string{ + "--single-child", + "--", "/usr/sbin/httpd", + "-DFOREGROUND", }, - Args: []string{"-DFOREGROUND"}, Image: instance.Spec.ContainerImage, SecurityContext: pod.RestrictiveSecurityContext(users.HeatUID, users.HeatGID), Env: env.MergeEnvs([]corev1.EnvVar{}, envVars), diff --git a/internal/heatcfnapi/deployment.go b/internal/heatcfnapi/deployment.go index ef7cb90a..48b4d8b1 100644 --- a/internal/heatcfnapi/deployment.go +++ b/internal/heatcfnapi/deployment.go @@ -118,9 +118,14 @@ func Deployment( { Name: heat.ServiceName + "-" + heat.CfnAPIComponent, Command: []string{ + "/usr/bin/dumb-init", + }, + Args: []string{ + "--single-child", + "--", "/usr/sbin/httpd", + "-DFOREGROUND", }, - Args: []string{"-DFOREGROUND"}, Image: instance.Spec.ContainerImage, SecurityContext: pod.RestrictiveSecurityContext(users.HeatUID, users.HeatGID), Env: env.MergeEnvs([]corev1.EnvVar{}, envVars), diff --git a/internal/heatengine/deployment.go b/internal/heatengine/deployment.go index 8352289e..93ef20d1 100644 --- a/internal/heatengine/deployment.go +++ b/internal/heatengine/deployment.go @@ -92,6 +92,11 @@ func Deployment(instance *heatv1beta1.HeatEngine, configHash string, labels map[ { Name: fmt.Sprintf("%s-%s", heat.ServiceName, heat.EngineComponent), Command: []string{ + "/usr/bin/dumb-init", + }, + Args: []string{ + "--single-child", + "--", "/usr/bin/heat-engine", "--config-dir", "/etc/heat/heat.conf.d", }, diff --git a/test/functional/heat_controller_test.go b/test/functional/heat_controller_test.go index 6d9cc84c..b7070db2 100644 --- a/test/functional/heat_controller_test.go +++ b/test/functional/heat_controller_test.go @@ -1502,6 +1502,25 @@ var _ = Describe("Heat controller", func() { th.SimulateJobSuccess(heatDbSyncName) }) + It("should wrap all service commands with dumb-init", func() { + for _, service := range []struct { + name string + args []string + }{ + {"heat-api", []string{"--single-child", "--", "/usr/sbin/httpd", "-DFOREGROUND"}}, + {"heat-cfnapi", []string{"--single-child", "--", "/usr/sbin/httpd", "-DFOREGROUND"}}, + {"heat-engine", []string{"--single-child", "--", "/usr/bin/heat-engine", "--config-dir", "/etc/heat/heat.conf.d"}}, + } { + Eventually(func(g Gomega) { + deployment := th.GetDeployment(types.NamespacedName{Namespace: namespace, Name: service.name}) + g.Expect(deployment.Spec.Template.Spec.Containers).NotTo(BeEmpty()) + container := deployment.Spec.Template.Spec.Containers[0] + g.Expect(container.Command).To(Equal([]string{"/usr/bin/dumb-init"})) + g.Expect(container.Args).To(Equal(service.args)) + }, timeout, interval).Should(Succeed(), service.name) + } + }) + It("should add the consumer finalizer to the transport secret", func() { Eventually(func(g Gomega) { secret := th.GetSecret(types.NamespacedName{ diff --git a/test/kuttl/tests/heat_tls/01-assert.yaml b/test/kuttl/tests/heat_tls/01-assert.yaml index dcc8c809..96b2e266 100644 --- a/test/kuttl/tests/heat_tls/01-assert.yaml +++ b/test/kuttl/tests/heat_tls/01-assert.yaml @@ -87,8 +87,11 @@ spec: spec: containers: - command: - - /usr/sbin/httpd + - /usr/bin/dumb-init args: + - --single-child + - -- + - /usr/sbin/httpd - -DFOREGROUND volumeMounts: - mountPath: /etc/heat/heat.conf.d @@ -166,8 +169,11 @@ spec: spec: containers: - command: - - /usr/sbin/httpd + - /usr/bin/dumb-init args: + - --single-child + - -- + - /usr/sbin/httpd - -DFOREGROUND volumeMounts: - mountPath: /etc/heat/heat.conf.d @@ -245,6 +251,10 @@ spec: spec: containers: - command: + - /usr/bin/dumb-init + args: + - --single-child + - -- - /usr/bin/heat-engine - --config-dir - /etc/heat/heat.conf.d