diff --git a/pkg/repo/index.go b/pkg/repo/index.go index 8a23ba060..2f062b028 100644 --- a/pkg/repo/index.go +++ b/pkg/repo/index.go @@ -362,7 +362,7 @@ func loadIndex(data []byte, source string) (*IndexFile, error) { if cvs[idx].APIVersion == "" { cvs[idx].APIVersion = chart.APIVersionV1 } - if err := cvs[idx].Validate(); err != nil { + if err := cvs[idx].Validate(); ignoreSkippableChartValidationError(err) != nil { 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:]...) } @@ -388,3 +388,23 @@ func jsonOrYamlUnmarshal(b []byte, i interface{}) error { } return yaml.UnmarshalStrict(b, i) } + +// ignoreSkippableChartValidationError inspect the given error and returns nil if +// the error isn't important for index loading +// +// In particular, charts may introduce validations that don't impact repository indexes +// And repository indexes may be generated by older/non-complient software, which doesn't +// conform to all validations. +func ignoreSkippableChartValidationError(err error) error { + verr, ok := err.(chart.ValidationError) + if !ok { + return err + } + + // https://github.com/helm/helm/issues/12748 (JFrog repository strips alias field) + if strings.HasPrefix(verr.Error(), "validation: more than one dependency with name or alias") { + return nil + } + + return err +} diff --git a/pkg/repo/index_test.go b/pkg/repo/index_test.go index cb9317f7e..9652b1f21 100644 --- a/pkg/repo/index_test.go +++ b/pkg/repo/index_test.go @@ -20,6 +20,7 @@ import ( "bufio" "bytes" "encoding/json" + "fmt" "net/http" "os" "path/filepath" @@ -592,3 +593,50 @@ func TestAddFileIndexEntriesNil(t *testing.T) { } } } + +func TestIgnoreSkippableChartValidationError(t *testing.T) { + type TestCase struct { + Input error + ErrorSkipped bool + } + testCases := map[string]TestCase{ + "nil": { + Input: nil, + }, + "generic_error": { + Input: fmt.Errorf("foo"), + }, + "non_skipped_validation_error": { + Input: chart.ValidationError("chart.metadata.type must be application or library"), + }, + "skipped_validation_error": { + Input: chart.ValidationErrorf("more than one dependency with name or alias %q", "foo"), + ErrorSkipped: true, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + result := ignoreSkippableChartValidationError(tc.Input) + + if tc.Input == nil { + if result != nil { + t.Error("") + } + return + } + + if tc.ErrorSkipped { + if result != nil { + t.Error("") + } + return + } + + if tc.Input != result { + t.Error("") + } + + }) + } +}