From 7bc0da90d1017979a1c7ae08af23543ec16b06f6 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Tue, 14 Jul 2020 11:02:43 +0100 Subject: [PATCH] Avoid panic when directory does not exist The PR #1559 rearranged the filesystem walk during Load, so that it only resulted in an error if there was a problem reading a YAML file or non-chart directory (which might contain YAML files). To decide whether a file is of interest, it first checks the stat to see if it's a directory (in which case, recurse if not a chart ..) -- but if there's an error, that will be nil, and it will panic. In general, you don't know if the file you can't read is (supposed to be) a directory or a regular file, so there's no way to treat those differently. Instead, this commit makes it check before walking that the path supplied exists, then during the walk, ignore errors unless it looks like a YAML file. --- pkg/cluster/kubernetes/resource/load.go | 12 ++++++++---- pkg/cluster/kubernetes/resource/load_test.go | 12 ++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/pkg/cluster/kubernetes/resource/load.go b/pkg/cluster/kubernetes/resource/load.go index 13506b8bb..dcfadab48 100644 --- a/pkg/cluster/kubernetes/resource/load.go +++ b/pkg/cluster/kubernetes/resource/load.go @@ -28,14 +28,18 @@ func Load(base string, paths []string, sopsEnabled bool) (map[string]KubeManifes return nil, errors.Wrapf(err, "walking %q for chartdirs", base) } for _, root := range paths { + // In the walk, we ignore errors (indicating a failure to read + // a file) if it's not a file of interest. However, we _are_ + // interested in the error if an explicitly-mentioned path + // does not exist. + if _, err := os.Stat(root); err != nil { + return nil, errors.Wrapf(err, "unable to read root path %q", root) + } err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { - if info.IsDir() { + if err == nil && info.IsDir() { if charts.isDirChart(path) { return filepath.SkipDir } - if err != nil { - return errors.Wrapf(err, "walking dir %q for yaml files", path) - } return nil } diff --git a/pkg/cluster/kubernetes/resource/load_test.go b/pkg/cluster/kubernetes/resource/load_test.go index 409388bcc..5c55be565 100644 --- a/pkg/cluster/kubernetes/resource/load_test.go +++ b/pkg/cluster/kubernetes/resource/load_test.go @@ -362,3 +362,15 @@ func TestLoadSomeWithSopsAllEncrypted(t *testing.T) { assert.NotNil(t, objs[expected.String()], "expected to find %s in manifest map after decryption", expected) } } + +func TestNoPanic(t *testing.T) { + dir, cleanup := testfiles.TempDir(t) + defer cleanup() + if err := testfiles.WriteTestFiles(dir, testfiles.Files); err != nil { + t.Fatal(err) + } + _, err := Load(dir, []string{filepath.Join(dir, "doesnotexist")}, true) + if err == nil { + t.Error("expected error (but not panic) when loading from directory that doesn't exist") + } +}