diff --git a/internal/planner/planner.go b/internal/planner/planner.go index 030b4851..db4d7b9f 100644 --- a/internal/planner/planner.go +++ b/internal/planner/planner.go @@ -622,6 +622,11 @@ func updateDeploymentWithPodTemplateSpec( connection temporaliov1alpha1.ConnectionSpec, ) { wdDepSpec := spec.DeploymentSpec() + // Hash the user template, excluding controller-managed fields. + podTemplateSpecHash := k8s.ComputePodTemplateSpecHash(wdDepSpec.Template) + // DeploymentSpec() shares the template with spec on the legacy spec.template path; + // copy so the modifications below don't mutate spec. + wdDepSpec.Template = *wdDepSpec.Template.DeepCopy() // Extract the build ID from the deployment's labels (with nil safety) var buildID string @@ -659,8 +664,7 @@ func updateDeploymentWithPodTemplateSpec( podAnnotations[k] = v } podAnnotations[k8s.ConnectionSpecHashAnnotation] = k8s.ComputeConnectionSpecHash(connection) - // Store the new pod template spec hash - podAnnotations[k8s.PodTemplateSpecHashAnnotation] = k8s.ComputePodTemplateSpecHash(wdDepSpec.Template) + podAnnotations[k8s.PodTemplateSpecHashAnnotation] = podTemplateSpecHash // Preserve existing pod labels and add/update required labels podLabels := make(map[string]string) diff --git a/internal/planner/planner_test.go b/internal/planner/planner_test.go index bd02c1e2..5f329496 100644 --- a/internal/planner/planner_test.go +++ b/internal/planner/planner_test.go @@ -3388,7 +3388,9 @@ func TestCheckAndUpdateDeploymentPodTemplateSpec(t *testing.T) { k8sState.Deployments[buildID] = tt.existingDeployment } + originalSpec := tt.newSpec.DeepCopy() result := checkAndUpdateDeploymentPodTemplateSpec(buildID, k8sState, tt.newSpec, tt.connection) + assert.Equal(t, originalSpec, tt.newSpec, "Controller modifications must not mutate the worker spec") if !tt.expectUpdate { assert.Nil(t, result, "Expected no update, but got deployment") @@ -3415,6 +3417,9 @@ func TestCheckAndUpdateDeploymentPodTemplateSpec(t *testing.T) { } } assert.True(t, found, "Should find TEMPORAL_WORKER_BUILD_ID environment variable") + + assert.Nil(t, checkAndUpdateDeploymentPodTemplateSpec(buildID, k8sState, tt.newSpec, tt.connection), + "An unchanged pod template should not trigger another update") }) } }