diff --git a/cmd/helm/repo.go b/cmd/helm/repo.go index fe093a385..86909c11e 100644 --- a/cmd/helm/repo.go +++ b/cmd/helm/repo.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "io/ioutil" @@ -44,11 +45,16 @@ func runRepoAdd(cmd *cobra.Command, args []string) error { if err := checkArgsLength(2, len(args), "name for the chart repository", "the url of the chart repository"); err != nil { return err } + name, url := args[0], args[1] - err := insertRepoLine(args[0], args[1]) - if err != nil { + if err := downloadCacheFile(name, url); err != nil { + return errors.New("Oops! Looks like " + url + " is not a valid chart repository or cannot be reached\n") + } + + if err := insertRepoLine(name, url); err != nil { return err } + fmt.Println(args[0] + " has been added to your repositories") return nil } diff --git a/cmd/helm/update.go b/cmd/helm/update.go new file mode 100644 index 000000000..4528d8f09 --- /dev/null +++ b/cmd/helm/update.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "strings" + "sync" + + "github.com/spf13/cobra" + "gopkg.in/yaml.v2" + + "github.com/kubernetes/helm/pkg/repo" +) + +var verboseUpdate bool + +var updateCommand = &cobra.Command{ + Use: "update", + Short: "Update information on available charts in the chart repositories.", + RunE: runUpdate, +} + +func init() { + updateCommand.Flags().BoolVar(&verboseUpdate, "verbose", false, "verbose error messages") + RootCommand.AddCommand(updateCommand) +} + +func runUpdate(cmd *cobra.Command, args []string) error { + + f, err := repo.LoadRepositoriesFile(repositoriesFile()) + if err != nil { + return err + } + + updateCharts(f.Repositories, verboseUpdate) + return nil +} + +func updateCharts(repos map[string]string, verbose bool) { + fmt.Println("Hang tight while we grab the latest from your chart repositories...") + var wg sync.WaitGroup + for name, url := range repos { + wg.Add(1) + go func(n, u string) { + defer wg.Done() + err := downloadCacheFile(n, u) + if err != nil { + updateErr := "...Unable to get an update from the " + n + " chart repository" + if verbose { + updateErr = updateErr + ": " + err.Error() + } + fmt.Println(updateErr) + } else { + fmt.Println("...Successfully got an update from the " + n + " chart repository") + } + }(name, url) + } + wg.Wait() + fmt.Println("Update Complete. Happy Helming!") +} + +func downloadCacheFile(name, url string) error { + var cacheURL string + + cacheURL = strings.TrimSuffix(url, "/") + "/cache.yaml" + resp, err := http.Get(cacheURL) + if err != nil { + return err + } + defer resp.Body.Close() + + var cacheFile *os.File + var r repo.RepoFile + + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + if err := yaml.Unmarshal(b, &r); err != nil { + return err + } + + cacheFile, err = os.Create(cacheDirectory(name + "-cache.yaml")) + if err != nil { + return err + } + + if _, err := io.Copy(cacheFile, resp.Body); err != nil { + return err + } + + return nil +}