mirror of
https://github.com/helmfile/helmfile.git
synced 2026-09-30 06:26:30 +02:00
fix: add trackFailOnError option to control kubedog exit code (#2576)
* fix: add trackFailOnError option to control kubedog exit code behavior When kubedog release tracking fails (e.g. pod ImagePullBackOff), helmfile exits with code 0 instead of a non-zero exit code. Add a trackFailOnError configuration option (default: false) that when set to true, propagates kubedog tracking failures to the exit code. The option is available as: - Per-release YAML: trackFailOnError: true - CLI flag: --track-fail-on-error (sync and apply commands) Extract trackReleaseIfEnabled helper to consolidate kubedog tracking logic from two duplicated call sites into a single maintainable method. Fixes #2507 Signed-off-by: yxxhero <aiopsclub@163.com> * fix: add //go:build ignore to server.go to fix go test CI failure The test/integration/test-cases/issue-2103/input/server.go is a package main helper binary used by the issue-2103 integration test. When go test -coverprofile runs on this package, it fails with "go: no such tool covdata" in the CI environment. Adding //go:build ignore excludes the file from go list ./... (and therefore from PKGS in the Makefile), while still allowing the integration test to build it explicitly via file path: go build -o server ./path/to/server.go Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/8a7000af-72b7-48f8-8a82-24813b5df341 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> * fix: update TestGenerateID expected hashes after adding TrackFailOnError field Adding TrackFailOnError *bool to ReleaseSpec changed the spew serialization of the struct, which changed the FNV-32a hash values produced by generateValuesID. Update temp_test.go with the new expected hash strings. Agent-Logs-Url: https://github.com/helmfile/helmfile/sessions/caa86cd9-73d1-4894-b745-fd70c0811fd6 Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com> --------- Signed-off-by: yxxhero <aiopsclub@163.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
copilot-swe-agent[bot]
parent
7cc5fe0358
commit
420cc3ba9c
@@ -197,6 +197,32 @@ func (st *HelmState) shouldUseKubedog(release *ReleaseSpec, ops *SyncOpts) bool
|
||||
return st.getTrackMode(release, ops) == string(kubedog.TrackModeKubedog)
|
||||
}
|
||||
|
||||
func (st *HelmState) shouldFailOnTrackError(release *ReleaseSpec, ops *SyncOpts) bool {
|
||||
if release.TrackFailOnError != nil {
|
||||
return *release.TrackFailOnError
|
||||
}
|
||||
if ops != nil {
|
||||
return ops.TrackFailOnError
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// trackReleaseIfEnabled performs kubedog tracking for a release if trackMode is "kubedog".
|
||||
// It returns a ReleaseError if tracking fails and shouldFailOnTrackError is true.
|
||||
// The caller is responsible for mutating affectedReleases when needed.
|
||||
func (st *HelmState) trackReleaseIfEnabled(ctx context.Context, release *ReleaseSpec, helm helmexec.Interface, opts *SyncOpts) *ReleaseError {
|
||||
if !st.shouldUseKubedog(release, opts) {
|
||||
return nil
|
||||
}
|
||||
if trackErr := st.trackWithKubedog(ctx, release, helm, opts); trackErr != nil {
|
||||
st.logger.Warnf("kubedog tracking failed for release %s: %v", release.Name, trackErr)
|
||||
if st.shouldFailOnTrackError(release, opts) {
|
||||
return newReleaseFailedError(release, trackErr)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *HelmState) getTrackMode(release *ReleaseSpec, ops *SyncOpts) string {
|
||||
trackMode := release.TrackMode
|
||||
if trackMode == "" && ops != nil && ops.TrackMode != "" {
|
||||
|
||||
+10
-8
@@ -478,6 +478,8 @@ type ReleaseSpec struct {
|
||||
KubedogQPS *float32 `yaml:"kubedogQPS,omitempty"`
|
||||
// KubedogBurst specifies the burst for kubedog kubernetes client
|
||||
KubedogBurst *int `yaml:"kubedogBurst,omitempty"`
|
||||
// TrackFailOnError controls whether kubedog tracking failures cause a non-zero exit code
|
||||
TrackFailOnError *bool `yaml:"trackFailOnError,omitempty"`
|
||||
}
|
||||
|
||||
// TrackResourceSpec specifies a resource to track
|
||||
@@ -912,6 +914,7 @@ type SyncOpts struct {
|
||||
TrackMode string
|
||||
TrackTimeout int
|
||||
TrackLogs bool
|
||||
TrackFailOnError bool
|
||||
Description string
|
||||
}
|
||||
|
||||
@@ -1138,10 +1141,8 @@ func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helme
|
||||
}
|
||||
} else if release.UpdateStrategy == UpdateStrategyReinstallIfForbidden {
|
||||
relErr = st.performSyncOrReinstallOfRelease(affectedReleases, helm, context, release, chart, m, flags...)
|
||||
if relErr == nil && st.shouldUseKubedog(release, opts) {
|
||||
if trackErr := st.trackWithKubedog(gocontext.Background(), release, helm, opts); trackErr != nil {
|
||||
st.logger.Warnf("kubedog tracking failed for release %s: %v", release.Name, trackErr)
|
||||
}
|
||||
if relErr == nil {
|
||||
relErr = st.trackReleaseIfEnabled(gocontext.Background(), release, helm, opts)
|
||||
}
|
||||
} else {
|
||||
if err := helm.SyncRelease(context, release.Name, chart, release.Namespace, flags...); err != nil {
|
||||
@@ -1160,10 +1161,11 @@ func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helme
|
||||
release.installedVersion = installedVersion
|
||||
}
|
||||
|
||||
if st.shouldUseKubedog(release, opts) {
|
||||
if trackErr := st.trackWithKubedog(gocontext.Background(), release, helm, opts); trackErr != nil {
|
||||
st.logger.Warnf("kubedog tracking failed for release %s: %v", release.Name, trackErr)
|
||||
}
|
||||
if trackErr := st.trackReleaseIfEnabled(gocontext.Background(), release, helm, opts); trackErr != nil {
|
||||
m.Lock()
|
||||
affectedReleases.Failed = append(affectedReleases.Failed, release)
|
||||
m.Unlock()
|
||||
relErr = trackErr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,39 +38,39 @@ func TestGenerateID(t *testing.T) {
|
||||
run(testcase{
|
||||
subject: "baseline",
|
||||
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
|
||||
want: "foo-values-6ccb848dcd",
|
||||
want: "foo-values-7f6f8d74dd",
|
||||
})
|
||||
|
||||
run(testcase{
|
||||
subject: "different bytes content",
|
||||
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
|
||||
data: []byte(`{"k":"v"}`),
|
||||
want: "foo-values-5bcbbc4c85",
|
||||
want: "foo-values-5fc74c864c",
|
||||
})
|
||||
|
||||
run(testcase{
|
||||
subject: "different map content",
|
||||
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
|
||||
data: map[string]any{"k": "v"},
|
||||
want: "foo-values-7c6468f955",
|
||||
want: "foo-values-77df88dd65",
|
||||
})
|
||||
|
||||
run(testcase{
|
||||
subject: "different chart",
|
||||
release: ReleaseSpec{Name: "foo", Chart: "stable/envoy"},
|
||||
want: "foo-values-8645f5847f",
|
||||
want: "foo-values-77c96457f7",
|
||||
})
|
||||
|
||||
run(testcase{
|
||||
subject: "different name",
|
||||
release: ReleaseSpec{Name: "bar", Chart: "incubator/raw"},
|
||||
want: "bar-values-54bd8c865",
|
||||
want: "bar-values-6695f7ff4c",
|
||||
})
|
||||
|
||||
run(testcase{
|
||||
subject: "specific ns",
|
||||
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw", Namespace: "myns"},
|
||||
want: "myns-foo-values-b4849b445",
|
||||
want: "myns-foo-values-9b9484d4c",
|
||||
})
|
||||
|
||||
for id, n := range ids {
|
||||
|
||||
Reference in New Issue
Block a user