Skip to content

Commit 230e713

Browse files
committed
Ignore force replace when server-side apply is enabled
ForceReplace (PUT) is incompatible with SSA (Apply) in the Helm SDK, which rejects the combination. Since ForceReplace does not handle immutable field updates anyway (it does a PUT, not delete+recreate), it is safe to ignore when SSA is active. Move ForceReplace assignment from the action constructors to after SSA resolution, setting it only when SSA is disabled. Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
1 parent 8a0f9d0 commit 230e713

4 files changed

Lines changed: 8 additions & 4 deletions

File tree

internal/action/rollback.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func Rollback(config *helmaction.Configuration, obj *v2.HelmRelease,
9191
rollback.ServerSideApply = fmt.Sprint(serverSideApply)
9292
}
9393
rollback.ForceConflicts = serverSideApply // We always force conflicts on server-side apply.
94+
rollback.ForceReplace = obj.GetRollback().Force && !serverSideApply
9495

9596
return rollback.Run(releaseName)
9697
}
@@ -109,7 +110,6 @@ func newRollback(config *helmaction.Configuration, obj *v2.HelmRelease,
109110
rollback.WaitStrategy = getWaitStrategy(obj.GetWaitStrategy(), obj.GetRollback())
110111
rollback.WaitForJobs = !obj.GetRollback().DisableWaitForJobs
111112
rollback.DisableHooks = obj.GetRollback().DisableHooks
112-
rollback.ForceReplace = obj.GetRollback().Force
113113
rollback.CleanupOnFail = obj.GetRollback().CleanupOnFail
114114
rollback.MaxHistory = obj.GetMaxHistory()
115115

internal/action/rollback_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ func Test_newRollback(t *testing.T) {
4848
got := newRollback(&helmaction.Configuration{}, obj, 0, nil)
4949
g.Expect(got).ToNot(BeNil())
5050
g.Expect(got.Timeout).To(Equal(obj.Spec.Rollback.Timeout.Duration))
51-
g.Expect(got.ForceReplace).To(Equal(obj.Spec.Rollback.Force))
51+
// ForceReplace is not set in the constructor; it is set after SSA resolution
52+
// in Rollback() to avoid the Helm SDK mutual exclusivity error.
53+
g.Expect(got.ForceReplace).To(BeFalse())
5254
g.Expect(got.MaxHistory).To(Equal(obj.GetMaxHistory()))
5355
})
5456

internal/action/upgrade.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ func Upgrade(ctx context.Context, config *helmaction.Configuration, obj *v2.Helm
7575
upgrade.ServerSideApply = fmt.Sprint(serverSideApply)
7676
}
7777
upgrade.ForceConflicts = serverSideApply // We always force conflicts on server-side apply.
78+
upgrade.ForceReplace = obj.GetUpgrade().Force && !serverSideApply
7879

7980
policy, err := crdPolicyOrDefault(obj.GetUpgrade().CRDs)
8081
if err != nil {
@@ -116,7 +117,6 @@ func newUpgrade(config *helmaction.Configuration, obj *v2.HelmRelease, opts []Up
116117
upgrade.DisableHooks = obj.GetUpgrade().DisableHooks
117118
upgrade.DisableOpenAPIValidation = obj.GetUpgrade().DisableOpenAPIValidation
118119
upgrade.SkipSchemaValidation = obj.GetUpgrade().DisableSchemaValidation
119-
upgrade.ForceReplace = obj.GetUpgrade().Force
120120
upgrade.CleanupOnFail = obj.GetUpgrade().CleanupOnFail
121121
upgrade.Devel = true
122122

internal/action/upgrade_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ func Test_newUpgrade(t *testing.T) {
4949
g.Expect(got).ToNot(BeNil())
5050
g.Expect(got.Namespace).To(Equal(obj.Namespace))
5151
g.Expect(got.Timeout).To(Equal(obj.Spec.Upgrade.Timeout.Duration))
52-
g.Expect(got.ForceReplace).To(Equal(obj.Spec.Upgrade.Force))
52+
// ForceReplace is not set in the constructor; it is set after SSA resolution
53+
// in Upgrade() to avoid the Helm SDK mutual exclusivity error.
54+
g.Expect(got.ForceReplace).To(BeFalse())
5355
})
5456

5557
t.Run("timeout fallback", func(t *testing.T) {

0 commit comments

Comments
 (0)