mirror of https://github.com/helm/helm
When users run `helm pull` without a version, OCI pulls already print “Pulled:” and “Digest:”. HTTP/repo pulls do not. Some providers (e.g. Bitnami) resolve --repo pulls to `oci://` but skip the registry client summary, so nothing is printed. - Now we print a summary for `--repo` and direct HTTP pulls after download. - Keep direct oci:// behavior unchanged (avoid duplicate output). - Mirror OCI format: ``` Pulled: <chart>:<version> Digest: sha256:<digest> ``` For HTTP/repo, the digest is the archive SHA-256 (.tgz). For OCI, the digest is the manifest digest (unchanged). I tested with command like: ```sh helm pull ingress-nginx --repo=https://kubernetes.github.io/ingress-nginx --version 4.10.1 helm pull oci://registry-1.docker.io/bitnamicharts/nginx --version '20.0.7' helm/bin/helm pull redis --repo=https://charts.bitnami.com/bitnami --version='22.0.4' ``` Signed-off-by: Benoit Tigeot <benoit.tigeot@lifen.fr>pull/31206/head
parent
934f761e08
commit
3ae2f48d02
@ -0,0 +1,129 @@
|
||||
/*
|
||||
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 action
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"helm.sh/helm/v4/pkg/cli"
|
||||
)
|
||||
|
||||
// helm pull testchart --repo=http://127.0.0.1:<port> --version 1.2.3
|
||||
func TestPull_PrintsSummary_ForHTTPRepo(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Minimal chart payload; verification is off so a plain byte buffer is fine.
|
||||
chartBytes := []byte("dummy-chart-content")
|
||||
sum := sha256.Sum256(chartBytes)
|
||||
wantDigest := fmt.Sprintf("sha256:%x", sum)
|
||||
|
||||
// Serve a valid index.yaml and the chart archive.
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/index.yaml", func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/yaml")
|
||||
// Valid index entry requires both name and version.
|
||||
fmt.Fprintf(w, `apiVersion: v1
|
||||
entries:
|
||||
testchart:
|
||||
- name: testchart
|
||||
version: 1.2.3
|
||||
urls:
|
||||
- testchart-1.2.3.tgz
|
||||
created: "2020-01-01T00:00:00Z"
|
||||
`)
|
||||
})
|
||||
mux.HandleFunc("/testchart-1.2.3.tgz", func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/gzip")
|
||||
_, _ = w.Write(chartBytes)
|
||||
})
|
||||
srv := httptest.NewServer(mux)
|
||||
defer srv.Close()
|
||||
|
||||
// Isolate Helm env/cache to temp dirs for deterministic tests.
|
||||
settings := cli.New()
|
||||
settings.RepositoryCache = t.TempDir()
|
||||
settings.RepositoryConfig = filepath.Join(t.TempDir(), "repositories.yaml")
|
||||
settings.ContentCache = t.TempDir()
|
||||
|
||||
cfg := &Configuration{} // minimal config; no K8s or registry for HTTP path
|
||||
|
||||
p := NewPull(WithConfig(cfg))
|
||||
p.Settings = settings
|
||||
p.DestDir = t.TempDir()
|
||||
p.RepoURL = srv.URL
|
||||
p.Version = "1.2.3"
|
||||
|
||||
out, err := p.Run("testchart")
|
||||
require.NoError(t, err, "Pull.Run() should succeed. Output:\n%s", out)
|
||||
|
||||
assert.Contains(t, out, "Pulled: testchart:1.2.3", "expected Pulled summary in output")
|
||||
assert.Contains(t, out, "Digest: "+wantDigest, "expected archive digest in output")
|
||||
|
||||
// Ensure the chart file was saved.
|
||||
_, statErr := os.Stat(filepath.Join(p.DestDir, "testchart-1.2.3.tgz"))
|
||||
require.NoError(t, statErr, "expected chart archive to be saved")
|
||||
}
|
||||
|
||||
// helm pull http://127.0.0.1:<port>/directchart-9.9.9.tgz
|
||||
func TestPull_PrintsSummary_ForDirectHTTPURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
chartBytes := []byte("another-dummy-chart")
|
||||
sum := sha256.Sum256(chartBytes)
|
||||
wantDigest := fmt.Sprintf("sha256:%x", sum)
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/directchart-9.9.9.tgz", func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/gzip")
|
||||
_, _ = w.Write(chartBytes)
|
||||
})
|
||||
srv := httptest.NewServer(mux)
|
||||
defer srv.Close()
|
||||
|
||||
settings := cli.New()
|
||||
settings.RepositoryCache = t.TempDir()
|
||||
settings.RepositoryConfig = filepath.Join(t.TempDir(), "repositories.yaml")
|
||||
settings.ContentCache = t.TempDir()
|
||||
|
||||
cfg := &Configuration{}
|
||||
|
||||
p := NewPull(WithConfig(cfg))
|
||||
p.Settings = settings
|
||||
p.DestDir = t.TempDir()
|
||||
|
||||
// Direct HTTP URL (absolute URL). Version is ignored for absolute URLs.
|
||||
chartURL := srv.URL + "/directchart-9.9.9.tgz"
|
||||
|
||||
out, err := p.Run(chartURL)
|
||||
require.NoError(t, err, "Pull.Run() should succeed. Output:\n%s", out)
|
||||
|
||||
// Output should reflect name-version.tgz from the URL.
|
||||
assert.Contains(t, out, "Pulled: directchart:9.9.9", "expected Pulled summary in output")
|
||||
assert.Contains(t, out, "Digest: "+wantDigest, "expected archive digest in output")
|
||||
|
||||
// Ensure the chart file was saved.
|
||||
_, statErr := os.Stat(filepath.Join(p.DestDir, "directchart-9.9.9.tgz"))
|
||||
require.NoError(t, statErr, "expected chart archive to be saved")
|
||||
}
|
Loading…
Reference in new issue