From 99065aa331ce1c4686e4cea9e97d891421f2dce1 Mon Sep 17 00:00:00 2001 From: Sushil Kumar Date: Mon, 17 Apr 2017 13:41:38 -0700 Subject: [PATCH] Validates chart-dir before running dependency list command Fixes issues/2276: helm dependency list hangs if run on large directory --- pkg/chartutil/chartfile.go | 38 +++++++++++++++++++++++++++++++++ pkg/chartutil/chartfile_test.go | 13 +++++++++++ pkg/chartutil/load.go | 3 +++ 3 files changed, 54 insertions(+) diff --git a/pkg/chartutil/chartfile.go b/pkg/chartutil/chartfile.go index ea40f5706..9897d66ff 100644 --- a/pkg/chartutil/chartfile.go +++ b/pkg/chartutil/chartfile.go @@ -17,7 +17,11 @@ limitations under the License. package chartutil import ( + "errors" + "fmt" "io/ioutil" + "os" + "path/filepath" "github.com/ghodss/yaml" @@ -58,3 +62,37 @@ func SaveChartfile(filename string, cf *chart.Metadata) error { } return ioutil.WriteFile(filename, out, 0644) } + +// IsChartDir validate a chart directory. +// +// Checks for a valid Chart.yaml. +func IsChartDir(dirName string) (bool, error) { + if fi, err := os.Stat(dirName); err != nil { + return false, err + } else if !fi.IsDir() { + return false, fmt.Errorf("%q is not a directory", dirName) + } + + chartYaml := filepath.Join(dirName, "Chart.yaml") + if _, err := os.Stat(chartYaml); os.IsNotExist(err) { + return false, fmt.Errorf("no Chart.yaml exists in directory %q", dirName) + } + + chartYamlContent, err := ioutil.ReadFile(chartYaml) + if err != nil { + return false, fmt.Errorf("cannot read Chart.Yaml in directory %q", dirName) + } + + chartContent, err := UnmarshalChartfile(chartYamlContent) + if err != nil { + return false, err + } + if chartContent == nil { + return false, errors.New("chart metadata (Chart.yaml) missing") + } + if chartContent.Name == "" { + return false, errors.New("invalid chart (Chart.yaml): name must not be empty") + } + + return true, nil +} diff --git a/pkg/chartutil/chartfile_test.go b/pkg/chartutil/chartfile_test.go index 643d80052..30bb0c69b 100755 --- a/pkg/chartutil/chartfile_test.go +++ b/pkg/chartutil/chartfile_test.go @@ -95,3 +95,16 @@ func verifyChartfile(t *testing.T, f *chart.Metadata, name string) { } } } + +func TestIsChartDir(t *testing.T) { + validChartDir, err := IsChartDir("testdata/frobnitz") + if !validChartDir { + t.Errorf("unexpected error while reading chart-directory: (%v)", err) + return + } + validChartDir, err = IsChartDir("testdata") + if validChartDir || err == nil { + t.Errorf("expected error but did not get any") + return + } +} diff --git a/pkg/chartutil/load.go b/pkg/chartutil/load.go index 71bd23f87..03ba20e12 100644 --- a/pkg/chartutil/load.go +++ b/pkg/chartutil/load.go @@ -48,6 +48,9 @@ func Load(name string) (*chart.Chart, error) { return nil, err } if fi.IsDir() { + if validChart, err := IsChartDir(name); !validChart { + return nil, err + } return LoadDir(name) } return LoadFile(name)