|
|
|
@ -275,7 +275,11 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error {
|
|
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(m.Out, "Saving %d charts\n", len(deps))
|
|
|
|
fmt.Fprintf(m.Out, "Saving %d charts\n", len(deps))
|
|
|
|
var saveError error
|
|
|
|
var saveError error
|
|
|
|
churls := make(map[string]struct{})
|
|
|
|
// Downloads are deduplicated by digest as well as URL, so an archive that
|
|
|
|
|
|
|
|
// another repository listed under a different digest, or none, is still
|
|
|
|
|
|
|
|
// checked against this one.
|
|
|
|
|
|
|
|
type download struct{ url, digest string }
|
|
|
|
|
|
|
|
churls := make(map[download]struct{})
|
|
|
|
for _, dep := range deps {
|
|
|
|
for _, dep := range deps {
|
|
|
|
// No repository means the chart is in charts directory
|
|
|
|
// No repository means the chart is in charts directory
|
|
|
|
if dep.Repository == "" {
|
|
|
|
if dep.Repository == "" {
|
|
|
|
@ -318,13 +322,13 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error {
|
|
|
|
|
|
|
|
|
|
|
|
// Any failure to resolve/download a chart should fail:
|
|
|
|
// Any failure to resolve/download a chart should fail:
|
|
|
|
// https://github.com/helm/helm/issues/1439
|
|
|
|
// https://github.com/helm/helm/issues/1439
|
|
|
|
churl, username, password, insecureSkipTLSVerify, passCredentialsAll, caFile, certFile, keyFile, err := m.findChartURL(dep.Name, dep.Version, dep.Repository, repos)
|
|
|
|
churl, digest, username, password, insecureSkipTLSVerify, passCredentialsAll, caFile, certFile, keyFile, err := m.findChartURL(dep.Name, dep.Version, dep.Repository, repos)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
saveError = fmt.Errorf("could not find %s: %w", churl, err)
|
|
|
|
saveError = fmt.Errorf("could not find %s: %w", churl, err)
|
|
|
|
break
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if _, ok := churls[churl]; ok {
|
|
|
|
if _, ok := churls[download{churl, digest}]; ok {
|
|
|
|
fmt.Fprintf(m.Out, "Already downloaded %s from repo %s\n", dep.Name, dep.Repository)
|
|
|
|
fmt.Fprintf(m.Out, "Already downloaded %s from repo %s\n", dep.Name, dep.Repository)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -340,6 +344,7 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error {
|
|
|
|
ContentCache: m.ContentCache,
|
|
|
|
ContentCache: m.ContentCache,
|
|
|
|
RegistryClient: m.RegistryClient,
|
|
|
|
RegistryClient: m.RegistryClient,
|
|
|
|
Getters: m.Getters,
|
|
|
|
Getters: m.Getters,
|
|
|
|
|
|
|
|
IndexDigest: digest,
|
|
|
|
Options: []getter.Option{
|
|
|
|
Options: []getter.Option{
|
|
|
|
getter.WithBasicAuth(username, password),
|
|
|
|
getter.WithBasicAuth(username, password),
|
|
|
|
getter.WithPassCredentialsAll(passCredentialsAll),
|
|
|
|
getter.WithPassCredentialsAll(passCredentialsAll),
|
|
|
|
@ -364,7 +369,7 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error {
|
|
|
|
break
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
churls[churl] = struct{}{}
|
|
|
|
churls[download{churl, digest}] = struct{}{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: this should probably be refactored to be a []error, so we can capture and provide more information rather than "last error wins".
|
|
|
|
// TODO: this should probably be refactored to be a []error, so we can capture and provide more information rather than "last error wins".
|
|
|
|
@ -722,9 +727,9 @@ func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error {
|
|
|
|
// repoURL is the repository to search
|
|
|
|
// repoURL is the repository to search
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// If it finds a URL that is "relative", it will prepend the repoURL.
|
|
|
|
// If it finds a URL that is "relative", it will prepend the repoURL.
|
|
|
|
func (m *Manager) findChartURL(name, version, repoURL string, repos map[string]*repo.ChartRepository) (url, username, password string, insecureSkipTLSVerify, passCredentialsAll bool, caFile, certFile, keyFile string, err error) {
|
|
|
|
func (m *Manager) findChartURL(name, version, repoURL string, repos map[string]*repo.ChartRepository) (url, digest, username, password string, insecureSkipTLSVerify, passCredentialsAll bool, caFile, certFile, keyFile string, err error) {
|
|
|
|
if registry.IsOCI(repoURL) {
|
|
|
|
if registry.IsOCI(repoURL) {
|
|
|
|
return fmt.Sprintf("%s/%s:%s", repoURL, name, version), "", "", false, false, "", "", "", nil
|
|
|
|
return fmt.Sprintf("%s/%s:%s", repoURL, name, version), "", "", "", false, false, "", "", "", nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, cr := range repos {
|
|
|
|
for _, cr := range repos {
|
|
|
|
@ -735,17 +740,18 @@ func (m *Manager) findChartURL(name, version, repoURL string, repos map[string]*
|
|
|
|
entry, err = findEntryByName(name, cr)
|
|
|
|
entry, err = findEntryByName(name, cr)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
// TODO: Consider refactoring this function to reduce the number of returned values while preserving behavior.
|
|
|
|
// TODO: Consider refactoring this function to reduce the number of returned values while preserving behavior.
|
|
|
|
return url, username, password, insecureSkipTLSVerify, passCredentialsAll, caFile, certFile, keyFile, err
|
|
|
|
return url, digest, username, password, insecureSkipTLSVerify, passCredentialsAll, caFile, certFile, keyFile, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var ve *repo.ChartVersion
|
|
|
|
var ve *repo.ChartVersion
|
|
|
|
ve, err = findVersionedEntry(version, entry)
|
|
|
|
ve, err = findVersionedEntry(version, entry)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return url, username, password, insecureSkipTLSVerify, passCredentialsAll, caFile, certFile, keyFile, err
|
|
|
|
return url, digest, username, password, insecureSkipTLSVerify, passCredentialsAll, caFile, certFile, keyFile, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
url, err = repo.ResolveReferenceURL(repoURL, ve.URLs[0])
|
|
|
|
url, err = repo.ResolveReferenceURL(repoURL, ve.URLs[0])
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return url, username, password, insecureSkipTLSVerify, passCredentialsAll, caFile, certFile, keyFile, err
|
|
|
|
return url, digest, username, password, insecureSkipTLSVerify, passCredentialsAll, caFile, certFile, keyFile, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
digest = ve.Digest
|
|
|
|
username = cr.Config.Username
|
|
|
|
username = cr.Config.Username
|
|
|
|
password = cr.Config.Password
|
|
|
|
password = cr.Config.Password
|
|
|
|
passCredentialsAll = cr.Config.PassCredentialsAll
|
|
|
|
passCredentialsAll = cr.Config.PassCredentialsAll
|
|
|
|
@ -754,14 +760,14 @@ func (m *Manager) findChartURL(name, version, repoURL string, repos map[string]*
|
|
|
|
certFile = cr.Config.CertFile
|
|
|
|
certFile = cr.Config.CertFile
|
|
|
|
keyFile = cr.Config.KeyFile
|
|
|
|
keyFile = cr.Config.KeyFile
|
|
|
|
|
|
|
|
|
|
|
|
return url, username, password, insecureSkipTLSVerify, passCredentialsAll, caFile, certFile, keyFile, err
|
|
|
|
return url, digest, username, password, insecureSkipTLSVerify, passCredentialsAll, caFile, certFile, keyFile, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
url, err = repo.FindChartInRepoURL(repoURL, name, m.Getters, repo.WithChartVersion(version), repo.WithClientTLS(certFile, keyFile, caFile))
|
|
|
|
url, digest, err = repo.FindChartInRepoURLWithDigest(repoURL, name, m.Getters, repo.WithChartVersion(version), repo.WithClientTLS(certFile, keyFile, caFile))
|
|
|
|
if err == nil {
|
|
|
|
if err == nil {
|
|
|
|
return url, username, password, false, false, "", "", "", nil
|
|
|
|
return url, digest, username, password, false, false, "", "", "", nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
err = fmt.Errorf("chart %s not found in %s: %w", name, repoURL, err)
|
|
|
|
err = fmt.Errorf("chart %s not found in %s: %w", name, repoURL, err)
|
|
|
|
return url, username, password, false, false, "", "", "", err
|
|
|
|
return url, digest, username, password, false, false, "", "", "", err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// findEntryByName finds an entry in the chart repository whose name matches the given name.
|
|
|
|
// findEntryByName finds an entry in the chart repository whose name matches the given name.
|
|
|
|
|