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

@ -44,12 +44,13 @@ var deprecatedRepos = map[string]string{
} }
type repoAddOptions struct { type repoAddOptions struct {
name string name string
url string url string
username string username string
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,9 +36,10 @@ 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
repoFile string update func([]*repo.ChartRepository, io.Writer, bool)
repoCache string repoFile string
repoCache string
} }
func newRepoUpdateCmd(out io.Writer) *cobra.Command { func newRepoUpdateCmd(out io.Writer) *cobra.Command {
@ -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") {

@ -63,14 +63,15 @@ Repositories are managed with 'helm repo' commands.
const searchMaxScore = 25 const searchMaxScore = 25
type searchRepoOptions struct { type searchRepoOptions struct {
versions bool versions bool
regexp bool regexp bool
devel bool devel bool
version string hideValidationWarnings bool
maxColWidth uint version string
repoFile string maxColWidth uint
repoCacheDir string repoFile string
outputFormat output.Format repoCacheDir string
outputFormat output.Format
} }
func newSearchRepoCmd(out io.Writer) *cobra.Command { func newSearchRepoCmd(out io.Writer) *cobra.Command {
@ -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 {
log.Printf("skipping loading invalid entry for chart %q %q from %s: %s", name, cvs[idx].Version, source, err) if !hideValidationWarnings {
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