-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add GetReleaseChecksum method and update UpgradeRelease signature #583
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR updates the checksum storage mechanism for Helm releases by transferring the checksum from environment variables to release labels, and it adjusts the UpgradeRelease method signatures across multiple packages.
- Moves checksum storage from variables to release labels in HelmModule
- Introduces a new GetReleaseChecksum method for both helm3lib and helm3 packages
- Updates UpgradeRelease method signatures and related calls in tests and client interfaces
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
pkg/module_manager/models/modules/helm.go | Updates RunHelmInstall and shouldRunHelmUpgrade to utilize release labels for the module checksum |
pkg/helm/helm_test.go | Updates test to call the new UpgradeRelease signature with labels |
pkg/helm/helm3lib/helm3lib.go | Updates UpgradeRelease and introduces GetReleaseChecksum with labels |
pkg/helm/helm3/helm3.go | Adjusts the UpgradeRelease signature and provides a GetReleaseChecksum implementation |
pkg/helm/client/client.go | Updates interface definitions to include new labels parameter and GetReleaseChecksum |
Comments suppressed due to low confidence (2)
pkg/helm/helm3lib/helm3lib.go:205
- Ensure that upg.Labels is initialized (e.g., to an empty map) before calling maps.Copy to avoid potential nil pointer issues when labels are provided.
maps.Copy(upg.Labels, labels)
pkg/helm/helm3/helm3.go:142
- The labels parameter is currently ignored in the Helm3 client UpgradeRelease implementation. Consider handling the moduleChecksum label similarly to the helm3lib version, or remove the unused parameter if not needed.
func (h *Helm3Client) UpgradeRelease(releaseName string, chart string, valuesPaths []string, setValues []string, _ map[string]string, namespace string) error {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR transfers storage of release checksums from environment variables to release labels and updates the UpgradeRelease signature across multiple modules. Key changes include:
- Adding a new GetReleaseChecksum method to retrieve the checksum from release labels.
- Updating the UpgradeRelease signature to accept a labels parameter instead of a set values slice.
- Adjusting tests and mocks to use the new method signatures.
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
pkg/module_manager/models/modules/helm.go | Replaced checksum storage with label-based storage in helm install and upgrade logic. |
pkg/helm/test/mock/mock.go | Introduced GetReleaseChecksum and updated UpgradeRelease signature. |
pkg/helm/helm_test.go | Updated test calls to match the new UpgradeRelease signature. |
pkg/helm/helm3lib/helm3lib.go | Updated UpgradeRelease and upgradeRelease methods to handle labels; added GetReleaseChecksum. |
pkg/helm/helm3/helm3.go | Updated UpgradeRelease and added GetReleaseChecksum implementation. |
pkg/helm/client/client.go | Updated HelmClient interface with new method signature for UpgradeRelease and added GetReleaseChecksum. |
@@ -38,7 +38,7 @@ func TestHelm3LibUpgradeDelete(t *testing.T) { | |||
|
|||
cl := initHelmClient(t) | |||
|
|||
err := cl.UpgradeRelease("test-release", "testdata/chart", nil, nil, cl.Namespace) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we need to start write tests for helm methods behaviour.
f.e. add this method for LibClient (not interface) and test with it
// ListReleases returns list of releases
func (h *LibClient) ListReleases() ([]*release.Release, error) {
l := action.NewList(actionConfig)
// list all releases regardless of their state
l.StateMask = action.ListAll
list, err := l.Run()
if err != nil {
return nil, fmt.Errorf("helm list failed: %s", err)
}
return list, nil
}
pkg/helm/helm3lib/helm3lib.go
Outdated
upg.Labels = make(map[string]string) | ||
} | ||
if labels != nil { | ||
maps.Copy(upg.Labels, labels) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't get the clue. why not to pass labels directly to the upgrade cli. Do the upgradeCli modify them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also have to add to the installCli below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to protect myself a little. But yes, you can just ignore the current labels and just make an assignment.
instClient also corrected it.
2f29530
to
b71a478
Compare
Signed-off-by: Evsyukov Denis <[email protected]> diff --git c/pkg/helm/client/client.go i/pkg/helm/client/client.go index beb810e..b5edbe8 100644 --- c/pkg/helm/client/client.go +++ i/pkg/helm/client/client.go @@ -1,12 +1,15 @@ package client -import "github.com/flant/addon-operator/pkg/utils" +import ( + "github.com/flant/addon-operator/pkg/utils" +) type HelmClient interface { LastReleaseStatus(releaseName string) (string, string, error) - UpgradeRelease(releaseName string, chart string, valuesPaths []string, setValues []string, namespace string) error + UpgradeRelease(releaseName string, chart string, valuesPaths []string, setValues []string, labels map[string]string, namespace string) error Render(releaseName string, chart string, valuesPaths []string, setValues []string, namespace string, debug bool) (string, error) GetReleaseValues(releaseName string) (utils.Values, error) + GetReleaseChecksum(releaseName string) (string, error) DeleteRelease(releaseName string) error ListReleasesNames() ([]string, error) IsReleaseExists(releaseName string) (bool, error) diff --git c/pkg/helm/helm3/helm3.go i/pkg/helm/helm3/helm3.go index e396daa..6737cda 100644 --- c/pkg/helm/helm3/helm3.go +++ i/pkg/helm/helm3/helm3.go @@ -9,9 +9,10 @@ import ( "strings" "time" - "github.com/deckhouse/deckhouse/pkg/log" k8syaml "sigs.k8s.io/yaml" + "github.com/deckhouse/deckhouse/pkg/log" + "github.com/flant/addon-operator/pkg/helm/client" "github.com/flant/addon-operator/pkg/utils" "github.com/flant/shell-operator/pkg/executor" @@ -145,7 +146,7 @@ func (h *Helm3Client) LastReleaseStatus(releaseName string) (string /*revision*/ return revision, status, nil } -func (h *Helm3Client) UpgradeRelease(releaseName string, chart string, valuesPaths []string, setValues []string, namespace string) error { +func (h *Helm3Client) UpgradeRelease(releaseName string, chart string, valuesPaths []string, setValues []string, _ map[string]string, namespace string) error { args := []string{ "upgrade", releaseName, chart, "--install", @@ -210,6 +211,20 @@ func (h *Helm3Client) GetReleaseValues(releaseName string) (utils.Values, error) return values, nil } +func (h *Helm3Client) GetReleaseChecksum(releaseName string) (string, error) { + args := []string{ + "get", "manifest", releaseName, + "--namespace", h.Namespace, + } + stdout, stderr, err := h.cmd(args...) + if err != nil { + return "", fmt.Errorf("cannot get manifest of helm release %s: %s\n%s %s", releaseName, err, stdout, stderr) + } + + checksum := utils.CalculateStringsChecksum(stdout) + return checksum, nil +} + func (h *Helm3Client) DeleteRelease(releaseName string) error { h.Logger.Debug("helm release: execute helm uninstall", slog.String("release", releaseName)) diff --git c/pkg/helm/helm3lib/helm3lib.go i/pkg/helm/helm3lib/helm3lib.go index defee5f..36dd480 100644 --- c/pkg/helm/helm3lib/helm3lib.go +++ i/pkg/helm/helm3lib/helm3lib.go @@ -5,14 +5,13 @@ import ( "errors" "fmt" "log/slog" + "maps" "os" "sort" "strconv" "strings" "time" - "github.com/deckhouse/deckhouse/pkg/log" - logContext "github.com/deckhouse/deckhouse/pkg/log/context" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/chartutil" @@ -26,6 +25,9 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/rest" + "github.com/deckhouse/deckhouse/pkg/log" + logContext "github.com/deckhouse/deckhouse/pkg/log/context" + "github.com/flant/addon-operator/pkg/helm/client" "github.com/flant/addon-operator/pkg/helm/post_renderer" "github.com/flant/addon-operator/pkg/utils" @@ -160,15 +162,15 @@ func (h *LibClient) LastReleaseStatus(releaseName string) (string /*revision*/, return strconv.FormatInt(int64(lastRelease.Version), 10), lastRelease.Info.Status.String(), nil } -func (h *LibClient) UpgradeRelease(releaseName string, chartName string, valuesPaths []string, setValues []string, namespace string) error { - err := h.upgradeRelease(releaseName, chartName, valuesPaths, setValues, namespace) +func (h *LibClient) UpgradeRelease(releaseName string, chartName string, valuesPaths []string, setValues []string, labels map[string]string, namespace string) error { + err := h.upgradeRelease(releaseName, chartName, valuesPaths, setValues, labels, namespace) if err != nil { // helm validation can fail because FeatureGate was enabled for example // handling this case we can reinitialize kubeClient and repeat one more time by backoff if err := actionConfigInit(h.Logger); err != nil { return err } - return h.upgradeRelease(releaseName, chartName, valuesPaths, setValues, namespace) + return h.upgradeRelease(releaseName, chartName, valuesPaths, setValues, labels, namespace) } h.Logger.Debug("helm release upgraded", slog.String("version", releaseName)) return nil @@ -178,7 +180,7 @@ func (h *LibClient) hasLabelsToApply() bool { return len(h.labels) > 0 } -func (h *LibClient) upgradeRelease(releaseName string, chartName string, valuesPaths []string, setValues []string, namespace string) error { +func (h *LibClient) upgradeRelease(releaseName string, chartName string, valuesPaths []string, setValues []string, labels map[string]string, namespace string) error { upg := action.NewUpgrade(actionConfig) if namespace != "" { upg.Namespace = namespace @@ -191,6 +193,8 @@ func (h *LibClient) upgradeRelease(releaseName string, chartName string, valuesP upg.SkipCRDs = true upg.MaxHistory = int(options.HistoryMax) upg.Timeout = options.Timeout + // copy labels to avoid modifying the original map + maps.Copy(upg.Labels, labels) chart, err := loader.Load(chartName) if err != nil { @@ -356,6 +360,19 @@ func (h *LibClient) GetReleaseValues(releaseName string) (utils.Values, error) { return gv.Run(releaseName) } +func (h *LibClient) GetReleaseChecksum(releaseName string) (string, error) { + gv := action.NewGet(actionConfig) + rel, err := gv.Run(releaseName) + if err != nil { + return "", fmt.Errorf("helm get failed: %s", err) + } + if checksum, ok := rel.Labels["moduleChecksum"]; ok { + return checksum, nil + } + + return "", fmt.Errorf("moduleChecksum label not found in release %s", releaseName) +} + func (h *LibClient) DeleteRelease(releaseName string) error { h.Logger.Debug("helm release: execute helm uninstall", slog.String("release", releaseName)) diff --git c/pkg/helm/helm_test.go i/pkg/helm/helm_test.go index 87458c9..d17f633 100644 --- c/pkg/helm/helm_test.go +++ i/pkg/helm/helm_test.go @@ -4,9 +4,10 @@ import ( "os" "testing" - "github.com/deckhouse/deckhouse/pkg/log" . "github.com/onsi/gomega" + "github.com/deckhouse/deckhouse/pkg/log" + "github.com/flant/addon-operator/pkg/helm/helm3" "github.com/flant/addon-operator/pkg/helm/helm3lib" ) @@ -51,7 +52,7 @@ func TestHelmFactory(t *testing.T) { g.Expect(err).ShouldNot(HaveOccurred()) g.Expect(isExists).Should(BeFalse(), "should not found release in the empty cluster") - err = helmCl.UpgradeRelease("test-release", "helm3lib/testdata/chart", nil, nil, namespace) + err = helmCl.UpgradeRelease("test-release", "helm3lib/testdata/chart", nil, nil, nil, namespace) g.Expect(err).ShouldNot(HaveOccurred()) releasesAfterUpgrade, err := helmCl.ListReleasesNames() diff --git c/pkg/module_manager/models/modules/helm.go i/pkg/module_manager/models/modules/helm.go index 6831c59..e7403fb 100644 --- c/pkg/module_manager/models/modules/helm.go +++ i/pkg/module_manager/models/modules/helm.go @@ -11,10 +11,11 @@ import ( "strings" "time" - "github.com/deckhouse/deckhouse/pkg/log" "github.com/gofrs/uuid/v5" "github.com/kennygrant/sanitize" + "github.com/deckhouse/deckhouse/pkg/log" + "github.com/flant/addon-operator/pkg/helm" "github.com/flant/addon-operator/pkg/helm/client" "github.com/flant/addon-operator/pkg/utils" @@ -272,7 +273,10 @@ func (hm *HelmModule) RunHelmInstall(logLabels map[string]string) error { helmReleaseName, hm.path, []string{valuesPath}, - []string{fmt.Sprintf("_addonOperatorModuleChecksum=%s", checksum)}, + []string{}, + map[string]string{ + "moduleChecksum": checksum, + }, hm.defaultNamespace, ) }() @@ -311,7 +315,7 @@ func (hm *HelmModule) shouldRunHelmUpgrade(helmClient client.HelmClient, release } // Get values for a non-failed release. - releaseValues, err := helmClient.GetReleaseValues(releaseName) + recordedChecksum, err := helmClient.GetReleaseChecksum(releaseName) if err != nil { logEntry.Debug("helm release get values error, no upgrade", slog.String("release", releaseName), @@ -319,24 +323,14 @@ func (hm *HelmModule) shouldRunHelmUpgrade(helmClient client.HelmClient, release return false, err } - // Run helm upgrade if there is no stored checksum - recordedChecksum, hasKey := releaseValues["_addonOperatorModuleChecksum"] - if !hasKey { - logEntry.Debug("helm release has no saved checksum of values: should run upgrade", - slog.String("release", releaseName)) - return true, nil - } - // Calculate a checksum of current values and compare to a stored checksum. // Run helm upgrade if checksum is changed. - if recordedChecksumStr, ok := recordedChecksum.(string); ok { - if recordedChecksumStr != checksum { - logEntry.Debug("helm release checksum is changed: should run upgrade", - slog.String("release", releaseName), - slog.String("checksum", recordedChecksumStr), - slog.String("newChecksum", checksum)) - return true, nil - } + if recordedChecksum != checksum { + logEntry.Debug("helm release checksum is changed: should run upgrade", + slog.String("release", releaseName), + slog.String("checksum", recordedChecksum), + slog.String("newChecksum", checksum)) + return true, nil } // Check if there are absent resources diff --git c/pkg/helm/helm3/helm3.go i/pkg/helm/helm3/helm3.go index 03cab1f..6737cda 100644 --- c/pkg/helm/helm3/helm3.go +++ i/pkg/helm/helm3/helm3.go @@ -9,9 +9,10 @@ import ( "strings" "time" - "github.com/deckhouse/deckhouse/pkg/log" k8syaml "sigs.k8s.io/yaml" + "github.com/deckhouse/deckhouse/pkg/log" + "github.com/flant/addon-operator/pkg/helm/client" "github.com/flant/addon-operator/pkg/utils" "github.com/flant/shell-operator/pkg/executor" diff --git c/pkg/helm/helm3lib/helm3lib.go i/pkg/helm/helm3lib/helm3lib.go index deb6451..f0a534d 100644 --- c/pkg/helm/helm3lib/helm3lib.go +++ i/pkg/helm/helm3lib/helm3lib.go @@ -12,8 +12,6 @@ import ( "strings" "time" - "github.com/deckhouse/deckhouse/pkg/log" - logContext "github.com/deckhouse/deckhouse/pkg/log/context" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/chartutil" @@ -27,6 +25,9 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/rest" + "github.com/deckhouse/deckhouse/pkg/log" + logContext "github.com/deckhouse/deckhouse/pkg/log/context" + "github.com/flant/addon-operator/pkg/helm/client" "github.com/flant/addon-operator/pkg/helm/post_renderer" "github.com/flant/addon-operator/pkg/utils" @@ -193,12 +194,17 @@ func (h *LibClient) upgradeRelease(releaseName string, chartName string, valuesP upg.MaxHistory = int(options.HistoryMax) upg.Timeout = options.Timeout // copy labels to avoid modifying the original map +<<<<<<< HEAD if upg.Labels == nil { upg.Labels = make(map[string]string) } if labels != nil { maps.Copy(upg.Labels, labels) } +||||||| parent of ad2b140 (feat: add GetReleaseChecksum method and update UpgradeRelease signature) +======= + maps.Copy(upg.Labels, labels) +>>>>>>> ad2b140 (feat: add GetReleaseChecksum method and update UpgradeRelease signature) chart, err := loader.Load(chartName) if err != nil { @@ -374,6 +380,7 @@ func (h *LibClient) GetReleaseChecksum(releaseName string) (string, error) { return checksum, nil } +<<<<<<< HEAD // fallback to old behavior releaseValues, err := h.GetReleaseValues(releaseName) if err != nil { @@ -385,6 +392,9 @@ func (h *LibClient) GetReleaseChecksum(releaseName string) (string, error) { } } +||||||| parent of ad2b140 (feat: add GetReleaseChecksum method and update UpgradeRelease signature) +======= +>>>>>>> ad2b140 (feat: add GetReleaseChecksum method and update UpgradeRelease signature) return "", fmt.Errorf("moduleChecksum label not found in release %s", releaseName) } diff --git c/pkg/helm/helm_test.go i/pkg/helm/helm_test.go index 168ea1f..d17f633 100644 --- c/pkg/helm/helm_test.go +++ i/pkg/helm/helm_test.go @@ -4,9 +4,10 @@ import ( "os" "testing" - "github.com/deckhouse/deckhouse/pkg/log" . "github.com/onsi/gomega" + "github.com/deckhouse/deckhouse/pkg/log" + "github.com/flant/addon-operator/pkg/helm/helm3" "github.com/flant/addon-operator/pkg/helm/helm3lib" ) diff --git c/pkg/module_manager/models/modules/helm.go i/pkg/module_manager/models/modules/helm.go index 1b0f0b6..e7403fb 100644 --- c/pkg/module_manager/models/modules/helm.go +++ i/pkg/module_manager/models/modules/helm.go @@ -11,10 +11,11 @@ import ( "strings" "time" - "github.com/deckhouse/deckhouse/pkg/log" "github.com/gofrs/uuid/v5" "github.com/kennygrant/sanitize" + "github.com/deckhouse/deckhouse/pkg/log" + "github.com/flant/addon-operator/pkg/helm" "github.com/flant/addon-operator/pkg/helm/client" "github.com/flant/addon-operator/pkg/utils" Signed-off-by: Evsyukov Denis <[email protected]>
…re to include additional parameters Signed-off-by: Evsyukov Denis <[email protected]>
Signed-off-by: Evsyukov Denis <[email protected]>
…ase values Signed-off-by: Evsyukov Denis <[email protected]>
Signed-off-by: Evsyukov Denis <[email protected]>
Signed-off-by: Evsyukov Denis <[email protected]>
…eRelease Signed-off-by: Evsyukov Denis <[email protected]>
b71a478
to
891a9f6
Compare
…elease Signed-off-by: Evsyukov Denis <[email protected]>
Overview
Transferring the release checksum storage from variables to labels
What this PR does / why we need it
Transfer the storage of checksums from environment variables to release tags