pull/9604/merge
rcousineau-xandr 4 years ago committed by GitHub
commit f614231ed3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -50,6 +50,7 @@ type repoAddOptions struct {
password string password string
forceUpdate bool forceUpdate bool
allowDeprecatedRepos bool allowDeprecatedRepos bool
hideValidationWarnings bool
certFile string certFile string
keyFile string keyFile string
@ -91,6 +92,7 @@ func newRepoAddCmd(out io.Writer) *cobra.Command {
f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&o.insecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the repository") f.BoolVar(&o.insecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the repository")
f.BoolVar(&o.allowDeprecatedRepos, "allow-deprecated-repos", false, "by default, this command will not allow adding official repos that have been permanently deleted. This disables that behavior") f.BoolVar(&o.allowDeprecatedRepos, "allow-deprecated-repos", false, "by default, this command will not allow adding official repos that have been permanently deleted. This disables that behavior")
f.BoolVar(&o.hideValidationWarnings, "hide-validation-warnings", false, "hide validation warnings while indexing repository")
return cmd return cmd
} }
@ -187,7 +189,12 @@ func (o *repoAddOptions) run(out io.Writer) error {
if o.repoCache != "" { if o.repoCache != "" {
r.CachePath = o.repoCache r.CachePath = o.repoCache
} }
if _, err := r.DownloadIndexFile(); err != nil { if o.hideValidationWarnings {
_, err = r.DownloadIndexFileHideValidationWarnings()
} else {
_, err = r.DownloadIndexFile()
}
if err != nil {
return errors.Wrapf(err, "looks like %q is not a valid chart repository or cannot be reached", o.url) return errors.Wrapf(err, "looks like %q is not a valid chart repository or cannot be reached", o.url)
} }

@ -24,7 +24,6 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm/require"
"helm.sh/helm/v3/pkg/getter" "helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/repo" "helm.sh/helm/v3/pkg/repo"
) )
@ -37,7 +36,8 @@ Information is cached locally, where it is used by commands like 'helm search'.
var errNoRepositories = errors.New("no repositories found. You must add one before updating") var errNoRepositories = errors.New("no repositories found. You must add one before updating")
type repoUpdateOptions struct { type repoUpdateOptions struct {
update func([]*repo.ChartRepository, io.Writer) hideValidationWarnings bool
update func([]*repo.ChartRepository, io.Writer, bool)
repoFile string repoFile string
repoCache string repoCache string
} }
@ -50,18 +50,21 @@ func newRepoUpdateCmd(out io.Writer) *cobra.Command {
Aliases: []string{"up"}, Aliases: []string{"up"},
Short: "update information of available charts locally from chart repositories", Short: "update information of available charts locally from chart repositories",
Long: updateDesc, Long: updateDesc,
Args: require.NoArgs,
ValidArgsFunction: noCompletions, ValidArgsFunction: noCompletions,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
o.repoFile = settings.RepositoryConfig o.repoFile = settings.RepositoryConfig
o.repoCache = settings.RepositoryCache o.repoCache = settings.RepositoryCache
return o.run(out) return o.run(out, args)
}, },
} }
f := cmd.Flags()
f.BoolVar(&o.hideValidationWarnings, "hide-validation-warnings", false, "hide validation warnings while indexing repository")
return cmd return cmd
} }
func (o *repoUpdateOptions) run(out io.Writer) error { func (o *repoUpdateOptions) run(out io.Writer, args []string) error {
f, err := repo.LoadFile(o.repoFile) f, err := repo.LoadFile(o.repoFile)
switch { switch {
case isNotExist(err): case isNotExist(err):
@ -84,18 +87,24 @@ func (o *repoUpdateOptions) run(out io.Writer) error {
repos = append(repos, r) repos = append(repos, r)
} }
o.update(repos, out) o.update(repos, out, o.hideValidationWarnings)
return nil return nil
} }
func updateCharts(repos []*repo.ChartRepository, out io.Writer) { func updateCharts(repos []*repo.ChartRepository, out io.Writer, hideValidationWarnings bool) {
fmt.Fprintln(out, "Hang tight while we grab the latest from your chart repositories...") fmt.Fprintln(out, "Hang tight while we grab the latest from your chart repositories...")
var wg sync.WaitGroup var wg sync.WaitGroup
for _, re := range repos { for _, re := range repos {
wg.Add(1) wg.Add(1)
go func(re *repo.ChartRepository) { go func(re *repo.ChartRepository) {
defer wg.Done() defer wg.Done()
if _, err := re.DownloadIndexFile(); err != nil { var err error
if hideValidationWarnings {
_, err = re.DownloadIndexFileHideValidationWarnings()
} else {
_, err = re.DownloadIndexFile()
}
if err != nil {
fmt.Fprintf(out, "...Unable to get an update from the %q chart repository (%s):\n\t%s\n", re.Config.Name, re.Config.URL, err) fmt.Fprintf(out, "...Unable to get an update from the %q chart repository (%s):\n\t%s\n", re.Config.Name, re.Config.URL, err)
} else { } else {
fmt.Fprintf(out, "...Successfully got an update from the %q chart repository\n", re.Config.Name) fmt.Fprintf(out, "...Successfully got an update from the %q chart repository\n", re.Config.Name)

@ -35,7 +35,7 @@ func TestUpdateCmd(t *testing.T) {
var out bytes.Buffer var out bytes.Buffer
// Instead of using the HTTP updater, we provide our own for this test. // Instead of using the HTTP updater, we provide our own for this test.
// The TestUpdateCharts test verifies the HTTP behavior independently. // The TestUpdateCharts test verifies the HTTP behavior independently.
updater := func(repos []*repo.ChartRepository, out io.Writer) { updater := func(repos []*repo.ChartRepository, out io.Writer, hideValidationWarnings bool) {
for _, re := range repos { for _, re := range repos {
fmt.Fprintln(out, re.Config.Name) fmt.Fprintln(out, re.Config.Name)
} }
@ -44,7 +44,7 @@ func TestUpdateCmd(t *testing.T) {
update: updater, update: updater,
repoFile: "testdata/repositories.yaml", repoFile: "testdata/repositories.yaml",
} }
if err := o.run(&out); err != nil { if err := o.run(&out, []string{}); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -71,7 +71,7 @@ func TestUpdateCustomCacheCmd(t *testing.T) {
repoCache: cachePath, repoCache: cachePath,
} }
b := ioutil.Discard b := ioutil.Discard
if err := o.run(b); err != nil { if err := o.run(b, []string{}); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := os.Stat(filepath.Join(cachePath, "test-index.yaml")); err != nil { if _, err := os.Stat(filepath.Join(cachePath, "test-index.yaml")); err != nil {
@ -98,7 +98,7 @@ func TestUpdateCharts(t *testing.T) {
} }
b := bytes.NewBuffer(nil) b := bytes.NewBuffer(nil)
updateCharts([]*repo.ChartRepository{r}, b) updateCharts([]*repo.ChartRepository{r}, b, false)
got := b.String() got := b.String()
if strings.Contains(got, "Unable to get an update") { if strings.Contains(got, "Unable to get an update") {

@ -66,6 +66,7 @@ type searchRepoOptions struct {
versions bool versions bool
regexp bool regexp bool
devel bool devel bool
hideValidationWarnings bool
version string version string
maxColWidth uint maxColWidth uint
repoFile string repoFile string
@ -91,6 +92,7 @@ func newSearchRepoCmd(out io.Writer) *cobra.Command {
f.BoolVarP(&o.regexp, "regexp", "r", false, "use regular expressions for searching repositories you have added") f.BoolVarP(&o.regexp, "regexp", "r", false, "use regular expressions for searching repositories you have added")
f.BoolVarP(&o.versions, "versions", "l", false, "show the long listing, with each version of each chart on its own line, for repositories you have added") f.BoolVarP(&o.versions, "versions", "l", false, "show the long listing, with each version of each chart on its own line, for repositories you have added")
f.BoolVar(&o.devel, "devel", false, "use development versions (alpha, beta, and release candidate releases), too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored") f.BoolVar(&o.devel, "devel", false, "use development versions (alpha, beta, and release candidate releases), too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored")
f.BoolVar(&o.hideValidationWarnings, "hide-validation-warnings", false, "hide validation warnings while indexing repository")
f.StringVar(&o.version, "version", "", "search using semantic versioning constraints on repositories you have added") f.StringVar(&o.version, "version", "", "search using semantic versioning constraints on repositories you have added")
f.UintVar(&o.maxColWidth, "max-col-width", 50, "maximum column width for output table") f.UintVar(&o.maxColWidth, "max-col-width", 50, "maximum column width for output table")
bindOutputFlag(cmd, &o.outputFormat) bindOutputFlag(cmd, &o.outputFormat)
@ -184,7 +186,12 @@ func (o *searchRepoOptions) buildIndex() (*search.Index, error) {
for _, re := range rf.Repositories { for _, re := range rf.Repositories {
n := re.Name n := re.Name
f := filepath.Join(o.repoCacheDir, helmpath.CacheIndexFile(n)) f := filepath.Join(o.repoCacheDir, helmpath.CacheIndexFile(n))
ind, err := repo.LoadIndexFile(f) var ind *repo.IndexFile
if o.hideValidationWarnings {
ind, err = repo.LoadIndexFileHideValidationWarnings(f)
} else {
ind, err = repo.LoadIndexFile(f)
}
if err != nil { if err != nil {
warning("Repo %q is corrupt or missing. Try 'helm repo update'.", n) warning("Repo %q is corrupt or missing. Try 'helm repo update'.", n)
warning("%s", err) warning("%s", err)

@ -115,6 +115,23 @@ func (r *ChartRepository) Load() error {
// DownloadIndexFile fetches the index from a repository. // DownloadIndexFile fetches the index from a repository.
func (r *ChartRepository) DownloadIndexFile() (string, error) { func (r *ChartRepository) DownloadIndexFile() (string, error) {
return r.downloadIndexFile(false)
}
func (r *ChartRepository) DownloadIndexFileHideValidationWarnings() (string, error) {
return r.downloadIndexFile(true)
}
// Index generates an index for the chart repository and writes an index.yaml file.
func (r *ChartRepository) Index() error {
err := r.generateIndex()
if err != nil {
return err
}
return r.saveIndexFile()
}
func (r *ChartRepository) downloadIndexFile(hideValidationWarnings bool) (string, error) {
parsedURL, err := url.Parse(r.Config.URL) parsedURL, err := url.Parse(r.Config.URL)
if err != nil { if err != nil {
return "", err return "", err
@ -139,7 +156,7 @@ func (r *ChartRepository) DownloadIndexFile() (string, error) {
return "", err return "", err
} }
indexFile, err := loadIndex(index, r.Config.URL) indexFile, err := loadIndex(index, r.Config.URL, hideValidationWarnings)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -159,15 +176,6 @@ func (r *ChartRepository) DownloadIndexFile() (string, error) {
return fname, ioutil.WriteFile(fname, index, 0644) return fname, ioutil.WriteFile(fname, index, 0644)
} }
// Index generates an index for the chart repository and writes an index.yaml file.
func (r *ChartRepository) Index() error {
err := r.generateIndex()
if err != nil {
return err
}
return r.saveIndexFile()
}
func (r *ChartRepository) saveIndexFile() error { func (r *ChartRepository) saveIndexFile() error {
index, err := yaml.Marshal(r.IndexFile) index, err := yaml.Marshal(r.IndexFile)
if err != nil { if err != nil {

@ -106,7 +106,20 @@ func LoadIndexFile(path string) (*IndexFile, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
i, err := loadIndex(b, path) i, err := loadIndex(b, path, false)
if err != nil {
return nil, errors.Wrapf(err, "error loading %s", path)
}
return i, nil
}
// LoadIndexFile takes a file at the given path and returns an IndexFile object
func LoadIndexFileHideValidationWarnings(path string) (*IndexFile, error) {
b, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
i, err := loadIndex(b, path, true)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error loading %s", path) return nil, errors.Wrapf(err, "error loading %s", path)
} }
@ -324,7 +337,7 @@ func IndexDirectory(dir, baseURL string) (*IndexFile, error) {
// //
// The source parameter is only used for logging. // The source parameter is only used for logging.
// This will fail if API Version is not set (ErrNoAPIVersion) or if the unmarshal fails. // This will fail if API Version is not set (ErrNoAPIVersion) or if the unmarshal fails.
func loadIndex(data []byte, source string) (*IndexFile, error) { func loadIndex(data []byte, source string, hideValidationWarnings bool) (*IndexFile, error) {
i := &IndexFile{} i := &IndexFile{}
if err := yaml.UnmarshalStrict(data, i); err != nil { if err := yaml.UnmarshalStrict(data, i); err != nil {
return i, err return i, err
@ -336,7 +349,9 @@ func loadIndex(data []byte, source string) (*IndexFile, error) {
cvs[idx].APIVersion = chart.APIVersionV1 cvs[idx].APIVersion = chart.APIVersionV1
} }
if err := cvs[idx].Validate(); err != nil { if err := cvs[idx].Validate(); err != nil {
if !hideValidationWarnings {
log.Printf("skipping loading invalid entry for chart %q %q from %s: %s", name, cvs[idx].Version, source, err) log.Printf("skipping loading invalid entry for chart %q %q from %s: %s", name, cvs[idx].Version, source, err)
}
cvs = append(cvs[:idx], cvs[idx+1:]...) cvs = append(cvs[:idx], cvs[idx+1:]...)
} }
} }

@ -147,7 +147,7 @@ func TestLoadIndex(t *testing.T) {
// TestLoadIndex_Duplicates is a regression to make sure that we don't non-deterministically allow duplicate packages. // TestLoadIndex_Duplicates is a regression to make sure that we don't non-deterministically allow duplicate packages.
func TestLoadIndex_Duplicates(t *testing.T) { func TestLoadIndex_Duplicates(t *testing.T) {
if _, err := loadIndex([]byte(indexWithDuplicates), "indexWithDuplicates"); err == nil { if _, err := loadIndex([]byte(indexWithDuplicates), "indexWithDuplicates", false); err == nil {
t.Errorf("Expected an error when duplicate entries are present") t.Errorf("Expected an error when duplicate entries are present")
} }
} }

Loading…
Cancel
Save