Add debug logging for helm pull command

Implemented debug output for HTTP-level logs in the helm pull command
by integrating cli.EnvSettings into the chart downloader. This addresses
the issue where the --debug flag was ignored during helm pull.

Fixes #31098

Signed-off-by: Sowmith Kuppa <soumith.odu@gmail.com>
pull/31108/head
Sowmith Kuppa 2 months ago
parent 99d42acf60
commit 89f391e674

@ -88,6 +88,7 @@ func (p *Pull) Run(chartRef string) (string, error) {
RegistryClient: p.cfg.RegistryClient,
RepositoryConfig: p.Settings.RepositoryConfig,
RepositoryCache: p.Settings.RepositoryCache,
Debug: p.Settings.Debug,
}
if registry.IsOCI(chartRef) {

@ -21,6 +21,8 @@ import (
"io"
"io/fs"
"net/url"
"net/http"
"net/http/httputil"
"os"
"path/filepath"
"strings"
@ -69,11 +71,44 @@ type ChartDownloader struct {
Getters getter.Providers
// Options provide parameters to be passed along to the Getter being initialized.
Options []getter.Option
Debug bool //Added to capture the --debug flag
RegistryClient *registry.Client
RepositoryConfig string
RepositoryCache string
}
type debugTransport struct {
*http.Transport
out io.Writer
}
func (t *debugTransport) RoundTrip(req *http.Request) (*http.Response, error) {
fmt.Fprintf(t.out, "DEBUG: HTTP request to %s\n", req.URL.String())
// Log the request
reqDump, err := httputil.DumpRequestOut(req, false)
if err == nil {
fmt.Fprintf(t.out, "%s\n", reqDump)
}
// Perform the request
resp, err := t.Transport.RoundTrip(req)
if err != nil {
fmt.Fprintf(t.out, "HTTP request failed: %v\n", err)
return nil, err
}
// Log the response
respDump, err := httputil.DumpResponse(resp, false)
if err == nil {
fmt.Fprintf(t.out, "HTTP Response: \n%s\n", respDump)
}
if resp.StatusCode >= 300 && resp.StatusCode < 400 {
location, _ := resp.Header["Location"]
fmt.Fprintf(t.out, "DEBUG: Redirect to: %v\n", location)
}
return resp, err
}
// DownloadTo retrieves a chart. Depending on the settings, it may also download a provenance file.
//
// If Verify is set to VerifyNever, the verification will be nil.
@ -88,18 +123,37 @@ type ChartDownloader struct {
func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *provenance.Verification, error) {
u, err := c.ResolveChartVersion(ref, version)
if err != nil {
fmt.Fprintf(c.Out, "DEBUG: Failed to resolve chart version: %v\n", err)
return "", nil, err
}
fmt.Fprintf(c.Out, "DEBUG: Resolved chart URL: %s\n", u.String())
g, err := c.Getters.ByScheme(u.Scheme)
if err != nil {
fmt.Fprintf(c.Out, "DEBUG: Failed to get getter for scheme %s: %v\n", u.Scheme, err)
return "", nil, err
}
fmt.Fprintf(c.Out, "DEBUG: Using getter for scheme: %s\n", u.Scheme)
c.Options = append(c.Options, getter.WithAcceptHeader("application/gzip,application/octet-stream"))
// If debug is enabled, wrap the getter's HTTP client with a debug transport
if c.Debug {
dt := &debugTransport{
Transport: http.DefaultTransport.(*http.Transport).Clone(),
out: c.Out,
}
dt.Transport.DisableKeepAlives = true
c.Options = append(c.Options, getter.WithClient(&http.Client{
Transport: dt,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
fmt.Fprintf(c.Out, "DEBUG: Following redirect to %s\n", req.URL.String())
return nil
},
}))
}
data, err := g.Get(u.String(), c.Options...)
if err != nil {
fmt.Fprintf(c.Out, "DEBUG: Failed to fetch chart: %v\n", err)
return "", nil, err
}
@ -117,6 +171,21 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven
// If provenance is requested, verify it.
ver := &provenance.Verification{}
if c.Verify > VerifyNever {
// If debug is enabled, use the same debug transport for provenance file
if c.Debug {
dt := &debugTransport{
Transport: http.DefaultTransport.(*http.Transport).Clone(),
out: c.Out,
}
dt.Transport.DisableKeepAlives = true
c.Options = append(c.Options, getter.WithClient(&http.Client{
Transport: dt,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
fmt.Fprintf(c.Out, "DEBUG: Following redirect to %s\n", req.URL.String())
return nil
},
}))
}
body, err := g.Get(u.String() + ".prov")
if err != nil {
if c.Verify == VerifyAlways {

@ -47,6 +47,7 @@ type options struct {
registryClient *registry.Client
timeout time.Duration
transport *http.Transport
client *http.Client
}
// Option allows specifying various settings configurable by the user for overriding the defaults

@ -35,6 +35,7 @@ type HTTPGetter struct {
once sync.Once
}
// Get performs a Get from repo.Getter and returns the body.
func (g *HTTPGetter) Get(href string, options ...Option) (*bytes.Buffer, error) {
for _, opt := range options {
@ -80,9 +81,13 @@ func (g *HTTPGetter) get(href string) (*bytes.Buffer, error) {
}
}
client, err := g.httpClient()
if err != nil {
return nil, err
client := g.opts.client
if client == nil {
var err error
client, err = g.httpClient()
if err != nil {
return nil, err
}
}
resp, err := client.Do(req)
@ -155,3 +160,10 @@ func (g *HTTPGetter) httpClient() (*http.Client, error) {
return client, nil
}
// WithClient sets the HTTP client for the getter
func WithClient(client *http.Client) Option {
return func(opts *options) {
opts.client = client
}
}

Loading…
Cancel
Save