diff --git a/cmd/helm/fetch.go b/cmd/helm/fetch.go index 79c526cf7..612ad973a 100644 --- a/cmd/helm/fetch.go +++ b/cmd/helm/fetch.go @@ -119,6 +119,8 @@ func (f *fetchCmd) run() error { Keyring: f.keyring, Verify: downloader.VerifyNever, Getters: getter.All(settings), + Username: f.username, + Password: f.password, } if f.verify { @@ -147,7 +149,7 @@ func (f *fetchCmd) run() error { f.chartRef = chartURL } - saved, v, err := c.DownloadTo(f.chartRef, f.username, f.password, f.version, dest) + saved, v, err := c.DownloadTo(f.chartRef, f.version, dest) if err != nil { return err } diff --git a/cmd/helm/install.go b/cmd/helm/install.go index bdbb2b7f3..f3debd913 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -418,6 +418,8 @@ func locateChartPath(repoURL, username, password, name, version string, verify b Out: os.Stdout, Keyring: keyring, Getters: getter.All(settings), + Username: username, + Password: password, } if verify { dl.Verify = downloader.VerifyAlways @@ -435,7 +437,7 @@ func locateChartPath(repoURL, username, password, name, version string, verify b os.MkdirAll(settings.Home.Archive(), 0744) } - filename, _, err := dl.DownloadTo(name, username, password, version, settings.Home.Archive()) + filename, _, err := dl.DownloadTo(name, version, settings.Home.Archive()) if err == nil { lname, err := filepath.Abs(filename) if err != nil { diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go index ff52fb3f0..65dbe7bcf 100644 --- a/pkg/downloader/chart_downloader.go +++ b/pkg/downloader/chart_downloader.go @@ -67,6 +67,10 @@ type ChartDownloader struct { HelmHome helmpath.Home // Getter collection for the operation Getters getter.Providers + // Chart repository username + Username string + // Chart repository password + Password string } // DownloadTo retrieves a chart. Depending on the settings, it may also download a provenance file. @@ -80,24 +84,26 @@ type ChartDownloader struct { // // Returns a string path to the location where the file was downloaded and a verification // (if provenance was verified), or an error if something bad happened. -func (c *ChartDownloader) DownloadTo(ref, username, password, version, dest string) (string, *provenance.Verification, error) { - u, g, e, err := c.ResolveChartVersion(ref, version) +func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *provenance.Verification, error) { + u, r, err := c.ResolveChartVersion(ref, version) if err != nil { return "", nil, err } - // If this method did not receive credentials, and the chart repository is - // configured with credentials, we should use the configured credentials. - if e != nil { + // If this ChartDownloader is not configured to use credentials, and the chart repository is, + // then we should use the repository's configured credentials. + username := c.Username + password := c.Password + if r.Config != nil { if username == "" { - username = e.Username + username = r.Config.Username } if password == "" { - password = e.Password + password = r.Config.Password } } - data, err := g.GetWithCredentials(u.String(), username, password) + data, err := r.Client.GetWithCredentials(u.String(), username, password) if err != nil { return "", nil, err } @@ -111,7 +117,7 @@ func (c *ChartDownloader) DownloadTo(ref, username, password, version, dest stri // If provenance is requested, verify it. ver := &provenance.Verification{} if c.Verify > VerifyNever { - body, err := g.Get(u.String() + ".prov") + body, err := r.Client.Get(u.String() + ".prov") if err != nil { if c.Verify == VerifyAlways { return destfile, ver, fmt.Errorf("Failed to fetch provenance %q", u.String()+".prov") @@ -150,15 +156,15 @@ func (c *ChartDownloader) DownloadTo(ref, username, password, version, dest stri // * If version is non-empty, this will return the URL for that version // * If version is empty, this will return the URL for the latest version // * If no version can be found, an error is returned -func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, getter.Getter, *repo.Entry, error) { +func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, *repo.ChartRepository, error) { u, err := url.Parse(ref) if err != nil { - return nil, nil, nil, fmt.Errorf("invalid chart URL format: %s", ref) + return nil, nil, fmt.Errorf("invalid chart URL format: %s", ref) } rf, err := repo.LoadRepositoriesFile(c.HelmHome.RepositoryFile()) if err != nil { - return u, nil, nil, err + return u, nil, err } if u.IsAbs() && len(u.Host) > 0 && len(u.Path) > 0 { @@ -174,73 +180,74 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, ge if err == ErrNoOwnerRepo { getterConstructor, err := c.Getters.ByScheme(u.Scheme) if err != nil { - return u, nil, nil, err + return u, nil, err } - getter, err := getterConstructor(ref, "", "", "") - return u, getter, nil, err + r := &repo.ChartRepository{} + r.Client, err = getterConstructor(ref, "", "", "") + return u, r, err } - return u, nil, nil, err + return u, nil, err } r, err := repo.NewChartRepository(rc, c.Getters) // If we get here, we don't need to go through the next phase of looking // up the URL. We have it already. So we just return. - return u, r.Client, r.Config, err + return u, r, err } // See if it's of the form: repo/path_to_chart p := strings.SplitN(u.Path, "/", 2) if len(p) < 2 { - return u, nil, nil, fmt.Errorf("Non-absolute URLs should be in form of repo_name/path_to_chart, got: %s", u) + return u, nil, fmt.Errorf("Non-absolute URLs should be in form of repo_name/path_to_chart, got: %s", u) } repoName := p[0] chartName := p[1] rc, err := pickChartRepositoryConfigByName(repoName, rf.Repositories) if err != nil { - return u, nil, nil, err + return u, nil, err } r, err := repo.NewChartRepository(rc, c.Getters) if err != nil { - return u, nil, nil, err + return u, nil, err } // Next, we need to load the index, and actually look up the chart. i, err := repo.LoadIndexFile(c.HelmHome.CacheIndex(r.Config.Name)) if err != nil { - return u, r.Client, r.Config, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err) + return u, r, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err) } cv, err := i.Get(chartName, version) if err != nil { - return u, r.Client, r.Config, fmt.Errorf("chart %q matching %s not found in %s index. (try 'helm repo update'). %s", chartName, version, r.Config.Name, err) + return u, r, fmt.Errorf("chart %q matching %s not found in %s index. (try 'helm repo update'). %s", chartName, version, r.Config.Name, err) } if len(cv.URLs) == 0 { - return u, r.Client, r.Config, fmt.Errorf("chart %q has no downloadable URLs", ref) + return u, r, fmt.Errorf("chart %q has no downloadable URLs", ref) } // TODO: Seems that picking first URL is not fully correct u, err = url.Parse(cv.URLs[0]) if err != nil { - return u, r.Client, r.Config, fmt.Errorf("invalid chart URL format: %s", ref) + return u, r, fmt.Errorf("invalid chart URL format: %s", ref) } // If the URL is relative (no scheme), prepend the chart repo's base URL if !u.IsAbs() { repoURL, err := url.Parse(rc.URL) if err != nil { - return repoURL, r.Client, r.Config, err + return repoURL, r, err } q := repoURL.Query() // We need a trailing slash for ResolveReference to work, but make sure there isn't already one repoURL.Path = strings.TrimSuffix(repoURL.Path, "/") + "/" u = repoURL.ResolveReference(u) u.RawQuery = q.Encode() - return u, r.Client, r.Config, err + return u, r, err } - return u, r.Client, r.Config, nil + return u, r, nil } // VerifyChart takes a path to a chart archive and a keyring, and verifies the chart. diff --git a/pkg/downloader/chart_downloader_test.go b/pkg/downloader/chart_downloader_test.go index 60028eb25..0100772e9 100644 --- a/pkg/downloader/chart_downloader_test.go +++ b/pkg/downloader/chart_downloader_test.go @@ -61,7 +61,7 @@ func TestResolveChartRef(t *testing.T) { } for _, tt := range tests { - u, _, _, err := c.ResolveChartVersion(tt.ref, tt.version) + u, _, err := c.ResolveChartVersion(tt.ref, tt.version) if err != nil { if tt.fail { continue @@ -195,7 +195,7 @@ func TestDownloadTo(t *testing.T) { Getters: getter.All(environment.EnvSettings{}), } cname := "/signtest-0.1.0.tgz" - where, v, err := c.DownloadTo(srv.URL()+cname, "", "", "", dest) + where, v, err := c.DownloadTo(srv.URL()+cname, "", dest) if err != nil { t.Error(err) return @@ -258,7 +258,7 @@ func TestDownloadTo_VerifyLater(t *testing.T) { Getters: getter.All(environment.EnvSettings{}), } cname := "/signtest-0.1.0.tgz" - where, _, err := c.DownloadTo(srv.URL()+cname, "", "", "", dest) + where, _, err := c.DownloadTo(srv.URL()+cname, "", dest) if err != nil { t.Error(err) return diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go index bac5c4823..89a839b54 100644 --- a/pkg/downloader/manager.go +++ b/pkg/downloader/manager.go @@ -197,14 +197,6 @@ func (m *Manager) downloadAll(deps []*chartutil.Dependency) error { return err } - dl := ChartDownloader{ - Out: m.Out, - Verify: m.Verify, - Keyring: m.Keyring, - HelmHome: m.HelmHome, - Getters: m.Getters, - } - destPath := filepath.Join(m.ChartPath, "charts") tmpPath := filepath.Join(m.ChartPath, "tmpcharts") @@ -251,7 +243,17 @@ func (m *Manager) downloadAll(deps []*chartutil.Dependency) error { break } - if _, _, err := dl.DownloadTo(churl, username, password, "", destPath); err != nil { + dl := ChartDownloader{ + Out: m.Out, + Verify: m.Verify, + Keyring: m.Keyring, + HelmHome: m.HelmHome, + Getters: m.Getters, + Username: username, + Password: password, + } + + if _, _, err := dl.DownloadTo(churl, "", destPath); err != nil { saveError = fmt.Errorf("could not download %s: %s", churl, err) break }