github.com/latiif/helm@v2.15.0+incompatible/cmd/helm/repo_update.go (about)

     1  /*
     2  Copyright The Helm Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  	"sync"
    24  
    25  	"github.com/spf13/cobra"
    26  
    27  	"k8s.io/helm/cmd/helm/installer"
    28  	"k8s.io/helm/pkg/getter"
    29  	"k8s.io/helm/pkg/helm/helmpath"
    30  	"k8s.io/helm/pkg/repo"
    31  )
    32  
    33  const updateDesc = `
    34  Update gets the latest information about charts from the respective chart repositories.
    35  Information is cached locally, where it is used by commands like 'helm search'.
    36  
    37  'helm update' is the deprecated form of 'helm repo update'. It will be removed in
    38  future releases.
    39  
    40  You can specify the name of a repository you want to update.
    41  
    42  	$ helm repo update <repo_name>
    43  
    44  To update all the repositories, use 'helm repo update'.
    45  
    46  `
    47  
    48  var errNoRepositories = errors.New("no repositories found. You must add one before updating")
    49  var errNoRepositoriesMatchingRepoName = errors.New("no repositories found matching the provided name. Verify if the repo exists")
    50  
    51  type repoUpdateCmd struct {
    52  	update func([]*repo.ChartRepository, io.Writer, helmpath.Home, bool) error
    53  	home   helmpath.Home
    54  	out    io.Writer
    55  	strict bool
    56  	name   string
    57  }
    58  
    59  func newRepoUpdateCmd(out io.Writer) *cobra.Command {
    60  	u := &repoUpdateCmd{
    61  		out:    out,
    62  		update: updateCharts,
    63  	}
    64  	cmd := &cobra.Command{
    65  		Use:     "update [REPO_NAME]",
    66  		Aliases: []string{"up"},
    67  		Short:   "Update information of available charts locally from chart repositories",
    68  		Long:    updateDesc,
    69  		RunE: func(cmd *cobra.Command, args []string) error {
    70  			u.home = settings.Home
    71  			if len(args) != 0 {
    72  				u.name = args[0]
    73  			}
    74  			return u.run()
    75  		},
    76  	}
    77  
    78  	f := cmd.Flags()
    79  	f.BoolVar(&u.strict, "strict", false, "Fail on update warnings")
    80  
    81  	return cmd
    82  }
    83  
    84  func (u *repoUpdateCmd) run() error {
    85  	f, err := repo.LoadRepositoriesFile(u.home.RepositoryFile())
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	if len(f.Repositories) == 0 {
    91  		return errNoRepositories
    92  	}
    93  	var repos []*repo.ChartRepository
    94  	for _, cfg := range f.Repositories {
    95  		r, err := repo.NewChartRepository(cfg, getter.All(settings))
    96  		if err != nil {
    97  			return err
    98  		}
    99  		if len(u.name) != 0 {
   100  			if cfg.Name == u.name {
   101  				repos = append(repos, r)
   102  				break
   103  			} else {
   104  				continue
   105  			}
   106  		} else {
   107  			repos = append(repos, r)
   108  		}
   109  	}
   110  
   111  	if len(repos) == 0 {
   112  		return errNoRepositoriesMatchingRepoName
   113  	}
   114  
   115  	return u.update(repos, u.out, u.home, u.strict)
   116  }
   117  
   118  func updateCharts(repos []*repo.ChartRepository, out io.Writer, home helmpath.Home, strict bool) error {
   119  	fmt.Fprintln(out, "Hang tight while we grab the latest from your chart repositories...")
   120  	var (
   121  		errorCounter int
   122  		wg           sync.WaitGroup
   123  		mu           sync.Mutex
   124  	)
   125  	for _, re := range repos {
   126  		wg.Add(1)
   127  		go func(re *repo.ChartRepository) {
   128  			defer wg.Done()
   129  			if re.Config.Name == installer.LocalRepository {
   130  				mu.Lock()
   131  				fmt.Fprintf(out, "...Skip %s chart repository\n", re.Config.Name)
   132  				mu.Unlock()
   133  				return
   134  			}
   135  			err := re.DownloadIndexFile(home.Cache())
   136  			if err != nil {
   137  				mu.Lock()
   138  				errorCounter++
   139  				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)
   140  				mu.Unlock()
   141  			} else {
   142  				mu.Lock()
   143  				fmt.Fprintf(out, "...Successfully got an update from the %q chart repository\n", re.Config.Name)
   144  				mu.Unlock()
   145  			}
   146  		}(re)
   147  	}
   148  	wg.Wait()
   149  
   150  	if errorCounter != 0 && strict {
   151  		return errors.New("Update Failed. Check log for details")
   152  	}
   153  
   154  	fmt.Fprintln(out, "Update Complete.")
   155  	return nil
   156  }