diff --git a/internal/resolver/resolver.go b/internal/resolver/resolver.go index e4dbab227..cec29c947 100644 --- a/internal/resolver/resolver.go +++ b/internal/resolver/resolver.go @@ -157,6 +157,22 @@ func HashReq(req, lock []*chart.Dependency) (string, error) { return "sha256:" + s, err } +// HashV2Req generates a hash of requirements generated in Helm v2. +// +// This should be used only to compare against another hash generated by the +// Helm v2 hash function. It is to handle issue: +// https://github.com/helm/helm/issues/7233 +func HashV2Req(req []*chart.Dependency) (string, error) { + dep := make(map[string][]*chart.Dependency) + dep["dependencies"] = req + data, err := json.Marshal(dep) + if err != nil { + return "", err + } + s, err := provenance.Digest(bytes.NewBuffer(data)) + return "sha256:" + s, err +} + // GetLocalPath generates absolute local path when use // "file://" in repository of dependencies func GetLocalPath(repo, chartpath string) (string, error) { diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go index 525a41d5d..083c44a21 100644 --- a/pkg/downloader/manager.go +++ b/pkg/downloader/manager.go @@ -19,6 +19,7 @@ import ( "fmt" "io" "io/ioutil" + "log" "net/url" "os" "path" @@ -87,11 +88,16 @@ func (m *Manager) Build() error { if sum, err := resolver.HashReq(req, lock.Dependencies); err != nil || sum != lock.Digest { // If lock digest differs and chart is apiVersion v1, it maybe because the lock was built - // with Helm 2 and should therefore be regenerated + // with Helm 2 and therefore should be checked with Helm v2 hash + // Fix for: https://github.com/helm/helm/issues/7233 if c.Metadata.APIVersion == chart.APIVersionV1 { - return m.Update() + log.Println("warning: a valid Helm v3 hash was not found. Checking against Helm v2 hash...") + if sum, err := resolver.HashV2Req(req); err != nil || sum != lock.Digest { + return errors.New("Chart.lock is out of sync with Chart.yaml") + } + } else { + return errors.New("Chart.lock is out of sync with Chart.yaml") } - return errors.New("Chart.lock is out of sync with Chart.yaml") } // Check that all of the repos we're dependent on actually exist.