Merge pull request #13578 from gjenkins8/rm_chart_repo_load_func

refactor: Remove ChartRepository `[]ChartPaths`
pull/30777/head
Matt Farina 5 months ago committed by GitHub
commit a842140ef6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -29,12 +29,9 @@ import (
"strings"
"github.com/pkg/errors"
"sigs.k8s.io/yaml"
"helm.sh/helm/v4/pkg/chart/v2/loader"
"helm.sh/helm/v4/pkg/getter"
"helm.sh/helm/v4/pkg/helmpath"
"helm.sh/helm/v4/pkg/provenance"
)
// Entry represents a collection of parameters for chart repository
@ -52,11 +49,10 @@ type Entry struct {
// ChartRepository represents a chart repository
type ChartRepository struct {
Config *Entry
ChartPaths []string
IndexFile *IndexFile
Client getter.Getter
CachePath string
Config *Entry
IndexFile *IndexFile
Client getter.Getter
CachePath string
}
// NewChartRepository constructs ChartRepository
@ -79,40 +75,6 @@ func NewChartRepository(cfg *Entry, getters getter.Providers) (*ChartRepository,
}, nil
}
// Load loads a directory of charts as if it were a repository.
//
// It requires the presence of an index.yaml file in the directory.
//
// Deprecated: remove in Helm 4.
func (r *ChartRepository) Load() error {
dirInfo, err := os.Stat(r.Config.Name)
if err != nil {
return err
}
if !dirInfo.IsDir() {
return errors.Errorf("%q is not a directory", r.Config.Name)
}
// FIXME: Why are we recursively walking directories?
// FIXME: Why are we not reading the repositories.yaml to figure out
// what repos to use?
filepath.Walk(r.Config.Name, func(path string, f os.FileInfo, _ error) error {
if !f.IsDir() {
if strings.Contains(f.Name(), "-index.yaml") {
i, err := LoadIndexFile(path)
if err != nil {
return err
}
r.IndexFile = i
} else if strings.HasSuffix(f.Name(), ".tgz") {
r.ChartPaths = append(r.ChartPaths, path)
}
}
return nil
})
return nil
}
// DownloadIndexFile fetches the index from a repository.
func (r *ChartRepository) DownloadIndexFile() (string, error) {
indexURL, err := ResolveReferenceURL(r.Config.URL, "index.yaml")
@ -156,46 +118,6 @@ func (r *ChartRepository) DownloadIndexFile() (string, error) {
return fname, os.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 {
index, err := yaml.Marshal(r.IndexFile)
if err != nil {
return err
}
return os.WriteFile(filepath.Join(r.Config.Name, indexPath), index, 0644)
}
func (r *ChartRepository) generateIndex() error {
for _, path := range r.ChartPaths {
ch, err := loader.Load(path)
if err != nil {
return err
}
digest, err := provenance.DigestFile(path)
if err != nil {
return err
}
if !r.IndexFile.Has(ch.Name(), ch.Metadata.Version) {
if err := r.IndexFile.MustAdd(ch.Metadata, path, r.Config.URL, digest); err != nil {
return errors.Wrapf(err, "failed adding to %s to index", path)
}
}
// TODO: If a chart exists, but has a different Digest, should we error?
}
r.IndexFile.SortEntries()
return nil
}
type findChartInRepoURLOptions struct {
Username string
Password string

@ -21,8 +21,6 @@ import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"reflect"
"runtime"
"strings"
"testing"
@ -30,87 +28,10 @@ import (
"sigs.k8s.io/yaml"
chart "helm.sh/helm/v4/pkg/chart/v2"
"helm.sh/helm/v4/pkg/cli"
"helm.sh/helm/v4/pkg/getter"
)
const (
testRepository = "testdata/repository"
testURL = "http://example-charts.com"
)
func TestLoadChartRepository(t *testing.T) {
r, err := NewChartRepository(&Entry{
Name: testRepository,
URL: testURL,
}, getter.All(&cli.EnvSettings{}))
if err != nil {
t.Errorf("Problem creating chart repository from %s: %v", testRepository, err)
}
if err := r.Load(); err != nil {
t.Errorf("Problem loading chart repository from %s: %v", testRepository, err)
}
paths := []string{
filepath.Join(testRepository, "frobnitz-1.2.3.tgz"),
filepath.Join(testRepository, "sprocket-1.1.0.tgz"),
filepath.Join(testRepository, "sprocket-1.2.0.tgz"),
filepath.Join(testRepository, "universe/zarthal-1.0.0.tgz"),
}
if r.Config.Name != testRepository {
t.Errorf("Expected %s as Name but got %s", testRepository, r.Config.Name)
}
if !reflect.DeepEqual(r.ChartPaths, paths) {
t.Errorf("Expected %#v but got %#v\n", paths, r.ChartPaths)
}
if r.Config.URL != testURL {
t.Errorf("Expected url for chart repository to be %s but got %s", testURL, r.Config.URL)
}
}
func TestIndex(t *testing.T) {
r, err := NewChartRepository(&Entry{
Name: testRepository,
URL: testURL,
}, getter.All(&cli.EnvSettings{}))
if err != nil {
t.Errorf("Problem creating chart repository from %s: %v", testRepository, err)
}
if err := r.Load(); err != nil {
t.Errorf("Problem loading chart repository from %s: %v", testRepository, err)
}
err = r.Index()
if err != nil {
t.Errorf("Error performing index: %v\n", err)
}
tempIndexPath := filepath.Join(testRepository, indexPath)
actual, err := LoadIndexFile(tempIndexPath)
defer os.Remove(tempIndexPath) // clean up
if err != nil {
t.Errorf("Error loading index file %v", err)
}
verifyIndex(t, actual)
// Re-index and test again.
err = r.Index()
if err != nil {
t.Errorf("Error performing re-index: %s\n", err)
}
second, err := LoadIndexFile(tempIndexPath)
if err != nil {
t.Errorf("Error re-loading index file %v", err)
}
verifyIndex(t, second)
}
type CustomGetter struct {
repoUrls []string
}
@ -169,97 +90,6 @@ func TestIndexCustomSchemeDownload(t *testing.T) {
}
}
func verifyIndex(t *testing.T, actual *IndexFile) {
var empty time.Time
if actual.Generated.Equal(empty) {
t.Errorf("Generated should be greater than 0: %s", actual.Generated)
}
if actual.APIVersion != APIVersionV1 {
t.Error("Expected v1 API")
}
entries := actual.Entries
if numEntries := len(entries); numEntries != 3 {
t.Errorf("Expected 3 charts to be listed in index file but got %v", numEntries)
}
expects := map[string]ChartVersions{
"frobnitz": {
{
Metadata: &chart.Metadata{
Name: "frobnitz",
Version: "1.2.3",
},
},
},
"sprocket": {
{
Metadata: &chart.Metadata{
Name: "sprocket",
Version: "1.2.0",
},
},
{
Metadata: &chart.Metadata{
Name: "sprocket",
Version: "1.1.0",
},
},
},
"zarthal": {
{
Metadata: &chart.Metadata{
Name: "zarthal",
Version: "1.0.0",
},
},
},
}
for name, versions := range expects {
got, ok := entries[name]
if !ok {
t.Errorf("Could not find %q entry", name)
continue
}
if len(versions) != len(got) {
t.Errorf("Expected %d versions, got %d", len(versions), len(got))
continue
}
for i, e := range versions {
g := got[i]
if e.Name != g.Name {
t.Errorf("Expected %q, got %q", e.Name, g.Name)
}
if e.Version != g.Version {
t.Errorf("Expected %q, got %q", e.Version, g.Version)
}
if len(g.Keywords) != 3 {
t.Error("Expected 3 keywords.")
}
if len(g.Maintainers) != 2 {
t.Error("Expected 2 maintainers.")
}
if g.Created.Equal(empty) {
t.Error("Expected created to be non-empty")
}
if g.Description == "" {
t.Error("Expected description to be non-empty")
}
if g.Home == "" {
t.Error("Expected home to be non-empty")
}
if g.Digest == "" {
t.Error("Expected digest to be non-empty")
}
if len(g.URLs) != 1 {
t.Error("Expected exactly 1 URL")
}
}
}
}
// startLocalServerForTests Start the local helm server
func startLocalServerForTests(handler http.Handler) (*httptest.Server, error) {
if handler == nil {

@ -38,8 +38,6 @@ import (
"helm.sh/helm/v4/pkg/provenance"
)
var indexPath = "index.yaml"
// APIVersionV1 is the v1 API version for index and repository files.
const APIVersionV1 = "v1"

Loading…
Cancel
Save