From 2de1728f058adde13a3df3d0975c468924227665 Mon Sep 17 00:00:00 2001 From: Andrew Stuart Date: Thu, 1 Dec 2016 09:09:46 -0700 Subject: [PATCH 1/4] feat(helm): Add Files.Glob method to permit file organization --- docs/chart_template_guide/accessing_files.md | 38 +++++++++++++++++++ glide.lock | 14 ++++++- glide.yaml | 2 + pkg/chartutil/files.go | 30 ++++++++++++++- pkg/chartutil/files_test.go | 39 ++++++++++++++------ 5 files changed, 108 insertions(+), 15 deletions(-) diff --git a/docs/chart_template_guide/accessing_files.md b/docs/chart_template_guide/accessing_files.md index e68ee22c9..5e276cb0b 100644 --- a/docs/chart_template_guide/accessing_files.md +++ b/docs/chart_template_guide/accessing_files.md @@ -9,6 +9,8 @@ Helm provides access to files through the `.Files` object. Before we get going w - Files in `templates/` cannot be accessed. - Charts to not preserve UNIX mode information, so file-level permissions will have no impact on the availability of a file when it comes to the `.Files` object. +## Basic example + With those caveats behind, let's write a template that reads three files into our ConfigMap. To get started, we will add three files to the chart, putting all three directly inside of the `mychart/` directory. `config1.toml`: @@ -65,6 +67,42 @@ data: message = Goodbye from config 3 ``` +As your chart grows, you may find you have a greater need to organize your +files more, and so we provide a `Files.Glob(pattern string)` method to assist +in extracting certain files however you need. + +For example, imagine the directory structure: + +``` +foo/: + foo.txt foo.yaml + +bar/: + bar.go bar.conf baz.yaml +``` + +## Glob patterns + +You have multiple options with Globs: + + +```yaml +{{ range $path := .Files.Glob "**.yaml" }} +{{ $path }}: | +{{ .Files.Get $path }} +{{ end }} +``` + +Or + +```yaml +{{ range $path, $bytes := .Files.Glob "foo/*" }} +{{ $path }}: '{{ b64enc $bytes }}' +{{ end }} +``` + +## Secrets + When working with a Secret resource, you can import a file and have the template base-64 encode it for you: ```yaml diff --git a/glide.lock b/glide.lock index d7b9736d1..837873285 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 89695daf5f2de706b79fdd8e8b095f9514f418c0fbcf80d7fdca4c208d114d19 -updated: 2016-11-29T14:56:31.55726541-07:00 +hash: 707ac6d1785d0029397f2f9a3b0bc45f7d8ce819f14f6c246967b0a404627a2c +updated: 2016-12-01T09:07:51.289370422-07:00 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -103,6 +103,16 @@ imports: version: 465937c80b3c07a7c7ad20cc934898646a91c1de - name: github.com/ghodss/yaml version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee +- name: github.com/gobwas/glob + version: 0354991b92587e2742549d3036f3b5bae5ab03f2 + subpackages: + - compiler + - match + - syntax + - syntax/ast + - syntax/lexer + - util/runes + - util/strings - name: github.com/gogo/protobuf version: e18d7aa8f8c624c915db340349aad4c49b10d173 subpackages: diff --git a/glide.yaml b/glide.yaml index ab2871485..487a3279a 100644 --- a/glide.yaml +++ b/glide.yaml @@ -49,3 +49,5 @@ import: - package: golang.org/x/crypto subpackages: - openpgp +- package: github.com/gobwas/glob + version: ^0.2.1 diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go index 89120a42f..3747776ba 100644 --- a/pkg/chartutil/files.go +++ b/pkg/chartutil/files.go @@ -16,6 +16,7 @@ limitations under the License. package chartutil import ( + "github.com/gobwas/glob" "github.com/golang/protobuf/ptypes/any" ) @@ -26,8 +27,10 @@ type Files map[string][]byte // Given an []*any.Any (the format for files in a chart.Chart), extract a map of files. func NewFiles(from []*any.Any) Files { files := map[string][]byte{} - for _, f := range from { - files[f.TypeUrl] = f.Value + if from != nil { + for _, f := range from { + files[f.TypeUrl] = f.Value + } } return files } @@ -56,3 +59,26 @@ func (f Files) GetBytes(name string) []byte { func (f Files) Get(name string) string { return string(f.GetBytes(name)) } + +// Glob takes a glob pattern and returns another files object only containing +// matched files. +// +// This is designed to be called from a template. +// {{ range $name, $content := .Files.Glob("foo/**") }} +// {{ $name }}: | +// {{ .Files.Get($name) | indent 4 }}{{ end }} +func (f Files) Glob(pattern string) Files { + g, err := glob.Compile(pattern, '/') + if err != nil { + g, _ = glob.Compile("**") + } + + nf := NewFiles(nil) + for name, contents := range f { + if g.Match(name) { + nf[name] = contents + } + } + + return nf +} diff --git a/pkg/chartutil/files_test.go b/pkg/chartutil/files_test.go index 5e162f19d..268ac1abd 100644 --- a/pkg/chartutil/files_test.go +++ b/pkg/chartutil/files_test.go @@ -21,23 +21,25 @@ import ( "github.com/golang/protobuf/ptypes/any" ) -func TestNewFiles(t *testing.T) { - - cases := []struct { - path, data string - }{ - {"ship/captain.txt", "The Captain"}, - {"ship/stowaway.txt", "Legatt"}, - {"story/name.txt", "The Secret Sharer"}, - {"story/author.txt", "Joseph Conrad"}, - } +var cases = []struct { + path, data string +}{ + {"ship/captain.txt", "The Captain"}, + {"ship/stowaway.txt", "Legatt"}, + {"story/name.txt", "The Secret Sharer"}, + {"story/author.txt", "Joseph Conrad"}, +} +func getTestFiles() []*any.Any { a := []*any.Any{} for _, c := range cases { a = append(a, &any.Any{TypeUrl: c.path, Value: []byte(c.data)}) } + return a +} - files := NewFiles(a) +func TestNewFiles(t *testing.T) { + files := NewFiles(getTestFiles()) if len(files) != len(cases) { t.Errorf("Expected len() = %d, got %d", len(cases), len(files)) } @@ -51,3 +53,18 @@ func TestNewFiles(t *testing.T) { } } } + +func TestFileGlob(t *testing.T) { + f := NewFiles(getTestFiles()) + + matched := f.Glob("story/**") + + if len(matched) != 2 { + t.Errorf("Expected two files in glob story/**, got %d", len(matched)) + } + + m, expect := matched.Get("story/author.txt"), "Joseph Conrad" + if m != expect { + t.Errorf("Wrong globbed file content. Expected %s, got %s", expect, m) + } +} From d07e5cdfb6fad29532974867282177e0c58fa1cf Mon Sep 17 00:00:00 2001 From: Andrew Stuart Date: Thu, 1 Dec 2016 11:02:51 -0700 Subject: [PATCH 2/4] Correct docs heading location --- docs/chart_template_guide/accessing_files.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/chart_template_guide/accessing_files.md b/docs/chart_template_guide/accessing_files.md index 5e276cb0b..8d380edd6 100644 --- a/docs/chart_template_guide/accessing_files.md +++ b/docs/chart_template_guide/accessing_files.md @@ -67,6 +67,8 @@ data: message = Goodbye from config 3 ``` +## Glob patterns + As your chart grows, you may find you have a greater need to organize your files more, and so we provide a `Files.Glob(pattern string)` method to assist in extracting certain files however you need. @@ -81,8 +83,6 @@ bar/: bar.go bar.conf baz.yaml ``` -## Glob patterns - You have multiple options with Globs: From c311b085d5ed554862ffe9ca894c53529ec543b1 Mon Sep 17 00:00:00 2001 From: Andrew Stuart Date: Thu, 1 Dec 2016 11:06:50 -0700 Subject: [PATCH 3/4] Improve language of glob explanation --- docs/chart_template_guide/accessing_files.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chart_template_guide/accessing_files.md b/docs/chart_template_guide/accessing_files.md index 8d380edd6..e14417fde 100644 --- a/docs/chart_template_guide/accessing_files.md +++ b/docs/chart_template_guide/accessing_files.md @@ -71,7 +71,7 @@ data: As your chart grows, you may find you have a greater need to organize your files more, and so we provide a `Files.Glob(pattern string)` method to assist -in extracting certain files however you need. +in extracting certain files with all the flexibility of [glob patterns](//godoc.org/github.com/gobwas/glob). For example, imagine the directory structure: From ec020a9e40ac34090590d73f59884223d2276792 Mon Sep 17 00:00:00 2001 From: Andrew Stuart Date: Thu, 1 Dec 2016 11:07:08 -0700 Subject: [PATCH 4/4] Improve formatting of godoc --- pkg/chartutil/files.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go index 3747776ba..ba07e5ebb 100644 --- a/pkg/chartutil/files.go +++ b/pkg/chartutil/files.go @@ -64,6 +64,7 @@ func (f Files) Get(name string) string { // matched files. // // This is designed to be called from a template. +// // {{ range $name, $content := .Files.Glob("foo/**") }} // {{ $name }}: | // {{ .Files.Get($name) | indent 4 }}{{ end }}