diff --git a/cmd/helm/dependency_build_test.go b/cmd/helm/dependency_build_test.go index 9e615a994..361d3ed6c 100644 --- a/cmd/helm/dependency_build_test.go +++ b/cmd/helm/dependency_build_test.go @@ -103,7 +103,7 @@ func TestDependencyBuildCmd(t *testing.T) { t.Fatal(err) } - i, err := repo.NewChartRepositoryIndexFromFile(dbc.helmhome.CacheIndex("test")) + i, err := repo.LoadIndexFile(dbc.helmhome.CacheIndex("test")) if err != nil { t.Fatal(err) } diff --git a/cmd/helm/dependency_update_test.go b/cmd/helm/dependency_update_test.go index 9c6171fe7..e47e494f5 100644 --- a/cmd/helm/dependency_update_test.go +++ b/cmd/helm/dependency_update_test.go @@ -88,7 +88,7 @@ func TestDependencyUpdateCmd(t *testing.T) { t.Fatal(err) } - i, err := repo.NewChartRepositoryIndexFromFile(duc.helmhome.CacheIndex("test")) + i, err := repo.LoadIndexFile(duc.helmhome.CacheIndex("test")) if err != nil { t.Fatal(err) } diff --git a/cmd/helm/downloader/chart_downloader.go b/cmd/helm/downloader/chart_downloader.go index 610eeca22..2b239d03d 100644 --- a/cmd/helm/downloader/chart_downloader.go +++ b/cmd/helm/downloader/chart_downloader.go @@ -136,14 +136,14 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, *r return nil, nil, fmt.Errorf("invalid chart URL format: %s", ref) } - rf, err := repo.LoadRepositoryFile(c.HelmHome.RepositoryFile()) + rf, err := repo.LoadRepositoriesFile(c.HelmHome.RepositoryFile()) if err != nil { return nil, nil, err } var ( chartName string - rc *repo.ChartRepositoryConfig + rc *repo.Entry ) if u.IsAbs() && len(u.Host) > 0 && len(u.Path) > 0 { // If it has a scheme and host and path, it's a full URL @@ -178,7 +178,7 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, *r } // Next, we need to load the index, and actually look up the chart. - i, err := repo.NewChartRepositoryIndexFromFile(c.HelmHome.CacheIndex(r.Config.Name)) + i, err := repo.LoadIndexFile(c.HelmHome.CacheIndex(r.Config.Name)) if err != nil { return nil, nil, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err) } @@ -252,7 +252,7 @@ func isTar(filename string) bool { return strings.ToLower(filepath.Ext(filename)) == ".tgz" } -func pickChartRepositoryConfigByName(name string, cfgs []*repo.ChartRepositoryConfig) (*repo.ChartRepositoryConfig, error) { +func pickChartRepositoryConfigByName(name string, cfgs []*repo.Entry) (*repo.Entry, error) { for _, rc := range cfgs { if rc.Name == name { if rc.URL == "" { @@ -264,7 +264,7 @@ func pickChartRepositoryConfigByName(name string, cfgs []*repo.ChartRepositoryCo return nil, fmt.Errorf("repo %s not found", name) } -func pickChartRepositoryConfigByURL(u string, cfgs []*repo.ChartRepositoryConfig) (*repo.ChartRepositoryConfig, error) { +func pickChartRepositoryConfigByURL(u string, cfgs []*repo.Entry) (*repo.Entry, error) { for _, rc := range cfgs { if rc.URL == u { return rc, nil diff --git a/cmd/helm/downloader/manager.go b/cmd/helm/downloader/manager.go index 5c9118888..a29dad99b 100644 --- a/cmd/helm/downloader/manager.go +++ b/cmd/helm/downloader/manager.go @@ -213,7 +213,7 @@ func (m *Manager) downloadAll(deps []*chartutil.Dependency) error { // hasAllRepos ensures that all of the referenced deps are in the local repo cache. func (m *Manager) hasAllRepos(deps []*chartutil.Dependency) error { - rf, err := repo.LoadRepositoryFile(m.HelmHome.RepositoryFile()) + rf, err := repo.LoadRepositoriesFile(m.HelmHome.RepositoryFile()) if err != nil { return err } @@ -244,7 +244,7 @@ func (m *Manager) hasAllRepos(deps []*chartutil.Dependency) error { // getRepoNames returns the repo names of the referenced deps which can be used to fetch the cahced index file. func (m *Manager) getRepoNames(deps []*chartutil.Dependency) (map[string]string, error) { - rf, err := repo.LoadRepositoryFile(m.HelmHome.RepositoryFile()) + rf, err := repo.LoadRepositoriesFile(m.HelmHome.RepositoryFile()) if err != nil { return nil, err } @@ -277,7 +277,7 @@ func (m *Manager) getRepoNames(deps []*chartutil.Dependency) (map[string]string, // UpdateRepositories updates all of the local repos to the latest. func (m *Manager) UpdateRepositories() error { - rf, err := repo.LoadRepositoryFile(m.HelmHome.RepositoryFile()) + rf, err := repo.LoadRepositoriesFile(m.HelmHome.RepositoryFile()) if err != nil { return err } @@ -291,7 +291,7 @@ func (m *Manager) UpdateRepositories() error { return nil } -func (m *Manager) parallelRepoUpdate(repos []*repo.ChartRepositoryConfig) error { +func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error { out := m.Out fmt.Fprintln(out, "Hang tight while we grab the latest from your chart repositories...") var wg sync.WaitGroup @@ -409,7 +409,7 @@ func (m *Manager) loadChartRepositories() (map[string]*repo.ChartRepository, err repoyaml := m.HelmHome.RepositoryFile() // Load repositories.yaml file - rf, err := repo.LoadRepositoryFile(repoyaml) + rf, err := repo.LoadRepositoriesFile(repoyaml) if err != nil { return indices, fmt.Errorf("failed to load %s: %s", repoyaml, err) } @@ -417,7 +417,7 @@ func (m *Manager) loadChartRepositories() (map[string]*repo.ChartRepository, err for _, re := range rf.Repositories { lname := re.Name cacheindex := m.HelmHome.CacheIndex(lname) - index, err := repo.NewChartRepositoryIndexFromFile(cacheindex) + index, err := repo.LoadIndexFile(cacheindex) if err != nil { return indices, err } diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index 7dfc34dae..682709f2d 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -254,12 +254,12 @@ func ensureTestHome(home helmpath.Home, t *testing.T) error { repoFile := home.RepositoryFile() if fi, err := os.Stat(repoFile); err != nil { - rf := repo.NewRepositoryFile() - rf.Add(&repo.ChartRepositoryConfig{ + rf := repo.NewRepoFile() + rf.Add(&repo.Entry{ Name: "charts", URL: "http://example.com/foo", Cache: "charts-index.yaml", - }, &repo.ChartRepositoryConfig{ + }, &repo.Entry{ Name: "local", URL: "http://localhost.com:7743/foo", Cache: "local-index.yaml", @@ -270,7 +270,7 @@ func ensureTestHome(home helmpath.Home, t *testing.T) error { } else if fi.IsDir() { return fmt.Errorf("%s must be a file, not a directory", repoFile) } - if r, err := repo.LoadRepositoryFile(repoFile); err == repo.ErrRepoOutOfDate { + if r, err := repo.LoadRepositoriesFile(repoFile); err == repo.ErrRepoOutOfDate { t.Log("Updating repository file format...") if err := r.WriteFile(repoFile, 0644); err != nil { return err @@ -279,7 +279,7 @@ func ensureTestHome(home helmpath.Home, t *testing.T) error { localRepoIndexFile := home.LocalRepository(localRepoIndexFilePath) if fi, err := os.Stat(localRepoIndexFile); err != nil { - i := repo.NewChartRepositoryIndex() + i := repo.NewIndexFile() if err := i.WriteFile(localRepoIndexFile, 0644); err != nil { return err } diff --git a/cmd/helm/init.go b/cmd/helm/init.go index 697e1bed7..b9e807cb0 100644 --- a/cmd/helm/init.go +++ b/cmd/helm/init.go @@ -179,7 +179,7 @@ func ensureDefaultRepos(home helmpath.Home, out io.Writer) error { repoFile := home.RepositoryFile() if fi, err := os.Stat(repoFile); err != nil { fmt.Fprintf(out, "Creating %s \n", repoFile) - f := repo.NewRepositoryFile() + f := repo.NewRepoFile() sr, err := initStableRepo(home.CacheIndex(stableRepository)) if err != nil { return err @@ -199,8 +199,8 @@ func ensureDefaultRepos(home helmpath.Home, out io.Writer) error { return nil } -func initStableRepo(cacheFile string) (*repo.ChartRepositoryConfig, error) { - c := repo.ChartRepositoryConfig{ +func initStableRepo(cacheFile string) (*repo.Entry, error) { + c := repo.Entry{ Name: stableRepository, URL: stableRepositoryURL, Cache: cacheFile, @@ -217,9 +217,9 @@ func initStableRepo(cacheFile string) (*repo.ChartRepositoryConfig, error) { return &c, nil } -func initLocalRepo(indexFile, cacheFile string) (*repo.ChartRepositoryConfig, error) { +func initLocalRepo(indexFile, cacheFile string) (*repo.Entry, error) { if fi, err := os.Stat(indexFile); err != nil { - i := repo.NewChartRepositoryIndex() + i := repo.NewIndexFile() if err := i.WriteFile(indexFile, 0644); err != nil { return nil, err } @@ -230,7 +230,7 @@ func initLocalRepo(indexFile, cacheFile string) (*repo.ChartRepositoryConfig, er return nil, fmt.Errorf("%s must be a file, not a directory", indexFile) } - return &repo.ChartRepositoryConfig{ + return &repo.Entry{ Name: localRepository, URL: localRepositoryURL, Cache: cacheFile, @@ -238,7 +238,7 @@ func initLocalRepo(indexFile, cacheFile string) (*repo.ChartRepositoryConfig, er } func ensureRepoFileFormat(file string, out io.Writer) error { - r, err := repo.LoadRepositoryFile(file) + r, err := repo.LoadRepositoriesFile(file) if err == repo.ErrRepoOutOfDate { fmt.Fprintln(out, "Updating repository file format...") if err := r.WriteFile(file, 0644); err != nil { diff --git a/cmd/helm/repo_add.go b/cmd/helm/repo_add.go index 2d9a62d1e..b349537a7 100644 --- a/cmd/helm/repo_add.go +++ b/cmd/helm/repo_add.go @@ -78,7 +78,7 @@ func (a *repoAddCmd) run() error { } func addRepository(name, url string, home helmpath.Home, certFile, keyFile, caFile string, noUpdate bool) error { - f, err := repo.LoadRepositoryFile(home.RepositoryFile()) + f, err := repo.LoadRepositoriesFile(home.RepositoryFile()) if err != nil { return err } @@ -88,7 +88,7 @@ func addRepository(name, url string, home helmpath.Home, certFile, keyFile, caFi } cif := home.CacheIndex(name) - c := repo.ChartRepositoryConfig{ + c := repo.Entry{ Name: name, Cache: cif, URL: url, diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index b823777f7..7c5342177 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -84,7 +84,7 @@ func TestRepoAdd(t *testing.T) { t.Error(err) } - f, err := repo.LoadRepositoryFile(hh.RepositoryFile()) + f, err := repo.LoadRepositoriesFile(hh.RepositoryFile()) if err != nil { t.Error(err) } diff --git a/cmd/helm/repo_index.go b/cmd/helm/repo_index.go index 925dffc17..ad5808946 100644 --- a/cmd/helm/repo_index.go +++ b/cmd/helm/repo_index.go @@ -83,12 +83,12 @@ func (i *repoIndexCmd) run() error { func index(dir, url, mergeTo string) error { out := filepath.Join(dir, "index.yaml") - i, err := repo.NewChartRepositoryIndexFromDirectory(dir, url) + i, err := repo.IndexDirectory(dir, url) if err != nil { return err } if mergeTo != "" { - i2, err := repo.NewChartRepositoryIndexFromFile(mergeTo) + i2, err := repo.LoadIndexFile(mergeTo) if err != nil { return fmt.Errorf("Merge failed: %s", err) } diff --git a/cmd/helm/repo_index_test.go b/cmd/helm/repo_index_test.go index b3e37e4b1..bd1010dd7 100644 --- a/cmd/helm/repo_index_test.go +++ b/cmd/helm/repo_index_test.go @@ -53,7 +53,7 @@ func TestRepoIndexCmd(t *testing.T) { destIndex := filepath.Join(dir, "index.yaml") - index, err := repo.NewChartRepositoryIndexFromFile(destIndex) + index, err := repo.LoadIndexFile(destIndex) if err != nil { t.Fatal(err) } @@ -94,7 +94,7 @@ func TestRepoIndexCmd(t *testing.T) { t.Error(err) } - index, err = repo.NewChartRepositoryIndexFromFile(destIndex) + index, err = repo.LoadIndexFile(destIndex) if err != nil { t.Fatal(err) } diff --git a/cmd/helm/repo_list.go b/cmd/helm/repo_list.go index a4f7edec5..a3816facd 100644 --- a/cmd/helm/repo_list.go +++ b/cmd/helm/repo_list.go @@ -51,7 +51,7 @@ func newRepoListCmd(out io.Writer) *cobra.Command { } func (a *repoListCmd) run() error { - f, err := repo.LoadRepositoryFile(a.home.RepositoryFile()) + f, err := repo.LoadRepositoriesFile(a.home.RepositoryFile()) if err != nil { return err } diff --git a/cmd/helm/repo_remove.go b/cmd/helm/repo_remove.go index ad2a9c188..f7671cab0 100644 --- a/cmd/helm/repo_remove.go +++ b/cmd/helm/repo_remove.go @@ -62,7 +62,7 @@ func (r *repoRemoveCmd) run() error { func removeRepoLine(out io.Writer, name string, home helmpath.Home) error { repoFile := home.RepositoryFile() - r, err := repo.LoadRepositoryFile(repoFile) + r, err := repo.LoadRepositoriesFile(repoFile) if err != nil { return err } diff --git a/cmd/helm/repo_remove_test.go b/cmd/helm/repo_remove_test.go index 1e0a4c382..12f534972 100644 --- a/cmd/helm/repo_remove_test.go +++ b/cmd/helm/repo_remove_test.go @@ -69,7 +69,7 @@ func TestRepoRemove(t *testing.T) { t.Errorf("Error cache file was not removed for repository %s", testName) } - f, err := repo.LoadRepositoryFile(hh.RepositoryFile()) + f, err := repo.LoadRepositoriesFile(hh.RepositoryFile()) if err != nil { t.Error(err) } diff --git a/cmd/helm/repo_update.go b/cmd/helm/repo_update.go index c08d840fb..8dfab9a5d 100644 --- a/cmd/helm/repo_update.go +++ b/cmd/helm/repo_update.go @@ -65,7 +65,7 @@ func newRepoUpdateCmd(out io.Writer) *cobra.Command { } func (u *repoUpdateCmd) run() error { - f, err := repo.LoadRepositoryFile(u.home.RepositoryFile()) + f, err := repo.LoadRepositoriesFile(u.home.RepositoryFile()) if err != nil { return err } diff --git a/cmd/helm/repo_update_test.go b/cmd/helm/repo_update_test.go index f7be052b6..97f023f13 100644 --- a/cmd/helm/repo_update_test.go +++ b/cmd/helm/repo_update_test.go @@ -80,7 +80,7 @@ func TestUpdateCharts(t *testing.T) { t.Fatal(err) } - r, err := repo.NewChartRepository(&repo.ChartRepositoryConfig{ + r, err := repo.NewChartRepository(&repo.Entry{ Name: "charts", URL: ts.URL(), Cache: hh.CacheIndex("charts"), diff --git a/cmd/helm/resolver/resolver.go b/cmd/helm/resolver/resolver.go index dfa1e74a7..480cea674 100644 --- a/cmd/helm/resolver/resolver.go +++ b/cmd/helm/resolver/resolver.go @@ -60,7 +60,7 @@ func (r *Resolver) Resolve(reqs *chartutil.Requirements, repoNames map[string]st return nil, fmt.Errorf("dependency %q has an invalid version/constraint format: %s", d.Name, err) } - repoIndex, err := repo.NewChartRepositoryIndexFromFile(r.helmhome.CacheIndex(repoNames[d.Name])) + repoIndex, err := repo.LoadIndexFile(r.helmhome.CacheIndex(repoNames[d.Name])) if err != nil { return nil, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err) } diff --git a/cmd/helm/search.go b/cmd/helm/search.go index 4804f6b92..a1d57adb0 100644 --- a/cmd/helm/search.go +++ b/cmd/helm/search.go @@ -110,7 +110,7 @@ func (s *searchCmd) formatSearchResults(res []*search.Result) string { func (s *searchCmd) buildIndex() (*search.Index, error) { // Load the repositories.yaml - rf, err := repo.LoadRepositoryFile(s.helmhome.RepositoryFile()) + rf, err := repo.LoadRepositoriesFile(s.helmhome.RepositoryFile()) if err != nil { return nil, err } @@ -119,7 +119,7 @@ func (s *searchCmd) buildIndex() (*search.Index, error) { for _, re := range rf.Repositories { n := re.Name f := s.helmhome.CacheIndex(n) - ind, err := repo.NewChartRepositoryIndexFromFile(f) + ind, err := repo.LoadIndexFile(f) if err != nil { fmt.Fprintf(s.out, "WARNING: Repo %q is corrupt or missing. Try 'helm repo update'.", n) continue diff --git a/cmd/helm/search/search.go b/cmd/helm/search/search.go index 5675332df..4d394e0f5 100644 --- a/cmd/helm/search/search.go +++ b/cmd/helm/search/search.go @@ -61,7 +61,7 @@ func NewIndex() *Index { const verSep = "$$" // AddRepo adds a repository index to the search index. -func (i *Index) AddRepo(rname string, ind *repo.ChartRepositoryIndex, all bool) { +func (i *Index) AddRepo(rname string, ind *repo.IndexFile, all bool) { for name, ref := range ind.Entries { if len(ref) == 0 { // Skip chart names that have zero releases. diff --git a/cmd/helm/search/search_test.go b/cmd/helm/search/search_test.go index 1a607fdc7..7f5d29409 100644 --- a/cmd/helm/search/search_test.go +++ b/cmd/helm/search/search_test.go @@ -95,8 +95,8 @@ var indexfileEntries = map[string]repo.ChartVersions{ func loadTestIndex(t *testing.T, all bool) *Index { i := NewIndex() - i.AddRepo("testing", &repo.ChartRepositoryIndex{Entries: indexfileEntries}, all) - i.AddRepo("ztesting", &repo.ChartRepositoryIndex{Entries: map[string]repo.ChartVersions{ + i.AddRepo("testing", &repo.IndexFile{Entries: indexfileEntries}, all) + i.AddRepo("ztesting", &repo.IndexFile{Entries: map[string]repo.ChartVersions{ "pinta": { { URLs: []string{"http://example.com/charts/pinta-2.0.0.tgz"}, diff --git a/pkg/repo/chartrepo.go b/pkg/repo/chartrepo.go index a2991ce79..6e2a3676c 100644 --- a/pkg/repo/chartrepo.go +++ b/pkg/repo/chartrepo.go @@ -32,8 +32,8 @@ import ( "k8s.io/helm/pkg/urlutil" ) -// ChartRepositoryConfig represents a collection of parameters for chart repository -type ChartRepositoryConfig struct { +// Entry represents a collection of parameters for chart repository +type Entry struct { Name string `json:"name"` Cache string `json:"cache"` URL string `json:"url"` @@ -44,18 +44,19 @@ type ChartRepositoryConfig struct { // ChartRepository represents a chart repository type ChartRepository struct { - Config *ChartRepositoryConfig + Config *Entry ChartPaths []string - IndexFile *ChartRepositoryIndex + IndexFile *IndexFile Client *http.Client } +// Getter is an interface to support GET to the specified URL. type Getter interface { Get(url string) (*http.Response, error) } // NewChartRepository constructs ChartRepository -func NewChartRepository(cfg *ChartRepositoryConfig) (*ChartRepository, error) { +func NewChartRepository(cfg *Entry) (*ChartRepository, error) { var client *http.Client if cfg.CertFile != "" && cfg.KeyFile != "" && cfg.CAFile != "" { tlsConf, err := tlsutil.NewClientTLS(cfg.CertFile, cfg.KeyFile, cfg.CAFile) @@ -81,11 +82,12 @@ func NewChartRepository(cfg *ChartRepositoryConfig) (*ChartRepository, error) { return &ChartRepository{ Config: cfg, - IndexFile: NewChartRepositoryIndex(), + IndexFile: NewIndexFile(), Client: client, }, nil } +// Get issues a GET using configured client to the specified URL. func (r *ChartRepository) Get(url string) (*http.Response, error) { resp, err := r.Client.Get(url) if err != nil { @@ -112,7 +114,7 @@ func (r *ChartRepository) Load() error { filepath.Walk(r.Config.Name, func(path string, f os.FileInfo, err error) error { if !f.IsDir() { if strings.Contains(f.Name(), "-index.yaml") { - i, err := NewChartRepositoryIndexFromFile(path) + i, err := LoadIndexFile(path) if err != nil { return nil } diff --git a/pkg/repo/chartrepo_test.go b/pkg/repo/chartrepo_test.go index b9a83a4c2..7148e39a4 100644 --- a/pkg/repo/chartrepo_test.go +++ b/pkg/repo/chartrepo_test.go @@ -32,7 +32,7 @@ const ( ) func TestLoadChartRepository(t *testing.T) { - r, err := NewChartRepository(&ChartRepositoryConfig{ + r, err := NewChartRepository(&Entry{ Name: testRepository, URL: testURL, }) @@ -64,7 +64,7 @@ func TestLoadChartRepository(t *testing.T) { } func TestIndex(t *testing.T) { - r, err := NewChartRepository(&ChartRepositoryConfig{ + r, err := NewChartRepository(&Entry{ Name: testRepository, URL: testURL, }) @@ -82,7 +82,7 @@ func TestIndex(t *testing.T) { } tempIndexPath := filepath.Join(testRepository, indexPath) - actual, err := NewChartRepositoryIndexFromFile(tempIndexPath) + actual, err := LoadIndexFile(tempIndexPath) defer os.Remove(tempIndexPath) // clean up if err != nil { t.Errorf("Error loading index file %v", err) @@ -94,14 +94,14 @@ func TestIndex(t *testing.T) { if err != nil { t.Errorf("Error performing re-index: %s\n", err) } - second, err := NewChartRepositoryIndexFromFile(tempIndexPath) + second, err := LoadIndexFile(tempIndexPath) if err != nil { t.Errorf("Error re-loading index file %v", err) } verifyIndex(t, second) } -func verifyIndex(t *testing.T, actual *ChartRepositoryIndex) { +func verifyIndex(t *testing.T, actual *IndexFile) { var empty time.Time if actual.Generated == empty { t.Errorf("Generated should be greater than 0: %s", actual.Generated) diff --git a/pkg/repo/index.go b/pkg/repo/index.go index 1676b118e..148caac4a 100644 --- a/pkg/repo/index.go +++ b/pkg/repo/index.go @@ -74,35 +74,17 @@ func (c ChartVersions) Less(a, b int) bool { return i.LessThan(j) } -// ChartRepositoryIndex represents the index file in a chart repository -type ChartRepositoryIndex struct { +// IndexFile represents the index file in a chart repository +type IndexFile struct { APIVersion string `json:"apiVersion"` Generated time.Time `json:"generated"` Entries map[string]ChartVersions `json:"entries"` PublicKeys []string `json:"publicKeys,omitempty"` } -// ChartVersion represents a chart entry in the ChartRepositoryIndex -type ChartVersion struct { - *chart.Metadata - URLs []string `json:"urls"` - Created time.Time `json:"created,omitempty"` - Removed bool `json:"removed,omitempty"` - Digest string `json:"digest,omitempty"` -} - -// unversionedEntry represents a deprecated pre-Alpha.5 format. -// -// This will be removed prior to v2.0.0 -type unversionedEntry struct { - Checksum string `json:"checksum"` - URL string `json:"url"` - Chartfile *chart.Metadata `json:"chartfile"` -} - -// NewChartRepositoryIndex initializes an index. -func NewChartRepositoryIndex() *ChartRepositoryIndex { - return &ChartRepositoryIndex{ +// NewIndexFile initializes an index. +func NewIndexFile() *IndexFile { + return &IndexFile{ APIVersion: APIVersionV1, Generated: time.Now(), Entries: map[string]ChartVersions{}, @@ -110,8 +92,8 @@ func NewChartRepositoryIndex() *ChartRepositoryIndex { } } -// NewChartRepositoryIndexFromFile takes a file at the given path and returns an ChartRepositoryIndex object -func NewChartRepositoryIndexFromFile(path string) (*ChartRepositoryIndex, error) { +// LoadIndexFile takes a file at the given path and returns an IndexFile object +func LoadIndexFile(path string) (*IndexFile, error) { b, err := ioutil.ReadFile(path) if err != nil { return nil, err @@ -119,89 +101,9 @@ func NewChartRepositoryIndexFromFile(path string) (*ChartRepositoryIndex, error) return loadIndex(b) } -// NewChartRepositoryIndexFromDirectory reads a (flat) directory and generates an index. -// -// It indexes only charts that have been packaged (*.tgz). -// -// The index returned will be in an unsorted state -func NewChartRepositoryIndexFromDirectory(dir, baseURL string) (*ChartRepositoryIndex, error) { - archives, err := filepath.Glob(filepath.Join(dir, "*.tgz")) - if err != nil { - return nil, err - } - index := NewChartRepositoryIndex() - for _, arch := range archives { - fname := filepath.Base(arch) - c, err := chartutil.Load(arch) - if err != nil { - // Assume this is not a chart. - continue - } - hash, err := provenance.DigestFile(arch) - if err != nil { - return index, err - } - index.Add(c.Metadata, fname, baseURL, hash) - } - return index, nil -} - -// loadIndex loads an index file and does minimal validity checking. -// -// This will fail if API Version is not set (ErrNoAPIVersion) or if the unmarshal fails. -func loadIndex(data []byte) (*ChartRepositoryIndex, error) { - i := &ChartRepositoryIndex{} - if err := yaml.Unmarshal(data, i); err != nil { - return i, err - } - if i.APIVersion == "" { - // When we leave Beta, we should remove legacy support and just - // return this error: - //return i, ErrNoAPIVersion - return loadUnversionedIndex(data) - } - return i, nil -} - -// loadUnversionedIndex loads a pre-Alpha.5 index.yaml file. -// -// This format is deprecated. This function will be removed prior to v2.0.0. -func loadUnversionedIndex(data []byte) (*ChartRepositoryIndex, error) { - fmt.Fprintln(os.Stderr, "WARNING: Deprecated index file format. Try 'helm repo update'") - i := map[string]unversionedEntry{} - - // This gets around an error in the YAML parser. Instead of parsing as YAML, - // we convert to JSON, and then decode again. - var err error - data, err = yaml.YAMLToJSON(data) - if err != nil { - return nil, err - } - if err := json.Unmarshal(data, &i); err != nil { - return nil, err - } - - if len(i) == 0 { - return nil, ErrNoAPIVersion - } - ni := NewChartRepositoryIndex() - for n, item := range i { - if item.Chartfile == nil || item.Chartfile.Name == "" { - parts := strings.Split(n, "-") - ver := "" - if len(parts) > 1 { - ver = strings.TrimSuffix(parts[1], ".tgz") - } - item.Chartfile = &chart.Metadata{Name: parts[0], Version: ver} - } - ni.Add(item.Chartfile, item.URL, "", item.Checksum) - } - return ni, nil -} - // Add adds a file to the index // This can leave the index in an unsorted state -func (i ChartRepositoryIndex) Add(md *chart.Metadata, filename, baseURL, digest string) { +func (i IndexFile) Add(md *chart.Metadata, filename, baseURL, digest string) { u := filename if baseURL != "" { var err error @@ -225,7 +127,7 @@ func (i ChartRepositoryIndex) Add(md *chart.Metadata, filename, baseURL, digest } // Has returns true if the index has an entry for a chart with the given name and exact version. -func (i ChartRepositoryIndex) Has(name, version string) bool { +func (i IndexFile) Has(name, version string) bool { _, err := i.Get(name, version) return err == nil } @@ -236,7 +138,7 @@ func (i ChartRepositoryIndex) Has(name, version string) bool { // the most recent release for every version is in the 0th slot in the // Entries.ChartVersions array. That way, tooling can predict the newest // version without needing to parse SemVers. -func (i ChartRepositoryIndex) SortEntries() { +func (i IndexFile) SortEntries() { for _, versions := range i.Entries { sort.Sort(sort.Reverse(versions)) } @@ -245,7 +147,7 @@ func (i ChartRepositoryIndex) SortEntries() { // Get returns the ChartVersion for the given name. // // If version is empty, this will return the chart with the highest version. -func (i ChartRepositoryIndex) Get(name, version string) (*ChartVersion, error) { +func (i IndexFile) Get(name, version string) (*ChartVersion, error) { vs, ok := i.Entries[name] if !ok { return nil, ErrNoChartName @@ -268,7 +170,7 @@ func (i ChartRepositoryIndex) Get(name, version string) (*ChartVersion, error) { // WriteFile writes an index file to the given destination path. // // The mode on the file is set to 'mode'. -func (i ChartRepositoryIndex) WriteFile(dest string, mode os.FileMode) error { +func (i IndexFile) WriteFile(dest string, mode os.FileMode) error { b, err := yaml.Marshal(i) if err != nil { return err @@ -284,7 +186,7 @@ func (i ChartRepositoryIndex) WriteFile(dest string, mode os.FileMode) error { // In all other cases, the existing record is preserved. // // This can leave the index in an unsorted state -func (i *ChartRepositoryIndex) Merge(f *ChartRepositoryIndex) { +func (i *IndexFile) Merge(f *IndexFile) { for _, cvs := range f.Entries { for _, cv := range cvs { if !i.Has(cv.Name, cv.Version) { @@ -294,3 +196,103 @@ func (i *ChartRepositoryIndex) Merge(f *ChartRepositoryIndex) { } } } + +// Need both JSON and YAML annotations until we get rid of gopkg.in/yaml.v2 + +// ChartVersion represents a chart entry in the IndexFile +type ChartVersion struct { + *chart.Metadata + URLs []string `json:"urls"` + Created time.Time `json:"created,omitempty"` + Removed bool `json:"removed,omitempty"` + Digest string `json:"digest,omitempty"` +} + +// IndexDirectory reads a (flat) directory and generates an index. +// +// It indexes only charts that have been packaged (*.tgz). +// +// The index returned will be in an unsorted state +func IndexDirectory(dir, baseURL string) (*IndexFile, error) { + archives, err := filepath.Glob(filepath.Join(dir, "*.tgz")) + if err != nil { + return nil, err + } + index := NewIndexFile() + for _, arch := range archives { + fname := filepath.Base(arch) + c, err := chartutil.Load(arch) + if err != nil { + // Assume this is not a chart. + continue + } + hash, err := provenance.DigestFile(arch) + if err != nil { + return index, err + } + index.Add(c.Metadata, fname, baseURL, hash) + } + return index, nil +} + +// loadIndex loads an index file and does minimal validity checking. +// +// This will fail if API Version is not set (ErrNoAPIVersion) or if the unmarshal fails. +func loadIndex(data []byte) (*IndexFile, error) { + i := &IndexFile{} + if err := yaml.Unmarshal(data, i); err != nil { + return i, err + } + if i.APIVersion == "" { + // When we leave Beta, we should remove legacy support and just + // return this error: + //return i, ErrNoAPIVersion + return loadUnversionedIndex(data) + } + return i, nil +} + +// unversionedEntry represents a deprecated pre-Alpha.5 format. +// +// This will be removed prior to v2.0.0 +type unversionedEntry struct { + Checksum string `json:"checksum"` + URL string `json:"url"` + Chartfile *chart.Metadata `json:"chartfile"` +} + +// loadUnversionedIndex loads a pre-Alpha.5 index.yaml file. +// +// This format is deprecated. This function will be removed prior to v2.0.0. +func loadUnversionedIndex(data []byte) (*IndexFile, error) { + fmt.Fprintln(os.Stderr, "WARNING: Deprecated index file format. Try 'helm repo update'") + i := map[string]unversionedEntry{} + + // This gets around an error in the YAML parser. Instead of parsing as YAML, + // we convert to JSON, and then decode again. + var err error + data, err = yaml.YAMLToJSON(data) + if err != nil { + return nil, err + } + if err := json.Unmarshal(data, &i); err != nil { + return nil, err + } + + if len(i) == 0 { + return nil, ErrNoAPIVersion + } + ni := NewIndexFile() + for n, item := range i { + if item.Chartfile == nil || item.Chartfile.Name == "" { + parts := strings.Split(n, "-") + ver := "" + if len(parts) > 1 { + ver = strings.TrimSuffix(parts[1], ".tgz") + } + item.Chartfile = &chart.Metadata{Name: parts[0], Version: ver} + } + ni.Add(item.Chartfile, item.URL, "", item.Checksum) + } + return ni, nil +} diff --git a/pkg/repo/index_test.go b/pkg/repo/index_test.go index 7ba4da6c5..2f23950f1 100644 --- a/pkg/repo/index_test.go +++ b/pkg/repo/index_test.go @@ -33,7 +33,7 @@ const ( ) func TestIndexFile(t *testing.T) { - i := NewChartRepositoryIndex() + i := NewIndexFile() i.Add(&chart.Metadata{Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890") i.Add(&chart.Metadata{Name: "cutter", Version: "0.1.1"}, "cutter-0.1.1.tgz", "http://example.com/charts", "sha256:1234567890abc") i.Add(&chart.Metadata{Name: "cutter", Version: "0.1.0"}, "cutter-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890abc") @@ -75,7 +75,7 @@ func TestLoadIndex(t *testing.T) { } func TestLoadIndexFile(t *testing.T) { - i, err := NewChartRepositoryIndexFromFile(testfile) + i, err := LoadIndexFile(testfile) if err != nil { t.Fatal(err) } @@ -83,13 +83,13 @@ func TestLoadIndexFile(t *testing.T) { } func TestMerge(t *testing.T) { - ind1 := NewChartRepositoryIndex() + ind1 := NewIndexFile() ind1.Add(&chart.Metadata{ Name: "dreadnought", Version: "0.1.0", }, "dreadnought-0.1.0.tgz", "http://example.com", "aaaa") - ind2 := NewChartRepositoryIndex() + ind2 := NewIndexFile() ind2.Add(&chart.Metadata{ Name: "dreadnought", Version: "0.2.0", @@ -133,7 +133,7 @@ func TestDownloadIndexFile(t *testing.T) { defer os.RemoveAll(dirName) indexFilePath := filepath.Join(dirName, testRepo+"-index.yaml") - r, err := NewChartRepository(&ChartRepositoryConfig{ + r, err := NewChartRepository(&Entry{ Name: testRepo, URL: srv.URL, Cache: indexFilePath, @@ -164,7 +164,7 @@ func TestDownloadIndexFile(t *testing.T) { verifyLocalIndex(t, i) } -func verifyLocalIndex(t *testing.T, i *ChartRepositoryIndex) { +func verifyLocalIndex(t *testing.T, i *IndexFile) { numEntries := len(i.Entries) if numEntries != 2 { t.Errorf("Expected 2 entries in index file but got %d", numEntries) @@ -264,7 +264,7 @@ func verifyLocalIndex(t *testing.T, i *ChartRepositoryIndex) { func TestIndexDirectory(t *testing.T) { dir := "testdata/repository" - index, err := NewChartRepositoryIndexFromDirectory(dir, "http://localhost:8080") + index, err := IndexDirectory(dir, "http://localhost:8080") if err != nil { t.Fatal(err) } @@ -314,7 +314,7 @@ func TestLoadUnversionedIndex(t *testing.T) { } func TestIndexAdd(t *testing.T) { - i := NewChartRepositoryIndex() + i := NewIndexFile() i.Add(&chart.Metadata{Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890") if i.Entries["clipper"][0].URLs[0] != "http://example.com/charts/clipper-0.1.0.tgz" { diff --git a/pkg/repo/local.go b/pkg/repo/local.go index 932811be2..f13a4d0ac 100644 --- a/pkg/repo/local.go +++ b/pkg/repo/local.go @@ -82,7 +82,7 @@ func (s *RepositoryServer) htmlIndex(w http.ResponseWriter, r *http.Request) { t := htemplate.Must(htemplate.New("index.html").Parse(indexHTMLTemplate)) // load index lrp := filepath.Join(s.RepoPath, "index.yaml") - i, err := NewChartRepositoryIndexFromFile(lrp) + i, err := LoadIndexFile(lrp) if err != nil { http.Error(w, err.Error(), 500) return @@ -107,7 +107,7 @@ func AddChartToLocalRepo(ch *chart.Chart, path string) error { // Reindex adds an entry to the index file at the given path func Reindex(ch *chart.Chart, path string) error { name := ch.Metadata.Name + "-" + ch.Metadata.Version - y, err := NewChartRepositoryIndexFromFile(path) + y, err := LoadIndexFile(path) if err != nil { return err } diff --git a/pkg/repo/repo.go b/pkg/repo/repo.go index bfc7d4c1d..cbf54c572 100644 --- a/pkg/repo/repo.go +++ b/pkg/repo/repo.go @@ -30,35 +30,35 @@ import ( // is fixable. var ErrRepoOutOfDate = errors.New("repository file is out of date") -// RepositoryFile represents the repositories.yaml file in $HELM_HOME -type RepositoryFile struct { - APIVersion string `json:"apiVersion"` - Generated time.Time `json:"generated"` - Repositories []*ChartRepositoryConfig `json:"repositories"` +// RepoFile represents the repositories.yaml file in $HELM_HOME +type RepoFile struct { + APIVersion string `json:"apiVersion"` + Generated time.Time `json:"generated"` + Repositories []*Entry `json:"repositories"` } -// NewRepositoryFile generates an empty repositories file. +// NewRepoFile generates an empty repositories file. // // Generated and APIVersion are automatically set. -func NewRepositoryFile() *RepositoryFile { - return &RepositoryFile{ +func NewRepoFile() *RepoFile { + return &RepoFile{ APIVersion: APIVersionV1, Generated: time.Now(), - Repositories: []*ChartRepositoryConfig{}, + Repositories: []*Entry{}, } } -// LoadRepositoryFile takes a file at the given path and returns a RepositoryFile object +// LoadRepositoriesFile takes a file at the given path and returns a RepoFile object // -// If this returns ErrRepoOutOfDate, it also returns a recovered RepositoryFile that +// If this returns ErrRepoOutOfDate, it also returns a recovered RepoFile that // can be saved as a replacement to the out of date file. -func LoadRepositoryFile(path string) (*RepositoryFile, error) { +func LoadRepositoriesFile(path string) (*RepoFile, error) { b, err := ioutil.ReadFile(path) if err != nil { return nil, err } - r := &RepositoryFile{} + r := &RepoFile{} err = yaml.Unmarshal(b, r) if err != nil { return nil, err @@ -70,9 +70,9 @@ func LoadRepositoryFile(path string) (*RepositoryFile, error) { if err = yaml.Unmarshal(b, &m); err != nil { return nil, err } - r := NewRepositoryFile() + r := NewRepoFile() for k, v := range m { - r.Add(&ChartRepositoryConfig{ + r.Add(&Entry{ Name: k, URL: v, Cache: fmt.Sprintf("%s-index.yaml", k), @@ -85,13 +85,13 @@ func LoadRepositoryFile(path string) (*RepositoryFile, error) { } // Add adds one or more repo entries to a repo file. -func (r *RepositoryFile) Add(re ...*ChartRepositoryConfig) { +func (r *RepoFile) Add(re ...*Entry) { r.Repositories = append(r.Repositories, re...) } // Update attempts to replace one or more repo entries in a repo file. If an // entry with the same name doesn't exist in the repo file it will add it. -func (r *RepositoryFile) Update(re ...*ChartRepositoryConfig) { +func (r *RepoFile) Update(re ...*Entry) { for _, target := range re { found := false for j, repo := range r.Repositories { @@ -108,7 +108,7 @@ func (r *RepositoryFile) Update(re ...*ChartRepositoryConfig) { } // Has returns true if the given name is already a repository name. -func (r *RepositoryFile) Has(name string) bool { +func (r *RepoFile) Has(name string) bool { for _, rf := range r.Repositories { if rf.Name == name { return true @@ -118,8 +118,8 @@ func (r *RepositoryFile) Has(name string) bool { } // Remove removes the entry from the list of repositories. -func (r *RepositoryFile) Remove(name string) bool { - cp := []*ChartRepositoryConfig{} +func (r *RepoFile) Remove(name string) bool { + cp := []*Entry{} found := false for _, rf := range r.Repositories { if rf.Name == name { @@ -133,7 +133,7 @@ func (r *RepositoryFile) Remove(name string) bool { } // WriteFile writes a repositories file to the given path. -func (r *RepositoryFile) WriteFile(path string, perm os.FileMode) error { +func (r *RepoFile) WriteFile(path string, perm os.FileMode) error { data, err := yaml.Marshal(r) if err != nil { return err diff --git a/pkg/repo/repo_test.go b/pkg/repo/repo_test.go index 451e035aa..c0b0e6da7 100644 --- a/pkg/repo/repo_test.go +++ b/pkg/repo/repo_test.go @@ -21,14 +21,14 @@ import "testing" const testRepositoriesFile = "testdata/repositories.yaml" func TestRepoFile(t *testing.T) { - rf := NewRepositoryFile() + rf := NewRepoFile() rf.Add( - &ChartRepositoryConfig{ + &Entry{ Name: "stable", URL: "https://example.com/stable/charts", Cache: "stable-index.yaml", }, - &ChartRepositoryConfig{ + &Entry{ Name: "incubator", URL: "https://example.com/incubator", Cache: "incubator-index.yaml", @@ -59,21 +59,21 @@ func TestRepoFile(t *testing.T) { } func TestNewRepositoriesFile(t *testing.T) { - expects := NewRepositoryFile() + expects := NewRepoFile() expects.Add( - &ChartRepositoryConfig{ + &Entry{ Name: "stable", URL: "https://example.com/stable/charts", Cache: "stable-index.yaml", }, - &ChartRepositoryConfig{ + &Entry{ Name: "incubator", URL: "https://example.com/incubator", Cache: "incubator-index.yaml", }, ) - repofile, err := LoadRepositoryFile(testRepositoriesFile) + repofile, err := LoadRepositoriesFile(testRepositoriesFile) if err != nil { t.Errorf("%q could not be loaded: %s", testRepositoriesFile, err) } @@ -97,7 +97,7 @@ func TestNewRepositoriesFile(t *testing.T) { } func TestNewPreV1RepositoriesFile(t *testing.T) { - r, err := LoadRepositoryFile("testdata/old-repositories.yaml") + r, err := LoadRepositoriesFile("testdata/old-repositories.yaml") if err != nil && err != ErrRepoOutOfDate { t.Fatal(err) } diff --git a/pkg/repo/repotest/server.go b/pkg/repo/repotest/server.go index 07973a692..4bb1f57a9 100644 --- a/pkg/repo/repotest/server.go +++ b/pkg/repo/repotest/server.go @@ -114,7 +114,7 @@ func (s *Server) CopyCharts(origin string) ([]string, error) { // CreateIndex will read docroot and generate an index.yaml file. func (s *Server) CreateIndex() error { // generate the index - index, err := repo.NewChartRepositoryIndexFromDirectory(s.docroot, s.URL()) + index, err := repo.IndexDirectory(s.docroot, s.URL()) if err != nil { return err } @@ -160,8 +160,8 @@ func (s *Server) LinkIndices() error { // setTestingRepository sets up a testing repository.yaml with only the given name/URL. func setTestingRepository(home helmpath.Home, name, url string) error { - r := repo.NewRepositoryFile() - r.Add(&repo.ChartRepositoryConfig{ + r := repo.NewRepoFile() + r.Add(&repo.Entry{ Name: name, URL: url, Cache: home.CacheIndex(name), diff --git a/pkg/repo/repotest/server_test.go b/pkg/repo/repotest/server_test.go index 99917fc3b..1d4c78e41 100644 --- a/pkg/repo/repotest/server_test.go +++ b/pkg/repo/repotest/server_test.go @@ -77,7 +77,7 @@ func TestServer(t *testing.T) { return } - m := repo.NewChartRepositoryIndex() + m := repo.NewIndexFile() if err := yaml.Unmarshal(data, m); err != nil { t.Error(err) return