feat: thread chart source provenance into Release

Signed-off-by: iammehrabsandhu <user.127.888@users.noreply.github.com>
pull/32018/head
iammehrabsandhu 5 days ago
parent 666fa05c28
commit d5cc5137af

@ -153,6 +153,9 @@ type ChartPathOptions struct {
// registryClient provides a registry client but is not added with
// options from a flag
registryClient *registry.Client
// resolvedSource is populated by LocateChart with chart provenance info.
resolvedSource *rcommon.ChartSource
}
// NewInstall creates a new Install object with the given configuration.
@ -669,6 +672,7 @@ func (i *Install) createRelease(chrt *chart.Chart, rawVals map[string]any, label
Version: 1,
Labels: labels,
ApplyMethod: string(determineReleaseSSApplyMethod(i.ServerSideApply)),
Source: i.resolvedSource,
}
return r
@ -980,6 +984,14 @@ func (c *ChartPathOptions) LocateChart(name string, settings *cli.EnvSettings) (
return "", err
}
// Capture source provenance from downloader or fallback context
if dl.ResolvedSource != nil {
c.resolvedSource = dl.ResolvedSource
}
if c.resolvedSource == nil && c.RepoURL != "" {
c.resolvedSource = &rcommon.ChartSource{RepoURL: c.RepoURL}
}
lname, err := filepath.Abs(filename)
if err != nil {
return filename, err

@ -329,6 +329,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chartv2.Chart, vals map[str
Hooks: hooks,
Labels: mergeCustomLabels(lastRelease.Labels, u.Labels),
ApplyMethod: string(determineReleaseSSApplyMethod(serverSideApply)),
Source: u.resolvedSource,
}
if len(notesTxt) > 0 {

@ -36,6 +36,7 @@ import (
"helm.sh/helm/v4/pkg/helmpath"
"helm.sh/helm/v4/pkg/provenance"
"helm.sh/helm/v4/pkg/registry"
rcommon "helm.sh/helm/v4/pkg/release/common"
"helm.sh/helm/v4/pkg/repo/v1"
)
@ -85,6 +86,10 @@ type ChartDownloader struct {
// Cache specifies the cache implementation to use.
Cache Cache
// ResolvedSource is populated after a successful download with the chart's
// source provenance (OCI ref and digest).
ResolvedSource *rcommon.ChartSource
}
// DownloadTo retrieves a chart. Depending on the settings, it may also download a provenance file.
@ -152,6 +157,14 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven
if err != nil {
return "", nil, err
}
// Capture source provenance via duck-typing
if u.Scheme == registry.OCIScheme {
c.ResolvedSource = &rcommon.ChartSource{RegistryRef: ref}
if dg, ok := g.(interface{ Digest() string }); ok {
c.ResolvedSource.Digest = dg.Digest()
}
}
}
name := filepath.Base(u.Path)
@ -267,6 +280,14 @@ func (c *ChartDownloader) DownloadToCache(ref, version string) (string, *provena
return "", nil, gerr
}
// Capture source provenance via duck-typing
if u.Scheme == registry.OCIScheme {
c.ResolvedSource = &rcommon.ChartSource{RegistryRef: ref}
if dg, ok := g.(interface{ Digest() string }); ok {
c.ResolvedSource.Digest = dg.Digest()
}
}
// Generate the digest
if len(digest) == 0 {
digest32 = sha256.Sum256(data.Bytes())

@ -36,6 +36,7 @@ type OCIGetter struct {
opts getterOptions
transport *http.Transport
once sync.Once
digest string
}
// Get performs a Get from repo.Getter and returns the body.
@ -82,6 +83,7 @@ func (g *OCIGetter) get(href string) (*bytes.Buffer, error) {
if err != nil {
return nil, err
}
g.digest = result.Manifest.Digest
if requestingProv {
return bytes.NewBuffer(result.Prov.Data), nil
@ -89,6 +91,11 @@ func (g *OCIGetter) get(href string) (*bytes.Buffer, error) {
return bytes.NewBuffer(result.Chart.Data), nil
}
// Digest returns the OCI manifest digest from the most recent pull.
func (g *OCIGetter) Digest() string {
return g.digest
}
// NewOCIGetter constructs a valid http/https client as a Getter
func NewOCIGetter(ops ...Option) (Getter, error) {
var client OCIGetter

@ -0,0 +1,23 @@
/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package common
// ChartSource records where a chart was fetched from.
type ChartSource struct {
RepoURL string `json:"repo_url,omitempty"`
RegistryRef string `json:"registry_ref,omitempty"`
Digest string `json:"digest,omitempty"`
}
Loading…
Cancel
Save