From 71f5809975ddc8f53530f28f6c54bfa21b110f04 Mon Sep 17 00:00:00 2001 From: Jason McClellan Date: Tue, 9 Jul 2019 09:04:03 -0400 Subject: [PATCH] Add support for kustomization resources (#2416) (#2420) As of version 2.1, Kustomize has deprecated bases in favor of combining the functionality with resources by enforcing merge order based on resource array order. This means resources now may act as bases do today instead of being simply files - they may point to kustomiziations (directories with a kustomization config in the root) or even to remote locations. The code to generate the list of dependencies for file watching has been updated accordingly. --- pkg/skaffold/deploy/kustomize.go | 33 +++++++++++++++---------- pkg/skaffold/deploy/kustomize_test.go | 35 ++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/pkg/skaffold/deploy/kustomize.go b/pkg/skaffold/deploy/kustomize.go index 2ed93981122..400c09ceecc 100644 --- a/pkg/skaffold/deploy/kustomize.go +++ b/pkg/skaffold/deploy/kustomize.go @@ -167,23 +167,30 @@ func dependenciesForKustomization(dir string) ([]string, error) { return nil, err } - for _, base := range content.Bases { + deps = append(deps, path) + + candidates := append(content.Bases, content.Resources...) + + for _, candidate := range candidates { // If the file doesn't exist locally, we can assume it's a remote file and // skip it, since we can't monitor remote files. Kustomize itself will // handle invalid/missing files. - if !fileExistsLocally(base, dir) { + local, mode := pathExistsLocally(candidate, dir) + if !local { continue } - baseDeps, err := dependenciesForKustomization(filepath.Join(dir, base)) - if err != nil { - return nil, err - } - deps = append(deps, baseDeps...) + if mode.IsDir() { + candidateDeps, err := dependenciesForKustomization(filepath.Join(dir, candidate)) + if err != nil { + return nil, err + } + deps = append(deps, candidateDeps...) + } else { + deps = append(deps, filepath.Join(dir, candidate)) + } } - deps = append(deps, path) - deps = append(deps, joinPaths(dir, content.Resources)...) deps = append(deps, joinPaths(dir, content.Patches)...) deps = append(deps, joinPaths(dir, content.PatchesStrategicMerge)...) deps = append(deps, joinPaths(dir, content.CRDs)...) @@ -210,15 +217,15 @@ func joinPaths(root string, paths []string) []string { return list } -func fileExistsLocally(filename string, workingDir string) bool { +func pathExistsLocally(filename string, workingDir string) (bool, os.FileMode) { path := filename if !filepath.IsAbs(filename) { path = filepath.Join(workingDir, filename) } - if _, err := os.Stat(path); err == nil { - return true + if f, err := os.Stat(path); err == nil { + return true, f.Mode() } - return false + return false, 0 } // Dependencies lists all the files that can change what needs to be deployed. diff --git a/pkg/skaffold/deploy/kustomize_test.go b/pkg/skaffold/deploy/kustomize_test.go index d6ad84c0998..e3054ce20de 100644 --- a/pkg/skaffold/deploy/kustomize_test.go +++ b/pkg/skaffold/deploy/kustomize_test.go @@ -167,6 +167,10 @@ func TestDependenciesForKustomization(t *testing.T) { description: "resources", yaml: `resources: [pod1.yaml, path/pod2.yaml]`, expected: []string{"kustomization.yaml", "pod1.yaml", "path/pod2.yaml"}, + createFiles: map[string]string{ + "pod1.yaml": "", + "path/pod2.yaml": "", + }, }, { description: "paches", @@ -207,9 +211,10 @@ func TestDependenciesForKustomization(t *testing.T) { { description: "base exists locally", yaml: `bases: [base]`, - expected: []string{"base/kustomization.yaml", "base/app.yaml", "kustomization.yaml"}, + expected: []string{"kustomization.yaml", "base/kustomization.yaml", "base/app.yaml"}, createFiles: map[string]string{ "base/kustomization.yaml": `resources: [app.yaml]`, + "base/app.yaml": "", }, }, { @@ -217,6 +222,34 @@ func TestDependenciesForKustomization(t *testing.T) { yaml: `bases: [missing-or-remote-base]`, expected: []string{"kustomization.yaml"}, }, + { + description: "local kustomization resource", + yaml: `resources: [app.yaml, base]`, + expected: []string{"kustomization.yaml", "app.yaml", "base/kustomization.yaml", "base/app.yaml"}, + createFiles: map[string]string{ + "app.yaml": "", + "base/kustomization.yaml": `resources: [app.yaml]`, + "base/app.yaml": "", + }, + }, + { + description: "missing local kustomization resource", + yaml: `resources: [app.yaml, missing-or-remote-base]`, + expected: []string{"kustomization.yaml", "app.yaml"}, + createFiles: map[string]string{ + "app.yaml": "", + }, + }, + { + description: "mixed resource types", + yaml: `resources: [app.yaml, missing-or-remote-base, base]`, + expected: []string{"kustomization.yaml", "app.yaml", "base/kustomization.yaml", "base/app.yaml"}, + createFiles: map[string]string{ + "app.yaml": "", + "base/kustomization.yaml": `resources: [app.yaml]`, + "base/app.yaml": "", + }, + }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) {