feat: add support for helm 4 --server-side upgrade flag (#2641)

* feat: add support for helm 4 --server-side upgrade flag

Add support for the helm 4 upgrade flag --server-side which accepts
"true", "false", or "auto" (default "auto"). This allows users to
explicitly control server-side apply behavior, which is needed for
releases originally installed with Helm 3 and being managed with Helm 4.

The flag can be configured via:
- CLI: --server-side flag on sync, apply, and diff commands
- helmDefaults.serverSide in helmfile.yaml
- releases[].serverSide per-release override

Precedence: release-level > CLI flag > helmDefaults.
Errors are returned when serverSide is set but running Helm 3, or when
an invalid value is provided.

Closes #2640

Signed-off-by: yxxhero <aiopsclub@163.com>

* test: update TestGenerateID expected hashes for new ServerSide field

Adding ServerSide *string to ReleaseSpec changes spew's %#v output and
shifts the FNV hash used by generateValuesID. Update the hard-coded want
values to the new deterministic hashes.

Signed-off-by: yxxhero <aiopsclub@163.com>

---------

Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
yxxhero
2026-06-16 08:24:47 +08:00
committed by GitHub
parent 047fdcd17d
commit a94fdf4194
15 changed files with 265 additions and 6 deletions
+23
View File
@@ -250,6 +250,8 @@ type HelmSpec struct {
SyncReleaseLabels *bool `yaml:"syncReleaseLabels,omitempty"`
// TakeOwnership is true if the helmfile should take ownership of the release
TakeOwnership *bool `yaml:"takeOwnership,omitempty"`
// ServerSide controls the helm 4 --server-side flag for upgrade. Must be "true", "false", or "auto".
ServerSide *string `yaml:"serverSide,omitempty"`
// TrackMode specifies whether to use 'helm' or 'kubedog' for tracking resources
TrackMode string `yaml:"trackMode,omitempty"`
}
@@ -477,6 +479,8 @@ type ReleaseSpec struct {
SyncReleaseLabels *bool `yaml:"syncReleaseLabels,omitempty"`
// TakeOwnership is true if release should take ownership of resources
TakeOwnership *bool `yaml:"takeOwnership,omitempty"`
// ServerSide controls the helm 4 --server-side flag for this release. Must be "true", "false", or "auto".
ServerSide *string `yaml:"serverSide,omitempty"`
// TrackMode specifies whether to use 'helm' or 'kubedog' for tracking resources
TrackMode string `yaml:"trackMode,omitempty"`
// TrackTimeout specifies timeout for kubedog tracking (in seconds)
@@ -965,6 +969,7 @@ type SyncOpts struct {
SyncArgs string
HideNotes bool
TakeOwnership bool
ServerSide string
TrackMode string
TrackTimeout int
TrackLogs bool
@@ -2908,6 +2913,7 @@ type DiffOpts struct {
SuppressOutputLineRegex []string
SkipSchemaValidation bool
TakeOwnership bool
ServerSide string
// DetectedKubeVersion is the Kubernetes version detected from the cluster.
// This is used when kubeVersion is not specified in helmfile.yaml
DetectedKubeVersion string
@@ -3766,10 +3772,12 @@ func (st *HelmState) flagsForUpgrade(helm helmexec.Interface, release *ReleaseSp
postRenderer := ""
syncReleaseLabels := false
takeOwnership := false
serverSide := ""
if opt != nil {
postRenderer = opt.PostRenderer
syncReleaseLabels = opt.SyncReleaseLabels
takeOwnership = opt.TakeOwnership
serverSide = opt.ServerSide
}
flags = st.appendConnectionFlags(flags, release)
@@ -3808,6 +3816,13 @@ func (st *HelmState) flagsForUpgrade(helm helmexec.Interface, release *ReleaseSp
// append take-ownership flag
flags = st.appendTakeOwnershipFlagsForUpgrade(flags, helm, release, takeOwnership)
// append server-side flag
var ssErr error
flags, ssErr = st.appendServerSideFlagsForUpgrade(flags, helm, release, serverSide)
if ssErr != nil {
return nil, nil, ssErr
}
flags = st.appendExtraSyncFlags(flags, opt)
common, clean, err := st.namespaceAndValuesFlags(helm, release, workerIndex)
@@ -3992,8 +4007,10 @@ func (st *HelmState) flagsForDiff(helm helmexec.Interface, release *ReleaseSpec,
}
takeOwnership := false
serverSide := ""
if opt != nil {
takeOwnership = opt.TakeOwnership
serverSide = opt.ServerSide
}
flags, err = st.appendTakeOwnershipFlagsForDiff(flags, release, takeOwnership, pluginsDir)
@@ -4001,6 +4018,12 @@ func (st *HelmState) flagsForDiff(helm helmexec.Interface, release *ReleaseSpec,
return nil, nil, err
}
// append server-side flag
flags, err = st.appendServerSideFlagsForUpgrade(flags, helm, release, serverSide)
if err != nil {
return nil, nil, err
}
common, files, err := st.namespaceAndValuesFlags(helm, release, workerIndex)
if err != nil {
return nil, files, err