From cff2746e02a288857643aecf474faf4fd5873b72 Mon Sep 17 00:00:00 2001 From: Steven Sheehy Date: Fri, 5 Apr 2019 14:48:48 -0500 Subject: [PATCH 01/82] Add sub-command support to plugin downloader Signed-off-by: Steven Sheehy --- docs/plugins.md | 5 +++++ pkg/getter/plugingetter.go | 6 ++++-- pkg/getter/plugingetter_test.go | 27 +++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/docs/plugins.md b/docs/plugins.md index 3087d1b39..5f5d163ce 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -144,6 +144,11 @@ The defined command will be invoked with the following scheme: repo definition, stored in `$HELM_HOME/repository/repositories.yaml`. Downloader plugin is expected to dump the raw content to stdout and report errors on stderr. +The downloader command also supports sub-commands or arguments, allowing you to specify +for example `bin/mydownloader subcommand -d` in the `plugin.yaml`. This is useful +if you want to use the same executable for the main plugin command and the downloader +command, but with a different sub-command for each. + ## Environment Variables When Helm executes a plugin, it passes the outer environment to the plugin, and diff --git a/pkg/getter/plugingetter.go b/pkg/getter/plugingetter.go index 8f2099de0..c918aa744 100644 --- a/pkg/getter/plugingetter.go +++ b/pkg/getter/plugingetter.go @@ -21,6 +21,7 @@ import ( "os" "os/exec" "path/filepath" + "strings" "k8s.io/helm/pkg/helm/environment" "k8s.io/helm/pkg/plugin" @@ -62,8 +63,9 @@ type pluginGetter struct { // Get runs downloader plugin command func (p *pluginGetter) Get(href string) (*bytes.Buffer, error) { - argv := []string{p.certFile, p.keyFile, p.cAFile, href} - prog := exec.Command(filepath.Join(p.base, p.command), argv...) + commands := strings.Split(p.command, " ") + argv := append(commands[1:], p.certFile, p.keyFile, p.cAFile, href) + prog := exec.Command(filepath.Join(p.base, commands[0]), argv...) plugin.SetupPluginEnv(p.settings, p.name, p.base) prog.Env = os.Environ() buf := bytes.NewBuffer(nil) diff --git a/pkg/getter/plugingetter_test.go b/pkg/getter/plugingetter_test.go index 7c0bd6c1e..c44729478 100644 --- a/pkg/getter/plugingetter_test.go +++ b/pkg/getter/plugingetter_test.go @@ -94,3 +94,30 @@ func TestPluginGetter(t *testing.T) { t.Errorf("Expected %q, got %q", expect, got) } } +func TestPluginSubCommands(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("TODO: refactor this test to work on windows") + } + + oldhh := os.Getenv("HELM_HOME") + defer os.Setenv("HELM_HOME", oldhh) + os.Setenv("HELM_HOME", "") + + env := hh(false) + pg := newPluginGetter("echo -n", env, "test", ".") + g, err := pg("test://foo/bar", "", "", "") + if err != nil { + t.Fatal(err) + } + + data, err := g.Get("test://foo/bar") + if err != nil { + t.Fatal(err) + } + + expect := " test://foo/bar" + got := data.String() + if got != expect { + t.Errorf("Expected %q, got %q", expect, got) + } +} From 3df75ec1d908f3c36da1b0e0c2c825eba6ffadac Mon Sep 17 00:00:00 2001 From: Scott Rigby Date: Fri, 19 Apr 2019 19:33:05 -0400 Subject: [PATCH 02/82] Improve getting LoadBalancer address in NOTES.txt See https://github.com/helm/charts/issues/84 Signed-off-by: Scott Rigby --- pkg/chartutil/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 9af4b8f45..736dc31b3 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -256,7 +256,7 @@ const defaultNotes = `1. Get the application URL by running these commands: {{- else if contains "LoadBalancer" .Values.service.type }} NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include ".fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include ".fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include ".fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") echo http://$SERVICE_IP:{{ .Values.service.port }} {{- else if contains "ClusterIP" .Values.service.type }} export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include ".name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") From ed9934adfaa8d6af770058004cb14e3682fd52a8 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Tue, 7 May 2019 01:24:17 +0200 Subject: [PATCH 03/82] Add test cases to reproduce issues with concurrent `helm repo add` commands Signed-off-by: Patrick Decat --- cmd/helm/repo_add_test.go | 113 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index 5a458cef7..0b7650fb2 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -17,13 +17,18 @@ limitations under the License. package main import ( + "fmt" "io" "os" + "os/exec" + "strings" + "sync" "testing" "github.com/spf13/cobra" "k8s.io/helm/pkg/helm" + "k8s.io/helm/pkg/helm/helmpath" "k8s.io/helm/pkg/repo" "k8s.io/helm/pkg/repo/repotest" ) @@ -101,3 +106,111 @@ func TestRepoAdd(t *testing.T) { t.Errorf("Duplicate repository name was added") } } +func TestRepoAddConcurrentGoRoutines(t *testing.T) { + ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*") + if err != nil { + t.Fatal(err) + } + + cleanup := resetEnv() + defer func() { + ts.Stop() + os.RemoveAll(thome.String()) + cleanup() + }() + + settings.Home = thome + if err := ensureTestHome(settings.Home, t); err != nil { + t.Fatal(err) + } + + var wg sync.WaitGroup + wg.Add(3) + for i := 0; i < 3; i++ { + go func(name string) { + defer wg.Done() + if err := addRepository(name, ts.URL(), "", "", settings.Home, "", "", "", true); err != nil { + t.Error(err) + } + }(fmt.Sprintf("%s-%d", testName, i)) + } + wg.Wait() + + f, err := repo.LoadRepositoriesFile(settings.Home.RepositoryFile()) + if err != nil { + t.Error(err) + } + + var name string + for i := 0; i < 3; i++ { + name = fmt.Sprintf("%s-%d", testName, i) + if !f.Has(name) { + t.Errorf("%s was not successfully inserted into %s", name, settings.Home.RepositoryFile()) + } + } +} + +// Same as TestRepoAddConcurrentGoRoutines but with repository additions in sub-processes +func TestRepoAddConcurrentSubProcesses(t *testing.T) { + goWantHelperProcess := os.Getenv("GO_WANT_HELPER_PROCESS") + if goWantHelperProcess == "" { + // parent + + ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*") + if err != nil { + t.Fatal(err) + } + + settings.Home = thome + + cleanup := resetEnv() + defer func() { + ts.Stop() + os.RemoveAll(thome.String()) + cleanup() + }() + if err := ensureTestHome(settings.Home, t); err != nil { + t.Fatal(err) + } + + var wg sync.WaitGroup + wg.Add(3) + for i := 0; i < 3; i++ { + go func(name string) { + defer wg.Done() + + cmd := exec.Command(os.Args[0], "-test.run=^TestRepoAddConcurrentSubProcesses$") + cmd.Env = append(os.Environ(), fmt.Sprintf("GO_WANT_HELPER_PROCESS=%s,%s", name, ts.URL()), fmt.Sprintf("HELM_HOME=%s", settings.Home)) + out, err := cmd.CombinedOutput() + if len(out) > 0 || err != nil { + t.Fatalf("child process: %q, %v", out, err) + } + }(fmt.Sprintf("%s-%d", testName, i)) + } + wg.Wait() + + f, err := repo.LoadRepositoriesFile(settings.Home.RepositoryFile()) + if err != nil { + t.Error(err) + } + + var name string + for i := 0; i < 3; i++ { + name = fmt.Sprintf("%s-%d", testName, i) + if !f.Has(name) { + t.Errorf("%s was not successfully inserted into %s", name, settings.Home.RepositoryFile()) + } + } + } else { + // child + s := strings.Split(goWantHelperProcess, ",") + settings.Home = helmpath.Home(os.Getenv("HELM_HOME")) + repoName := s[0] + tsURL := s[1] + if err := addRepository(repoName, tsURL, "", "", settings.Home, "", "", "", true); err != nil { + t.Fatal(err) + } + + os.Exit(0) + } +} From e07dfcbc00f910bcf0ee0357b1af8c3ab7cd39c9 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Tue, 7 May 2019 11:32:23 +0200 Subject: [PATCH 04/82] Lock the repository file for concurrent processes synchronization and re-read its content before updating it Signed-off-by: Patrick Decat --- cmd/helm/repo_add.go | 27 ++++++++++++++++++++++++++- cmd/helm/repo_add_test.go | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/cmd/helm/repo_add.go b/cmd/helm/repo_add.go index bfb3f0174..b93222f4a 100644 --- a/cmd/helm/repo_add.go +++ b/cmd/helm/repo_add.go @@ -22,11 +22,12 @@ import ( "github.com/spf13/cobra" + "syscall" + "golang.org/x/crypto/ssh/terminal" "k8s.io/helm/pkg/getter" "k8s.io/helm/pkg/helm/helmpath" "k8s.io/helm/pkg/repo" - "syscall" ) type repoAddCmd struct { @@ -131,6 +132,30 @@ func addRepository(name, url, username, password string, home helmpath.Home, cer return fmt.Errorf("Looks like %q is not a valid chart repository or cannot be reached: %s", url, err.Error()) } + // Lock the repository file for concurrent processes synchronization and re-read its content before updating it + fd, err := syscall.Open(home.RepositoryFile(), syscall.O_CREAT|syscall.O_RDWR|syscall.O_CLOEXEC, 0) + if err != nil { + return err + } + defer syscall.Close(fd) + + flock := syscall.Flock_t{ + Type: syscall.F_WRLCK, + Start: 0, + Len: 0, + Whence: io.SeekStart, + } + + syscall.FcntlFlock(uintptr(fd), syscall.F_SETLK, &flock) + if err != nil { + return err + } + + f, err = repo.LoadRepositoriesFile(home.RepositoryFile()) + if err != nil { + return err + } + f.Update(&c) return f.WriteFile(home.RepositoryFile(), 0644) diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index 0b7650fb2..e8ad35086 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -128,6 +128,7 @@ func TestRepoAddConcurrentGoRoutines(t *testing.T) { wg.Add(3) for i := 0; i < 3; i++ { go func(name string) { + // TODO: launch repository additions in sub-processes as file locks are bound to processes, not file descriptors defer wg.Done() if err := addRepository(name, ts.URL(), "", "", settings.Home, "", "", "", true); err != nil { t.Error(err) From 7a470252a934020ca9720ba35dcc901a2a6359c6 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Tue, 7 May 2019 12:19:05 +0200 Subject: [PATCH 05/82] Use github.com/gofrs/flock for cross platform file locking Signed-off-by: Patrick Decat --- cmd/helm/repo_add.go | 28 ++++++++++++---------------- glide.lock | 2 ++ glide.yaml | 2 ++ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cmd/helm/repo_add.go b/cmd/helm/repo_add.go index b93222f4a..ef9ddf223 100644 --- a/cmd/helm/repo_add.go +++ b/cmd/helm/repo_add.go @@ -17,14 +17,17 @@ limitations under the License. package main import ( + "context" "fmt" "io" - - "github.com/spf13/cobra" - "syscall" + "time" "golang.org/x/crypto/ssh/terminal" + + "github.com/gofrs/flock" + "github.com/spf13/cobra" + "k8s.io/helm/pkg/getter" "k8s.io/helm/pkg/helm/helmpath" "k8s.io/helm/pkg/repo" @@ -133,20 +136,13 @@ func addRepository(name, url, username, password string, home helmpath.Home, cer } // Lock the repository file for concurrent processes synchronization and re-read its content before updating it - fd, err := syscall.Open(home.RepositoryFile(), syscall.O_CREAT|syscall.O_RDWR|syscall.O_CLOEXEC, 0) - if err != nil { - return err + fileLock := flock.New(home.RepositoryFile()) + lockCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + defer cancel() + locked, err := fileLock.TryLockContext(lockCtx, time.Second) + if err == nil && locked { + defer fileLock.Unlock() } - defer syscall.Close(fd) - - flock := syscall.Flock_t{ - Type: syscall.F_WRLCK, - Start: 0, - Len: 0, - Whence: io.SeekStart, - } - - syscall.FcntlFlock(uintptr(fd), syscall.F_SETLK, &flock) if err != nil { return err } diff --git a/glide.lock b/glide.lock index 4f031a502..f05bd18f1 100644 --- a/glide.lock +++ b/glide.lock @@ -114,6 +114,8 @@ imports: - syntax/lexer - util/runes - util/strings +- name: github.com/gofrs/flock + version: 392e7fae8f1b0bdbd67dad7237d23f618feb6dbb - name: github.com/gogo/protobuf version: 342cbe0a04158f6dcb03ca0079991a51a4248c02 subpackages: diff --git a/glide.yaml b/glide.yaml index c9ac54b98..fd6613b71 100644 --- a/glide.yaml +++ b/glide.yaml @@ -67,6 +67,8 @@ import: - package: github.com/jmoiron/sqlx version: ^1.2.0 - package: github.com/rubenv/sql-migrate + - package: github.com/gofrs/flock + version: v0.7.1 testImports: - package: github.com/stretchr/testify From 848d54f451fba67596adc138e1b57daca4744e7d Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Tue, 7 May 2019 17:14:42 +0200 Subject: [PATCH 06/82] Remove obsolete comment from early file locking implementation Signed-off-by: Patrick Decat --- cmd/helm/repo_add_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index e8ad35086..0b7650fb2 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -128,7 +128,6 @@ func TestRepoAddConcurrentGoRoutines(t *testing.T) { wg.Add(3) for i := 0; i < 3; i++ { go func(name string) { - // TODO: launch repository additions in sub-processes as file locks are bound to processes, not file descriptors defer wg.Done() if err := addRepository(name, ts.URL(), "", "", settings.Home, "", "", "", true); err != nil { t.Error(err) From 3f3b5b42f80538f2814e6a00016d0a968c76c860 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Tue, 7 May 2019 18:01:44 +0200 Subject: [PATCH 07/82] Lower repository file rewriting timeout from 5 minutes to 30 seconds Signed-off-by: Patrick Decat --- cmd/helm/repo_add.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/repo_add.go b/cmd/helm/repo_add.go index ef9ddf223..0257367d6 100644 --- a/cmd/helm/repo_add.go +++ b/cmd/helm/repo_add.go @@ -137,7 +137,7 @@ func addRepository(name, url, username, password string, home helmpath.Home, cer // Lock the repository file for concurrent processes synchronization and re-read its content before updating it fileLock := flock.New(home.RepositoryFile()) - lockCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + lockCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() locked, err := fileLock.TryLockContext(lockCtx, time.Second) if err == nil && locked { From 6b800509d0a4166c83192789ea4b679fba76387a Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Tue, 7 May 2019 18:05:18 +0200 Subject: [PATCH 08/82] Add comment to explain why the repositories file is read a second time Signed-off-by: Patrick Decat --- cmd/helm/repo_add.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/helm/repo_add.go b/cmd/helm/repo_add.go index 0257367d6..ebb27e684 100644 --- a/cmd/helm/repo_add.go +++ b/cmd/helm/repo_add.go @@ -135,7 +135,7 @@ func addRepository(name, url, username, password string, home helmpath.Home, cer return fmt.Errorf("Looks like %q is not a valid chart repository or cannot be reached: %s", url, err.Error()) } - // Lock the repository file for concurrent processes synchronization and re-read its content before updating it + // Lock the repository file for concurrent goroutines or processes synchronization fileLock := flock.New(home.RepositoryFile()) lockCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() @@ -147,6 +147,8 @@ func addRepository(name, url, username, password string, home helmpath.Home, cer return err } + // Re-read the repositories file before updating it as its content may have been changed + // by a concurrent execution after the first read and before being locked f, err = repo.LoadRepositoriesFile(home.RepositoryFile()) if err != nil { return err From 79a190a6d0a0014a24213a84e281efef6c786705 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Thu, 9 May 2019 09:35:54 +0200 Subject: [PATCH 09/82] Decrease number of concurrent subprocesses for helm repo add test case to fit within CircleCI's pipeline memory limit Signed-off-by: Patrick Decat --- cmd/helm/repo_add_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index 0b7650fb2..7443a476a 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -174,8 +174,8 @@ func TestRepoAddConcurrentSubProcesses(t *testing.T) { } var wg sync.WaitGroup - wg.Add(3) - for i := 0; i < 3; i++ { + wg.Add(2) + for i := 0; i < 2; i++ { go func(name string) { defer wg.Done() @@ -195,7 +195,7 @@ func TestRepoAddConcurrentSubProcesses(t *testing.T) { } var name string - for i := 0; i < 3; i++ { + for i := 0; i < 2; i++ { name = fmt.Sprintf("%s-%d", testName, i) if !f.Has(name) { t.Errorf("%s was not successfully inserted into %s", name, settings.Home.RepositoryFile()) From 0880703a40e4464a31c1da61a2f14b770e97d17c Mon Sep 17 00:00:00 2001 From: ialidzhikov Date: Sun, 19 May 2019 00:07:54 +0300 Subject: [PATCH 10/82] Change extension rule to warning severity Signed-off-by: ialidzhikov --- pkg/lint/rules/template.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 192150737..69b9c397f 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -99,7 +99,7 @@ func Templates(linter *support.Linter, values []byte, namespace string, strict b fileName, _ := template.Name, template.Data path = fileName - linter.RunLinterRule(support.ErrorSev, path, validateAllowedExtension(fileName)) + linter.RunLinterRule(support.WarningSev, path, validateAllowedExtension(fileName)) // We only apply the following lint rules to yaml files if filepath.Ext(fileName) != ".yaml" || filepath.Ext(fileName) == ".yml" { From b2eed7644ae5bab07925fd1bcf8e42132e769901 Mon Sep 17 00:00:00 2001 From: Daniel Badea Date: Tue, 4 Jun 2019 17:38:23 +0300 Subject: [PATCH 11/82] doc: tuple replaced by list Built-in function 'tuple' is implemented in Sprig as 'list'. (see https://github.com/Masterminds/sprig/blob/2625cd487a689ca112e1301a58b89b347ba2c994/functions.go#L237 ) Replace documentation references to 'tuple' with 'list' so there is no need to explain what a tuple is. Signed-off-by: Daniel Badea --- docs/chart_template_guide/accessing_files.md | 4 ++-- docs/chart_template_guide/builtin_objects.md | 2 +- docs/chart_template_guide/control_structures.md | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/chart_template_guide/accessing_files.md b/docs/chart_template_guide/accessing_files.md index 206ad0cec..23bead122 100644 --- a/docs/chart_template_guide/accessing_files.md +++ b/docs/chart_template_guide/accessing_files.md @@ -54,13 +54,13 @@ metadata: name: {{ .Release.Name }}-configmap data: {{- $files := .Files }} - {{- range tuple "config1.toml" "config2.toml" "config3.toml" }} + {{- range list "config1.toml" "config2.toml" "config3.toml" }} {{ . }}: |- {{ $files.Get . }} {{- end }} ``` -This config map uses several of the techniques discussed in previous sections. For example, we create a `$files` variable to hold a reference to the `.Files` object. We also use the `tuple` function to create a list of files that we loop through. Then we print each file name (`{{.}}: |-`) followed by the contents of the file `{{ $files.Get . }}`. +This config map uses several of the techniques discussed in previous sections. For example, we create a `$files` variable to hold a reference to the `.Files` object. We also use the `list` function to create a list of files that we loop through. Then we print each file name (`{{.}}: |-`) followed by the contents of the file `{{ $files.Get . }}`. Running this template will produce a single ConfigMap with the contents of all three files: diff --git a/docs/chart_template_guide/builtin_objects.md b/docs/chart_template_guide/builtin_objects.md index f7b2857bc..c38edb17a 100644 --- a/docs/chart_template_guide/builtin_objects.md +++ b/docs/chart_template_guide/builtin_objects.md @@ -1,6 +1,6 @@ # Built-in Objects -Objects are passed into a template from the template engine. And your code can pass objects around (we'll see examples when we look at the `with` and `range` statements). There are even a few ways to create new objects within your templates, like with the `tuple` function we'll see later. +Objects are passed into a template from the template engine. And your code can pass objects around (we'll see examples when we look at the `with` and `range` statements). There are even a few ways to create new objects within your templates, like with the `list` function we'll see later. Objects can be simple, and have just one value. Or they can contain other objects or functions. For example. the `Release` object contains several objects (like `Release.Name`) and the `Files` object has a few functions. diff --git a/docs/chart_template_guide/control_structures.md b/docs/chart_template_guide/control_structures.md index d411c2f79..c9d2dd0bf 100644 --- a/docs/chart_template_guide/control_structures.md +++ b/docs/chart_template_guide/control_structures.md @@ -333,11 +333,11 @@ Now, in this example we've done something tricky. The `toppings: |-` line is dec > The `|-` marker in YAML takes a multi-line string. This can be a useful technique for embedding big blocks of data inside of your manifests, as exemplified here. -Sometimes it's useful to be able to quickly make a list inside of your template, and then iterate over that list. Helm templates have a function to make this easy: `tuple`. In computer science, a tuple is a list-like collection of fixed size, but with arbitrary data types. This roughly conveys the way a `tuple` is used. +Sometimes it's useful to be able to quickly make a list inside of your template, and then iterate over that list. Helm templates have a function that's called just that: `list`. ```yaml sizes: |- - {{- range tuple "small" "medium" "large" }} + {{- range list "small" "medium" "large" }} - {{ . }} {{- end }} ``` @@ -351,4 +351,4 @@ The above will produce this: - large ``` -In addition to lists and tuples, `range` can be used to iterate over collections that have a key and a value (like a `map` or `dict`). We'll see how to do that in the next section when we introduce template variables. +In addition to lists, `range` can be used to iterate over collections that have a key and a value (like a `map` or `dict`). We'll see how to do that in the next section when we introduce template variables. From 35b740af22b2170e1ed8fd747cdfe1fad382cffb Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Tue, 4 Jun 2019 14:49:52 -0400 Subject: [PATCH 12/82] Adding Kinds to the capabilities apiversions lookup for templates This will enable the detection of specific objects including CRDs that may vary widely between kubernetes clusters Signed-off-by: Matt Farina --- pkg/tiller/release_server.go | 55 ++++++++++++++++++++++++++++++- pkg/tiller/release_server_test.go | 14 ++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index c5638d20d..291135706 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -251,7 +251,7 @@ func capabilities(disc discovery.DiscoveryInterface) (*chartutil.Capabilities, e if err != nil { return nil, err } - vs, err := GetVersionSet(disc) + vs, err := GetAllVersionSet(disc) if err != nil { return nil, fmt.Errorf("Could not get apiVersions from Kubernetes: %s", err) } @@ -262,6 +262,59 @@ func capabilities(disc discovery.DiscoveryInterface) (*chartutil.Capabilities, e }, nil } +// GetAllVersionSet retrieves a set of available k8s API versions and objects +// +// This is a different function from GetVersionSet because the signature changed. +// To keep compatibility through the public functions this needed to be a new +// function.GetAllVersionSet +// TODO(mattfarina): In Helm v3 merge with GetVersionSet +func GetAllVersionSet(client discovery.ServerResourcesInterface) (chartutil.VersionSet, error) { + groups, resources, err := client.ServerGroupsAndResources() + if err != nil { + return chartutil.DefaultVersionSet, err + } + + // FIXME: The Kubernetes test fixture for cli appears to always return nil + // for calls to Discovery().ServerGroupsAndResources(). So in this case, we + // return the default API list. This is also a safe value to return in any + // other odd-ball case. + if len(groups) == 0 && len(resources) == 0 { + return chartutil.DefaultVersionSet, nil + } + + versionMap := make(map[string]interface{}) + versions := []string{} + + // Extract the groups + for _, g := range groups { + for _, gv := range g.Versions { + versionMap[gv.GroupVersion] = struct{}{} + } + } + + // Extract the resources + var id string + var ok bool + for _, r := range resources { + for _, rl := range r.APIResources { + + // A Kind at a GroupVersion can show up more than once. We only want + // it displayed once in the final output. + id = path.Join(r.GroupVersion, rl.Kind) + if _, ok = versionMap[id]; !ok { + versionMap[id] = struct{}{} + } + } + } + + // Convert to a form that NewVersionSet can use + for k := range versionMap { + versions = append(versions, k) + } + + return chartutil.NewVersionSet(versions...), nil +} + // GetVersionSet retrieves a set of available k8s API versions func GetVersionSet(client discovery.ServerGroupsInterface) (chartutil.VersionSet, error) { groups, err := client.ServerGroups() diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index d70221ed1..6fc1d48f6 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -338,6 +338,20 @@ func TestValidName(t *testing.T) { } } +func TestGetAllVersionSet(t *testing.T) { + rs := rsFixture() + vs, err := GetAllVersionSet(rs.clientset.Discovery()) + if err != nil { + t.Error(err) + } + if !vs.Has("v1") { + t.Errorf("Expected supported versions to at least include v1.") + } + if vs.Has("nosuchversion/v1") { + t.Error("Non-existent version is reported found.") + } +} + func TestGetVersionSet(t *testing.T) { rs := rsFixture() vs, err := GetVersionSet(rs.clientset.Discovery()) From 4c6e67b5db5bd5b757c6556a5beb3be4fab79720 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Tue, 4 Jun 2019 14:55:50 -0400 Subject: [PATCH 13/82] Updating docs on resources in capabilities apiversions search Signed-off-by: Matt Farina --- docs/chart_template_guide/builtin_objects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chart_template_guide/builtin_objects.md b/docs/chart_template_guide/builtin_objects.md index f7b2857bc..77d95f5f3 100644 --- a/docs/chart_template_guide/builtin_objects.md +++ b/docs/chart_template_guide/builtin_objects.md @@ -22,7 +22,7 @@ In the previous section, we use `{{.Release.Name}}` to insert the name of a rele - `Files.GetBytes` is a function for getting the contents of a file as an array of bytes instead of as a string. This is useful for things like images. - `Capabilities`: This provides information about what capabilities the Kubernetes cluster supports. - `Capabilities.APIVersions` is a set of versions. - - `Capabilities.APIVersions.Has $version` indicates whether a version (`batch/v1`) is enabled on the cluster. + - `Capabilities.APIVersions.Has $version` indicates whether a version (e.g., `batch/v1`) or resource (e.g., `apps/v1/Deployment`) is available on the cluster. Note, resources were not available before Helm v2.15. - `Capabilities.KubeVersion` provides a way to look up the Kubernetes version. It has the following values: `Major`, `Minor`, `GitVersion`, `GitCommit`, `GitTreeState`, `BuildDate`, `GoVersion`, `Compiler`, and `Platform`. - `Capabilities.TillerVersion` provides a way to look up the Tiller version. It has the following values: `SemVer`, `GitCommit`, and `GitTreeState`. - `Template`: Contains information about the current template that is being executed From 5703bc9699fd05bb8066c344f5639883f5fa27fb Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 5 Jun 2019 19:01:20 -0400 Subject: [PATCH 14/82] Use the latest version of Cobra Signed-off-by: Marc Khouzam --- glide.lock | 6 +++--- glide.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/glide.lock b/glide.lock index c8b75c737..b736eec9a 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: d633cc94d6f7fd656b85a64cd1eccffdeed7c45848369ce55ed9a4ae731dd843 -updated: 2019-06-04T12:50:58.563587342-07:00 +hash: 7104a8ce1f0b3f2338d10b102b3ba9bfd308000396cc9edb43095c2a2e133272 +updated: 2019-06-05T21:58:04.295502-04:00 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -254,7 +254,7 @@ imports: - name: github.com/sirupsen/logrus version: 89742aefa4b206dcf400792f3bd35b542998eb3b - name: github.com/spf13/cobra - version: fe5e611709b0c57fa4a89136deaa8e1d4004d053 + version: 67fc4837d267bc9bfd6e47f77783fcc3dffc68de subpackages: - doc - name: github.com/spf13/pflag diff --git a/glide.yaml b/glide.yaml index 565ba1069..ef2d27cf5 100644 --- a/glide.yaml +++ b/glide.yaml @@ -12,7 +12,7 @@ import: - unix - windows - package: github.com/spf13/cobra - version: fe5e611709b0c57fa4a89136deaa8e1d4004d053 + version: ^0.0.4 - package: github.com/spf13/pflag version: ~1.0.1 - package: github.com/Masterminds/vcs From c49ba7da852c5e4d918a0a1b6a152a3e0b5e6cd9 Mon Sep 17 00:00:00 2001 From: Deepak Sattiraju Date: Thu, 17 Jan 2019 19:17:40 +0530 Subject: [PATCH 15/82] feat(helm): adding --name to update single repo Signed-off-by: Deepak Sattiraju Lint Signed-off-by: ds-ms make docs Signed-off-by: ds-ms make docs Signed-off-by: ds-ms Signed-off-by: Deepak Sattiraju using args instead of --name Signed-off-by: ds-ms Adding [repo_name] to use Signed-off-by: ds-ms Adding test Signed-off-by: ds-ms Adding positive test case Signed-off-by: ds-ms lint Signed-off-by: ds-ms Renaming Signed-off-by: ds-ms Updating repo_name to REPO_NAME feat(helm): adding --name to update single repo Signed-off-by: Deepak Sattiraju Lint Signed-off-by: ds-ms make docs Signed-off-by: ds-ms make docs Signed-off-by: ds-ms Signed-off-by: Deepak Sattiraju using args instead of --name Signed-off-by: ds-ms Adding [repo_name] to use Signed-off-by: ds-ms Adding test Signed-off-by: ds-ms Adding positive test case Signed-off-by: ds-ms lint Signed-off-by: ds-ms Renaming Signed-off-by: ds-ms Updating repo_name to REPO_NAME --- cmd/helm/repo_update.go | 30 +++++++++++++- cmd/helm/repo_update_test.go | 75 +++++++++++++++++++++++++++++++++++ docs/helm/helm_repo_update.md | 11 ++++- 3 files changed, 112 insertions(+), 4 deletions(-) diff --git a/cmd/helm/repo_update.go b/cmd/helm/repo_update.go index 9d5e04b5d..f1e9fb566 100644 --- a/cmd/helm/repo_update.go +++ b/cmd/helm/repo_update.go @@ -36,15 +36,24 @@ Information is cached locally, where it is used by commands like 'helm search'. 'helm update' is the deprecated form of 'helm repo update'. It will be removed in future releases. + +You can specify the name of a repository you want to update. + + $ helm repo update + +To update all the repositories, use 'helm repo update'. + ` var errNoRepositories = errors.New("no repositories found. You must add one before updating") +var errNoRepositoriesMatchingRepoName = errors.New("no repositories found matching the provided name. Verify if the repo exists") type repoUpdateCmd struct { update func([]*repo.ChartRepository, io.Writer, helmpath.Home, bool) error home helmpath.Home out io.Writer strict bool + name string } func newRepoUpdateCmd(out io.Writer) *cobra.Command { @@ -53,12 +62,15 @@ func newRepoUpdateCmd(out io.Writer) *cobra.Command { update: updateCharts, } cmd := &cobra.Command{ - Use: "update", + Use: "update [REPO_NAME]", Aliases: []string{"up"}, Short: "Update information of available charts locally from chart repositories", Long: updateDesc, RunE: func(cmd *cobra.Command, args []string) error { u.home = settings.Home + if len(args) != 0 { + u.name = args[0] + } return u.run() }, } @@ -84,8 +96,22 @@ func (u *repoUpdateCmd) run() error { if err != nil { return err } - repos = append(repos, r) + if len(u.name) != 0 { + if cfg.Name == u.name { + repos = append(repos, r) + break + } else { + continue + } + } else { + repos = append(repos, r) + } } + + if len(repos) == 0 { + return errNoRepositoriesMatchingRepoName + } + return u.update(repos, u.out, u.home, u.strict) } diff --git a/cmd/helm/repo_update_test.go b/cmd/helm/repo_update_test.go index 5b1058008..d26df98c5 100644 --- a/cmd/helm/repo_update_test.go +++ b/cmd/helm/repo_update_test.go @@ -132,3 +132,78 @@ func TestUpdateCmdStrictFlag(t *testing.T) { t.Errorf("Expected 'Unable to get an update', got %q", got) } } + +func TestUpdateCmdWithSingleRepoNameWhichDoesntExist(t *testing.T) { + thome, err := tempHelmHome(t) + if err != nil { + t.Fatal(err) + } + + cleanup := resetEnv() + defer func() { + os.RemoveAll(thome.String()) + cleanup() + }() + + settings.Home = thome + + out := bytes.NewBuffer(nil) + cmd := newRepoUpdateCmd(out) + + if err = cmd.RunE(cmd, []string{"randomRepo"}); err == nil { + t.Fatal("expected error due to wrong repo name") + } + + if got := fmt.Sprintf("%v", err); !strings.Contains(got, "no repositories found matching the provided name. Verify if the repo exists") { + t.Errorf("Expected 'no repositories found matching the provided name. Verify if the repo exists', got %q", got) + } +} + +func TestUpdateRepo(t *testing.T) { + ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*") + if err != nil { + t.Fatal(err) + } + + hh := helmpath.Home(thome) + cleanup := resetEnv() + defer func() { + ts.Stop() + os.RemoveAll(thome.String()) + cleanup() + }() + if err := ensureTestHome(hh, t); err != nil { + t.Fatal(err) + } + + settings.Home = thome + + if err := addRepository("repo1", ts.URL(), "", "", hh, "", "", "", true); err != nil { + t.Error(err) + } + + if err := addRepository("repo2", ts.URL(), "", "", hh, "", "", "", true); err != nil { + t.Error(err) + } + + out := bytes.NewBuffer(nil) + cmd := newRepoUpdateCmd(out) + + if err = cmd.RunE(cmd, []string{"repo1"}); err != nil { + t.Fatal("expected to update repo1 correctly") + } + + got := out.String() + + if !strings.Contains(got, "Successfully got an update from the \"repo1\"") { + t.Errorf("Expected to successfully update \"repo1\" repository, got %q", got) + } + + if strings.Contains(got, "Successfully got an update from the \"repo2\"") { + t.Errorf("Shouldn't have updated \"repo2\" repository, got %q", got) + } + + if !strings.Contains(got, "Update Complete.") { + t.Error("Update was not successful") + } +} diff --git a/docs/helm/helm_repo_update.md b/docs/helm/helm_repo_update.md index e374620ac..d5e8849bc 100644 --- a/docs/helm/helm_repo_update.md +++ b/docs/helm/helm_repo_update.md @@ -11,9 +11,16 @@ Information is cached locally, where it is used by commands like 'helm search'. 'helm update' is the deprecated form of 'helm repo update'. It will be removed in future releases. +You can specify the name of a repository you want to update. + + $ helm repo update + +To update all the repositories, use 'helm repo update'. + + ``` -helm repo update [flags] +helm repo update [REPO_NAME] [flags] ``` ### Options @@ -39,4 +46,4 @@ helm repo update [flags] * [helm repo](helm_repo.md) - Add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 16-May-2019 +###### Auto generated by spf13/cobra on 7-Jun-2019 From 2f0a89a96109ddd77b6053e62b6e8430144a2b84 Mon Sep 17 00:00:00 2001 From: Patrik Fuhrmann Date: Mon, 10 Jun 2019 02:42:37 +0200 Subject: [PATCH 16/82] Adding newline to references More readable this way. Signed-off-by: Patrik Fuhrmann --- docs/tiller_ssl.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tiller_ssl.md b/docs/tiller_ssl.md index 3705723fa..703c9e4a8 100644 --- a/docs/tiller_ssl.md +++ b/docs/tiller_ssl.md @@ -312,6 +312,6 @@ If your tiller certificate has expired, you'll need to sign a new certificate, b ## References -https://github.com/denji/golang-tls -https://www.openssl.org/docs/ +https://github.com/denji/golang-tls +https://www.openssl.org/docs/ https://jamielinux.com/docs/openssl-certificate-authority/sign-server-and-client-certificates.html From b4475775fd670ed223479e743960e3b7c5934b61 Mon Sep 17 00:00:00 2001 From: Patrik Fuhrmann Date: Mon, 10 Jun 2019 21:21:41 +0200 Subject: [PATCH 17/82] Making references into list Signed-off-by: Patrik Fuhrmann --- docs/tiller_ssl.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tiller_ssl.md b/docs/tiller_ssl.md index 703c9e4a8..8491c2c78 100644 --- a/docs/tiller_ssl.md +++ b/docs/tiller_ssl.md @@ -312,6 +312,6 @@ If your tiller certificate has expired, you'll need to sign a new certificate, b ## References -https://github.com/denji/golang-tls -https://www.openssl.org/docs/ -https://jamielinux.com/docs/openssl-certificate-authority/sign-server-and-client-certificates.html +- https://github.com/denji/golang-tls +- https://www.openssl.org/docs/ +- https://jamielinux.com/docs/openssl-certificate-authority/sign-server-and-client-certificates.html From 29a295eb84ffdfd00e3174818123f37033a02a3e Mon Sep 17 00:00:00 2001 From: Adam Eijdenberg Date: Wed, 12 Jun 2019 10:05:05 +1000 Subject: [PATCH 18/82] Add test for existing merging behaviour of mixed types Signed-off-by: Adam Eijdenberg --- pkg/chartutil/values_test.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pkg/chartutil/values_test.go b/pkg/chartutil/values_test.go index af6c77d27..fb26c6938 100644 --- a/pkg/chartutil/values_test.go +++ b/pkg/chartutil/values_test.go @@ -585,3 +585,27 @@ anotherNewKey: } } } + +func TestOverriteTableItemWithNonTableValue(t *testing.T) { + // src has a table value for "foo" + src := map[string]interface{}{ + "foo": map[string]interface{}{ + "baz": "boz", + }, + } + + // dst has a non-table value for "foo" + dst := map[string]interface{}{ + "foo": "bar", + } + + // result - this may print a warning, but we has always "worked" + result := coalesceTables(dst, src, "") + expected := map[string]interface{}{ + "foo": "bar", + } + + if !reflect.DeepEqual(result, expected) { + t.Errorf("Expected %v, but got %v", expected, result) + } +} From dda84976bf75e4f3fca9090f0aabe6a7208d709d Mon Sep 17 00:00:00 2001 From: Adam Eijdenberg Date: Fri, 18 Jan 2019 15:37:16 +1100 Subject: [PATCH 19/82] Refactor to use common codepath for table coalescing Stop mutating maps passed on input Signed-off-by: Adam Eijdenberg --- pkg/chartutil/requirements.go | 5 +- pkg/chartutil/values.go | 131 ++++++++++++---------------------- 2 files changed, 49 insertions(+), 87 deletions(-) diff --git a/pkg/chartutil/requirements.go b/pkg/chartutil/requirements.go index f21a22005..ac2649d7c 100644 --- a/pkg/chartutil/requirements.go +++ b/pkg/chartutil/requirements.go @@ -391,7 +391,7 @@ func processImportValues(c *chart.Chart) error { if err != nil { return err } - b := make(map[string]interface{}, 0) + b := cvals.AsMap() // import values from each dependency if specified in import-values for _, r := range reqs.Dependencies { // only process raw requirement that is found in chart's dependencies (enabled) @@ -428,7 +428,7 @@ func processImportValues(c *chart.Chart) error { } // create value map from child to be merged into parent vm := pathToMap(nm["parent"], vv.AsMap()) - b = coalesceTables(cvals, vm, c.Metadata.Name) + b = coalesceTables(b, vm, c.Metadata.Name) case string: nm := map[string]string{ "child": "exports." + iv, @@ -448,7 +448,6 @@ func processImportValues(c *chart.Chart) error { r.ImportValues = outiv } } - b = coalesceTables(b, cvals, c.Metadata.Name) y, err := yaml.Marshal(b) if err != nil { return err diff --git a/pkg/chartutil/values.go b/pkg/chartutil/values.go index 6270531d7..1612b7596 100644 --- a/pkg/chartutil/values.go +++ b/pkg/chartutil/values.go @@ -172,9 +172,7 @@ func CoalesceValues(chrt *chart.Chart, vals *chart.Config) (Values, error) { } } - var err error - cvals, err = coalesceDeps(chrt, cvals) - return cvals, err + return coalesceDeps(chrt, cvals) } // coalesce coalesces the dest values and the chart values, giving priority to the dest values. @@ -186,8 +184,7 @@ func coalesce(ch *chart.Chart, dest map[string]interface{}) (map[string]interfac if err != nil { return dest, err } - coalesceDeps(ch, dest) - return dest, nil + return coalesceDeps(ch, dest) } // coalesceDeps coalesces the dependencies of the given chart. @@ -203,7 +200,7 @@ func coalesceDeps(chrt *chart.Chart, dest map[string]interface{}) (map[string]in dvmap := dv.(map[string]interface{}) // Get globals out of dest and merge them into dvmap. - coalesceGlobals(dvmap, dest, chrt.Metadata.Name) + dvmap = coalesceGlobals(dvmap, dest, chrt.Metadata.Name) var err error // Now coalesce the rest of the values. @@ -236,45 +233,20 @@ func coalesceGlobals(dest, src map[string]interface{}, chartName string) map[str return dg } + rv := make(map[string]interface{}) + for k, v := range dest { + rv[k] = v + } + // EXPERIMENTAL: In the past, we have disallowed globals to test tables. This // reverses that decision. It may somehow be possible to introduce a loop // here, but I haven't found a way. So for the time being, let's allow // tables in globals. - for key, val := range sg { - if istable(val) { - vv := copyMap(val.(map[string]interface{})) - if destv, ok := dg[key]; ok { - if destvmap, ok := destv.(map[string]interface{}); ok { - // Basically, we reverse order of coalesce here to merge - // top-down. - coalesceTables(vv, destvmap, chartName) - dg[key] = vv - continue - } else { - log.Printf("Warning: For chart '%s', cannot merge map onto non-map for key '%q'. Skipping.", chartName, key) - } - } else { - // Here there is no merge. We're just adding. - dg[key] = vv - } - } else if dv, ok := dg[key]; ok && istable(dv) { - // It's not clear if this condition can actually ever trigger. - log.Printf("Warning: For chart '%s', key '%s' is a table. Skipping.", chartName, key) - continue - } - // TODO: Do we need to do any additional checking on the value? - dg[key] = val - } - dest[GlobalKey] = dg - return dest -} -func copyMap(src map[string]interface{}) map[string]interface{} { - dest := make(map[string]interface{}, len(src)) - for k, v := range src { - dest[k] = v - } - return dest + // Basically, we reverse order of coalesce here to merge + // top-down. + rv[GlobalKey] = coalesceTables(sg, dg, chartName) + return rv } // coalesceValues builds up a values map for a particular chart. @@ -294,30 +266,7 @@ func coalesceValues(c *chart.Chart, v map[string]interface{}) (map[string]interf return v, fmt.Errorf("Error: Reading chart '%s' default values (%s): %s", c.Metadata.Name, c.Values.Raw, err) } - for key, val := range nv { - if value, ok := v[key]; ok { - if value == nil { - // When the YAML value is null, we remove the value's key. - // This allows Helm's various sources of values (value files or --set) to - // remove incompatible keys from any previous chart, file, or set values. - delete(v, key) - } else if dest, ok := value.(map[string]interface{}); ok { - // if v[key] is a table, merge nv's val table into v[key]. - src, ok := val.(map[string]interface{}) - if !ok { - log.Printf("Warning: Building values map for chart '%s'. Skipped value (%+v) for '%s', as it is not a table.", c.Metadata.Name, src, key) - continue - } - // Because v has higher precedence than nv, dest values override src - // values. - coalesceTables(dest, src, c.Metadata.Name) - } - } else { - // If the key is not in v, copy it from nv. - v[key] = val - } - } - return v, nil + return coalesceTables(v, nv.AsMap(), c.Metadata.Name), nil } // coalesceTables merges a source map into a destination map. @@ -326,36 +275,50 @@ func coalesceValues(c *chart.Chart, v map[string]interface{}) (map[string]interf func coalesceTables(dst, src map[string]interface{}, chartName string) map[string]interface{} { // Because dest has higher precedence than src, dest values override src // values. + + rv := make(map[string]interface{}) for key, val := range src { dv, ok := dst[key] - if ok && dv == nil { - // skip here, we delete at end + if !ok { // if not in dst, then copy from src + rv[key] = val continue } - if istable(val) { - if !ok { - dst[key] = val - } else if istable(dv) { - coalesceTables(dv.(map[string]interface{}), val.(map[string]interface{}), chartName) - } else { - log.Printf("Warning: Merging destination map for chart '%s'. Cannot overwrite table item '%s', with non table value: %v", chartName, key, val) - } + if dv == nil { // if set to nil in dst, then ignore + // When the YAML value is null, we skip the value's key. + // This allows Helm's various sources of values (value files or --set) to + // remove incompatible keys from any previous chart, file, or set values. continue - } else if ok && istable(dv) { + } + + srcTable, srcIsTable := val.(map[string]interface{}) + dstTable, dstIsTable := dv.(map[string]interface{}) + switch { + case srcIsTable && dstIsTable: // both tables, we coalesce + rv[key] = coalesceTables(dstTable, srcTable, chartName) + case srcIsTable && !dstIsTable: + log.Printf("Warning: Merging destination map for chart '%s'. Cannot overwrite table item '%s', with non table value: %v", chartName, key, val) + // despite message in warning, we appear to do exactly that, and do take the dst value + rv[key] = dv + case !srcIsTable && dstIsTable: log.Printf("Warning: Merging destination map for chart '%s'. The destination item '%s' is a table and ignoring the source '%s' as it has a non-table value of: %v", chartName, key, key, val) - continue - } else if !ok { // <- ok is still in scope from preceding conditional. - dst[key] = val - continue + rv[key] = dv + default: // neither are tables, simply take the dst value + rv[key] = dv } } - // never return a nil value, rather delete the key - for k, v := range dst { - if v == nil { - delete(dst, k) + + // do we have anything in dst that wasn't processed already that we need to copy across? + for key, val := range dst { + if val == nil { + continue + } + _, ok := rv[key] + if !ok { + rv[key] = val } } - return dst + + return rv } // ReleaseOptions represents the additional release options needed From 0ba4c63546a3688e57ca34f4db00123d67ccd70c Mon Sep 17 00:00:00 2001 From: Adam Eijdenberg Date: Wed, 12 Jun 2019 10:05:51 +1000 Subject: [PATCH 20/82] Update warning to be more accurate Signed-off-by: Adam Eijdenberg --- pkg/chartutil/values.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/chartutil/values.go b/pkg/chartutil/values.go index 1612b7596..890cd5540 100644 --- a/pkg/chartutil/values.go +++ b/pkg/chartutil/values.go @@ -296,8 +296,7 @@ func coalesceTables(dst, src map[string]interface{}, chartName string) map[strin case srcIsTable && dstIsTable: // both tables, we coalesce rv[key] = coalesceTables(dstTable, srcTable, chartName) case srcIsTable && !dstIsTable: - log.Printf("Warning: Merging destination map for chart '%s'. Cannot overwrite table item '%s', with non table value: %v", chartName, key, val) - // despite message in warning, we appear to do exactly that, and do take the dst value + log.Printf("Warning: Merging destination map for chart '%s'. Overwriting table item '%s', with non table value: %v", chartName, key, dv) rv[key] = dv case !srcIsTable && dstIsTable: log.Printf("Warning: Merging destination map for chart '%s'. The destination item '%s' is a table and ignoring the source '%s' as it has a non-table value of: %v", chartName, key, key, val) From 94201711ff37d97c2211df6e4776cbaa34b367c2 Mon Sep 17 00:00:00 2001 From: Ihor Dvoretskyi Date: Thu, 13 Jun 2019 14:54:40 +0000 Subject: [PATCH 21/82] Snap installation information Installation information added (and a minor fix) Signed-off-by: Ihor Dvoretskyi --- README.md | 2 ++ docs/install.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1889e818e..3262ba54f 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,8 @@ If you want to use a package manager: - [Chocolatey](https://chocolatey.org/) users can use `choco install kubernetes-helm`. - [Scoop](https://scoop.sh/) users can use `scoop install helm`. - [GoFish](https://gofi.sh/) users can use `gofish install helm`. +- [Snap](https://snapcraft.io/) users can use `sudo snap install helm + --classic`. To rapidly get Helm up and running, start with the [Quick Start Guide](https://docs.helm.sh/using_helm/#quickstart-guide). diff --git a/docs/install.md b/docs/install.md index d9a345f80..3742385f3 100755 --- a/docs/install.md +++ b/docs/install.md @@ -30,7 +30,7 @@ The Snap package for Helm is maintained by [Snapcrafters](https://github.com/snapcrafters/helm). ``` -$ sudo snap install helm --classic +sudo snap install helm --classic ``` ### From Homebrew (macOS) From a985f34b810967b710f32599ffe1a9b4080f3916 Mon Sep 17 00:00:00 2001 From: Naseem Date: Thu, 13 Jun 2019 15:14:43 -0400 Subject: [PATCH 22/82] Add sa Signed-off-by: Naseem --- cmd/helm/create_test.go | 2 +- pkg/chartutil/create.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/cmd/helm/create_test.go b/cmd/helm/create_test.go index c9459b477..20bace864 100644 --- a/cmd/helm/create_test.go +++ b/cmd/helm/create_test.go @@ -143,7 +143,7 @@ func TestCreateStarterCmd(t *testing.T) { t.Errorf("Wrong API version: %q", c.Metadata.ApiVersion) } - expectedTemplateCount := 7 + expectedTemplateCount := 8 if l := len(c.Templates); l != expectedTemplateCount { t.Errorf("Expected %d templates, got %d", expectedTemplateCount, l) } diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 74607aff2..3aa0808b0 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -42,6 +42,8 @@ const ( DeploymentName = "deployment.yaml" // ServiceName is the name of the example service file. ServiceName = "service.yaml" + // ServiceAccountName is the name of the example serviceaccount file. + ServiceAccountName = "serviceaccount.yaml" // NotesName is the name of the example NOTES.txt file. NotesName = "NOTES.txt" // HelpersName is the name of the example helpers file. @@ -67,6 +69,13 @@ imagePullSecrets: [] nameOverride: "" fullnameOverride: "" +serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: + service: type: ClusterIP port: 80 @@ -189,6 +198,7 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} + serviceAccountName: {{ template ".serviceAccountName" . }} containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" @@ -238,6 +248,15 @@ spec: app.kubernetes.io/name: {{ include ".name" . }} app.kubernetes.io/instance: {{ .Release.Name }} ` +const defaultServiceAccount = `{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template ".serviceAccountName" . }} + labels: + {{ include ".labels" . | indent 4 }} +{{- end -}} +` const defaultNotes = `1. Get the application URL by running these commands: {{- if .Values.ingress.enabled }} @@ -307,6 +326,17 @@ app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define ".serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include ".fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} ` const defaultTestConnection = `apiVersion: v1 @@ -425,6 +455,11 @@ func Create(chartfile *chart.Metadata, dir string) (string, error) { path: filepath.Join(cdir, TemplatesDir, ServiceName), content: Transform(defaultService, "", chartfile.Name), }, + { + // serviceaccount.yaml + path: filepath.Join(cdir, TemplatesDir, ServiceAccountName), + content: Transform(defaultServiceAccount, "", chartfile.Name), + }, { // NOTES.txt path: filepath.Join(cdir, TemplatesDir, NotesName), From ab8585faea4955abf38ad190807876b14221fde2 Mon Sep 17 00:00:00 2001 From: Naseem Date: Fri, 14 Jun 2019 15:29:37 -0400 Subject: [PATCH 23/82] Keep indentation consistent Signed-off-by: Naseem --- pkg/chartutil/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 3aa0808b0..f8785b46f 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -254,7 +254,7 @@ kind: ServiceAccount metadata: name: {{ template ".serviceAccountName" . }} labels: - {{ include ".labels" . | indent 4 }} +{{ include ".labels" . | indent 4 }} {{- end -}} ` From 2868aed3218db9c0519bc65208cda2c3790708bc Mon Sep 17 00:00:00 2001 From: Aisuko Date: Sat, 15 Jun 2019 15:03:28 +0800 Subject: [PATCH 24/82] Change port forward command order in default note Signed-off-by: Aisuko --- pkg/chartutil/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 74607aff2..0a68856e2 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -257,8 +257,8 @@ const defaultNotes = `1. Get the application URL by running these commands: echo http://$SERVICE_IP:{{ .Values.service.port }} {{- else if contains "ClusterIP" .Values.service.type }} export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include ".name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:8080 to use your application" kubectl port-forward $POD_NAME 8080:80 + echo "Visit http://127.0.0.1:8080 to use your application" {{- end }} ` From d93b660c62f9a9655747b0d00ff2b941df203730 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Mon, 17 Jun 2019 07:30:28 -0700 Subject: [PATCH 25/82] Revert "Change port forward command order in default note" Signed-off-by: Matthew Fisher --- pkg/chartutil/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 6828ae902..f8785b46f 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -276,8 +276,8 @@ const defaultNotes = `1. Get the application URL by running these commands: echo http://$SERVICE_IP:{{ .Values.service.port }} {{- else if contains "ClusterIP" .Values.service.type }} export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include ".name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - kubectl port-forward $POD_NAME 8080:80 echo "Visit http://127.0.0.1:8080 to use your application" + kubectl port-forward $POD_NAME 8080:80 {{- end }} ` From 79235eef11a311e400e9c27ad2df55932390c01d Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Mon, 17 Jun 2019 10:44:49 -0400 Subject: [PATCH 26/82] Add more capabilities to the detault set used by helm template - These are the capabilities as of k8s 1.14 - They are generated because getting them at runtime uses so much memory it causes CI errors Signed-off-by: Matt Farina --- Makefile | 4 + docs/helm/helm_template.md | 4 +- pkg/chartutil/capabilities.go | 10 +- pkg/chartutil/capabilities_test.go | 7 +- .../capabilities_versions_generated.go | 575 ++++++++++++++++++ .../capabilities_default_versions_generate.go | 106 ++++ 6 files changed, 697 insertions(+), 9 deletions(-) create mode 100644 pkg/chartutil/capabilities_versions_generated.go create mode 100644 pkg/chartutil/generator/capabilities_default_versions_generate.go diff --git a/Makefile b/Makefile index 0c474c135..fc175a781 100644 --- a/Makefile +++ b/Makefile @@ -141,6 +141,10 @@ docker-test-style: check-docker protoc: $(MAKE) -C _proto/ all +.PHONY: generate +generate: + $(GO) generate ./... + .PHONY: docs docs: build @scripts/update-docs.sh diff --git a/docs/helm/helm_template.md b/docs/helm/helm_template.md index ffc0ecc83..8f890e27d 100644 --- a/docs/helm/helm_template.md +++ b/docs/helm/helm_template.md @@ -27,7 +27,7 @@ helm template [flags] CHART -x, --execute stringArray Only execute the given templates -h, --help help for template --is-upgrade Set .Release.IsUpgrade instead of .Release.IsInstall - --kube-version string Kubernetes version used as Capabilities.KubeVersion.Major/Minor (default "1.9") + --kube-version string Kubernetes version used as Capabilities.KubeVersion.Major/Minor (default "1.14") -n, --name string Release name (default "release-name") --name-template string Specify template used to name the release --namespace string Namespace to install the release into @@ -55,4 +55,4 @@ helm template [flags] CHART * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 16-May-2019 +###### Auto generated by spf13/cobra on 17-Jun-2019 diff --git a/pkg/chartutil/capabilities.go b/pkg/chartutil/capabilities.go index b4533e417..a6808c702 100644 --- a/pkg/chartutil/capabilities.go +++ b/pkg/chartutil/capabilities.go @@ -12,6 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +//go:generate go run generator/capabilities_default_versions_generate.go package chartutil @@ -24,14 +25,15 @@ import ( ) var ( - // DefaultVersionSet is the default version set, which includes only Core V1 ("v1"). - DefaultVersionSet = NewVersionSet("v1") + // DefaultVersionSet is the default version set in included in Kubernetes for workloads + // Default versions as of Kubernetes 1.14 + DefaultVersionSet = NewVersionSet(defaultVersions()...) // DefaultKubeVersion is the default kubernetes version DefaultKubeVersion = &version.Info{ Major: "1", - Minor: "9", - GitVersion: "v1.9.0", + Minor: "14", + GitVersion: "v1.14.0", GoVersion: runtime.Version(), Compiler: runtime.Compiler, Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), diff --git a/pkg/chartutil/capabilities_test.go b/pkg/chartutil/capabilities_test.go index 1f7020a39..666303e44 100644 --- a/pkg/chartutil/capabilities_test.go +++ b/pkg/chartutil/capabilities_test.go @@ -38,9 +38,6 @@ func TestDefaultVersionSet(t *testing.T) { if !DefaultVersionSet.Has("v1") { t.Error("Expected core v1 version set") } - if d := len(DefaultVersionSet); d != 1 { - t.Errorf("Expected only one version, got %d", d) - } } func TestCapabilities(t *testing.T) { @@ -51,4 +48,8 @@ func TestCapabilities(t *testing.T) { if !cap.APIVersions.Has("v1") { t.Error("APIVersions should have v1") } + + if !cap.APIVersions.Has("apps/v1/Deployment") { + t.Error("APIVersions should have apps/v1/Deployment") + } } diff --git a/pkg/chartutil/capabilities_versions_generated.go b/pkg/chartutil/capabilities_versions_generated.go new file mode 100644 index 000000000..bc33a40e8 --- /dev/null +++ b/pkg/chartutil/capabilities_versions_generated.go @@ -0,0 +1,575 @@ +/* +Copyright The Helm Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by capabilities_default_versions_generate.go; DO NOT EDIT. +package chartutil + +func defaultVersions() []string { + return []string{ + "__internal", + "__internal/WatchEvent", + "admissionregistration.k8s.io/__internal", + "admissionregistration.k8s.io/__internal/WatchEvent", + "admissionregistration.k8s.io/v1beta1", + "admissionregistration.k8s.io/v1beta1/CreateOptions", + "admissionregistration.k8s.io/v1beta1/DeleteOptions", + "admissionregistration.k8s.io/v1beta1/ExportOptions", + "admissionregistration.k8s.io/v1beta1/GetOptions", + "admissionregistration.k8s.io/v1beta1/ListOptions", + "admissionregistration.k8s.io/v1beta1/MutatingWebhookConfiguration", + "admissionregistration.k8s.io/v1beta1/MutatingWebhookConfigurationList", + "admissionregistration.k8s.io/v1beta1/PatchOptions", + "admissionregistration.k8s.io/v1beta1/UpdateOptions", + "admissionregistration.k8s.io/v1beta1/ValidatingWebhookConfiguration", + "admissionregistration.k8s.io/v1beta1/ValidatingWebhookConfigurationList", + "admissionregistration.k8s.io/v1beta1/WatchEvent", + "apps/__internal", + "apps/__internal/WatchEvent", + "apps/v1", + "apps/v1/ControllerRevision", + "apps/v1/ControllerRevisionList", + "apps/v1/CreateOptions", + "apps/v1/DaemonSet", + "apps/v1/DaemonSetList", + "apps/v1/DeleteOptions", + "apps/v1/Deployment", + "apps/v1/DeploymentList", + "apps/v1/ExportOptions", + "apps/v1/GetOptions", + "apps/v1/ListOptions", + "apps/v1/PatchOptions", + "apps/v1/ReplicaSet", + "apps/v1/ReplicaSetList", + "apps/v1/StatefulSet", + "apps/v1/StatefulSetList", + "apps/v1/UpdateOptions", + "apps/v1/WatchEvent", + "apps/v1beta1", + "apps/v1beta1/ControllerRevision", + "apps/v1beta1/ControllerRevisionList", + "apps/v1beta1/CreateOptions", + "apps/v1beta1/DeleteOptions", + "apps/v1beta1/Deployment", + "apps/v1beta1/DeploymentList", + "apps/v1beta1/DeploymentRollback", + "apps/v1beta1/ExportOptions", + "apps/v1beta1/GetOptions", + "apps/v1beta1/ListOptions", + "apps/v1beta1/PatchOptions", + "apps/v1beta1/Scale", + "apps/v1beta1/StatefulSet", + "apps/v1beta1/StatefulSetList", + "apps/v1beta1/UpdateOptions", + "apps/v1beta1/WatchEvent", + "apps/v1beta2", + "apps/v1beta2/ControllerRevision", + "apps/v1beta2/ControllerRevisionList", + "apps/v1beta2/CreateOptions", + "apps/v1beta2/DaemonSet", + "apps/v1beta2/DaemonSetList", + "apps/v1beta2/DeleteOptions", + "apps/v1beta2/Deployment", + "apps/v1beta2/DeploymentList", + "apps/v1beta2/ExportOptions", + "apps/v1beta2/GetOptions", + "apps/v1beta2/ListOptions", + "apps/v1beta2/PatchOptions", + "apps/v1beta2/ReplicaSet", + "apps/v1beta2/ReplicaSetList", + "apps/v1beta2/Scale", + "apps/v1beta2/StatefulSet", + "apps/v1beta2/StatefulSetList", + "apps/v1beta2/UpdateOptions", + "apps/v1beta2/WatchEvent", + "auditregistration.k8s.io/__internal", + "auditregistration.k8s.io/__internal/WatchEvent", + "auditregistration.k8s.io/v1alpha1", + "auditregistration.k8s.io/v1alpha1/AuditSink", + "auditregistration.k8s.io/v1alpha1/AuditSinkList", + "auditregistration.k8s.io/v1alpha1/CreateOptions", + "auditregistration.k8s.io/v1alpha1/DeleteOptions", + "auditregistration.k8s.io/v1alpha1/ExportOptions", + "auditregistration.k8s.io/v1alpha1/GetOptions", + "auditregistration.k8s.io/v1alpha1/ListOptions", + "auditregistration.k8s.io/v1alpha1/PatchOptions", + "auditregistration.k8s.io/v1alpha1/UpdateOptions", + "auditregistration.k8s.io/v1alpha1/WatchEvent", + "authentication.k8s.io/__internal", + "authentication.k8s.io/__internal/WatchEvent", + "authentication.k8s.io/v1", + "authentication.k8s.io/v1/CreateOptions", + "authentication.k8s.io/v1/DeleteOptions", + "authentication.k8s.io/v1/ExportOptions", + "authentication.k8s.io/v1/GetOptions", + "authentication.k8s.io/v1/ListOptions", + "authentication.k8s.io/v1/PatchOptions", + "authentication.k8s.io/v1/TokenRequest", + "authentication.k8s.io/v1/TokenReview", + "authentication.k8s.io/v1/UpdateOptions", + "authentication.k8s.io/v1/WatchEvent", + "authentication.k8s.io/v1beta1", + "authentication.k8s.io/v1beta1/CreateOptions", + "authentication.k8s.io/v1beta1/DeleteOptions", + "authentication.k8s.io/v1beta1/ExportOptions", + "authentication.k8s.io/v1beta1/GetOptions", + "authentication.k8s.io/v1beta1/ListOptions", + "authentication.k8s.io/v1beta1/PatchOptions", + "authentication.k8s.io/v1beta1/TokenReview", + "authentication.k8s.io/v1beta1/UpdateOptions", + "authentication.k8s.io/v1beta1/WatchEvent", + "authorization.k8s.io/__internal", + "authorization.k8s.io/__internal/WatchEvent", + "authorization.k8s.io/v1", + "authorization.k8s.io/v1/CreateOptions", + "authorization.k8s.io/v1/DeleteOptions", + "authorization.k8s.io/v1/ExportOptions", + "authorization.k8s.io/v1/GetOptions", + "authorization.k8s.io/v1/ListOptions", + "authorization.k8s.io/v1/LocalSubjectAccessReview", + "authorization.k8s.io/v1/PatchOptions", + "authorization.k8s.io/v1/SelfSubjectAccessReview", + "authorization.k8s.io/v1/SelfSubjectRulesReview", + "authorization.k8s.io/v1/SubjectAccessReview", + "authorization.k8s.io/v1/UpdateOptions", + "authorization.k8s.io/v1/WatchEvent", + "authorization.k8s.io/v1beta1", + "authorization.k8s.io/v1beta1/CreateOptions", + "authorization.k8s.io/v1beta1/DeleteOptions", + "authorization.k8s.io/v1beta1/ExportOptions", + "authorization.k8s.io/v1beta1/GetOptions", + "authorization.k8s.io/v1beta1/ListOptions", + "authorization.k8s.io/v1beta1/LocalSubjectAccessReview", + "authorization.k8s.io/v1beta1/PatchOptions", + "authorization.k8s.io/v1beta1/SelfSubjectAccessReview", + "authorization.k8s.io/v1beta1/SelfSubjectRulesReview", + "authorization.k8s.io/v1beta1/SubjectAccessReview", + "authorization.k8s.io/v1beta1/UpdateOptions", + "authorization.k8s.io/v1beta1/WatchEvent", + "autoscaling/__internal", + "autoscaling/__internal/WatchEvent", + "autoscaling/v1", + "autoscaling/v1/CreateOptions", + "autoscaling/v1/DeleteOptions", + "autoscaling/v1/ExportOptions", + "autoscaling/v1/GetOptions", + "autoscaling/v1/HorizontalPodAutoscaler", + "autoscaling/v1/HorizontalPodAutoscalerList", + "autoscaling/v1/ListOptions", + "autoscaling/v1/PatchOptions", + "autoscaling/v1/Scale", + "autoscaling/v1/UpdateOptions", + "autoscaling/v1/WatchEvent", + "autoscaling/v2beta1", + "autoscaling/v2beta1/CreateOptions", + "autoscaling/v2beta1/DeleteOptions", + "autoscaling/v2beta1/ExportOptions", + "autoscaling/v2beta1/GetOptions", + "autoscaling/v2beta1/HorizontalPodAutoscaler", + "autoscaling/v2beta1/HorizontalPodAutoscalerList", + "autoscaling/v2beta1/ListOptions", + "autoscaling/v2beta1/PatchOptions", + "autoscaling/v2beta1/UpdateOptions", + "autoscaling/v2beta1/WatchEvent", + "autoscaling/v2beta2", + "autoscaling/v2beta2/CreateOptions", + "autoscaling/v2beta2/DeleteOptions", + "autoscaling/v2beta2/ExportOptions", + "autoscaling/v2beta2/GetOptions", + "autoscaling/v2beta2/HorizontalPodAutoscaler", + "autoscaling/v2beta2/HorizontalPodAutoscalerList", + "autoscaling/v2beta2/ListOptions", + "autoscaling/v2beta2/PatchOptions", + "autoscaling/v2beta2/UpdateOptions", + "autoscaling/v2beta2/WatchEvent", + "batch/__internal", + "batch/__internal/WatchEvent", + "batch/v1", + "batch/v1/CreateOptions", + "batch/v1/DeleteOptions", + "batch/v1/ExportOptions", + "batch/v1/GetOptions", + "batch/v1/Job", + "batch/v1/JobList", + "batch/v1/ListOptions", + "batch/v1/PatchOptions", + "batch/v1/UpdateOptions", + "batch/v1/WatchEvent", + "batch/v1beta1", + "batch/v1beta1/CreateOptions", + "batch/v1beta1/CronJob", + "batch/v1beta1/CronJobList", + "batch/v1beta1/DeleteOptions", + "batch/v1beta1/ExportOptions", + "batch/v1beta1/GetOptions", + "batch/v1beta1/JobTemplate", + "batch/v1beta1/ListOptions", + "batch/v1beta1/PatchOptions", + "batch/v1beta1/UpdateOptions", + "batch/v1beta1/WatchEvent", + "batch/v2alpha1", + "batch/v2alpha1/CreateOptions", + "batch/v2alpha1/CronJob", + "batch/v2alpha1/CronJobList", + "batch/v2alpha1/DeleteOptions", + "batch/v2alpha1/ExportOptions", + "batch/v2alpha1/GetOptions", + "batch/v2alpha1/JobTemplate", + "batch/v2alpha1/ListOptions", + "batch/v2alpha1/PatchOptions", + "batch/v2alpha1/UpdateOptions", + "batch/v2alpha1/WatchEvent", + "certificates.k8s.io/__internal", + "certificates.k8s.io/__internal/WatchEvent", + "certificates.k8s.io/v1beta1", + "certificates.k8s.io/v1beta1/CertificateSigningRequest", + "certificates.k8s.io/v1beta1/CertificateSigningRequestList", + "certificates.k8s.io/v1beta1/CreateOptions", + "certificates.k8s.io/v1beta1/DeleteOptions", + "certificates.k8s.io/v1beta1/ExportOptions", + "certificates.k8s.io/v1beta1/GetOptions", + "certificates.k8s.io/v1beta1/ListOptions", + "certificates.k8s.io/v1beta1/PatchOptions", + "certificates.k8s.io/v1beta1/UpdateOptions", + "certificates.k8s.io/v1beta1/WatchEvent", + "coordination.k8s.io/__internal", + "coordination.k8s.io/__internal/WatchEvent", + "coordination.k8s.io/v1", + "coordination.k8s.io/v1/CreateOptions", + "coordination.k8s.io/v1/DeleteOptions", + "coordination.k8s.io/v1/ExportOptions", + "coordination.k8s.io/v1/GetOptions", + "coordination.k8s.io/v1/Lease", + "coordination.k8s.io/v1/LeaseList", + "coordination.k8s.io/v1/ListOptions", + "coordination.k8s.io/v1/PatchOptions", + "coordination.k8s.io/v1/UpdateOptions", + "coordination.k8s.io/v1/WatchEvent", + "coordination.k8s.io/v1beta1", + "coordination.k8s.io/v1beta1/CreateOptions", + "coordination.k8s.io/v1beta1/DeleteOptions", + "coordination.k8s.io/v1beta1/ExportOptions", + "coordination.k8s.io/v1beta1/GetOptions", + "coordination.k8s.io/v1beta1/Lease", + "coordination.k8s.io/v1beta1/LeaseList", + "coordination.k8s.io/v1beta1/ListOptions", + "coordination.k8s.io/v1beta1/PatchOptions", + "coordination.k8s.io/v1beta1/UpdateOptions", + "coordination.k8s.io/v1beta1/WatchEvent", + "events.k8s.io/__internal", + "events.k8s.io/__internal/WatchEvent", + "events.k8s.io/v1beta1", + "events.k8s.io/v1beta1/CreateOptions", + "events.k8s.io/v1beta1/DeleteOptions", + "events.k8s.io/v1beta1/Event", + "events.k8s.io/v1beta1/EventList", + "events.k8s.io/v1beta1/ExportOptions", + "events.k8s.io/v1beta1/GetOptions", + "events.k8s.io/v1beta1/ListOptions", + "events.k8s.io/v1beta1/PatchOptions", + "events.k8s.io/v1beta1/UpdateOptions", + "events.k8s.io/v1beta1/WatchEvent", + "extensions/__internal", + "extensions/__internal/WatchEvent", + "extensions/v1beta1", + "extensions/v1beta1/CreateOptions", + "extensions/v1beta1/DaemonSet", + "extensions/v1beta1/DaemonSetList", + "extensions/v1beta1/DeleteOptions", + "extensions/v1beta1/Deployment", + "extensions/v1beta1/DeploymentList", + "extensions/v1beta1/DeploymentRollback", + "extensions/v1beta1/ExportOptions", + "extensions/v1beta1/GetOptions", + "extensions/v1beta1/Ingress", + "extensions/v1beta1/IngressList", + "extensions/v1beta1/ListOptions", + "extensions/v1beta1/NetworkPolicy", + "extensions/v1beta1/NetworkPolicyList", + "extensions/v1beta1/PatchOptions", + "extensions/v1beta1/PodSecurityPolicy", + "extensions/v1beta1/PodSecurityPolicyList", + "extensions/v1beta1/ReplicaSet", + "extensions/v1beta1/ReplicaSetList", + "extensions/v1beta1/ReplicationControllerDummy", + "extensions/v1beta1/Scale", + "extensions/v1beta1/UpdateOptions", + "extensions/v1beta1/WatchEvent", + "networking.k8s.io/__internal", + "networking.k8s.io/__internal/WatchEvent", + "networking.k8s.io/v1", + "networking.k8s.io/v1/CreateOptions", + "networking.k8s.io/v1/DeleteOptions", + "networking.k8s.io/v1/ExportOptions", + "networking.k8s.io/v1/GetOptions", + "networking.k8s.io/v1/ListOptions", + "networking.k8s.io/v1/NetworkPolicy", + "networking.k8s.io/v1/NetworkPolicyList", + "networking.k8s.io/v1/PatchOptions", + "networking.k8s.io/v1/UpdateOptions", + "networking.k8s.io/v1/WatchEvent", + "networking.k8s.io/v1beta1", + "networking.k8s.io/v1beta1/CreateOptions", + "networking.k8s.io/v1beta1/DeleteOptions", + "networking.k8s.io/v1beta1/ExportOptions", + "networking.k8s.io/v1beta1/GetOptions", + "networking.k8s.io/v1beta1/Ingress", + "networking.k8s.io/v1beta1/IngressList", + "networking.k8s.io/v1beta1/ListOptions", + "networking.k8s.io/v1beta1/PatchOptions", + "networking.k8s.io/v1beta1/UpdateOptions", + "networking.k8s.io/v1beta1/WatchEvent", + "node.k8s.io/__internal", + "node.k8s.io/__internal/WatchEvent", + "node.k8s.io/v1alpha1", + "node.k8s.io/v1alpha1/CreateOptions", + "node.k8s.io/v1alpha1/DeleteOptions", + "node.k8s.io/v1alpha1/ExportOptions", + "node.k8s.io/v1alpha1/GetOptions", + "node.k8s.io/v1alpha1/ListOptions", + "node.k8s.io/v1alpha1/PatchOptions", + "node.k8s.io/v1alpha1/RuntimeClass", + "node.k8s.io/v1alpha1/RuntimeClassList", + "node.k8s.io/v1alpha1/UpdateOptions", + "node.k8s.io/v1alpha1/WatchEvent", + "node.k8s.io/v1beta1", + "node.k8s.io/v1beta1/CreateOptions", + "node.k8s.io/v1beta1/DeleteOptions", + "node.k8s.io/v1beta1/ExportOptions", + "node.k8s.io/v1beta1/GetOptions", + "node.k8s.io/v1beta1/ListOptions", + "node.k8s.io/v1beta1/PatchOptions", + "node.k8s.io/v1beta1/RuntimeClass", + "node.k8s.io/v1beta1/RuntimeClassList", + "node.k8s.io/v1beta1/UpdateOptions", + "node.k8s.io/v1beta1/WatchEvent", + "policy/__internal", + "policy/__internal/WatchEvent", + "policy/v1beta1", + "policy/v1beta1/CreateOptions", + "policy/v1beta1/DeleteOptions", + "policy/v1beta1/Eviction", + "policy/v1beta1/ExportOptions", + "policy/v1beta1/GetOptions", + "policy/v1beta1/ListOptions", + "policy/v1beta1/PatchOptions", + "policy/v1beta1/PodDisruptionBudget", + "policy/v1beta1/PodDisruptionBudgetList", + "policy/v1beta1/PodSecurityPolicy", + "policy/v1beta1/PodSecurityPolicyList", + "policy/v1beta1/UpdateOptions", + "policy/v1beta1/WatchEvent", + "rbac.authorization.k8s.io/__internal", + "rbac.authorization.k8s.io/__internal/WatchEvent", + "rbac.authorization.k8s.io/v1", + "rbac.authorization.k8s.io/v1/ClusterRole", + "rbac.authorization.k8s.io/v1/ClusterRoleBinding", + "rbac.authorization.k8s.io/v1/ClusterRoleBindingList", + "rbac.authorization.k8s.io/v1/ClusterRoleList", + "rbac.authorization.k8s.io/v1/CreateOptions", + "rbac.authorization.k8s.io/v1/DeleteOptions", + "rbac.authorization.k8s.io/v1/ExportOptions", + "rbac.authorization.k8s.io/v1/GetOptions", + "rbac.authorization.k8s.io/v1/ListOptions", + "rbac.authorization.k8s.io/v1/PatchOptions", + "rbac.authorization.k8s.io/v1/Role", + "rbac.authorization.k8s.io/v1/RoleBinding", + "rbac.authorization.k8s.io/v1/RoleBindingList", + "rbac.authorization.k8s.io/v1/RoleList", + "rbac.authorization.k8s.io/v1/UpdateOptions", + "rbac.authorization.k8s.io/v1/WatchEvent", + "rbac.authorization.k8s.io/v1alpha1", + "rbac.authorization.k8s.io/v1alpha1/ClusterRole", + "rbac.authorization.k8s.io/v1alpha1/ClusterRoleBinding", + "rbac.authorization.k8s.io/v1alpha1/ClusterRoleBindingList", + "rbac.authorization.k8s.io/v1alpha1/ClusterRoleList", + "rbac.authorization.k8s.io/v1alpha1/CreateOptions", + "rbac.authorization.k8s.io/v1alpha1/DeleteOptions", + "rbac.authorization.k8s.io/v1alpha1/ExportOptions", + "rbac.authorization.k8s.io/v1alpha1/GetOptions", + "rbac.authorization.k8s.io/v1alpha1/ListOptions", + "rbac.authorization.k8s.io/v1alpha1/PatchOptions", + "rbac.authorization.k8s.io/v1alpha1/Role", + "rbac.authorization.k8s.io/v1alpha1/RoleBinding", + "rbac.authorization.k8s.io/v1alpha1/RoleBindingList", + "rbac.authorization.k8s.io/v1alpha1/RoleList", + "rbac.authorization.k8s.io/v1alpha1/UpdateOptions", + "rbac.authorization.k8s.io/v1alpha1/WatchEvent", + "rbac.authorization.k8s.io/v1beta1", + "rbac.authorization.k8s.io/v1beta1/ClusterRole", + "rbac.authorization.k8s.io/v1beta1/ClusterRoleBinding", + "rbac.authorization.k8s.io/v1beta1/ClusterRoleBindingList", + "rbac.authorization.k8s.io/v1beta1/ClusterRoleList", + "rbac.authorization.k8s.io/v1beta1/CreateOptions", + "rbac.authorization.k8s.io/v1beta1/DeleteOptions", + "rbac.authorization.k8s.io/v1beta1/ExportOptions", + "rbac.authorization.k8s.io/v1beta1/GetOptions", + "rbac.authorization.k8s.io/v1beta1/ListOptions", + "rbac.authorization.k8s.io/v1beta1/PatchOptions", + "rbac.authorization.k8s.io/v1beta1/Role", + "rbac.authorization.k8s.io/v1beta1/RoleBinding", + "rbac.authorization.k8s.io/v1beta1/RoleBindingList", + "rbac.authorization.k8s.io/v1beta1/RoleList", + "rbac.authorization.k8s.io/v1beta1/UpdateOptions", + "rbac.authorization.k8s.io/v1beta1/WatchEvent", + "scheduling.k8s.io/__internal", + "scheduling.k8s.io/__internal/WatchEvent", + "scheduling.k8s.io/v1", + "scheduling.k8s.io/v1/CreateOptions", + "scheduling.k8s.io/v1/DeleteOptions", + "scheduling.k8s.io/v1/ExportOptions", + "scheduling.k8s.io/v1/GetOptions", + "scheduling.k8s.io/v1/ListOptions", + "scheduling.k8s.io/v1/PatchOptions", + "scheduling.k8s.io/v1/PriorityClass", + "scheduling.k8s.io/v1/PriorityClassList", + "scheduling.k8s.io/v1/UpdateOptions", + "scheduling.k8s.io/v1/WatchEvent", + "scheduling.k8s.io/v1alpha1", + "scheduling.k8s.io/v1alpha1/CreateOptions", + "scheduling.k8s.io/v1alpha1/DeleteOptions", + "scheduling.k8s.io/v1alpha1/ExportOptions", + "scheduling.k8s.io/v1alpha1/GetOptions", + "scheduling.k8s.io/v1alpha1/ListOptions", + "scheduling.k8s.io/v1alpha1/PatchOptions", + "scheduling.k8s.io/v1alpha1/PriorityClass", + "scheduling.k8s.io/v1alpha1/PriorityClassList", + "scheduling.k8s.io/v1alpha1/UpdateOptions", + "scheduling.k8s.io/v1alpha1/WatchEvent", + "scheduling.k8s.io/v1beta1", + "scheduling.k8s.io/v1beta1/CreateOptions", + "scheduling.k8s.io/v1beta1/DeleteOptions", + "scheduling.k8s.io/v1beta1/ExportOptions", + "scheduling.k8s.io/v1beta1/GetOptions", + "scheduling.k8s.io/v1beta1/ListOptions", + "scheduling.k8s.io/v1beta1/PatchOptions", + "scheduling.k8s.io/v1beta1/PriorityClass", + "scheduling.k8s.io/v1beta1/PriorityClassList", + "scheduling.k8s.io/v1beta1/UpdateOptions", + "scheduling.k8s.io/v1beta1/WatchEvent", + "settings.k8s.io/__internal", + "settings.k8s.io/__internal/WatchEvent", + "settings.k8s.io/v1alpha1", + "settings.k8s.io/v1alpha1/CreateOptions", + "settings.k8s.io/v1alpha1/DeleteOptions", + "settings.k8s.io/v1alpha1/ExportOptions", + "settings.k8s.io/v1alpha1/GetOptions", + "settings.k8s.io/v1alpha1/ListOptions", + "settings.k8s.io/v1alpha1/PatchOptions", + "settings.k8s.io/v1alpha1/PodPreset", + "settings.k8s.io/v1alpha1/PodPresetList", + "settings.k8s.io/v1alpha1/UpdateOptions", + "settings.k8s.io/v1alpha1/WatchEvent", + "storage.k8s.io/__internal", + "storage.k8s.io/__internal/WatchEvent", + "storage.k8s.io/v1", + "storage.k8s.io/v1/CreateOptions", + "storage.k8s.io/v1/DeleteOptions", + "storage.k8s.io/v1/ExportOptions", + "storage.k8s.io/v1/GetOptions", + "storage.k8s.io/v1/ListOptions", + "storage.k8s.io/v1/PatchOptions", + "storage.k8s.io/v1/StorageClass", + "storage.k8s.io/v1/StorageClassList", + "storage.k8s.io/v1/UpdateOptions", + "storage.k8s.io/v1/VolumeAttachment", + "storage.k8s.io/v1/VolumeAttachmentList", + "storage.k8s.io/v1/WatchEvent", + "storage.k8s.io/v1alpha1", + "storage.k8s.io/v1alpha1/CreateOptions", + "storage.k8s.io/v1alpha1/DeleteOptions", + "storage.k8s.io/v1alpha1/ExportOptions", + "storage.k8s.io/v1alpha1/GetOptions", + "storage.k8s.io/v1alpha1/ListOptions", + "storage.k8s.io/v1alpha1/PatchOptions", + "storage.k8s.io/v1alpha1/UpdateOptions", + "storage.k8s.io/v1alpha1/VolumeAttachment", + "storage.k8s.io/v1alpha1/VolumeAttachmentList", + "storage.k8s.io/v1alpha1/WatchEvent", + "storage.k8s.io/v1beta1", + "storage.k8s.io/v1beta1/CSIDriver", + "storage.k8s.io/v1beta1/CSIDriverList", + "storage.k8s.io/v1beta1/CSINode", + "storage.k8s.io/v1beta1/CSINodeList", + "storage.k8s.io/v1beta1/CreateOptions", + "storage.k8s.io/v1beta1/DeleteOptions", + "storage.k8s.io/v1beta1/ExportOptions", + "storage.k8s.io/v1beta1/GetOptions", + "storage.k8s.io/v1beta1/ListOptions", + "storage.k8s.io/v1beta1/PatchOptions", + "storage.k8s.io/v1beta1/StorageClass", + "storage.k8s.io/v1beta1/StorageClassList", + "storage.k8s.io/v1beta1/UpdateOptions", + "storage.k8s.io/v1beta1/VolumeAttachment", + "storage.k8s.io/v1beta1/VolumeAttachmentList", + "storage.k8s.io/v1beta1/WatchEvent", + "v1", + "v1/APIGroup", + "v1/APIGroupList", + "v1/APIResourceList", + "v1/APIVersions", + "v1/Binding", + "v1/ComponentStatus", + "v1/ComponentStatusList", + "v1/ConfigMap", + "v1/ConfigMapList", + "v1/CreateOptions", + "v1/DeleteOptions", + "v1/Endpoints", + "v1/EndpointsList", + "v1/Event", + "v1/EventList", + "v1/ExportOptions", + "v1/GetOptions", + "v1/LimitRange", + "v1/LimitRangeList", + "v1/List", + "v1/ListOptions", + "v1/Namespace", + "v1/NamespaceList", + "v1/Node", + "v1/NodeList", + "v1/NodeProxyOptions", + "v1/PatchOptions", + "v1/PersistentVolume", + "v1/PersistentVolumeClaim", + "v1/PersistentVolumeClaimList", + "v1/PersistentVolumeList", + "v1/Pod", + "v1/PodAttachOptions", + "v1/PodExecOptions", + "v1/PodList", + "v1/PodLogOptions", + "v1/PodPortForwardOptions", + "v1/PodProxyOptions", + "v1/PodStatusResult", + "v1/PodTemplate", + "v1/PodTemplateList", + "v1/RangeAllocation", + "v1/ReplicationController", + "v1/ReplicationControllerList", + "v1/ResourceQuota", + "v1/ResourceQuotaList", + "v1/Secret", + "v1/SecretList", + "v1/SerializedReference", + "v1/Service", + "v1/ServiceAccount", + "v1/ServiceAccountList", + "v1/ServiceList", + "v1/ServiceProxyOptions", + "v1/Status", + "v1/UpdateOptions", + "v1/WatchEvent", + } +} diff --git a/pkg/chartutil/generator/capabilities_default_versions_generate.go b/pkg/chartutil/generator/capabilities_default_versions_generate.go new file mode 100644 index 000000000..4ed312465 --- /dev/null +++ b/pkg/chartutil/generator/capabilities_default_versions_generate.go @@ -0,0 +1,106 @@ +/* +Copyright The Helm Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Generates the default versions to use with capabilities. This cannot be loaded +// dynamically as it uses enough memory to cause out of memory issues in CI. +// +// +build ignore +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "path" + "sort" + + "k8s.io/client-go/kubernetes/scheme" +) + +const licenseHeader = `/* +Copyright The Helm Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/` + +func main() { + v := getVersions() + + o := createOutput(v) + + err := ioutil.WriteFile("capabilities_versions_generated.go", o, 0644) + if err != nil { + fmt.Printf("writing output: %s", err) + os.Exit(1) + } +} + +func createOutput(v []string) []byte { + var out bytes.Buffer + + fmt.Fprintln(&out, licenseHeader) + fmt.Fprintln(&out, "// Code generated by capabilities_default_versions_generate.go; DO NOT EDIT.") + fmt.Fprint(&out, "package chartutil\n\n") + fmt.Fprintln(&out, "func defaultVersions() []string {") + fmt.Fprintln(&out, "\treturn []string{") + + for _, v := range v { + fmt.Fprintf(&out, "\t\t\"%s\",\n", v) + } + + fmt.Fprintln(&out, "\t}") + fmt.Fprintln(&out, "}") + + return out.Bytes() +} + +func getVersions() []string { + + var s []string + var gv string + var gvk string + + // Check is used so that we only add an item once to the return + check := make(map[string]struct{}) + + // Client go has a default scheme set with everything in it + // This includes over 500 group versions and group versioned kinds + for k := range scheme.Scheme.AllKnownTypes() { + gv = path.Join(k.Group, k.Version) + gvk = path.Join(k.Group, k.Version, k.Kind) + if _, ok := check[gv]; !ok { + check[gv] = struct{}{} + s = append(s, gv) + } + if _, ok := check[gvk]; !ok { + check[gvk] = struct{}{} + s = append(s, gvk) + } + } + + // Put the names in a consistent order + sort.Strings(s) + + return s +} From 23b61a183d0d1ef107e4f34f57178c5fcbaf4832 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Tue, 18 Jun 2019 12:17:16 -0400 Subject: [PATCH 27/82] Updating sprig dependency version Also updated cobra Signed-off-by: Matt Farina --- glide.lock | 8 ++++---- glide.yaml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/glide.lock b/glide.lock index a9d12597c..11f8aba60 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 7104a8ce1f0b3f2338d10b102b3ba9bfd308000396cc9edb43095c2a2e133272 -updated: 2019-06-05T21:58:04.295502-04:00 +hash: 9e12e35a6ad263380590ad000d9013499107f3ed47a454e2f96133156b6f09d5 +updated: 2019-06-18T12:14:56.802884-04:00 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -200,7 +200,7 @@ imports: - name: github.com/Masterminds/semver version: c7af12943936e8c39859482e61f0574c2fd7fc75 - name: github.com/Masterminds/sprig - version: 9f8fceff796fb9f4e992cd2bece016be0121ab74 + version: 258b00ffa7318e8b109a141349980ffbd30a35db - name: github.com/Masterminds/vcs version: 3084677c2c188840777bff30054f2b553729d329 - name: github.com/mattn/go-runewidth @@ -256,7 +256,7 @@ imports: - name: github.com/sirupsen/logrus version: 89742aefa4b206dcf400792f3bd35b542998eb3b - name: github.com/spf13/cobra - version: 67fc4837d267bc9bfd6e47f77783fcc3dffc68de + version: f2b07da1e2c38d5f12845a4f607e2e1018cbb1f5 subpackages: - doc - name: github.com/spf13/pflag diff --git a/glide.yaml b/glide.yaml index 49e9eec4d..ecefde2e0 100644 --- a/glide.yaml +++ b/glide.yaml @@ -19,7 +19,7 @@ import: - package: github.com/imdario/mergo version: v0.3.5 - package: github.com/Masterminds/sprig - version: ^2.19.0 + version: ^2.20.0 - package: github.com/ghodss/yaml - package: github.com/Masterminds/semver version: ~1.4.2 From cb2207c2fbddba7f0cabb626ecb7b02370ca9faa Mon Sep 17 00:00:00 2001 From: Morten Torkildsen Date: Sat, 30 Mar 2019 18:11:03 -0700 Subject: [PATCH 28/82] fix(helm): Delete hooks should wait for resource to be removed from etcd before continuing Signed-off-by: Morten Torkildsen --- _proto/hapi/release/hook.proto | 2 + docs/charts_hooks.md | 4 + pkg/hooks/hooks.go | 2 + pkg/kube/client.go | 42 +++++++- pkg/kube/client_test.go | 48 ++++++++++ pkg/proto/hapi/release/hook.pb.go | 90 +++++++++-------- pkg/tiller/environment/environment.go | 18 ++++ pkg/tiller/environment/environment_test.go | 3 + pkg/tiller/hooks.go | 15 +++ pkg/tiller/hooks_test.go | 106 +++++++++++++++++++++ pkg/tiller/release_server.go | 3 +- pkg/tiller/release_server_test.go | 7 ++ 12 files changed, 298 insertions(+), 42 deletions(-) diff --git a/_proto/hapi/release/hook.proto b/_proto/hapi/release/hook.proto index cf7e25bf6..77fbbe5d5 100644 --- a/_proto/hapi/release/hook.proto +++ b/_proto/hapi/release/hook.proto @@ -56,4 +56,6 @@ message Hook { int32 weight = 7; // DeletePolicies are the policies that indicate when to delete the hook repeated DeletePolicy delete_policies = 8; + // DeleteTimeout indicates how long to wait for a resource to be deleted before timing out + int64 delete_timeout = 9; } diff --git a/docs/charts_hooks.md b/docs/charts_hooks.md index 3044414c3..1a9341d5c 100644 --- a/docs/charts_hooks.md +++ b/docs/charts_hooks.md @@ -199,6 +199,10 @@ You can choose one or more defined annotation values: * `"hook-failed"` specifies Tiller should delete the hook if the hook failed during execution. * `"before-hook-creation"` specifies Tiller should delete the previous hook before the new hook is launched. +By default Tiller will wait for 60 seconds for a deleted hook to no longer exist in the API server before timing out. This +behavior can be changed using the `helm.sh/hook-delete-timeout` annotation. The value is the number of seconds Tiller +should wait for the hook to be fully deleted. A value of 0 means Tiller does not wait at all. + ### Defining a CRD with the `crd-install` Hook Custom Resource Definitions (CRDs) are a special kind in Kubernetes. They provide diff --git a/pkg/hooks/hooks.go b/pkg/hooks/hooks.go index 13a09b08b..6d60fad51 100644 --- a/pkg/hooks/hooks.go +++ b/pkg/hooks/hooks.go @@ -27,6 +27,8 @@ const ( HookWeightAnno = "helm.sh/hook-weight" // HookDeleteAnno is the label name for the delete policy for a hook HookDeleteAnno = "helm.sh/hook-delete-policy" + // HookDeleteTimeoutAnno is the label name for the timeout value for delete policies + HookDeleteTimeoutAnno = "helm.sh/hook-delete-timeout" ) // Types of hooks diff --git a/pkg/kube/client.go b/pkg/kube/client.go index aa025eb0a..b9c7f8a96 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -449,15 +449,34 @@ func (c *Client) cleanup(newlyCreatedResources []*resource.Info) (cleanupErrors // // Namespace will set the namespace. func (c *Client) Delete(namespace string, reader io.Reader) error { + return c.DeleteWithTimeout(namespace, reader, 0, false) +} + +// DeleteWithTimeout deletes Kubernetes resources from an io.reader. If shouldWait is true, the function +// will wait for all resources to be deleted from etcd before returning, or when the timeout +// has expired. +// +// Namespace will set the namespace. +func (c *Client) DeleteWithTimeout(namespace string, reader io.Reader, timeout int64, shouldWait bool) error { infos, err := c.BuildUnstructured(namespace, reader) if err != nil { return err } - return perform(infos, func(info *resource.Info) error { + err = perform(infos, func(info *resource.Info) error { c.Log("Starting delete for %q %s", info.Name, info.Mapping.GroupVersionKind.Kind) err := deleteResource(info) return c.skipIfNotFound(err) }) + if err != nil { + return err + } + + if shouldWait { + c.Log("Waiting for %d seconds for delete to be completed", timeout) + return waitUntilAllResourceDeleted(infos, time.Duration(timeout)*time.Second) + } + + return nil } func (c *Client) skipIfNotFound(err error) error { @@ -468,6 +487,27 @@ func (c *Client) skipIfNotFound(err error) error { return err } +func waitUntilAllResourceDeleted(infos Result, timeout time.Duration) error { + return wait.Poll(2*time.Second, timeout, func() (bool, error) { + allDeleted := true + err := perform(infos, func(info *resource.Info) error { + innerErr := info.Get() + if errors.IsNotFound(innerErr) { + return nil + } + if innerErr != nil { + return innerErr + } + allDeleted = false + return nil + }) + if err != nil { + return false, err + } + return allDeleted, nil + }) +} + func (c *Client) watchTimeout(t time.Duration) ResourceActorFunc { return func(info *resource.Info) error { return c.watchUntilReady(t, info) diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go index 810abdf17..0c280f3e5 100644 --- a/pkg/kube/client_test.go +++ b/pkg/kube/client_test.go @@ -283,6 +283,54 @@ func TestUpdateNonManagedResourceError(t *testing.T) { } } +func TestDeleteWithTimeout(t *testing.T) { + testCases := map[string]struct { + deleteTimeout int64 + deleteAfter time.Duration + success bool + }{ + "resource is deleted within timeout period": { + int64((2 * time.Minute).Seconds()), + 10 * time.Second, + true, + }, + "resource is not deleted within the timeout period": { + int64((10 * time.Second).Seconds()), + 20 * time.Second, + false, + }, + } + + for tn, tc := range testCases { + t.Run(tn, func(t *testing.T) { + c := newTestClient() + defer c.Cleanup() + + service := newService("my-service") + startTime := time.Now() + c.TestFactory.UnstructuredClient = &fake.RESTClient{ + GroupVersion: schema.GroupVersion{Version: "v1"}, + NegotiatedSerializer: unstructuredSerializer, + Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { + currentTime := time.Now() + if startTime.Add(tc.deleteAfter).Before(currentTime) { + return newResponse(404, notFoundBody()) + } + return newResponse(200, &service) + }), + } + + err := c.DeleteWithTimeout(metav1.NamespaceDefault, strings.NewReader(testServiceManifest), tc.deleteTimeout, true) + if err != nil && tc.success { + t.Errorf("expected no error, but got %v", err) + } + if err == nil && !tc.success { + t.Errorf("expected error, but didn't get one") + } + }) + } +} + func TestBuild(t *testing.T) { tests := []struct { name string diff --git a/pkg/proto/hapi/release/hook.pb.go b/pkg/proto/hapi/release/hook.pb.go index bec2049b6..2faf756d7 100644 --- a/pkg/proto/hapi/release/hook.pb.go +++ b/pkg/proto/hapi/release/hook.pb.go @@ -69,7 +69,7 @@ func (x Hook_Event) String() string { return proto.EnumName(Hook_Event_name, int32(x)) } func (Hook_Event) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_hook_8076b1a80af16030, []int{0, 0} + return fileDescriptor_hook_e64400ca8195038e, []int{0, 0} } type Hook_DeletePolicy int32 @@ -95,7 +95,7 @@ func (x Hook_DeletePolicy) String() string { return proto.EnumName(Hook_DeletePolicy_name, int32(x)) } func (Hook_DeletePolicy) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_hook_8076b1a80af16030, []int{0, 1} + return fileDescriptor_hook_e64400ca8195038e, []int{0, 1} } // Hook defines a hook object. @@ -114,17 +114,19 @@ type Hook struct { // Weight indicates the sort order for execution among similar Hook type Weight int32 `protobuf:"varint,7,opt,name=weight,proto3" json:"weight,omitempty"` // DeletePolicies are the policies that indicate when to delete the hook - DeletePolicies []Hook_DeletePolicy `protobuf:"varint,8,rep,packed,name=delete_policies,json=deletePolicies,proto3,enum=hapi.release.Hook_DeletePolicy" json:"delete_policies,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + DeletePolicies []Hook_DeletePolicy `protobuf:"varint,8,rep,packed,name=delete_policies,json=deletePolicies,proto3,enum=hapi.release.Hook_DeletePolicy" json:"delete_policies,omitempty"` + // DeleteTimeout indicates how long to wait for a resource to be deleted before timing out + DeleteTimeout int64 `protobuf:"varint,9,opt,name=delete_timeout,json=deleteTimeout,proto3" json:"delete_timeout,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Hook) Reset() { *m = Hook{} } func (m *Hook) String() string { return proto.CompactTextString(m) } func (*Hook) ProtoMessage() {} func (*Hook) Descriptor() ([]byte, []int) { - return fileDescriptor_hook_8076b1a80af16030, []int{0} + return fileDescriptor_hook_e64400ca8195038e, []int{0} } func (m *Hook) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Hook.Unmarshal(m, b) @@ -200,43 +202,51 @@ func (m *Hook) GetDeletePolicies() []Hook_DeletePolicy { return nil } +func (m *Hook) GetDeleteTimeout() int64 { + if m != nil { + return m.DeleteTimeout + } + return 0 +} + func init() { proto.RegisterType((*Hook)(nil), "hapi.release.Hook") proto.RegisterEnum("hapi.release.Hook_Event", Hook_Event_name, Hook_Event_value) proto.RegisterEnum("hapi.release.Hook_DeletePolicy", Hook_DeletePolicy_name, Hook_DeletePolicy_value) } -func init() { proto.RegisterFile("hapi/release/hook.proto", fileDescriptor_hook_8076b1a80af16030) } - -var fileDescriptor_hook_8076b1a80af16030 = []byte{ - // 453 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x51, 0x8f, 0x9a, 0x40, - 0x10, 0x80, 0x8f, 0x53, 0x41, 0x47, 0xcf, 0xdb, 0x6e, 0x9a, 0x76, 0xe3, 0xcb, 0x19, 0x9f, 0x7c, - 0xc2, 0xe6, 0x9a, 0xfe, 0x00, 0x84, 0xb9, 0x6a, 0x24, 0x60, 0x16, 0x4c, 0x93, 0xbe, 0x10, 0xae, - 0xee, 0x29, 0x11, 0x81, 0x08, 0xb6, 0xe9, 0x1f, 0xed, 0x3f, 0xe8, 0xff, 0x68, 0x76, 0x45, 0x7a, - 0x49, 0xfb, 0x36, 0xf3, 0xcd, 0xb7, 0xb3, 0x33, 0xbb, 0xf0, 0x7e, 0x1f, 0x17, 0xc9, 0xec, 0x24, - 0x52, 0x11, 0x97, 0x62, 0xb6, 0xcf, 0xf3, 0x83, 0x59, 0x9c, 0xf2, 0x2a, 0xa7, 0x03, 0x59, 0x30, - 0xeb, 0xc2, 0xe8, 0x61, 0x97, 0xe7, 0xbb, 0x54, 0xcc, 0x54, 0xed, 0xf9, 0xfc, 0x32, 0xab, 0x92, - 0xa3, 0x28, 0xab, 0xf8, 0x58, 0x5c, 0xf4, 0xc9, 0xaf, 0x36, 0xb4, 0x17, 0x79, 0x7e, 0xa0, 0x14, - 0xda, 0x59, 0x7c, 0x14, 0x4c, 0x1b, 0x6b, 0xd3, 0x1e, 0x57, 0xb1, 0x64, 0x87, 0x24, 0xdb, 0xb2, - 0xdb, 0x0b, 0x93, 0xb1, 0x64, 0x45, 0x5c, 0xed, 0x59, 0xeb, 0xc2, 0x64, 0x4c, 0x47, 0xd0, 0x3d, - 0xc6, 0x59, 0xf2, 0x22, 0xca, 0x8a, 0xb5, 0x15, 0x6f, 0x72, 0xfa, 0x01, 0x74, 0xf1, 0x5d, 0x64, - 0x55, 0xc9, 0x3a, 0xe3, 0xd6, 0x74, 0xf8, 0xc8, 0xcc, 0xd7, 0x03, 0x9a, 0xf2, 0x6e, 0x13, 0xa5, - 0xc0, 0x6b, 0x8f, 0x7e, 0x82, 0x6e, 0x1a, 0x97, 0x55, 0x74, 0x3a, 0x67, 0x4c, 0x1f, 0x6b, 0xd3, - 0xfe, 0xe3, 0xc8, 0xbc, 0xac, 0x61, 0x5e, 0xd7, 0x30, 0xc3, 0xeb, 0x1a, 0xdc, 0x90, 0x2e, 0x3f, - 0x67, 0xf4, 0x1d, 0xe8, 0x3f, 0x44, 0xb2, 0xdb, 0x57, 0xcc, 0x18, 0x6b, 0xd3, 0x0e, 0xaf, 0x33, - 0xba, 0x80, 0xfb, 0xad, 0x48, 0x45, 0x25, 0xa2, 0x22, 0x4f, 0x93, 0x6f, 0x89, 0x28, 0x59, 0x57, - 0x4d, 0xf2, 0xf0, 0x9f, 0x49, 0x1c, 0x65, 0xae, 0xa5, 0xf8, 0x93, 0x0f, 0xb7, 0x7f, 0xb3, 0x44, - 0x94, 0x93, 0xdf, 0x1a, 0x74, 0xd4, 0xa8, 0xb4, 0x0f, 0xc6, 0xc6, 0x5b, 0x79, 0xfe, 0x17, 0x8f, - 0xdc, 0xd0, 0x7b, 0xe8, 0xaf, 0x39, 0x46, 0x4b, 0x2f, 0x08, 0x2d, 0xd7, 0x25, 0x1a, 0x25, 0x30, - 0x58, 0xfb, 0x41, 0xd8, 0x90, 0x5b, 0x3a, 0x04, 0x90, 0x8a, 0x83, 0x2e, 0x86, 0x48, 0x5a, 0xea, - 0x88, 0x34, 0x6a, 0xd0, 0xbe, 0xf6, 0xd8, 0xac, 0x3f, 0x73, 0xcb, 0x41, 0xd2, 0x69, 0x7a, 0x5c, - 0x89, 0xae, 0x08, 0xc7, 0x88, 0xfb, 0xae, 0x3b, 0xb7, 0xec, 0x15, 0x31, 0xe8, 0x1b, 0xb8, 0x53, - 0x4e, 0x83, 0xba, 0x94, 0xc1, 0x5b, 0x8e, 0x2e, 0x5a, 0x01, 0x46, 0x21, 0x06, 0x61, 0x14, 0x6c, - 0x6c, 0x1b, 0x83, 0x80, 0xf4, 0xfe, 0xa9, 0x3c, 0x59, 0x4b, 0x77, 0xc3, 0x91, 0x80, 0xbc, 0xdb, - 0xe6, 0x4e, 0x33, 0x6d, 0x7f, 0x62, 0xc3, 0xe0, 0xf5, 0x3b, 0xd0, 0x3b, 0xe8, 0xa9, 0x3e, 0xe8, - 0xa0, 0x43, 0x6e, 0x28, 0x80, 0x2e, 0x0f, 0xa3, 0x43, 0x34, 0xd9, 0x75, 0x8e, 0x4f, 0x3e, 0xc7, - 0x68, 0xe1, 0xfb, 0xab, 0xc8, 0xe6, 0x68, 0x85, 0x4b, 0xdf, 0x23, 0xb7, 0xf3, 0xde, 0x57, 0xa3, - 0x7e, 0xd9, 0x67, 0x5d, 0x7d, 0xdb, 0xc7, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x3b, 0xcf, 0xed, - 0xd9, 0xb4, 0x02, 0x00, 0x00, +func init() { proto.RegisterFile("hapi/release/hook.proto", fileDescriptor_hook_e64400ca8195038e) } + +var fileDescriptor_hook_e64400ca8195038e = []byte{ + // 473 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0xdb, 0x8e, 0xda, 0x3c, + 0x10, 0x80, 0x37, 0x1c, 0x02, 0x0c, 0x87, 0xf5, 0x6f, 0xfd, 0x6a, 0x2d, 0x6e, 0x16, 0x21, 0x55, + 0xe2, 0x2a, 0x54, 0x5b, 0xf5, 0x01, 0x42, 0xe2, 0x2d, 0x88, 0x88, 0x20, 0x27, 0xa8, 0x52, 0x6f, + 0xa2, 0x6c, 0xf1, 0x42, 0x44, 0x88, 0x23, 0x62, 0x5a, 0xf5, 0x81, 0xfb, 0x18, 0x95, 0x2a, 0x3b, + 0x21, 0x5d, 0xa9, 0xbd, 0x9b, 0xf9, 0xe6, 0xf3, 0x78, 0xc6, 0x86, 0xb7, 0xc7, 0x38, 0x4f, 0xe6, + 0x17, 0x9e, 0xf2, 0xb8, 0xe0, 0xf3, 0xa3, 0x10, 0x27, 0x2b, 0xbf, 0x08, 0x29, 0xf0, 0x40, 0x15, + 0xac, 0xaa, 0x30, 0x7e, 0x38, 0x08, 0x71, 0x48, 0xf9, 0x5c, 0xd7, 0x9e, 0xaf, 0x2f, 0x73, 0x99, + 0x9c, 0x79, 0x21, 0xe3, 0x73, 0x5e, 0xea, 0xd3, 0x5f, 0x2d, 0x68, 0x2d, 0x85, 0x38, 0x61, 0x0c, + 0xad, 0x2c, 0x3e, 0x73, 0x62, 0x4c, 0x8c, 0x59, 0x8f, 0xe9, 0x58, 0xb1, 0x53, 0x92, 0xed, 0x49, + 0xa3, 0x64, 0x2a, 0x56, 0x2c, 0x8f, 0xe5, 0x91, 0x34, 0x4b, 0xa6, 0x62, 0x3c, 0x86, 0xee, 0x39, + 0xce, 0x92, 0x17, 0x5e, 0x48, 0xd2, 0xd2, 0xbc, 0xce, 0xf1, 0x7b, 0x30, 0xf9, 0x37, 0x9e, 0xc9, + 0x82, 0xb4, 0x27, 0xcd, 0xd9, 0xe8, 0x91, 0x58, 0xaf, 0x07, 0xb4, 0xd4, 0xdd, 0x16, 0x55, 0x02, + 0xab, 0x3c, 0xfc, 0x11, 0xba, 0x69, 0x5c, 0xc8, 0xe8, 0x72, 0xcd, 0x88, 0x39, 0x31, 0x66, 0xfd, + 0xc7, 0xb1, 0x55, 0xae, 0x61, 0xdd, 0xd6, 0xb0, 0xc2, 0xdb, 0x1a, 0xac, 0xa3, 0x5c, 0x76, 0xcd, + 0xf0, 0x1b, 0x30, 0xbf, 0xf3, 0xe4, 0x70, 0x94, 0xa4, 0x33, 0x31, 0x66, 0x6d, 0x56, 0x65, 0x78, + 0x09, 0xf7, 0x7b, 0x9e, 0x72, 0xc9, 0xa3, 0x5c, 0xa4, 0xc9, 0xd7, 0x84, 0x17, 0xa4, 0xab, 0x27, + 0x79, 0xf8, 0xc7, 0x24, 0xae, 0x36, 0xb7, 0x4a, 0xfc, 0xc1, 0x46, 0xfb, 0x3f, 0x59, 0xc2, 0x0b, + 0xfc, 0x0e, 0x2a, 0x12, 0xa9, 0x57, 0x14, 0x57, 0x49, 0x7a, 0x13, 0x63, 0xd6, 0x64, 0xc3, 0x92, + 0x86, 0x25, 0x9c, 0xfe, 0x34, 0xa0, 0xad, 0x37, 0xc2, 0x7d, 0xe8, 0xec, 0x36, 0xeb, 0x8d, 0xff, + 0x79, 0x83, 0xee, 0xf0, 0x3d, 0xf4, 0xb7, 0x8c, 0x46, 0xab, 0x4d, 0x10, 0xda, 0x9e, 0x87, 0x0c, + 0x8c, 0x60, 0xb0, 0xf5, 0x83, 0xb0, 0x26, 0x0d, 0x3c, 0x02, 0x50, 0x8a, 0x4b, 0x3d, 0x1a, 0x52, + 0xd4, 0xd4, 0x47, 0x94, 0x51, 0x81, 0xd6, 0xad, 0xc7, 0x6e, 0xfb, 0x89, 0xd9, 0x2e, 0x45, 0xed, + 0xba, 0xc7, 0x8d, 0x98, 0x9a, 0x30, 0x1a, 0x31, 0xdf, 0xf3, 0x16, 0xb6, 0xb3, 0x46, 0x1d, 0xfc, + 0x1f, 0x0c, 0xb5, 0x53, 0xa3, 0x2e, 0x26, 0xf0, 0x3f, 0xa3, 0x1e, 0xb5, 0x03, 0x1a, 0x85, 0x34, + 0x08, 0xa3, 0x60, 0xe7, 0x38, 0x34, 0x08, 0x50, 0xef, 0xaf, 0xca, 0x93, 0xbd, 0xf2, 0x76, 0x8c, + 0x22, 0x50, 0x77, 0x3b, 0xcc, 0xad, 0xa7, 0xed, 0x4f, 0x1d, 0x18, 0xbc, 0x7e, 0x2e, 0x3c, 0x84, + 0x9e, 0xee, 0x43, 0x5d, 0xea, 0xa2, 0x3b, 0x0c, 0x60, 0xaa, 0xc3, 0xd4, 0x45, 0x86, 0xea, 0xba, + 0xa0, 0x4f, 0x3e, 0xa3, 0xd1, 0xd2, 0xf7, 0xd7, 0x91, 0xc3, 0xa8, 0x1d, 0xae, 0xfc, 0x0d, 0x6a, + 0x2c, 0x7a, 0x5f, 0x3a, 0xd5, 0x07, 0x3c, 0x9b, 0xfa, 0x77, 0x3f, 0xfc, 0x0e, 0x00, 0x00, 0xff, + 0xff, 0xce, 0x84, 0xd9, 0x98, 0xdb, 0x02, 0x00, 0x00, } diff --git a/pkg/tiller/environment/environment.go b/pkg/tiller/environment/environment.go index 21c23d421..bfb6c638f 100644 --- a/pkg/tiller/environment/environment.go +++ b/pkg/tiller/environment/environment.go @@ -127,6 +127,16 @@ type KubeClient interface { // by "\n---\n"). Delete(namespace string, reader io.Reader) error + // DeleteWithTimeout destroys one or more resources. If shouldWait is true, the function + // will not return until all the resources have been fully deleted or the provided + // timeout has expired. + // + // namespace must contain a valid existing namespace. + // + // reader must contain a YAML stream (one or more YAML documents separated + // by "\n---\n"). + DeleteWithTimeout(namespace string, reader io.Reader, timeout int64, shouldWait bool) error + // WatchUntilReady watch the resource in reader until it is "ready". // // For Jobs, "ready" means the job ran to completion (excited without error). @@ -182,6 +192,14 @@ func (p *PrintingKubeClient) Delete(ns string, r io.Reader) error { return err } +// DeleteWithTimeout implements KubeClient DeleteWithTimeout. +// +// It only prints out the content to be deleted. +func (p *PrintingKubeClient) DeleteWithTimeout(ns string, r io.Reader, timeout int64, shouldWait bool) error { + _, err := io.Copy(p.Out, r) + return err +} + // WatchUntilReady implements KubeClient WatchUntilReady. func (p *PrintingKubeClient) WatchUntilReady(ns string, r io.Reader, timeout int64, shouldWait bool) error { _, err := io.Copy(p.Out, r) diff --git a/pkg/tiller/environment/environment_test.go b/pkg/tiller/environment/environment_test.go index 24ff8b88d..4c6452b00 100644 --- a/pkg/tiller/environment/environment_test.go +++ b/pkg/tiller/environment/environment_test.go @@ -49,6 +49,9 @@ func (k *mockKubeClient) Get(ns string, r io.Reader) (string, error) { func (k *mockKubeClient) Delete(ns string, r io.Reader) error { return nil } +func (k *mockKubeClient) DeleteWithTimeout(ns string, r io.Reader, timeout int64, shouldWait bool) error { + return nil +} func (k *mockKubeClient) Update(ns string, currentReader, modifiedReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error { return nil } diff --git a/pkg/tiller/hooks.go b/pkg/tiller/hooks.go index 0fb7c92f8..5aa961080 100644 --- a/pkg/tiller/hooks.go +++ b/pkg/tiller/hooks.go @@ -53,6 +53,9 @@ var deletePolices = map[string]release.Hook_DeletePolicy{ hooks.BeforeHookCreation: release.Hook_BEFORE_HOOK_CREATION, } +// Timout used when deleting resources with a hook-delete-policy. +const defaultHookDeleteTimeoutInSeconds = int64(60) + // Manifest represents a manifest file, which has a name and some content. type Manifest = manifest.Manifest @@ -192,6 +195,18 @@ func (file *manifestFile) sort(result *result) error { log.Printf("info: skipping unknown hook delete policy: %q", value) } }) + + // Only check for delete timeout annotation if there is a deletion policy. + if len(h.DeletePolicies) > 0 { + h.DeleteTimeout = defaultHookDeleteTimeoutInSeconds + operateAnnotationValues(entry, hooks.HookDeleteTimeoutAnno, func(value string) { + timeout, err := strconv.ParseInt(value, 10, 64) + if err != nil || timeout < 0 { + log.Printf("info: ignoring invalid hook delete timeout value: %q", value) + } + h.DeleteTimeout = timeout + }) + } } return nil } diff --git a/pkg/tiller/hooks_test.go b/pkg/tiller/hooks_test.go index 8bd928500..daf07252e 100644 --- a/pkg/tiller/hooks_test.go +++ b/pkg/tiller/hooks_test.go @@ -17,8 +17,10 @@ limitations under the License. package tiller import ( + "bytes" "reflect" "testing" + "text/template" "github.com/ghodss/yaml" @@ -229,6 +231,110 @@ metadata: } } +var manifestTemplate = ` +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: example.com + labels: + app: example-crd + annotations: + helm.sh/hook: crd-install +{{- if .HookDeletePolicy}} + {{ .HookDeletePolicy }} +{{- end }} +{{- if .HookDeleteTimeout}} + {{ .HookDeleteTimeout }} +{{- end }} +spec: + group: example.com + version: v1alpha1 + names: + kind: example + plural: examples + scope: Cluster +` + +type manifestTemplateData struct { + HookDeletePolicy, HookDeleteTimeout string +} + +func TestSortManifestsHookDeletion(t *testing.T) { + testCases := map[string]struct { + templateData manifestTemplateData + hasDeletePolicy bool + deletePolicy release.Hook_DeletePolicy + deleteTimeout int64 + }{ + "No delete policy": { + templateData: manifestTemplateData{}, + hasDeletePolicy: false, + deletePolicy: release.Hook_BEFORE_HOOK_CREATION, + deleteTimeout: 0, + }, + "Delete policy, no delete timeout": { + templateData: manifestTemplateData{ + HookDeletePolicy: "helm.sh/hook-delete-policy: before-hook-creation", + }, + hasDeletePolicy: true, + deletePolicy: release.Hook_BEFORE_HOOK_CREATION, + deleteTimeout: defaultHookDeleteTimeoutInSeconds, + }, + "Delete policy and delete timeout": { + templateData: manifestTemplateData{ + HookDeletePolicy: "helm.sh/hook-delete-policy: hook-succeeded", + HookDeleteTimeout: `helm.sh/hook-delete-timeout: "420"`, + }, + hasDeletePolicy: true, + deletePolicy: release.Hook_SUCCEEDED, + deleteTimeout: 420, + }, + } + + for tn, tc := range testCases { + t.Run(tn, func(t *testing.T) { + tmpl := template.Must(template.New("manifest").Parse(manifestTemplate)) + var buf bytes.Buffer + err := tmpl.Execute(&buf, tc.templateData) + if err != nil { + t.Error(err) + } + + manifests := map[string]string{ + "exampleManifest": buf.String(), + } + + hs, _, err := sortManifests(manifests, chartutil.NewVersionSet("v1", "v1beta1"), InstallOrder) + if err != nil { + t.Error(err) + } + + if got, want := len(hs), 1; got != want { + t.Errorf("expected %d hooks, but got %d", want, got) + } + hook := hs[0] + + if len(hook.DeletePolicies) == 0 { + if tc.hasDeletePolicy { + t.Errorf("expected a policy, but got zero") + } + } else { + if !tc.hasDeletePolicy { + t.Errorf("expected no delete policies, but got one") + } + policy := hook.DeletePolicies[0] + if got, want := policy, tc.deletePolicy; got != want { + t.Errorf("expected delete policy %q, but got %q", want, got) + } + } + + if got, want := hook.DeleteTimeout, tc.deleteTimeout; got != want { + t.Errorf("expected timeout %d, but got %d", want, got) + } + }) + } +} + func TestVersionSet(t *testing.T) { vs := chartutil.NewVersionSet("v1", "v1beta1", "extensions/alpha5", "batch/v1") diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index 6733035f7..652234c5f 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -456,7 +456,8 @@ func (s *ReleaseServer) deleteHookByPolicy(h *release.Hook, policy string, name, b := bytes.NewBufferString(h.Manifest) if hookHasDeletePolicy(h, policy) { s.Log("deleting %s hook %s for release %s due to %q policy", hook, h.Name, name, policy) - if errHookDelete := kubeCli.Delete(namespace, b); errHookDelete != nil { + waitForDelete := h.DeleteTimeout > 0 + if errHookDelete := kubeCli.DeleteWithTimeout(namespace, b, h.DeleteTimeout, waitForDelete); errHookDelete != nil { s.Log("warning: Release %s %s %S could not be deleted: %s", name, hook, h.Path, errHookDelete) return errHookDelete } diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index 05b41be20..015fe0b54 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -540,6 +540,10 @@ func (d *deleteFailingKubeClient) Delete(ns string, r io.Reader) error { return kube.ErrNoObjectsVisited } +func (d *deleteFailingKubeClient) DeleteWithTimeout(ns string, r io.Reader, timeout int64, shouldWait bool) error { + return kube.ErrNoObjectsVisited +} + type mockListServer struct { val *services.ListReleasesResponse } @@ -612,6 +616,9 @@ func (kc *mockHooksKubeClient) Get(ns string, r io.Reader) (string, error) { return "", nil } func (kc *mockHooksKubeClient) Delete(ns string, r io.Reader) error { + return kc.DeleteWithTimeout(ns, r, 0, false) +} +func (kc *mockHooksKubeClient) DeleteWithTimeout(ns string, r io.Reader, timeout int64, shouldWait bool) error { manifest, err := kc.makeManifest(r) if err != nil { return err From 9af767c0e56b35bd87b5dcd22a4e98f8a632ca07 Mon Sep 17 00:00:00 2001 From: Naseem Date: Thu, 20 Jun 2019 09:57:05 -0400 Subject: [PATCH 29/82] Add security context Signed-off-by: Naseem --- pkg/chartutil/create.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index f8785b46f..2c9717e80 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -76,6 +76,17 @@ serviceAccount: # If not set and create is true, a name is generated using the fullname template name: +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + service: type: ClusterIP port: 80 @@ -199,8 +210,12 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ template ".serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} containers: - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: From cdb0571c79b7fc3b71d86e6ca48e1b5f25709ce5 Mon Sep 17 00:00:00 2001 From: Jintao Zhang Date: Mon, 24 Jun 2019 01:46:19 +0800 Subject: [PATCH 30/82] update to alpine 3.10 Signed-off-by: Jintao Zhang --- rootfs/Dockerfile | 2 +- rootfs/Dockerfile.experimental | 2 +- rootfs/Dockerfile.rudder | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rootfs/Dockerfile b/rootfs/Dockerfile index 2aa775a55..59ead977a 100644 --- a/rootfs/Dockerfile +++ b/rootfs/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.9 +FROM alpine:3.10 RUN apk add --no-cache ca-certificates socat diff --git a/rootfs/Dockerfile.experimental b/rootfs/Dockerfile.experimental index 9c1cab126..0fa9254ee 100644 --- a/rootfs/Dockerfile.experimental +++ b/rootfs/Dockerfile.experimental @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.9 +FROM alpine:3.10 RUN apk add --no-cache ca-certificates diff --git a/rootfs/Dockerfile.rudder b/rootfs/Dockerfile.rudder index 87efba401..ed153ee67 100644 --- a/rootfs/Dockerfile.rudder +++ b/rootfs/Dockerfile.rudder @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.9 +FROM alpine:3.10 RUN apk add --no-cache ca-certificates From b16ec08899658cad65cd5ae6a14334aed47f0101 Mon Sep 17 00:00:00 2001 From: Shao Yang Hong Date: Mon, 24 Jun 2019 11:50:21 +0800 Subject: [PATCH 31/82] Revert "Fixed default value for `helm.sh/chart` label" Signed-off-by: Shao Yang --- docs/chart_best_practices/labels.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chart_best_practices/labels.md b/docs/chart_best_practices/labels.md index 5a41ed1cc..6b7d24c49 100644 --- a/docs/chart_best_practices/labels.md +++ b/docs/chart_best_practices/labels.md @@ -26,7 +26,7 @@ are recommended, and _should_ be placed onto a chart for global consistency. Tho Name|Status|Description -----|------|---------- `app.kubernetes.io/name` | REC | This should be the app name, reflecting the entire app. Usually `{{ template "name" . }}` is used for this. This is used by many Kubernetes manifests, and is not Helm-specific. -`helm.sh/chart` | REC | This should be the chart name and version: `{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}`. +`helm.sh/chart` | REC | This should be the chart name and version: `{{ .Chart.Name }}-{{ .Chart.Version \| replace "+" "_" }}`. `app.kubernetes.io/managed-by` | REC | This should always be set to `{{ .Release.Service }}`. It is for finding all things managed by Tiller. `app.kubernetes.io/instance` | REC | This should be the `{{ .Release.Name }}`. It aids in differentiating between different instances of the same application. `app.kubernetes.io/version` | OPT | The version of the app and can be set to `{{ .Chart.AppVersion }}`. From b280fa5a7d5e48ce6730bda42fb99a2f436875ea Mon Sep 17 00:00:00 2001 From: ds-ms Date: Tue, 25 Jun 2019 19:07:14 +0530 Subject: [PATCH 32/82] Adding extra debug logs Signed-off-by: ds-ms Using debug function instead Signed-off-by: ds-ms Removing [INFO] from the message --- cmd/helm/init.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/helm/init.go b/cmd/helm/init.go index c7617e705..f02700508 100644 --- a/cmd/helm/init.go +++ b/cmd/helm/init.go @@ -284,6 +284,7 @@ func (i *initCmd) run() error { } fmt.Fprintln(i.out, "\nTiller (the Helm server-side component) has been upgraded to the current version.") } else { + debug("The error received while trying to init: %s", err) fmt.Fprintln(i.out, "Warning: Tiller is already installed in the cluster.\n"+ "(Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)") } From 34bb64c0ff3241a81e2612e91a1d75c5ee07fd87 Mon Sep 17 00:00:00 2001 From: Neha Gupta Date: Wed, 3 Jul 2019 15:15:33 +0530 Subject: [PATCH 33/82] Documentation upgrade According to documentation helm install [CHART] [flags] should be the usage pattern. Seems a new update. Signed-off-by: Neha Gupta --- docs/chart_template_guide/getting_started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/chart_template_guide/getting_started.md b/docs/chart_template_guide/getting_started.md index eb1d966d3..c6daec1c6 100644 --- a/docs/chart_template_guide/getting_started.md +++ b/docs/chart_template_guide/getting_started.md @@ -187,10 +187,10 @@ instead of `mychart-configmap`. You can run `helm get manifest clunky-serval` to see the entire generated YAML. -At this point, we've seen templates at their most basic: YAML files that have template directives embedded in `{{` and `}}`. In the next part, we'll take a deeper look into templates. But before moving on, there's one quick trick that can make building templates faster: When you want to test the template rendering, but not actually install anything, you can use `helm install --debug --dry-run ./mychart`. This will send the chart to the Tiller server, which will render the templates. But instead of installing the chart, it will return the rendered template to you so you can see the output: +At this point, we've seen templates at their most basic: YAML files that have template directives embedded in `{{` and `}}`. In the next part, we'll take a deeper look into templates. But before moving on, there's one quick trick that can make building templates faster: When you want to test the template rendering, but not actually install anything, you can use `helm install ./mychart --debug --dry-run`. This will send the chart to the Tiller server, which will render the templates. But instead of installing the chart, it will return the rendered template to you so you can see the output: ```console -$ helm install --debug --dry-run ./mychart +$ helm install ./mychart --debug --dry-run SERVER: "localhost:44134" CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart NAME: goodly-guppy From 98b7738081ab87b14172466a7668656cc777133e Mon Sep 17 00:00:00 2001 From: "Kostis (Codefresh)" <39800303+kostis-codefresh@users.noreply.github.com> Date: Wed, 3 Jul 2019 16:19:37 +0300 Subject: [PATCH 34/82] Mentioned Codefresh in related Helm services. Signed-off-by: Kostis Kapelonis --- docs/related.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/related.md b/docs/related.md index dc8d62091..06527d75d 100644 --- a/docs/related.md +++ b/docs/related.md @@ -92,6 +92,7 @@ Tools layered on top of Helm or Tiller. Platforms, distributions, and services that include Helm support. +- [Codefresh](https://codefresh.io/) - A CI/CD solution designed specifically for Docker/Kubernetes/Helm. Includes a private Helm repository and graphical dashboards for Helm charts, Helm releases and Helm environments. - [Fabric8](https://fabric8.io) - Integrated development platform for Kubernetes - [Jenkins X](https://jenkins-x.io/) - open source automated CI/CD for Kubernetes which uses Helm for [promoting](https://jenkins-x.io/about/features/#promotion) applications through [environments via GitOps](https://jenkins-x.io/about/features/#environments) - [Kubernetic](https://kubernetic.com/) - Kubernetes Desktop Client From a1b391951e97cc3a4f9204bd04b218dfcfed162b Mon Sep 17 00:00:00 2001 From: willise Date: Wed, 3 Jul 2019 17:07:18 +0800 Subject: [PATCH 35/82] ref(tiller): add more info when force update Signed-off-by: willise --- pkg/tiller/release_update.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/tiller/release_update.go b/pkg/tiller/release_update.go index 2f5dc24b4..5fb1552bf 100644 --- a/pkg/tiller/release_update.go +++ b/pkg/tiller/release_update.go @@ -38,8 +38,10 @@ func (s *ReleaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease s.Log("preparing update for %s", req.Name) currentRelease, updatedRelease, err := s.prepareUpdate(req) if err != nil { + s.Log("failed to prepare update: %s", err) if req.Force { // Use the --force, Luke. + s.Log("performing force update for %s", req.Name) return s.performUpdateForce(req) } return nil, err From 86f9b9fa4c2369d518ec82913ddbd82b19c914f1 Mon Sep 17 00:00:00 2001 From: Ross Fairbanks Date: Tue, 9 Jul 2019 19:19:18 +0100 Subject: [PATCH 36/82] chore(glide): bump kubernetes to 1.15.0 Signed-off-by: Ross Fairbanks --- glide.lock | 191 ++++++++++++++++++++++++++++++++++++----------------- glide.yaml | 14 ++-- 2 files changed, 136 insertions(+), 69 deletions(-) diff --git a/glide.lock b/glide.lock index 11f8aba60..92e7c50dd 100644 --- a/glide.lock +++ b/glide.lock @@ -1,11 +1,10 @@ -hash: 9e12e35a6ad263380590ad000d9013499107f3ed47a454e2f96133156b6f09d5 -updated: 2019-06-18T12:14:56.802884-04:00 +hash: 277f7be1b21149bc06b361fa61c0a2ff81a7f00c59a6e35c21b6516f6ddfd9f7 +updated: 2019-07-03T21:59:06.87934+02:00 imports: - name: cloud.google.com/go - version: 3b1ae45394a234c385be014e9a488f2bb6eef821 + version: 0ebda48a7f143b1cce9eb37a8c1106ac762a3430 subpackages: - compute/metadata - - internal - name: github.com/asaskevich/govalidator version: 7664702784775e51966f0885f5cd27435916517b - name: github.com/Azure/go-ansiterm @@ -13,7 +12,7 @@ imports: subpackages: - winterm - name: github.com/Azure/go-autorest - version: ea233b6412b0421a65dc6160e16c893364664a95 + version: 1ffcc8896ef6dfe022d90a4317d866f925cf0f9e subpackages: - autorest - autorest/adal @@ -22,7 +21,7 @@ imports: - logger - version - name: github.com/beorn7/perks - version: 3ac7bf7a47d159a033b107610db8a1b6575507a4 + version: 3a771d992973f24aa725d07868b467d1ddfceafb subpackages: - quantile - name: github.com/BurntSushi/toml @@ -41,7 +40,7 @@ imports: - name: github.com/cyphar/filepath-securejoin version: a261ee33d7a517f054effbf451841abaafe3e0fd - name: github.com/davecgh/go-spew - version: 782f4967f2dc4564575ca782fe2d04090b5faca8 + version: 8991bc29aa16c548c550c7ff78260e27b9ab7c73 subpackages: - spew - name: github.com/dgrijalva/jwt-go @@ -52,32 +51,8 @@ imports: - digestset - reference - name: github.com/docker/docker - version: a9fbbdc8dd8794b20af358382ab780559bca589d - subpackages: - - api - - api/types - - api/types/blkiodev - - api/types/container - - api/types/events - - api/types/filters - - api/types/image - - api/types/mount - - api/types/network - - api/types/registry - - api/types/strslice - - api/types/swarm - - api/types/swarm/runtime - - api/types/time - - api/types/versions - - api/types/volume - - client - - daemon/logger/jsonfilelog/jsonlog - - pkg/jsonmessage - - pkg/mount - - pkg/parsers - - pkg/parsers/operatingsystem - - pkg/stdcopy - - pkg/sysinfo + version: be7ac8be2ae072032a4005e8f232be3fc57e4127 + subpackages: - pkg/term - pkg/term/windows - name: github.com/docker/spdystream @@ -135,6 +110,14 @@ imports: - ptypes/timestamp - name: github.com/google/btree version: 7d79101e329e5a3adf994758c578dab82b90c017 +- name: github.com/google/go-cmp + version: 6f77996f0c42f7b84e5a2b252227263f93432e9b + subpackages: + - cmp + - cmp/internal/diff + - cmp/internal/flags + - cmp/internal/function + - cmp/internal/value - name: github.com/google/gofuzz version: 24818f796faf91cd76ec7bddd72458fbced7a6c1 - name: github.com/google/uuid @@ -181,6 +164,8 @@ imports: - reflectx - name: github.com/json-iterator/go version: ab8a2e0c74be9d3be70b3184d9acc634935ded82 +- name: github.com/konsorten/go-windows-terminal-sequences + version: 5c8c8bd35d3832f5d134ae1e1e375b69a4d25242 - name: github.com/lib/pq version: 88edab0803230a3898347e77b474f8c1820a1f20 subpackages: @@ -188,7 +173,7 @@ imports: - name: github.com/liggitt/tabwriter version: 89fcab3d43de07060e4fd4c1547430ed57e87f24 - name: github.com/mailru/easyjson - version: 2f5df55504ebc322e4d52d34df6a1f5b503bf26d + version: 60711f1a8329503b04e1c88535f419d0bb440bff subpackages: - buffer - jlexer @@ -232,19 +217,21 @@ imports: subpackages: - go - name: github.com/prometheus/common - version: cfeb6f9992ffa54aaa4f2170ade4067ee478b250 + version: 4724e9255275ce38f7179b2478abeae4e28c904f subpackages: - expfmt - internal/bitbucket.org/ww/goautoneg - model - name: github.com/prometheus/procfs - version: 65c1f6f8f0fc1e2185eb9863a3bc751496404259 + version: 1dc9a6cbc91aacc3e8b2d63db4d2e957a5394ac4 subpackages: + - internal/util + - nfs - xfs - name: github.com/PuerkitoBio/purell - version: 8a290539e2e8629dbc4e6bad948158f790ec31f4 + version: 0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4 - name: github.com/PuerkitoBio/urlesc - version: 5bd2802263f21d8788851d5305584c82a5c75d7e + version: de5bf2ad457846296e2031421a34e2568e304e35 - name: github.com/rubenv/sql-migrate version: 1007f53448d75fe14190968f5de4d95ed63ebb83 subpackages: @@ -254,7 +241,7 @@ imports: - name: github.com/shurcooL/sanitized_anchor_name version: 10ef21a441db47d8b13ebcc5fd2310f636973c77 - name: github.com/sirupsen/logrus - version: 89742aefa4b206dcf400792f3bd35b542998eb3b + version: bcd833dfe83d3cebad139e4a29ed79cb2318bf95 - name: github.com/spf13/cobra version: f2b07da1e2c38d5f12845a4f607e2e1018cbb1f5 subpackages: @@ -264,7 +251,7 @@ imports: - name: github.com/technosophos/moniker version: a5dbd03a2245d554160e3ae6bfdcf969fe58b431 - name: golang.org/x/crypto - version: de0752318171da717af4ce24d0a2e8626afaeb11 + version: e84da0312774c21d64ee2317962ef669b27ffb41 subpackages: - cast5 - ed25519 @@ -291,7 +278,7 @@ imports: - internal/timeseries - trace - name: golang.org/x/oauth2 - version: a6bd8cefa1811bd24b86f8902872e4e8225f74c4 + version: 9f3314589c9a9136388751d9adae6b0ed400978a subpackages: - google - internal @@ -307,20 +294,15 @@ imports: - unix - windows - name: golang.org/x/text - version: b19bf474d317b857955b12035d2c5acb57ce8b01 + version: e6919f6577db79269a6443b9dc46d18f2238fb5d subpackages: - - cases - encoding - encoding/internal - encoding/internal/identifier - encoding/unicode - - internal - - internal/tag - internal/utf8internal - - language - runes - secure/bidirule - - secure/precis - transform - unicode/bidi - unicode/norm @@ -330,7 +312,7 @@ imports: subpackages: - rate - name: google.golang.org/appengine - version: 12d5545dc1cfa6047a286d5e853841b6471f4c19 + version: 54a98f90d1c46b7731eb8fb305d2a321c30ef610 subpackages: - internal - internal/app_identity @@ -393,7 +375,7 @@ imports: - name: gopkg.in/yaml.v2 version: 5420a8b6744d3b0345ab293f6fcba19c978f1183 - name: k8s.io/api - version: a675ac48af67cf21d815b5f8df288462096eb9c9 + version: 7cf5895f2711098d7d9527db0a4a49fb0dff7de2 subpackages: - admission/v1beta1 - admissionregistration/v1beta1 @@ -434,13 +416,13 @@ imports: - storage/v1alpha1 - storage/v1beta1 - name: k8s.io/apiextensions-apiserver - version: bf6753f2aa24fe1d69a2abeea1c106042bcf3f5f + version: 14e95df34f1f469647f494f5185a036e26fddcab subpackages: - pkg/apis/apiextensions - pkg/apis/apiextensions/v1beta1 - pkg/features - name: k8s.io/apimachinery - version: 6a84e37a896db9780c75367af8d2ed2bb944022e + version: 1799e75a07195de9460b8ef7300883499f12127b subpackages: - pkg/api/equality - pkg/api/errors @@ -496,7 +478,7 @@ imports: - third_party/forked/golang/netutil - third_party/forked/golang/reflect - name: k8s.io/apiserver - version: f89599b3f64533b7e94fa4d169acbc861b464f2e + version: 47dc9a115b1874c96c20cea91d02b36e4faa1bb1 subpackages: - pkg/authentication/authenticator - pkg/authentication/serviceaccount @@ -504,7 +486,7 @@ imports: - pkg/features - pkg/util/feature - name: k8s.io/cli-runtime - version: 17bc0b7fcef59215541144136f75284656a789fb + version: 2090e6d8f84c1db3e23968b0ee97fb677b363fcf subpackages: - pkg/genericclioptions - pkg/kustomize @@ -519,13 +501,66 @@ imports: - pkg/printers - pkg/resource - name: k8s.io/client-go - version: ae8359b20417914b73a4b514b7a3d642597700bb + version: 78d2af792babf2dd937ba2e2a8d99c753a5eda89 subpackages: - discovery - discovery/cached/disk - discovery/fake - dynamic + - dynamic/dynamicinformer + - dynamic/dynamiclister - dynamic/fake + - informers + - informers/admissionregistration + - informers/admissionregistration/v1beta1 + - informers/apps + - informers/apps/v1 + - informers/apps/v1beta1 + - informers/apps/v1beta2 + - informers/auditregistration + - informers/auditregistration/v1alpha1 + - informers/autoscaling + - informers/autoscaling/v1 + - informers/autoscaling/v2beta1 + - informers/autoscaling/v2beta2 + - informers/batch + - informers/batch/v1 + - informers/batch/v1beta1 + - informers/batch/v2alpha1 + - informers/certificates + - informers/certificates/v1beta1 + - informers/coordination + - informers/coordination/v1 + - informers/coordination/v1beta1 + - informers/core + - informers/core/v1 + - informers/events + - informers/events/v1beta1 + - informers/extensions + - informers/extensions/v1beta1 + - informers/internalinterfaces + - informers/networking + - informers/networking/v1 + - informers/networking/v1beta1 + - informers/node + - informers/node/v1alpha1 + - informers/node/v1beta1 + - informers/policy + - informers/policy/v1beta1 + - informers/rbac + - informers/rbac/v1 + - informers/rbac/v1alpha1 + - informers/rbac/v1beta1 + - informers/scheduling + - informers/scheduling/v1 + - informers/scheduling/v1alpha1 + - informers/scheduling/v1beta1 + - informers/settings + - informers/settings/v1alpha1 + - informers/storage + - informers/storage/v1 + - informers/storage/v1alpha1 + - informers/storage/v1beta1 - kubernetes - kubernetes/fake - kubernetes/scheme @@ -601,6 +636,38 @@ imports: - kubernetes/typed/storage/v1alpha1/fake - kubernetes/typed/storage/v1beta1 - kubernetes/typed/storage/v1beta1/fake + - listers/admissionregistration/v1beta1 + - listers/apps/v1 + - listers/apps/v1beta1 + - listers/apps/v1beta2 + - listers/auditregistration/v1alpha1 + - listers/autoscaling/v1 + - listers/autoscaling/v2beta1 + - listers/autoscaling/v2beta2 + - listers/batch/v1 + - listers/batch/v1beta1 + - listers/batch/v2alpha1 + - listers/certificates/v1beta1 + - listers/coordination/v1 + - listers/coordination/v1beta1 + - listers/core/v1 + - listers/events/v1beta1 + - listers/extensions/v1beta1 + - listers/networking/v1 + - listers/networking/v1beta1 + - listers/node/v1alpha1 + - listers/node/v1beta1 + - listers/policy/v1beta1 + - listers/rbac/v1 + - listers/rbac/v1alpha1 + - listers/rbac/v1beta1 + - listers/scheduling/v1 + - listers/scheduling/v1alpha1 + - listers/scheduling/v1beta1 + - listers/settings/v1alpha1 + - listers/storage/v1 + - listers/storage/v1alpha1 + - listers/storage/v1beta1 - pkg/apis/clientauthentication - pkg/apis/clientauthentication/v1alpha1 - pkg/apis/clientauthentication/v1beta1 @@ -649,12 +716,12 @@ imports: - util/jsonpath - util/keyutil - util/retry -- name: k8s.io/cloud-provider - version: 9c9d72d1bf90eb62005f5112f3eea019b272c44b +- name: k8s.io/component-base + version: 185d68e6e6ea654214f444cab8f645ec3af3092e subpackages: - - features + - featuregate - name: k8s.io/klog - version: 8e90cee79f823779174776412c13478955131846 + version: 89e63fd5117f8c20208186ef85f096703a280c20 - name: k8s.io/kube-openapi version: b3a7cee44a305be0a69e1b9ac03018307287e1b0 subpackages: @@ -663,7 +730,7 @@ imports: - pkg/util/proto/testing - pkg/util/proto/validation - name: k8s.io/kubernetes - version: 66049e3b21efe110454d67df4fa62b08ea79a19b + version: e8462b5b5dc2584fdcd18e6bcfe9f1e4d970a529 subpackages: - pkg/api/legacyscheme - pkg/api/service @@ -758,6 +825,7 @@ imports: - pkg/kubectl/util/event - pkg/kubectl/util/fieldpath - pkg/kubectl/util/i18n + - pkg/kubectl/util/interrupt - pkg/kubectl/util/podutils - pkg/kubectl/util/printers - pkg/kubectl/util/qos @@ -768,6 +836,7 @@ imports: - pkg/kubectl/util/templates - pkg/kubectl/util/term - pkg/kubectl/validation + - pkg/kubectl/version - pkg/kubelet/types - pkg/master/ports - pkg/printers @@ -775,12 +844,10 @@ imports: - pkg/security/apparmor - pkg/serviceaccount - pkg/util/hash - - pkg/util/interrupt - pkg/util/labels - pkg/util/node - pkg/util/parsers - pkg/util/taints - - pkg/version - name: k8s.io/utils version: c2654d5206da6b7b6ace12841e8f359bb89b443c subpackages: @@ -826,7 +893,7 @@ testImports: - name: github.com/DATA-DOG/go-sqlmock version: 472e287dbafe67e526a3797165b64cb14f34705a - name: github.com/pmezard/go-difflib - version: 5d4384ee4fb2527b0a1256a821ebfc92f91efefc + version: 792786c7400a136282c1664665ae0a8db921c6c2 subpackages: - difflib - name: github.com/stretchr/testify diff --git a/glide.yaml b/glide.yaml index ecefde2e0..96401aa8c 100644 --- a/glide.yaml +++ b/glide.yaml @@ -49,19 +49,19 @@ import: version: 0.9.2 - package: github.com/grpc-ecosystem/go-grpc-prometheus - package: k8s.io/kubernetes - version: v1.14.2 + version: v1.15.0 - package: k8s.io/client-go - version: kubernetes-1.14.2 + version: kubernetes-1.15.0 - package: k8s.io/api - version: kubernetes-1.14.2 + version: kubernetes-1.15.0 - package: k8s.io/apimachinery - version: kubernetes-1.14.2 + version: kubernetes-1.15.0 - package: k8s.io/apiserver - version: kubernetes-1.14.2 + version: kubernetes-1.15.0 - package: k8s.io/cli-runtime - version: kubernetes-1.14.2 + version: kubernetes-1.15.0 - package: k8s.io/apiextensions-apiserver - version: kubernetes-1.14.2 + version: kubernetes-1.15.0 - package: github.com/cyphar/filepath-securejoin version: ^0.2.1 - package: github.com/jmoiron/sqlx From 9014bd9c502d92fb78bfee553abdba5cf35e878f Mon Sep 17 00:00:00 2001 From: Oleg Sidorov Date: Thu, 11 Jul 2019 15:12:02 +0200 Subject: [PATCH 37/82] chartutil.ReadValues is forced to unmarshal numbers into json.Number This change is an attempt to address the common problem of json number unmarshalling where any number is converted into a float64 and represented in a scientific notation on a marshall call. This behavior breaks things like: chart versions and image tags if not converted to yaml strings explicitly. An example of this behavior: k8s failure to fetch an image tagged with a big number like: $IMAGE:20190612073634 after a few steps of yaml re-rendering turns into: $IMAGE:2.0190612073634e+13. Example issue: https://github.com/helm/helm/issues/1707 This commit forces yaml parser to use JSON modifiers and explicitly enables interface{} unmarshalling instead of float64. The change introduced might be breaking so should be processed with an extra care. Due to the fact helm mostly dals with human-produced data (charts), we have a decent level of confidence this change looses no functionality helm users rely upon (the scientific notation). Relevant doc: https://golang.org/pkg/encoding/json/#Decoder.UseNumber Signed-off-by: Oleg Sidorov --- pkg/chartutil/requirements_test.go | 5 +++++ pkg/chartutil/testdata/coleridge.yaml | 1 + pkg/chartutil/values.go | 6 +++++- pkg/chartutil/values_test.go | 7 +++++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/pkg/chartutil/requirements_test.go b/pkg/chartutil/requirements_test.go index e433f92ea..6a41635d2 100644 --- a/pkg/chartutil/requirements_test.go +++ b/pkg/chartutil/requirements_test.go @@ -15,6 +15,7 @@ limitations under the License. package chartutil import ( + "encoding/json" "os" "path/filepath" "sort" @@ -302,6 +303,10 @@ func verifyRequirementsImportValues(t *testing.T, c *chart.Chart, v *chart.Confi } switch pv.(type) { + case json.Number: + if s := pv.(json.Number).String(); s != vv { + t.Errorf("Failed to match imported number value %v with expected %v", s, vv) + } case float64: s := strconv.FormatFloat(pv.(float64), 'f', -1, 64) if s != vv { diff --git a/pkg/chartutil/testdata/coleridge.yaml b/pkg/chartutil/testdata/coleridge.yaml index b6579628b..15535988b 100644 --- a/pkg/chartutil/testdata/coleridge.yaml +++ b/pkg/chartutil/testdata/coleridge.yaml @@ -10,3 +10,4 @@ water: water: where: "everywhere" nor: "any drop to drink" + temperature: 1234567890 diff --git a/pkg/chartutil/values.go b/pkg/chartutil/values.go index 890cd5540..1b7ba7a81 100644 --- a/pkg/chartutil/values.go +++ b/pkg/chartutil/values.go @@ -17,6 +17,7 @@ limitations under the License. package chartutil import ( + "encoding/json" "errors" "fmt" "io" @@ -132,7 +133,10 @@ func tableLookup(v Values, simple string) (Values, error) { // ReadValues will parse YAML byte data into a Values. func ReadValues(data []byte) (vals Values, err error) { - err = yaml.Unmarshal(data, &vals) + err = yaml.Unmarshal(data, &vals, func(d *json.Decoder) *json.Decoder { + d.UseNumber() + return d + }) if len(vals) == 0 { vals = Values{} } diff --git a/pkg/chartutil/values_test.go b/pkg/chartutil/values_test.go index fb26c6938..cf2d1360c 100644 --- a/pkg/chartutil/values_test.go +++ b/pkg/chartutil/values_test.go @@ -53,6 +53,7 @@ water: water: where: "everywhere" nor: "any drop to drink" + temperature: 1234567890 ` data, err := ReadValues([]byte(doc)) @@ -266,6 +267,12 @@ func matchValues(t *testing.T, data map[string]interface{}) { } else if o != "everywhere" { t.Errorf("Expected water water everywhere") } + + if o, err := ttpl("{{.water.water.temperature}}", data); err != nil { + t.Errorf(".water.water.temperature: %s", err) + } else if o != "1234567890" { + t.Errorf("Expected water water temperature: 1234567890, got: %s", o) + } } func ttpl(tpl string, v map[string]interface{}) (string, error) { From 70cd32c4cebac2af67f4da3934e141f0f0c00842 Mon Sep 17 00:00:00 2001 From: Oleg Sidorov Date: Thu, 11 Jul 2019 18:24:48 +0200 Subject: [PATCH 38/82] Fixed failing tests for helm installer Signed-off-by: Oleg Sidorov --- cmd/helm/installer/install_test.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/cmd/helm/installer/install_test.go b/cmd/helm/installer/install_test.go index 50cc8b1d8..1c7063450 100644 --- a/cmd/helm/installer/install_test.go +++ b/cmd/helm/installer/install_test.go @@ -17,6 +17,7 @@ limitations under the License. package installer // import "k8s.io/helm/cmd/helm/installer" import ( + "encoding/json" "os" "path/filepath" "reflect" @@ -716,9 +717,32 @@ func TestDeployment_WithSetValues(t *testing.T) { // convert our expected value to match the result type for comparison ev := tt.expect + intType := reflect.TypeOf(int64(0)) + floatType := reflect.TypeOf(float64(0)) + switch pvt := pv.(type) { + case json.Number: + evv := reflect.ValueOf(ev) + evv = reflect.Indirect(evv) + switch ev.(type) { + case float32, float64: + evv = evv.Convert(floatType) + if fpv, err := pv.(json.Number).Float64(); err != nil { + t.Errorf("Failed to convert json number to float: %s", err) + } else if fpv != evv.Float() { + t.Errorf("%s: expected float value %q, got %f", tt.name, tt.expect, fpv) + } + case byte, int, int32, int64: + evv = evv.Convert(intType) + if ipv, err := pv.(json.Number).Int64(); err != nil { + t.Errorf("Failed to convert json number to int: %s", err) + } else if ipv != evv.Int() { + t.Errorf("%s: expected int value %q, got %d", tt.name, tt.expect, ipv) + } + default: + t.Errorf("Unknown primitive type: %s", reflect.TypeOf(ev)) + } case float64: - floatType := reflect.TypeOf(float64(0)) v := reflect.ValueOf(ev) v = reflect.Indirect(v) if !v.Type().ConvertibleTo(floatType) { From 320e853b8dd5a1b91e1934b12bad6bd49b9708bf Mon Sep 17 00:00:00 2001 From: Seb Ospina Date: Thu, 16 May 2019 19:07:28 +0200 Subject: [PATCH 39/82] Added List mode for Role, ClusterRole and Bindings Kubernetes supports RoleList, RoleBindingList, ClusterRoleList and ClusterRoleBindingList, in order for a Role to be bound, it must already exist. For the List reference, see: https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/rbac/types.go Signed-off-by: Seb Ospina --- pkg/tiller/kind_sorter.go | 8 ++++++++ pkg/tiller/kind_sorter_test.go | 20 ++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pkg/tiller/kind_sorter.go b/pkg/tiller/kind_sorter.go index f980277d2..2c11aa855 100644 --- a/pkg/tiller/kind_sorter.go +++ b/pkg/tiller/kind_sorter.go @@ -40,9 +40,13 @@ var InstallOrder SortOrder = []string{ "ServiceAccount", "CustomResourceDefinition", "ClusterRole", + "ClusterRoleList", "ClusterRoleBinding", + "ClusterRoleBindingList", "Role", + "RoleList", "RoleBinding", + "RoleBindingList", "Service", "DaemonSet", "Pod", @@ -71,9 +75,13 @@ var UninstallOrder SortOrder = []string{ "ReplicationController", "Pod", "DaemonSet", + "RoleBindingList", "RoleBinding", + "RoleList", "Role", + "ClusterRoleBindingList", "ClusterRoleBinding", + "ClusterRoleList", "ClusterRole", "CustomResourceDefinition", "ServiceAccount", diff --git a/pkg/tiller/kind_sorter_test.go b/pkg/tiller/kind_sorter_test.go index 56822f995..626e80ee6 100644 --- a/pkg/tiller/kind_sorter_test.go +++ b/pkg/tiller/kind_sorter_test.go @@ -29,10 +29,18 @@ func TestKindSorter(t *testing.T) { Name: "i", Head: &util.SimpleHead{Kind: "ClusterRole"}, }, + { + Name: "I", + Head: &util.SimpleHead{Kind: "ClusterRoleList"}, + }, { Name: "j", Head: &util.SimpleHead{Kind: "ClusterRoleBinding"}, }, + { + Name: "J", + Head: &util.SimpleHead{Kind: "ClusterRoleBindingList"}, + }, { Name: "e", Head: &util.SimpleHead{Kind: "ConfigMap"}, @@ -105,10 +113,18 @@ func TestKindSorter(t *testing.T) { Name: "k", Head: &util.SimpleHead{Kind: "Role"}, }, + { + Name: "K", + Head: &util.SimpleHead{Kind: "RoleList"}, + }, { Name: "l", Head: &util.SimpleHead{Kind: "RoleBinding"}, }, + { + Name: "L", + Head: &util.SimpleHead{Kind: "RoleBindingList"}, + }, { Name: "d", Head: &util.SimpleHead{Kind: "Secret"}, @@ -144,8 +160,8 @@ func TestKindSorter(t *testing.T) { order SortOrder expected string }{ - {"install", InstallOrder, "abc3zde1fgh2ijklmnopqrstuvw!"}, - {"uninstall", UninstallOrder, "wvmutsrqponlkji2hgf1edz3cba!"}, + {"install", InstallOrder, "abc3zde1fgh2iIjJkKlLmnopqrstuvw!"}, + {"uninstall", UninstallOrder, "wvmutsrqponLlKkJjIi2hgf1edz3cba!"}, } { var buf bytes.Buffer t.Run(test.description, func(t *testing.T) { From 5a39ff90ad25647b75a9e5351dd73ed36fe958e5 Mon Sep 17 00:00:00 2001 From: Nenad Merdanovic Date: Tue, 16 Jul 2019 11:39:28 +0200 Subject: [PATCH 40/82] Fix documentation to use existing chart in the stable repository Signed-off-by: Nenad Merdanovic --- docs/rbac.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rbac.md b/docs/rbac.md index 9d4531ffe..a89579c61 100644 --- a/docs/rbac.md +++ b/docs/rbac.md @@ -107,7 +107,7 @@ $HELM_HOME has been configured at /Users/awesome-user/.helm. Tiller (the Helm server side component) has been installed into your Kubernetes Cluster. -$ helm install nginx --tiller-namespace tiller-world --namespace tiller-world +$ helm install stable/lamp --tiller-namespace tiller-world --namespace tiller-world NAME: wayfaring-yak LAST DEPLOYED: Mon Aug 7 16:00:16 2017 NAMESPACE: tiller-world From 5b67d6fbd97ca1258e5ae9276c9c88905fc56a2e Mon Sep 17 00:00:00 2001 From: Tine Jozelj Date: Tue, 16 Jul 2019 14:47:20 +0200 Subject: [PATCH 41/82] feat(helm:create): allow absolute paths If starter template path is an absolute path, it shouldn't be prefixed with c.home.Starters() but rather be used as is. Signed-off-by: Tine Jozelj --- cmd/helm/create.go | 6 ++- cmd/helm/create_test.go | 92 ++++++++++++++++++++++++++++++++++++++++ docs/helm/helm_create.md | 4 +- 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/cmd/helm/create.go b/cmd/helm/create.go index 451b4ce86..da91291fd 100644 --- a/cmd/helm/create.go +++ b/cmd/helm/create.go @@ -88,7 +88,7 @@ func newCreateCmd(out io.Writer) *cobra.Command { }, } - cmd.Flags().StringVarP(&cc.starter, "starter", "p", "", "The named Helm starter scaffold") + cmd.Flags().StringVarP(&cc.starter, "starter", "p", "", "The name or absolute path to Helm starter scaffold") return cmd } @@ -106,6 +106,10 @@ func (c *createCmd) run() error { if c.starter != "" { // Create from the starter lstarter := filepath.Join(c.home.Starters(), c.starter) + // If path is absolute, we dont want to prefix it with helm starters folder + if filepath.IsAbs(c.starter) { + lstarter = c.starter + } return chartutil.CreateFrom(cfile, filepath.Dir(c.name), lstarter) } diff --git a/cmd/helm/create_test.go b/cmd/helm/create_test.go index 20bace864..fb118ba58 100644 --- a/cmd/helm/create_test.go +++ b/cmd/helm/create_test.go @@ -163,3 +163,95 @@ func TestCreateStarterCmd(t *testing.T) { } } + +func TestCreateStarterAbsoluteCmd(t *testing.T) { + cname := "testchart" + // Make a temp dir + tdir, err := ioutil.TempDir("", "helm-create-") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tdir) + + thome, err := tempHelmHome(t) + if err != nil { + t.Fatal(err) + } + cleanup := resetEnv() + defer func() { + os.RemoveAll(thome.String()) + cleanup() + }() + + settings.Home = thome + + // Create a starter. + starterchart := filepath.Join(tdir, "starters") + os.Mkdir(starterchart, 0755) + if dest, err := chartutil.Create(&chart.Metadata{Name: "starterchart"}, starterchart); err != nil { + t.Fatalf("Could not create chart: %s", err) + } else { + t.Logf("Created %s", dest) + } + tplpath := filepath.Join(starterchart, "starterchart", "templates", "foo.tpl") + if err := ioutil.WriteFile(tplpath, []byte("test"), 0755); err != nil { + t.Fatalf("Could not write template: %s", err) + } + + // CD into it + pwd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + if err := os.Chdir(tdir); err != nil { + t.Fatal(err) + } + defer os.Chdir(pwd) + + // Run a create + cmd := newCreateCmd(ioutil.Discard) + cmd.ParseFlags([]string{"--starter", filepath.Join(starterchart, "starterchart")}) + if err := cmd.RunE(cmd, []string{cname}); err != nil { + t.Errorf("Failed to run create: %s", err) + return + } + + // Test that the chart is there + if fi, err := os.Stat(cname); err != nil { + t.Fatalf("no chart directory: %s", err) + } else if !fi.IsDir() { + t.Fatalf("chart is not directory") + } + + c, err := chartutil.LoadDir(cname) + if err != nil { + t.Fatal(err) + } + + if c.Metadata.Name != cname { + t.Errorf("Expected %q name, got %q", cname, c.Metadata.Name) + } + if c.Metadata.ApiVersion != chartutil.ApiVersionV1 { + t.Errorf("Wrong API version: %q", c.Metadata.ApiVersion) + } + + expectedTemplateCount := 8 + if l := len(c.Templates); l != expectedTemplateCount { + t.Errorf("Expected %d templates, got %d", expectedTemplateCount, l) + } + + found := false + for _, tpl := range c.Templates { + if tpl.Name == "templates/foo.tpl" { + found = true + data := tpl.Data + if string(data) != "test" { + t.Errorf("Expected template 'test', got %q", string(data)) + } + } + } + if !found { + t.Error("Did not find foo.tpl") + } + +} diff --git a/docs/helm/helm_create.md b/docs/helm/helm_create.md index 0bf526a22..f0c5cd037 100644 --- a/docs/helm/helm_create.md +++ b/docs/helm/helm_create.md @@ -44,7 +44,7 @@ helm create NAME [flags] ``` -h, --help help for create - -p, --starter string The named Helm starter scaffold + -p, --starter string The name or absolute path to Helm starter scaffold ``` ### Options inherited from parent commands @@ -63,4 +63,4 @@ helm create NAME [flags] * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 5-Jun-2019 +###### Auto generated by spf13/cobra on 7-Jul-2019 From 535df90cc8d13978c016aaecf575dbd3f3f3541e Mon Sep 17 00:00:00 2001 From: Constantin Bugneac Date: Thu, 18 Jul 2019 15:24:32 +0100 Subject: [PATCH 42/82] Added HorizontalPodAutoscaler to sort order. Signed-off-by: Constantin Bugneac --- pkg/tiller/kind_sorter.go | 2 ++ pkg/tiller/kind_sorter_test.go | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pkg/tiller/kind_sorter.go b/pkg/tiller/kind_sorter.go index 2c11aa855..5c7193dee 100644 --- a/pkg/tiller/kind_sorter.go +++ b/pkg/tiller/kind_sorter.go @@ -53,6 +53,7 @@ var InstallOrder SortOrder = []string{ "ReplicationController", "ReplicaSet", "Deployment", + "HorizontalPodAutoscaler", "StatefulSet", "Job", "CronJob", @@ -70,6 +71,7 @@ var UninstallOrder SortOrder = []string{ "CronJob", "Job", "StatefulSet", + "HorizontalPodAutoscaler", "Deployment", "ReplicaSet", "ReplicationController", diff --git a/pkg/tiller/kind_sorter_test.go b/pkg/tiller/kind_sorter_test.go index 626e80ee6..3b37256ed 100644 --- a/pkg/tiller/kind_sorter_test.go +++ b/pkg/tiller/kind_sorter_test.go @@ -153,6 +153,10 @@ func TestKindSorter(t *testing.T) { Name: "z", Head: &util.SimpleHead{Kind: "PodDisruptionBudget"}, }, + { + Name: "x", + Head: &util.SimpleHead{Kind: "HorizontalPodAutoscaler"}, + }, } for _, test := range []struct { @@ -160,8 +164,8 @@ func TestKindSorter(t *testing.T) { order SortOrder expected string }{ - {"install", InstallOrder, "abc3zde1fgh2iIjJkKlLmnopqrstuvw!"}, - {"uninstall", UninstallOrder, "wvmutsrqponLlKkJjIi2hgf1edz3cba!"}, + {"install", InstallOrder, "abc3zde1fgh2iIjJkKlLmnopqrxstuvw!"}, + {"uninstall", UninstallOrder, "wvmutsxrqponLlKkJjIi2hgf1edz3cba!"}, } { var buf bytes.Buffer t.Run(test.description, func(t *testing.T) { From e98534d69414c53c9c7309e1ce9805096dc34b25 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Mon, 22 Jul 2019 12:44:15 -0700 Subject: [PATCH 43/82] docs(CONTRIBUTING): one LGTM for maintainers Signed-off-by: Matthew Fisher --- CONTRIBUTING.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3965e18db..996f6d224 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -263,6 +263,8 @@ Like any good open source project, we use Pull Requests (PRs) to track code chan - PRs should stay open until merged or if they have not been active for more than 30 days. This will help keep the PR queue to a manageable size and reduce noise. Should the PR need to stay open (like in the case of a WIP), the `keep open` label can be added. + - Before merging a PR, refer to the topic on [Size Labels](#size-labels) below to determine if + the PR requires more than one LGTM to merge. - If the owner of the PR is listed in `OWNERS`, that user **must** merge their own PRs or explicitly request another OWNER do that for them. - If the owner of a PR is _not_ listed in `OWNERS`, any maintainer may merge the PR once it is approved. @@ -320,11 +322,15 @@ The following tables define all label types used for Helm. It is split up by cat Size labels are used to indicate how "dangerous" a PR is. The guidelines below are used to assign the labels, but ultimately this can be changed by the maintainers. For example, even if a PR only makes -30 lines of changes in 1 file, but it changes key functionality, it will likely be labeled as `size/large` +30 lines of changes in 1 file, but it changes key functionality, it will likely be labeled as `size/L` because it requires sign off from multiple people. Conversely, a PR that adds a small feature, but requires -another 150 lines of tests to cover all cases, could be labeled as `size/small` even though the number +another 150 lines of tests to cover all cases, could be labeled as `size/S` even though the number lines is greater than defined below. +PRs submitted by a core maintainer, regardless of size, only requires approval from one additional +maintainer. This ensures there are at least two maintainers who are aware of any significant PRs +introduced to the codebase. + | Label | Description | | ----- | ----------- | | `size/XS` | Anything less than or equal to 9 lines ignoring generated files. Only small amounts of manual testing may be required. | From 7247956b96d0f038195af41f1be9b7ce6002c662 Mon Sep 17 00:00:00 2001 From: Pete Hodgson Date: Tue, 23 Jul 2019 09:48:17 -0700 Subject: [PATCH 44/82] Fix broken link in docs/related.md Looks like this hackernoon link is now broken, probably from when they moved off of Medium. Signed-off-by: Pete Hodgson --- docs/related.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/related.md b/docs/related.md index 06527d75d..63919790b 100644 --- a/docs/related.md +++ b/docs/related.md @@ -14,7 +14,7 @@ or [pull request](https://github.com/helm/helm/pulls). - [GitLab, Consumer Driven Contracts, Helm and Kubernetes](https://medium.com/@enxebre/gitlab-consumer-driven-contracts-helm-and-kubernetes-b7235a60a1cb#.xwp1y4tgi) - [Honestbee's Helm Chart Conventions](https://gist.github.com/so0k/f927a4b60003cedd101a0911757c605a) - [Releasing backward-incompatible changes: Kubernetes, Jenkins, Prometheus Operator, Helm and Traefik](https://medium.com/@enxebre/releasing-backward-incompatible-changes-kubernetes-jenkins-plugin-prometheus-operator-helm-self-6263ca61a1b1#.e0c7elxhq) -- [The Missing CI/CD Kubernetes Component: Helm package manager](https://hackernoon.com/the-missing-ci-cd-kubernetes-component-helm-package-manager-1fe002aac680#.691sk2zhu) +- [The Missing CI/CD Kubernetes Component: Helm package manager](https://medium.com/@gajus/the-missing-ci-cd-kubernetes-component-helm-package-manager-1fe002aac680) - [Using Helm to Deploy to Kubernetes](https://daemonza.github.io/2017/02/20/using-helm-to-deploy-to-kubernetes/) - [Writing a Helm Chart](https://www.influxdata.com/packaged-kubernetes-deployments-writing-helm-chart/) - [A basic walk through Kubernetes Helm](https://github.com/muffin87/helm-tutorial) From d8b7984d75e958c2e160363af1128ad3bdbc2ba7 Mon Sep 17 00:00:00 2001 From: Bridget Kromhout Date: Tue, 23 Jul 2019 13:13:55 -0500 Subject: [PATCH 45/82] Fixing link; adding AKS. Signed-off-by: Bridget Kromhout --- docs/install.md | 2 +- docs/kubernetes_distros.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/install.md b/docs/install.md index 3742385f3..759ec1759 100755 --- a/docs/install.md +++ b/docs/install.md @@ -123,7 +123,7 @@ configured to talk to a remote Kubernetes cluster. Most cloud providers enable a feature called Role-Based Access Control - RBAC for short. If your cloud provider enables this feature, you will need to create a service account for Tiller with the right roles and permissions to access resources. -Check the [Kubernetes Distribution Guide](kubernetes_distros.md) to see if there's any further points of interest on using Helm with your cloud provider. Also check out the guide on [Tiller and Role-Based Access Control](rbac.md) for more information on how to run Tiller in an RBAC-enabled Kubernetes cluster. +Check the [Kubernetes Distribution Guide](kubernetes-distribution-guide) to see if there's any further points of interest on using Helm with your cloud provider. Also check out the guide on [Tiller and Role-Based Access Control](rbac.md) for more information on how to run Tiller in an RBAC-enabled Kubernetes cluster. ### Easy In-Cluster Installation diff --git a/docs/kubernetes_distros.md b/docs/kubernetes_distros.md index bb14043da..48a73204c 100644 --- a/docs/kubernetes_distros.md +++ b/docs/kubernetes_distros.md @@ -22,6 +22,10 @@ Google's GKE hosted Kubernetes platform enables RBAC by default. You will need t See [Tiller and role-based access control](https://docs.helm.sh/using_helm/#role-based-access-control) for more information. +## AKS + +Helm works with [Azure Kubernetes Service](https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm). If using an RBAC-enabled AKS cluster, you need [a service account and role binding for the Tiller service](https://helm.sh/docs/using_helm/#tiller-namespaces-and-rbac). + ## Ubuntu with 'kubeadm' Kubernetes bootstrapped with `kubeadm` is known to work on the following Linux From ce0ad06e941e12e335c5d083c145f830bf7f3083 Mon Sep 17 00:00:00 2001 From: Bridget Kromhout Date: Tue, 23 Jul 2019 15:47:11 -0500 Subject: [PATCH 46/82] Fixes per helpful feedback Signed-off-by: Bridget Kromhout --- docs/install.md | 2 +- docs/kubernetes_distros.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/install.md b/docs/install.md index 759ec1759..06a319486 100755 --- a/docs/install.md +++ b/docs/install.md @@ -123,7 +123,7 @@ configured to talk to a remote Kubernetes cluster. Most cloud providers enable a feature called Role-Based Access Control - RBAC for short. If your cloud provider enables this feature, you will need to create a service account for Tiller with the right roles and permissions to access resources. -Check the [Kubernetes Distribution Guide](kubernetes-distribution-guide) to see if there's any further points of interest on using Helm with your cloud provider. Also check out the guide on [Tiller and Role-Based Access Control](rbac.md) for more information on how to run Tiller in an RBAC-enabled Kubernetes cluster. +Check the [Kubernetes Distribution Guide](#kubernetes-distribution-guide) to see if there's any further points of interest on using Helm with your cloud provider. Also check out the guide on [Tiller and Role-Based Access Control](rbac.md) for more information on how to run Tiller in an RBAC-enabled Kubernetes cluster. ### Easy In-Cluster Installation diff --git a/docs/kubernetes_distros.md b/docs/kubernetes_distros.md index 48a73204c..52a5e1acc 100644 --- a/docs/kubernetes_distros.md +++ b/docs/kubernetes_distros.md @@ -24,7 +24,7 @@ See [Tiller and role-based access control](https://docs.helm.sh/using_helm/#role ## AKS -Helm works with [Azure Kubernetes Service](https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm). If using an RBAC-enabled AKS cluster, you need [a service account and role binding for the Tiller service](https://helm.sh/docs/using_helm/#tiller-namespaces-and-rbac). +Helm works with [Azure Kubernetes Service](https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm). If using an RBAC-enabled AKS cluster, you need [a service account and role binding for the Tiller service](https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm#create-a-service-account). ## Ubuntu with 'kubeadm' From 276bb9b1c8ee3c51064f768e8c0e2fb64c3fd5f2 Mon Sep 17 00:00:00 2001 From: Tariq Ibrahim Date: Wed, 24 Jul 2019 16:22:46 -0700 Subject: [PATCH 47/82] fix golint issues reported by make test Signed-off-by: Tariq Ibrahim --- pkg/kube/client.go | 18 +++++++++++++----- pkg/kube/client_test.go | 2 +- pkg/lint/rules/chartfile.go | 4 ++-- pkg/tiller/environment/environment.go | 1 + 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index fcaa28760..8fbfba1fd 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -314,7 +314,14 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) { return buf.String(), nil } -// Deprecated; use UpdateWithOptions instead +// Update reads the current configuration and a target configuration from io.reader +// and creates resources that don't already exist, updates resources that have been modified +// in the target configuration and deletes resources from the current configuration that are +// not present in the target configuration. +// +// Namespace will set the namespaces. +// +// Deprecated: use UpdateWithOptions instead. func (c *Client) Update(namespace string, originalReader, targetReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error { return c.UpdateWithOptions(namespace, originalReader, targetReader, UpdateOptions{ Force: force, @@ -334,12 +341,13 @@ type UpdateOptions struct { CleanupOnFail bool } -// UpdateWithOptions reads in the current configuration and a target configuration from io.reader -// and creates resources that don't already exists, updates resources that have been modified +// UpdateWithOptions reads the current configuration and a target configuration from io.reader +// and creates resources that don't already exist, updates resources that have been modified // in the target configuration and deletes resources from the current configuration that are // not present in the target configuration. // -// Namespace will set the namespaces. +// Namespace will set the namespaces. UpdateOptions provides additional parameters to control +// update behavior. func (c *Client) UpdateWithOptions(namespace string, originalReader, targetReader io.Reader, opts UpdateOptions) error { original, err := c.BuildUnstructured(namespace, originalReader) if err != nil { @@ -552,7 +560,7 @@ func (c *Client) WatchUntilReady(namespace string, reader io.Reader, timeout int return perform(infos, c.watchTimeout(time.Duration(timeout)*time.Second)) } -// WatchUntilCRDEstablished polls the given CRD until it reaches the established +// WaitUntilCRDEstablished polls the given CRD until it reaches the established // state. A CRD needs to reach the established state before CRs can be created. // // If a naming conflict condition is found, this function will return an error. diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go index 6faea02d0..d33b4b9d9 100644 --- a/pkg/kube/client_test.go +++ b/pkg/kube/client_test.go @@ -558,7 +558,7 @@ func TestWaitUntilCRDEstablished(t *testing.T) { } else { crd = crdWithConditions } - requestCount += 1 + requestCount++ return newResponse(200, &crd) }), } diff --git a/pkg/lint/rules/chartfile.go b/pkg/lint/rules/chartfile.go index 8ef33d0c5..8f6c16d94 100644 --- a/pkg/lint/rules/chartfile.go +++ b/pkg/lint/rules/chartfile.go @@ -51,7 +51,7 @@ func Chartfile(linter *support.Linter) { linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartNameDirMatch(linter.ChartDir, chartFile)) // Chart metadata - linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartApiVersion(chartFile)) + linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartAPIVersion(chartFile)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartVersion(chartFile)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartEngine(chartFile)) linter.RunLinterRule(support.ErrorSev, chartFileName, validateChartMaintainer(chartFile)) @@ -97,7 +97,7 @@ func validateChartNameDirMatch(chartDir string, cf *chart.Metadata) error { return nil } -func validateChartApiVersion(cf *chart.Metadata) error { +func validateChartAPIVersion(cf *chart.Metadata) error { if cf.ApiVersion == "" { return errors.New("apiVersion is required") } diff --git a/pkg/tiller/environment/environment.go b/pkg/tiller/environment/environment.go index d84ad55db..83ec5e647 100644 --- a/pkg/tiller/environment/environment.go +++ b/pkg/tiller/environment/environment.go @@ -255,6 +255,7 @@ func (p *PrintingKubeClient) WaitAndGetCompletedPodPhase(namespace string, reade return v1.PodUnknown, err } +// WaitUntilCRDEstablished implements KubeClient WaitUntilCRDEstablished. func (p *PrintingKubeClient) WaitUntilCRDEstablished(reader io.Reader, timeout time.Duration) error { _, err := io.Copy(p.Out, reader) return err From e53613db3f386b8728ac3d6038b9d13eba9caece Mon Sep 17 00:00:00 2001 From: Stefan Deitmer Date: Thu, 25 Jul 2019 14:29:45 +0200 Subject: [PATCH 48/82] Fix subchart values not being deleted by setting value to nil in parent chart's values Signed-off-by: Stefan Deitmer --- .../testdata/moby/charts/spouter/values.yaml | 1 + pkg/chartutil/testdata/moby/values.yaml | 4 +++ pkg/chartutil/values.go | 5 +--- pkg/chartutil/values_test.go | 27 +++++++++++++++++++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/pkg/chartutil/testdata/moby/charts/spouter/values.yaml b/pkg/chartutil/testdata/moby/charts/spouter/values.yaml index f71d92a9f..36cdff290 100644 --- a/pkg/chartutil/testdata/moby/charts/spouter/values.yaml +++ b/pkg/chartutil/testdata/moby/charts/spouter/values.yaml @@ -1 +1,2 @@ scope: spouter +foo: bar \ No newline at end of file diff --git a/pkg/chartutil/testdata/moby/values.yaml b/pkg/chartutil/testdata/moby/values.yaml index ecf22b563..8cea245ce 100644 --- a/pkg/chartutil/testdata/moby/values.yaml +++ b/pkg/chartutil/testdata/moby/values.yaml @@ -22,3 +22,7 @@ web: httpGet: path: /api/v1/info port: atc + +# for testing deleting default values in sub charts +spouter: + foo: null \ No newline at end of file diff --git a/pkg/chartutil/values.go b/pkg/chartutil/values.go index 1b7ba7a81..f82b95950 100644 --- a/pkg/chartutil/values.go +++ b/pkg/chartutil/values.go @@ -170,10 +170,7 @@ func CoalesceValues(chrt *chart.Chart, vals *chart.Config) (Values, error) { if err != nil { return cvals, err } - cvals, err = coalesce(chrt, evals) - if err != nil { - return cvals, err - } + return coalesce(chrt, evals) } return coalesceDeps(chrt, cvals) diff --git a/pkg/chartutil/values_test.go b/pkg/chartutil/values_test.go index cf2d1360c..dfb38387e 100644 --- a/pkg/chartutil/values_test.go +++ b/pkg/chartutil/values_test.go @@ -475,6 +475,33 @@ func TestCoalesceTables(t *testing.T) { t.Errorf("Expected boat string, got %v", dst["boat"]) } } + +func TestCoalesceSubchart(t *testing.T) { + tchart := "testdata/moby" + c, err := LoadDir(tchart) + if err != nil { + t.Fatal(err) + } + + tvals := &chart.Config{} + + v, err := CoalesceValues(c, tvals) + if err != nil { + t.Fatal(err) + } + j, _ := json.MarshalIndent(v, "", " ") + t.Logf("Coalesced Values: %s", string(j)) + + subchartValues, ok := v["spouter"].(map[string]interface{}) + if !ok { + t.Errorf("Subchart values not found") + } + + if _, ok := subchartValues["foo"]; ok { + t.Errorf("Expected key foo to be removed, still present") + } +} + func TestPathValue(t *testing.T) { doc := ` title: "Moby Dick" From c086f78583f1996939b73ab8dfdb6f24f0cb1488 Mon Sep 17 00:00:00 2001 From: ethan Date: Thu, 25 Jul 2019 22:36:25 +0800 Subject: [PATCH 49/82] cleanup: error message typos in sql.go Signed-off-by: ethan --- pkg/storage/driver/sql.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/storage/driver/sql.go b/pkg/storage/driver/sql.go index 46bcccc32..be2962da4 100644 --- a/pkg/storage/driver/sql.go +++ b/pkg/storage/driver/sql.go @@ -199,7 +199,7 @@ func (s *SQL) Query(labels map[string]string) ([]*rspb.Release, error) { sqlFilter[dbField] = val } else { s.Log("unknown label %s", key) - return nil, fmt.Errorf("unknow label %s", key) + return nil, fmt.Errorf("unknown label %s", key) } } sort.Strings(sqlFilterKeys) From ae52477fbd1c9fd177a638a7954332772463b77f Mon Sep 17 00:00:00 2001 From: Yusuke Kuoka Date: Fri, 26 Jul 2019 23:08:01 +0900 Subject: [PATCH 50/82] fix: upgrade with CRD changes Probably since K8s 1.13.x, `converter.ConvertToVersion(info.Object, groupVersioner)` which is the body of `asVersioned` doesn't return an error or an "unstructured" object, but `apiextensions/v1beta1.CustomResourceDefinition`. The result was `helm upgrade` with any changes in CRD consistently failing. This fixes that by adding an additional case of the conversion result being `v1beta1.CustomResourceDefinition`. This is a backward-compatible change as it doesn't remove existing switch cases for older K8s versions. Fixes #5853 Signed-off-by: Yusuke Kuoka --- pkg/kube/client.go | 35 +++++++++++++++++++++++++---------- pkg/kube/wait.go | 2 +- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 8fbfba1fd..e61d526a7 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -656,7 +656,7 @@ func createPatch(target *resource.Info, current runtime.Object) ([]byte, types.P } // Get a versioned object - versionedObject := asVersioned(target) + versionedObject, err := asVersioned(target) // Unstructured objects, such as CRDs, may not have an not registered error // returned from ConvertToVersion. Anything that's unstructured should @@ -664,16 +664,25 @@ func createPatch(target *resource.Info, current runtime.Object) ([]byte, types.P // on objects like CRDs. _, isUnstructured := versionedObject.(runtime.Unstructured) + // On newer K8s versions, CRDs aren't unstructured but has this dedicated type + _, isCRD := versionedObject.(*apiextv1beta1.CustomResourceDefinition) + switch { - case runtime.IsNotRegisteredError(err), isUnstructured: + case runtime.IsNotRegisteredError(err), isUnstructured, isCRD: // fall back to generic JSON merge patch patch, err := jsonpatch.CreateMergePatch(oldData, newData) - return patch, types.MergePatchType, err + if err != nil { + return nil, types.MergePatchType, fmt.Errorf("failed to create merge patch: %v", err) + } + return patch, types.MergePatchType, nil case err != nil: return nil, types.StrategicMergePatchType, fmt.Errorf("failed to get versionedObject: %s", err) default: patch, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, versionedObject) - return patch, types.StrategicMergePatchType, err + if err != nil { + return nil, types.StrategicMergePatchType, fmt.Errorf("failed to create two-way merge patch: %v", err) + } + return patch, types.StrategicMergePatchType, nil } } @@ -728,7 +737,7 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, return nil } - versioned := asVersioned(target) + versioned := asVersionedOrUnstructured(target) selector, ok := getSelectorFromObject(versioned) if !ok { return nil @@ -944,7 +953,7 @@ func (c *Client) getSelectRelationPod(info *resource.Info, objPods map[string][] c.Log("get relation pod of object: %s/%s/%s", info.Namespace, info.Mapping.GroupVersionKind.Kind, info.Name) - versioned := asVersioned(info) + versioned := asVersionedOrUnstructured(info) selector, ok := getSelectorFromObject(versioned) if !ok { return objPods, nil @@ -977,17 +986,23 @@ func isFoundPod(podItem []v1.Pod, pod v1.Pod) bool { return false } -func asVersioned(info *resource.Info) runtime.Object { +func asVersionedOrUnstructured(info *resource.Info) runtime.Object { + obj, _ := asVersioned(info) + return obj +} + +func asVersioned(info *resource.Info) (runtime.Object, error) { converter := runtime.ObjectConvertor(scheme.Scheme) groupVersioner := runtime.GroupVersioner(schema.GroupVersions(scheme.Scheme.PrioritizedVersionsAllGroups())) if info.Mapping != nil { groupVersioner = info.Mapping.GroupVersionKind.GroupVersion() } - if obj, err := converter.ConvertToVersion(info.Object, groupVersioner); err == nil { - return obj + obj, err := converter.ConvertToVersion(info.Object, groupVersioner) + if err != nil { + return info.Object, err } - return info.Object + return obj, nil } func asInternal(info *resource.Info) (runtime.Object, error) { diff --git a/pkg/kube/wait.go b/pkg/kube/wait.go index 105d79b93..51fa6a6df 100644 --- a/pkg/kube/wait.go +++ b/pkg/kube/wait.go @@ -53,7 +53,7 @@ func (c *Client) waitForResources(timeout time.Duration, created Result) error { pvc := []v1.PersistentVolumeClaim{} deployments := []deployment{} for _, v := range created { - switch value := asVersioned(v).(type) { + switch value := asVersionedOrUnstructured(v).(type) { case *v1.ReplicationController: list, err := getPods(kcs, value.Namespace, value.Spec.Selector) if err != nil { From 88fc1f03c39631bc4c3f1bbbcb54b8fb284134b1 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Fri, 26 Jul 2019 10:32:44 -0400 Subject: [PATCH 51/82] Adding a KEYS file with public pgp signing keys for Helm releases This file contains the keys and instructions for adding KEYS and importing them. It follows the model Apache uses for a file like this. Signed-off-by: Matt Farina --- KEYS | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 KEYS diff --git a/KEYS b/KEYS new file mode 100644 index 000000000..bd0b7e3b1 --- /dev/null +++ b/KEYS @@ -0,0 +1,152 @@ +This file contains the PGP keys of developers who have signed releases of Helm. + +For your convenience, commands are provided for those who use pgp and gpg. + +For users to import keys: + pgp < KEYS + or + gpg --import KEYS + +Developers to add their keys: + pgp -kxa and append it to this file. + or + (pgpk -ll && pgpk -xa ) >> KEYS + or + (gpg --list-sigs + && gpg --armor --export ) >> KEYS + +pub rsa4096/0x461449C25E36B98E 2017-11-10 [SC] + 672C657BE06B4B30969C4A57461449C25E36B98E +uid [ultimate] Matthew Farina +sig 3 0x461449C25E36B98E 2017-11-10 Matthew Farina +sig 0x2CDBBFBB37AE822A 2018-12-12 Adnan Abdulhussein +sig 0x1EF612347F8A9958 2018-12-12 Adam Reese +sig 0x62F49E747D911B60 2018-12-12 Matt Butcher +sub rsa4096/0xCCCE67689DF05738 2017-11-10 [E] +sig 0x461449C25E36B98E 2017-11-10 Matthew Farina +sub rsa4096/0x9436E80BFBA46909 2017-11-10 [S] [expires: 2022-11-09] +sig 0x461449C25E36B98E 2017-11-10 Matthew Farina + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 ++YMbPW0/IQ== +=g11H +-----END PGP PUBLIC KEY BLOCK----- + From 50386b29170810da639f09c42fbe9cffc70aacf4 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Fri, 26 Jul 2019 11:02:15 -0400 Subject: [PATCH 52/82] Adding release docs for the KEYS file and keyservers Signed-off-by: Matt Farina --- docs/release_checklist.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/release_checklist.md b/docs/release_checklist.md index 7474a01a6..0d877fc66 100644 --- a/docs/release_checklist.md +++ b/docs/release_checklist.md @@ -86,6 +86,11 @@ If you do not have GPG already setup you can follow these steps: 3. [Add key to GitHub account](https://help.github.com/en/articles/adding-a-new-gpg-key-to-your-github-account) 4. [Set signing key in Git](https://help.github.com/en/articles/telling-git-about-your-signing-key) +Once you have a signing key you need to add it to the KEYS file at the root of +the repository. The instructions for adding it to the KEYS file are in the file. +If you have not done so already, you need to add your public key to the keyserver +network. If you use GnuPG you can follow the [instructions provided by Debian](https://debian-administration.org/article/451/Submitting_your_GPG_key_to_a_keyserver). + ## 1. Create the Release Branch ### Major/Minor Releases From 9e33f84a6f7c4483b88a916b44029c38a9bc5f42 Mon Sep 17 00:00:00 2001 From: Martin Hickey Date: Mon, 29 Jul 2019 15:32:43 +0100 Subject: [PATCH 53/82] Add public signing key Signed-off-by: Martin Hickey --- KEYS | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/KEYS b/KEYS index bd0b7e3b1..3a34a468b 100644 --- a/KEYS +++ b/KEYS @@ -150,3 +150,62 @@ qdCDQHoUOgtZ4v6+QaxI3WV1KPBsPb7SAjuphubIQVK/6qHse9OoWVwWAABXHFqX =g11H -----END PGP PUBLIC KEY BLOCK----- +pub rsa4096 2019-05-15 [SC] + F1261BDE929012C8FF2E501D6EA5D7598529A53E +uid [ultimate] Martin Hickey +sig 3 6EA5D7598529A53E 2019-05-15 Martin Hickey +sub rsa4096 2019-05-15 [E] +sig 6EA5D7598529A53E 2019-05-15 Martin Hickey + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +1qneNQ== +=oCPv +-----END PGP PUBLIC KEY BLOCK----- From 5af2c31822aea4b717a804e3a9ec2bf376cea515 Mon Sep 17 00:00:00 2001 From: Dominic Joseph Date: Mon, 29 Jul 2019 15:32:39 -0700 Subject: [PATCH 54/82] Update example to set selector labels Signed-off-by: Dominic Joseph --- docs/examples/nginx/templates/deployment.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/examples/nginx/templates/deployment.yaml b/docs/examples/nginx/templates/deployment.yaml index 139d780cd..59b94a8aa 100644 --- a/docs/examples/nginx/templates/deployment.yaml +++ b/docs/examples/nginx/templates/deployment.yaml @@ -19,6 +19,10 @@ metadata: app.kubernetes.io/name: {{ template "nginx.name" . }} spec: replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "nginx.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} template: metadata: {{- if .Values.podAnnotations }} From 6485fec30979357284ae989f29f223bf08b7034f Mon Sep 17 00:00:00 2001 From: AllenZMC Date: Tue, 30 Jul 2019 21:11:04 +0800 Subject: [PATCH 55/82] fix word `constrint` to `constraint` Signed-off-by: czm --- pkg/plugin/installer/vcs_installer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/plugin/installer/vcs_installer.go b/pkg/plugin/installer/vcs_installer.go index 4b502dae4..9ec61ccfe 100644 --- a/pkg/plugin/installer/vcs_installer.go +++ b/pkg/plugin/installer/vcs_installer.go @@ -136,7 +136,7 @@ func (i *VCSInstaller) solveVersion(repo vcs.Repo) (string, error) { sort.Sort(sort.Reverse(semver.Collection(semvers))) for _, v := range semvers { if constraint.Check(v) { - // If the constrint passes get the original reference + // If the constraint passes get the original reference ver := v.Original() debug("setting to %s", ver) return ver, nil From d600c927240b1ffd25164957b886f141acf5361e Mon Sep 17 00:00:00 2001 From: dinesh reddy Date: Wed, 31 Jul 2019 09:04:47 -0500 Subject: [PATCH 56/82] Clean code: delete commented code Signed-off-by: dinesh reddy --- pkg/lint/rules/template.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 69b9c397f..26c548bac 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -106,13 +106,6 @@ func Templates(linter *support.Linter, values []byte, namespace string, strict b continue } - // NOTE: disabled for now, Refs https://github.com/kubernetes/helm/issues/1463 - // Check that all the templates have a matching value - //linter.RunLinterRule(support.WarningSev, path, validateNoMissingValues(templatesPath, valuesToRender, preExecutedTemplate)) - - // NOTE: disabled for now, Refs https://github.com/kubernetes/helm/issues/1037 - // linter.RunLinterRule(support.WarningSev, path, validateQuotes(string(preExecutedTemplate))) - renderedContent := renderedContentMap[filepath.Join(chart.GetMetadata().Name, fileName)] var yamlStruct K8sYamlStruct // Even though K8sYamlStruct only defines Metadata namespace, an error in any other From 6105acd3a89d62dd740672f41de4fe715dc67aa2 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Wed, 31 Jul 2019 16:27:17 -0400 Subject: [PATCH 57/82] Uploading KEYS file to azure along with dist files Signed-off-by: Matt Farina --- .circleci/deploy.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/deploy.sh b/.circleci/deploy.sh index fe95a5634..bdaef92ca 100755 --- a/.circleci/deploy.sh +++ b/.circleci/deploy.sh @@ -75,3 +75,6 @@ ${HOME}/google-cloud-sdk/bin/gsutil cp ./_dist/* "gs://${PROJECT_NAME}" echo "Pushing binaries to Azure" az storage blob upload-batch -s _dist/ -d "$AZURE_STORAGE_CONTAINER_NAME" --pattern 'helm-*' --connection-string "$AZURE_STORAGE_CONNECTION_STRING" + +echo "Pushing KEYS file to Azure" +az storage blob upload -f "KEYS" -n "KEYS" -c "$AZURE_STORAGE_CONTAINER_NAME" --connection-string "$AZURE_STORAGE_CONNECTION_STRING" \ No newline at end of file From b788e3dce965e76368f8af66b93c6a21abf730a3 Mon Sep 17 00:00:00 2001 From: AllenZMC Date: Thu, 1 Aug 2019 21:55:54 +0800 Subject: [PATCH 58/82] fix word 'potgres' to 'postgres' Signed-off-by: czm --- pkg/storage/driver/sql.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/storage/driver/sql.go b/pkg/storage/driver/sql.go index be2962da4..e1677c9ed 100644 --- a/pkg/storage/driver/sql.go +++ b/pkg/storage/driver/sql.go @@ -25,7 +25,7 @@ import ( "github.com/jmoiron/sqlx" migrate "github.com/rubenv/sql-migrate" - // Import pq for potgres dialect + // Import pq for postgres dialect _ "github.com/lib/pq" rspb "k8s.io/helm/pkg/proto/hapi/release" From b80fbeef630c5341e7ac6e5892e7eed30a22d443 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Thu, 1 Aug 2019 09:04:25 -0700 Subject: [PATCH 59/82] feat(KEYS): add bacongobbler's keys Signed-off-by: Matthew Fisher --- KEYS | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/KEYS b/KEYS index 3a34a468b..e01cfdb9d 100644 --- a/KEYS +++ b/KEYS @@ -209,3 +209,63 @@ m3MUub704EDCTSqz9LJc+4/NbA2esZj7mExCtsMEqaoHW7BU4ws6BRHTyeHgi+Le 1qneNQ== =oCPv -----END PGP PUBLIC KEY BLOCK----- + +pub rsa4096 2018-03-14 [SC] + 967F8AC5E2216F9F4FD270AD92AA783CBAAE8E3B +uid [ultimate] Matthew Fisher +sig 3 92AA783CBAAE8E3B 2018-03-14 Matthew Fisher +sub rsa4096 2018-03-14 [E] +sig 92AA783CBAAE8E3B 2018-03-14 Matthew Fisher + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +Qknjx8fW +=jz9T +-----END PGP PUBLIC KEY BLOCK----- From 4117b38ae621a8061563417c4b125dfb8ff59b00 Mon Sep 17 00:00:00 2001 From: dzzg Date: Fri, 2 Aug 2019 10:04:59 +0800 Subject: [PATCH 60/82] cleanup: log message typo fix Signed-off-by: dzzg --- cmd/helm/reset.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/reset.go b/cmd/helm/reset.go index cbe1795db..9e7a14710 100644 --- a/cmd/helm/reset.go +++ b/cmd/helm/reset.go @@ -115,7 +115,7 @@ func (d *resetCmd) run() error { } if err := installer.Uninstall(d.kubeClient, &installer.Options{Namespace: d.namespace}); err != nil { - return fmt.Errorf("error unstalling Tiller: %s", err) + return fmt.Errorf("error uninstalling Tiller: %s", err) } if d.removeHelmHome { From f653192882b488afd34422c9168e3d492f7df09f Mon Sep 17 00:00:00 2001 From: Kevin Lau Date: Fri, 2 Aug 2019 01:08:58 -0700 Subject: [PATCH 61/82] Fix typo notes -> note Signed-off-by: Kevin Lau --- docs/charts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/charts.md b/docs/charts.md index ed2e2f9eb..62b77647d 100644 --- a/docs/charts.md +++ b/docs/charts.md @@ -302,7 +302,7 @@ In the above example all charts with the tag `front-end` would be disabled but s `front-end` tag and `subchart1` will be enabled. Since `subchart2` is tagged with `back-end` and that tag evaluates to `true`, `subchart2` will be -enabled. Also notes that although `subchart2` has a condition specified in `requirements.yaml`, there +enabled. Also note that although `subchart2` has a condition specified in `requirements.yaml`, there is no corresponding path and value in the parent's values so that condition has no effect. ##### Using the CLI with Tags and Conditions From 6b5ab08a61d73980ca6f84ccdb3f6b996d950cae Mon Sep 17 00:00:00 2001 From: AllenZMC Date: Fri, 2 Aug 2019 22:54:00 +0800 Subject: [PATCH 62/82] fix word 'efault' to 'default' Signed-off-by: czm --- pkg/getter/httpgetter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/getter/httpgetter.go b/pkg/getter/httpgetter.go index 66ea82863..bf99b1cfa 100644 --- a/pkg/getter/httpgetter.go +++ b/pkg/getter/httpgetter.go @@ -26,7 +26,7 @@ import ( "k8s.io/helm/pkg/version" ) -//HttpGetter is the efault HTTP(/S) backend handler +//HttpGetter is the default HTTP(/S) backend handler // TODO: change the name to HTTPGetter in Helm 3 type HttpGetter struct { //nolint client *http.Client From bb69a1edd68cffe6aec4be8bfaa47f38135e8af8 Mon Sep 17 00:00:00 2001 From: Kevin Lau Date: Fri, 2 Aug 2019 09:22:15 -0700 Subject: [PATCH 63/82] Clarify operator docs wording The original is explaining the negation, when the body would not be included. Which would happen in the complement of the if expression, ie. flipped by De Morgan's law's: ``` not (or .Values.anUnsetVariable (not .Values.aSetVariable)) == and (not .Values.anUnsetVariable) .Values.aSetVariable ``` > unset variables evaluate to false is equivalent to `not .Values.anUnsetVariable`. > and is equivalent to `and`. > .Values.setVariable was negated with the not function doesn't seem to match `.Values.aSetVariable`. To me, that would be `not .Values.aSetVariable` instead. Anyway, explaining the `if` expression as-is and not the negation is clearer and parallels the first `if` operator. Signed-off-by: Kevin Lau --- docs/chart_template_guide/functions_and_pipelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chart_template_guide/functions_and_pipelines.md b/docs/chart_template_guide/functions_and_pipelines.md index 1c099887d..bbce53e71 100644 --- a/docs/chart_template_guide/functions_and_pipelines.md +++ b/docs/chart_template_guide/functions_and_pipelines.md @@ -159,7 +159,7 @@ Operators are implemented as functions that return a boolean value. To use `eq`, {{ end }} -{{/* do not include the body of this if statement because unset variables evaluate to false and .Values.setVariable was negated with the not function. */}} +{{/* include the body of this if statement when the variable .Values.anUnsetVariable is set or .values.aSetVariable is not set */}} {{ if or .Values.anUnsetVariable (not .Values.aSetVariable) }} {{ ... }} {{ end }} From 915d69a2c6a0026599f28c4857edff1c1f45bab9 Mon Sep 17 00:00:00 2001 From: AllenZMC Date: Sat, 3 Aug 2019 22:02:11 +0800 Subject: [PATCH 64/82] fix word 'resoures' to 'resources Signed-off-by: czm --- pkg/tiller/environment/environment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/tiller/environment/environment.go b/pkg/tiller/environment/environment.go index 83ec5e647..d3a478ea0 100644 --- a/pkg/tiller/environment/environment.go +++ b/pkg/tiller/environment/environment.go @@ -160,7 +160,7 @@ type KubeClient interface { // BuildUnstructured reads a stream of manifests from a reader and turns them into // info objects. Manifests are not validated against the schema, but it will fail if - // any resoures types are not known by the apiserver. + // any resources types are not known by the apiserver. // // reader must contain a YAML stream (one or more YAML documents separated by "\n---\n"). BuildUnstructured(namespace string, reader io.Reader) (kube.Result, error) From 53f1ab50e5ec38a33e7329c79a2ad61e747c4e18 Mon Sep 17 00:00:00 2001 From: AllenZMC Date: Tue, 6 Aug 2019 10:14:00 +0800 Subject: [PATCH 65/82] fix wrong spells in hooks.go Signed-off-by: czm --- pkg/tiller/hooks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/tiller/hooks.go b/pkg/tiller/hooks.go index 5aa961080..0eae3c475 100644 --- a/pkg/tiller/hooks.go +++ b/pkg/tiller/hooks.go @@ -53,7 +53,7 @@ var deletePolices = map[string]release.Hook_DeletePolicy{ hooks.BeforeHookCreation: release.Hook_BEFORE_HOOK_CREATION, } -// Timout used when deleting resources with a hook-delete-policy. +// Timeout used when deleting resources with a hook-delete-policy. const defaultHookDeleteTimeoutInSeconds = int64(60) // Manifest represents a manifest file, which has a name and some content. From 7b0a407ff7247aa41ad8efc6c4c1e0bd2cc2a046 Mon Sep 17 00:00:00 2001 From: AllenZMC Date: Wed, 7 Aug 2019 20:51:31 +0800 Subject: [PATCH 66/82] fix mis-spelling in manager.go Signed-off-by: czm --- pkg/downloader/manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go index 970bd9546..dfaa56bf3 100644 --- a/pkg/downloader/manager.go +++ b/pkg/downloader/manager.go @@ -357,7 +357,7 @@ func (m *Manager) hasAllRepos(deps []*chartutil.Dependency) error { return nil } -// getRepoNames returns the repo names of the referenced deps which can be used to fetch the cahced index file. +// getRepoNames returns the repo names of the referenced deps which can be used to fetch the cached index file. func (m *Manager) getRepoNames(deps []*chartutil.Dependency) (map[string]string, error) { rf, err := repo.LoadRepositoriesFile(m.HelmHome.RepositoryFile()) if err != nil { From e9ea2e0d1524b7de68feb3efb7a763d92a360f91 Mon Sep 17 00:00:00 2001 From: AllenZMC Date: Fri, 9 Aug 2019 21:27:33 +0800 Subject: [PATCH 67/82] fix some log typos in tlsutil_test.go Signed-off-by: czm --- pkg/tlsutil/tlsutil_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/tlsutil/tlsutil_test.go b/pkg/tlsutil/tlsutil_test.go index a4b3c9c22..e4df1e7e7 100644 --- a/pkg/tlsutil/tlsutil_test.go +++ b/pkg/tlsutil/tlsutil_test.go @@ -47,7 +47,7 @@ func TestClientConfig(t *testing.T) { t.Fatalf("expecting 1 client certificates, got %d", got) } if cfg.InsecureSkipVerify { - t.Fatalf("insecure skip verify mistmatch, expecting false") + t.Fatalf("insecure skip verify mismatch, expecting false") } if cfg.RootCAs == nil { t.Fatalf("mismatch tls RootCAs, expecting non-nil") From dd4afa6af0d6b4994243e8bc401f5c5b9c6cd8c1 Mon Sep 17 00:00:00 2001 From: Martin Hickey Date: Sat, 10 Aug 2019 11:55:26 +0100 Subject: [PATCH 68/82] Fail to load charts that are not v1 apiVersion (#6180) Signed-off-by: Martin Hickey --- pkg/chartutil/load.go | 4 ++++ pkg/chartutil/load_test.go | 12 +++++++++++ .../testdata/frobnitz.v2/.helmignore | 1 + pkg/chartutil/testdata/frobnitz.v2/Chart.yaml | 20 ++++++++++++++++++ .../testdata/frobnitz.v2/INSTALL.txt | 1 + pkg/chartutil/testdata/frobnitz.v2/LICENSE | 1 + pkg/chartutil/testdata/frobnitz.v2/README.md | 11 ++++++++++ .../testdata/frobnitz.v2/charts/_ignore_me | 1 + .../frobnitz.v2/charts/alpine/Chart.yaml | 4 ++++ .../frobnitz.v2/charts/alpine/README.md | 9 ++++++++ .../charts/alpine/charts/mast1/Chart.yaml | 4 ++++ .../charts/alpine/charts/mast1/values.yaml | 4 ++++ .../charts/alpine/charts/mast2-0.1.0.tgz | Bin 0 -> 325 bytes .../charts/alpine/templates/alpine-pod.yaml | 16 ++++++++++++++ .../frobnitz.v2/charts/alpine/values.yaml | 2 ++ .../frobnitz.v2/charts/mariner-4.3.2.tgz | Bin 0 -> 1012 bytes .../testdata/frobnitz.v2/docs/README.md | 1 + pkg/chartutil/testdata/frobnitz.v2/icon.svg | 8 +++++++ .../testdata/frobnitz.v2/ignore/me.txt | 0 .../testdata/frobnitz.v2/requirements.lock | 8 +++++++ .../testdata/frobnitz.v2/requirements.yaml | 7 ++++++ .../frobnitz.v2/templates/template.tpl | 1 + .../testdata/frobnitz.v2/values.yaml | 6 ++++++ 23 files changed, 121 insertions(+) create mode 100644 pkg/chartutil/testdata/frobnitz.v2/.helmignore create mode 100644 pkg/chartutil/testdata/frobnitz.v2/Chart.yaml create mode 100644 pkg/chartutil/testdata/frobnitz.v2/INSTALL.txt create mode 100644 pkg/chartutil/testdata/frobnitz.v2/LICENSE create mode 100644 pkg/chartutil/testdata/frobnitz.v2/README.md create mode 100644 pkg/chartutil/testdata/frobnitz.v2/charts/_ignore_me create mode 100644 pkg/chartutil/testdata/frobnitz.v2/charts/alpine/Chart.yaml create mode 100644 pkg/chartutil/testdata/frobnitz.v2/charts/alpine/README.md create mode 100644 pkg/chartutil/testdata/frobnitz.v2/charts/alpine/charts/mast1/Chart.yaml create mode 100644 pkg/chartutil/testdata/frobnitz.v2/charts/alpine/charts/mast1/values.yaml create mode 100644 pkg/chartutil/testdata/frobnitz.v2/charts/alpine/charts/mast2-0.1.0.tgz create mode 100644 pkg/chartutil/testdata/frobnitz.v2/charts/alpine/templates/alpine-pod.yaml create mode 100644 pkg/chartutil/testdata/frobnitz.v2/charts/alpine/values.yaml create mode 100644 pkg/chartutil/testdata/frobnitz.v2/charts/mariner-4.3.2.tgz create mode 100644 pkg/chartutil/testdata/frobnitz.v2/docs/README.md create mode 100644 pkg/chartutil/testdata/frobnitz.v2/icon.svg create mode 100644 pkg/chartutil/testdata/frobnitz.v2/ignore/me.txt create mode 100644 pkg/chartutil/testdata/frobnitz.v2/requirements.lock create mode 100644 pkg/chartutil/testdata/frobnitz.v2/requirements.yaml create mode 100644 pkg/chartutil/testdata/frobnitz.v2/templates/template.tpl create mode 100644 pkg/chartutil/testdata/frobnitz.v2/values.yaml diff --git a/pkg/chartutil/load.go b/pkg/chartutil/load.go index b0927a5cf..95b835d5b 100644 --- a/pkg/chartutil/load.go +++ b/pkg/chartutil/load.go @@ -171,6 +171,10 @@ func LoadFiles(files []*BufferedFile) (*chart.Chart, error) { return c, err } c.Metadata = m + var apiVersion = c.Metadata.ApiVersion + if apiVersion != "" && apiVersion != ApiVersionV1 { + return c, fmt.Errorf("apiVersion '%s' is not valid. The value must be \"v1\"", apiVersion) + } } else if f.Name == "values.toml" { return c, errors.New("values.toml is illegal as of 2.0.0-alpha.2") } else if f.Name == "values.yaml" { diff --git a/pkg/chartutil/load_test.go b/pkg/chartutil/load_test.go index c031a6a96..f139abf5c 100644 --- a/pkg/chartutil/load_test.go +++ b/pkg/chartutil/load_test.go @@ -23,6 +23,7 @@ import ( "os" "path" "path/filepath" + "strings" "testing" "time" @@ -39,6 +40,17 @@ func TestLoadDir(t *testing.T) { verifyRequirements(t, c) } +func TestLoadNonV1Chart(t *testing.T) { + _, err := Load("testdata/frobnitz.v2") + if err != nil { + if strings.Compare(err.Error(), "apiVersion 'v2' is not valid. The value must be \"v1\"") != 0 { + t.Errorf("Unexpected message: %s", err) + } + return + } + t.Fatalf("chart with v2 apiVersion should not load") +} + func TestLoadFile(t *testing.T) { c, err := Load("testdata/frobnitz-1.2.3.tgz") if err != nil { diff --git a/pkg/chartutil/testdata/frobnitz.v2/.helmignore b/pkg/chartutil/testdata/frobnitz.v2/.helmignore new file mode 100644 index 000000000..9973a57b8 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/.helmignore @@ -0,0 +1 @@ +ignore/ diff --git a/pkg/chartutil/testdata/frobnitz.v2/Chart.yaml b/pkg/chartutil/testdata/frobnitz.v2/Chart.yaml new file mode 100644 index 000000000..157af54c1 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/Chart.yaml @@ -0,0 +1,20 @@ +apiVersion: v2 +name: frobnitz +description: This is a frobnitz as a v2 chart +version: "1.2.3" +keywords: + - frobnitz + - sprocket + - dodad +maintainers: + - name: The Helm Team + email: helm@example.com + - name: Someone Else + email: nobody@example.com +sources: + - https://example.com/foo/bar +home: http://example.com +icon: https://example.com/64x64.png +annotations: + extrakey: extravalue + anotherkey: anothervalue diff --git a/pkg/chartutil/testdata/frobnitz.v2/INSTALL.txt b/pkg/chartutil/testdata/frobnitz.v2/INSTALL.txt new file mode 100644 index 000000000..2010438c2 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/INSTALL.txt @@ -0,0 +1 @@ +This is an install document. The client may display this. diff --git a/pkg/chartutil/testdata/frobnitz.v2/LICENSE b/pkg/chartutil/testdata/frobnitz.v2/LICENSE new file mode 100644 index 000000000..6121943b1 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/LICENSE @@ -0,0 +1 @@ +LICENSE placeholder. diff --git a/pkg/chartutil/testdata/frobnitz.v2/README.md b/pkg/chartutil/testdata/frobnitz.v2/README.md new file mode 100644 index 000000000..8cf4cc3d7 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/README.md @@ -0,0 +1,11 @@ +# Frobnitz + +This is an example chart. + +## Usage + +This is an example. It has no usage. + +## Development + +For developer info, see the top-level repository. diff --git a/pkg/chartutil/testdata/frobnitz.v2/charts/_ignore_me b/pkg/chartutil/testdata/frobnitz.v2/charts/_ignore_me new file mode 100644 index 000000000..2cecca682 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/charts/_ignore_me @@ -0,0 +1 @@ +This should be ignored by the loader, but may be included in a chart. diff --git a/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/Chart.yaml b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/Chart.yaml new file mode 100644 index 000000000..38a4aaa54 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/Chart.yaml @@ -0,0 +1,4 @@ +name: alpine +description: Deploy a basic Alpine Linux pod +version: 0.1.0 +home: https://k8s.io/helm diff --git a/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/README.md b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/README.md new file mode 100644 index 000000000..a7c84fc41 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/README.md @@ -0,0 +1,9 @@ +This example was generated using the command `helm create alpine`. + +The `templates/` directory contains a very simple pod resource with a +couple of parameters. + +The `values.toml` file contains the default values for the +`alpine-pod.yaml` template. + +You can install this example using `helm install docs/examples/alpine`. diff --git a/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/charts/mast1/Chart.yaml b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/charts/mast1/Chart.yaml new file mode 100644 index 000000000..171e36156 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/charts/mast1/Chart.yaml @@ -0,0 +1,4 @@ +name: mast1 +description: A Helm chart for Kubernetes +version: 0.1.0 +home: "" diff --git a/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/charts/mast1/values.yaml b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/charts/mast1/values.yaml new file mode 100644 index 000000000..42c39c262 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/charts/mast1/values.yaml @@ -0,0 +1,4 @@ +# Default values for mast1. +# This is a YAML-formatted file. +# Declare name/value pairs to be passed into your templates. +# name = "value" diff --git a/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/charts/mast2-0.1.0.tgz b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/charts/mast2-0.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..ced5a4a6adf946f76033b6ee584affc12433cb78 GIT binary patch literal 325 zcmV-L0lNMliwFRxBUV=c1MSw|YJ)Ho2Jl|{6o>BKov2ah-PkS$dy3RWS}syLpID4If6g{VtOEXtaBMKbNS zqRDw>=dBp!{dV&0PTP0q&C|N>lXXt-@itxw6Y{^`DeLnWW%?A)n7>C|RUhXsgbeu$ zF~=_IIe#g+SrMn$%(;J_|DcTCP^g0JS-aNm4}L!m8@i)M-5Y9`%Ajtv^fYa?9kkaj zJ8J8~B+f<7*=}6cSg*6cei`_&c>Y7mE>#=&?)@Lnf3ci@t|adNONjYC00000 X0000000000z?FFgy`&fL04M+ebFHRB literal 0 HcmV?d00001 diff --git a/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/templates/alpine-pod.yaml b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/templates/alpine-pod.yaml new file mode 100644 index 000000000..c34fa8c47 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/templates/alpine-pod.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: {{.Release.Name}}-{{.Chart.Name}} + labels: + app.kubernetes.io/managed-by: {{.Release.Service}} + chartName: {{.Chart.Name}} + chartVersion: {{.Chart.Version | quote}} + annotations: + "helm.sh/created": "{{.Release.Time.Seconds}}" +spec: + restartPolicy: {{default "Never" .restart_policy}} + containers: + - name: waiter + image: "alpine:3.3" + command: ["/bin/sleep","9000"] diff --git a/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/values.yaml b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/values.yaml new file mode 100644 index 000000000..6c2aab7ba --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/charts/alpine/values.yaml @@ -0,0 +1,2 @@ +# The pod name +name: "my-alpine" diff --git a/pkg/chartutil/testdata/frobnitz.v2/charts/mariner-4.3.2.tgz b/pkg/chartutil/testdata/frobnitz.v2/charts/mariner-4.3.2.tgz new file mode 100644 index 0000000000000000000000000000000000000000..78fabe241b042dcd5ec2ce08dacaaf26fc110640 GIT binary patch literal 1012 zcmVXdFct$FCMzS*7)(8lmGQQS%|2-P@PLQ%XW@8+wgs zC{cqN=XU3ETlOupvu)3qh#>i3n-2{XEL0(gmeQ(NX#^|8)Y=AHVz8k>LqKV1T8daG zEj<%$=k{JmQfgYfTrJLzgPFUVotfQdp8x+@3u41YxGuDa2!aq*6cDs(t`#D3uFV5P zDWXcUtctP>1W^(NH3XE!+*ASIBM{TAXenrG=+@)tuw?Qd=E>hjvAsvI^6_7jf|&4W zXqly7gFX*cmTw(@QH;{~3yLaB(TF0^_$z`Wg@91{t=!E2JpMMcPz>Zx0jDER!-h)? z$Buyp(1=V6XxWnik`4xOKY_4~2=cfs2z$XGnV0womvXYRgu~q3z8%ILQpo=x%HHDG z!0qY(?EI%4iRphiD8wJ54&T7YLN@VAZ37GHzY>`je^n7>rvK$YM=r8;WNQZUVjKXq zAm<3sOhAGi&!fKqfRXEX261pY22zB$UaYPTZG)C;B3^T>y16P6TvBw1u)vGFz^viF zNg;9s(O^Pq?TcUmw_X3!tQSQ&sQ;o0)Bkc%i2oL7`l#f}pJO5YmqcaW`=1ht3QYgY zK_z$&C82K;kUIfEq5tff#)jri&o?x!UCncqU{lKQ0R2GlN<-7eS~|jlgdiOx4XXb| zLufZh%1;D-Kpe}gHKE-e^tkLInh7xq%q4f$fC~-m0pfr}w(og#KEtM8(~gfpQI4|f z=Nu^Y)DCL+s!aQ+Hp#}@qe}Xbs|08rDtN+Tv z?ChQ$d5&A}IC>(DKxZf4k~4>F9)h=ko)?VpRtKAUxT}lh-M!1a_y1zqUmH~IJZXRP z->${wV*aZl_5Y|Mi!A@k!K&@|hdSOLX$>v?eJsBDJK>>aZ+z~*H?-WXjvpL4 z+}G5<_l3u*R}8o8JX`OyO}(?U->9kT8ofSoa@}xcZ+FF4a?Q1eR~7Y2d{^PMLneEN5o@_g@A$io99Pa!(Gqe2EM9;aGzHLzl;B?va8(XMXA#dZOazk)CZYAAR6O_jKm3)#;J$KkF}5PtE+Xqr&>;_{v|u zobg_3J2%*OU*`IX%QJf~eIop_=ZoIU@iULE(~pg1Mn{i4Q!%i=ckS0p=02G2kD@hK icf1~Y>h8pa!C){L3 + + Example icon + + + diff --git a/pkg/chartutil/testdata/frobnitz.v2/ignore/me.txt b/pkg/chartutil/testdata/frobnitz.v2/ignore/me.txt new file mode 100644 index 000000000..e69de29bb diff --git a/pkg/chartutil/testdata/frobnitz.v2/requirements.lock b/pkg/chartutil/testdata/frobnitz.v2/requirements.lock new file mode 100644 index 000000000..6fcc2ed9f --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/requirements.lock @@ -0,0 +1,8 @@ +dependencies: + - name: alpine + version: "0.1.0" + repository: https://example.com/charts + - name: mariner + version: "4.3.2" + repository: https://example.com/charts +digest: invalid diff --git a/pkg/chartutil/testdata/frobnitz.v2/requirements.yaml b/pkg/chartutil/testdata/frobnitz.v2/requirements.yaml new file mode 100644 index 000000000..5eb0bc98b --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/requirements.yaml @@ -0,0 +1,7 @@ +dependencies: + - name: alpine + version: "0.1.0" + repository: https://example.com/charts + - name: mariner + version: "4.3.2" + repository: https://example.com/charts diff --git a/pkg/chartutil/testdata/frobnitz.v2/templates/template.tpl b/pkg/chartutil/testdata/frobnitz.v2/templates/template.tpl new file mode 100644 index 000000000..c651ee6a0 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/templates/template.tpl @@ -0,0 +1 @@ +Hello {{.Name | default "world"}} diff --git a/pkg/chartutil/testdata/frobnitz.v2/values.yaml b/pkg/chartutil/testdata/frobnitz.v2/values.yaml new file mode 100644 index 000000000..61f501258 --- /dev/null +++ b/pkg/chartutil/testdata/frobnitz.v2/values.yaml @@ -0,0 +1,6 @@ +# A values file contains configuration. + +name: "Some Name" + +section: + name: "Name in a section" From 03443bb0b5f2c47a75539476afac83bb14c74cc8 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 13 Aug 2019 14:01:56 -0700 Subject: [PATCH 69/82] docs(OWNERS): add jdolitsky as a core maintainer Signed-off-by: Matthew Fisher --- OWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/OWNERS b/OWNERS index 3fa911034..715c8993d 100644 --- a/OWNERS +++ b/OWNERS @@ -3,6 +3,7 @@ maintainers: - bacongobbler - fibonacci1729 - hickeyma + - jdolitsky - mattfarina - michelleN - prydonius From 66974afddb661b0e350c07e675e6d03ecf972cdd Mon Sep 17 00:00:00 2001 From: Xiang Dai <764524258@qq.com> Date: Fri, 16 Aug 2019 16:44:40 +0800 Subject: [PATCH 70/82] remove duplicate check Signed-off-by: Xiang Dai <764524258@qq.com> --- pkg/downloader/manager.go | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go index dfaa56bf3..cca198916 100644 --- a/pkg/downloader/manager.go +++ b/pkg/downloader/manager.go @@ -407,24 +407,22 @@ func (m *Manager) getRepoNames(deps []*chartutil.Dependency) (map[string]string, } } if len(missing) > 0 { - if len(missing) > 0 { - errorMessage := fmt.Sprintf("no repository definition for %s. Please add them via 'helm repo add'", strings.Join(missing, ", ")) - // It is common for people to try to enter "stable" as a repository instead of the actual URL. - // For this case, let's give them a suggestion. - containsNonURL := false - for _, repo := range missing { - if !strings.Contains(repo, "//") && !strings.HasPrefix(repo, "@") && !strings.HasPrefix(repo, "alias:") { - containsNonURL = true - } + errorMessage := fmt.Sprintf("no repository definition for %s. Please add them via 'helm repo add'", strings.Join(missing, ", ")) + // It is common for people to try to enter "stable" as a repository instead of the actual URL. + // For this case, let's give them a suggestion. + containsNonURL := false + for _, repo := range missing { + if !strings.Contains(repo, "//") && !strings.HasPrefix(repo, "@") && !strings.HasPrefix(repo, "alias:") { + containsNonURL = true } - if containsNonURL { - errorMessage += ` + } + if containsNonURL { + errorMessage += ` Note that repositories must be URLs or aliases. For example, to refer to the stable repository, use "https://kubernetes-charts.storage.googleapis.com/" or "@stable" instead of "stable". Don't forget to add the repo, too ('helm repo add').` - } - return nil, errors.New(errorMessage) } + return nil, errors.New(errorMessage) } return reposMap, nil } From 627283ac7441c7fc1890be843d15e580705f45b8 Mon Sep 17 00:00:00 2001 From: Sakura Date: Fri, 23 Aug 2019 12:02:21 +0800 Subject: [PATCH 71/82] fix typo Signed-off-by: Sakura --- _proto/hapi/release/status.proto | 2 +- docs/charts.md | 2 +- pkg/kube/client.go | 2 +- pkg/proto/hapi/release/status.pb.go | 2 +- pkg/storage/storage.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/_proto/hapi/release/status.proto b/_proto/hapi/release/status.proto index e6ccd3d6e..6cc16b351 100644 --- a/_proto/hapi/release/status.proto +++ b/_proto/hapi/release/status.proto @@ -41,7 +41,7 @@ message Status { PENDING_INSTALL = 6; // Status_PENDING_UPGRADE indicates that an upgrade operation is underway. PENDING_UPGRADE = 7; - // Status_PENDING_ROLLBACK indicates that an rollback operation is underway. + // Status_PENDING_ROLLBACK indicates that a rollback operation is underway. PENDING_ROLLBACK = 8; } diff --git a/docs/charts.md b/docs/charts.md index 62b77647d..9affe50cb 100644 --- a/docs/charts.md +++ b/docs/charts.md @@ -479,7 +479,7 @@ Furthermore, A is dependent on chart B that creates objects - replicaset "B-ReplicaSet" - service "B-Service" -After installation/upgrade of chart A a single Helm release is created/modified. The release will +After installation/upgrade of chart A, a single Helm release is created/modified. The release will create/update all of the above Kubernetes objects in the following order: - A-Namespace diff --git a/pkg/kube/client.go b/pkg/kube/client.go index e61d526a7..aa6f54ae0 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -658,7 +658,7 @@ func createPatch(target *resource.Info, current runtime.Object) ([]byte, types.P // Get a versioned object versionedObject, err := asVersioned(target) - // Unstructured objects, such as CRDs, may not have an not registered error + // Unstructured objects, such as CRDs, may not have a not registered error // returned from ConvertToVersion. Anything that's unstructured should // use the jsonpatch.CreateMergePatch. Strategic Merge Patch is not supported // on objects like CRDs. diff --git a/pkg/proto/hapi/release/status.pb.go b/pkg/proto/hapi/release/status.pb.go index c5ed59202..99bcbc585 100644 --- a/pkg/proto/hapi/release/status.pb.go +++ b/pkg/proto/hapi/release/status.pb.go @@ -38,7 +38,7 @@ const ( Status_PENDING_INSTALL Status_Code = 6 // Status_PENDING_UPGRADE indicates that an upgrade operation is underway. Status_PENDING_UPGRADE Status_Code = 7 - // Status_PENDING_ROLLBACK indicates that an rollback operation is underway. + // Status_PENDING_ROLLBACK indicates that a rollback operation is underway. Status_PENDING_ROLLBACK Status_Code = 8 ) diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index 9520db08b..e79cacc8d 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -50,7 +50,7 @@ func (s *Storage) Get(name string, version int32) (*rspb.Release, error) { // Create creates a new storage entry holding the release. An // error is returned if the storage driver failed to store the -// release, or a release with identical an key already exists. +// release, or a release with identical key already exists. func (s *Storage) Create(rls *rspb.Release) error { s.Log("creating release %q", makeKey(rls.Name, rls.Version)) if s.MaxHistory > 0 { From aaf24e065851e96632997b4849c98721745a7a12 Mon Sep 17 00:00:00 2001 From: kamal namdeo Date: Fri, 23 Aug 2019 16:15:05 +0200 Subject: [PATCH 72/82] Fix the developer.md typo (#6203) Signed-off-by: kamal namdeo --- docs/developers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developers.md b/docs/developers.md index 70203b2d0..32adbf823 100644 --- a/docs/developers.md +++ b/docs/developers.md @@ -103,7 +103,7 @@ helm init --canary-image For developing on Tiller, it is sometimes more expedient to run Tiller locally instead of packaging it into an image and running it in-cluster. You can do -this by telling the Helm client to us a local instance. +this by telling the Helm client to use a local instance. ```console $ make build From f8f8b5d076483291adc6713923a8409baee40f8c Mon Sep 17 00:00:00 2001 From: Adam Eijdenberg Date: Sat, 24 Aug 2019 02:22:54 +1000 Subject: [PATCH 73/82] Add test for subchart with null value (#6146) Signed-off-by: Adam Eijdenberg --- pkg/chartutil/values_test.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/pkg/chartutil/values_test.go b/pkg/chartutil/values_test.go index dfb38387e..04b507fbc 100644 --- a/pkg/chartutil/values_test.go +++ b/pkg/chartutil/values_test.go @@ -643,3 +643,35 @@ func TestOverriteTableItemWithNonTableValue(t *testing.T) { t.Errorf("Expected %v, but got %v", expected, result) } } + +func TestSubchartCoaleseWithNullValue(t *testing.T) { + v, err := CoalesceValues(&chart.Chart{ + Metadata: &chart.Metadata{Name: "demo"}, + Dependencies: []*chart.Chart{ + { + Metadata: &chart.Metadata{Name: "logstash"}, + Values: &chart.Config{ + Raw: `livenessProbe: {httpGet: {path: "/", port: monitor}}`, + }, + }, + }, + Values: &chart.Config{ + Raw: `logstash: {livenessProbe: {httpGet: null, exec: "/bin/true"}}`, + }, + }, &chart.Config{}) + if err != nil { + t.Errorf("Failed with %s", err) + } + result := v.AsMap() + expected := map[string]interface{}{ + "logstash": map[string]interface{}{ + "global": map[string]interface{}{}, + "livenessProbe": map[string]interface{}{ + "exec": "/bin/true", + }, + }, + } + if !reflect.DeepEqual(result, expected) { + t.Errorf("got %+v, expected %+v", result, expected) + } +} From 256765aa741d0b6559b4c449baeb56ebb9c285f3 Mon Sep 17 00:00:00 2001 From: Gasmi Christophe Date: Mon, 26 Aug 2019 11:43:07 +0200 Subject: [PATCH 74/82] Networkpolicy kind sort (#6266) * Add NetworkPolicy in kind sorter Signed-off-by: Christophe GASMI * Added NetworkPolicy to sort order test Signed-off-by: Christophe GASMI --- pkg/tiller/kind_sorter.go | 2 ++ pkg/tiller/kind_sorter_test.go | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pkg/tiller/kind_sorter.go b/pkg/tiller/kind_sorter.go index 5c7193dee..90678cce5 100644 --- a/pkg/tiller/kind_sorter.go +++ b/pkg/tiller/kind_sorter.go @@ -28,6 +28,7 @@ type SortOrder []string // Those occurring earlier in the list get installed before those occurring later in the list. var InstallOrder SortOrder = []string{ "Namespace", + "NetworkPolicy", "ResourceQuota", "LimitRange", "PodSecurityPolicy", @@ -96,6 +97,7 @@ var UninstallOrder SortOrder = []string{ "PodSecurityPolicy", "LimitRange", "ResourceQuota", + "NetworkPolicy", "Namespace", } diff --git a/pkg/tiller/kind_sorter_test.go b/pkg/tiller/kind_sorter_test.go index 3b37256ed..f4106f62e 100644 --- a/pkg/tiller/kind_sorter_test.go +++ b/pkg/tiller/kind_sorter_test.go @@ -157,6 +157,10 @@ func TestKindSorter(t *testing.T) { Name: "x", Head: &util.SimpleHead{Kind: "HorizontalPodAutoscaler"}, }, + { + Name: "B", + Head: &util.SimpleHead{Kind: "NetworkPolicy"}, + }, } for _, test := range []struct { @@ -164,8 +168,8 @@ func TestKindSorter(t *testing.T) { order SortOrder expected string }{ - {"install", InstallOrder, "abc3zde1fgh2iIjJkKlLmnopqrxstuvw!"}, - {"uninstall", UninstallOrder, "wvmutsxrqponLlKkJjIi2hgf1edz3cba!"}, + {"install", InstallOrder, "aBbc3zde1fgh2iIjJkKlLmnopqrxstuvw!"}, + {"uninstall", UninstallOrder, "wvmutsxrqponLlKkJjIi2hgf1edz3cbBa!"}, } { var buf bytes.Buffer t.Run(test.description, func(t *testing.T) { From 95ec21339549e2242ff2fa9a0940ca0527bcbe83 Mon Sep 17 00:00:00 2001 From: yuxiaobo Date: Fri, 30 Aug 2019 13:10:06 +0800 Subject: [PATCH 75/82] delete extra space Signed-off-by: yuxiaobo --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 996f6d224..aee515e37 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -199,7 +199,7 @@ $ git pull upstream master ```sh $ git checkout -b new-feature ``` -6. Make any change on the branch `new-feature` then build and test your codes. +6. Make any change on the branch `new-feature` then build and test your codes. 7. Include in what will be committed. ```sh $ git add From 55ccdd040d8a6f244f1ebd93323c17a46aa890f7 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Fri, 12 Jul 2019 13:58:12 +0100 Subject: [PATCH 76/82] Use watcher with retries to wait for resources When waiting for resources use the `ListWatchUntil` instead of `UntilWithoutRetry` so that if the connection drops between tiller and the API while waiting the operation can still succeed. Signed-off-by: Richard Connon --- pkg/kube/client.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index aa6f54ae0..e78c10f2d 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -41,6 +41,7 @@ import ( apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -51,6 +52,7 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/resource" "k8s.io/client-go/kubernetes/scheme" + cachetools "k8s.io/client-go/tools/cache" watchtools "k8s.io/client-go/tools/watch" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/core" @@ -810,10 +812,7 @@ func getSelectorFromObject(obj runtime.Object) (map[string]string, bool) { } func (c *Client) watchUntilReady(timeout time.Duration, info *resource.Info) error { - w, err := resource.NewHelper(info.Client, info.Mapping).WatchSingle(info.Namespace, info.Name, info.ResourceVersion) - if err != nil { - return err - } + lw := cachetools.NewListWatchFromClient(info.Client, info.Mapping.Resource.Resource, info.Namespace, fields.Everything()) kind := info.Mapping.GroupVersionKind.Kind c.Log("Watching for changes to %s %s with timeout of %v", kind, info.Name, timeout) @@ -826,7 +825,7 @@ func (c *Client) watchUntilReady(timeout time.Duration, info *resource.Info) err ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), timeout) defer cancel() - _, err = watchtools.UntilWithoutRetry(ctx, w, func(e watch.Event) (bool, error) { + _, err := watchtools.ListWatchUntil(ctx, lw, func(e watch.Event) (bool, error) { switch e.Type { case watch.Added, watch.Modified: // For things like a secret or a config map, this is the best indicator @@ -914,15 +913,12 @@ func (c *Client) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, } func (c *Client) watchPodUntilComplete(timeout time.Duration, info *resource.Info) error { - w, err := resource.NewHelper(info.Client, info.Mapping).WatchSingle(info.Namespace, info.Name, info.ResourceVersion) - if err != nil { - return err - } + lw := cachetools.NewListWatchFromClient(info.Client, info.Mapping.Resource.Resource, info.Namespace, fields.Everything()) c.Log("Watching pod %s for completion with timeout of %v", info.Name, timeout) ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), timeout) defer cancel() - _, err = watchtools.UntilWithoutRetry(ctx, w, func(e watch.Event) (bool, error) { + _, err := watchtools.ListWatchUntil(ctx, lw, func(e watch.Event) (bool, error) { return isPodComplete(e) }) From 540fe23b692ab22b04e4718644cc654d694abc04 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 2 Sep 2019 19:20:36 +0200 Subject: [PATCH 77/82] fix BusyBox sed (#6327) BusyBox sed works the same way as GNU sed Signed-off-by: tipok --- cmd/helm/completion.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/completion.go b/cmd/helm/completion.go index 039dcbe5f..e6ca1c6ac 100644 --- a/cmd/helm/completion.go +++ b/cmd/helm/completion.go @@ -194,7 +194,7 @@ autoload -U +X bashcompinit && bashcompinit # use word boundary patterns for BSD or GNU sed LWORD='[[:<:]]' RWORD='[[:>:]]' -if sed --help 2>&1 | grep -q GNU; then +if sed --help 2>&1 | grep -q 'GNU\|BusyBox'; then LWORD='\<' RWORD='\>' fi From 3ed073b2e0c37dd5c994562d6fe8e04b5f3609eb Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 3 Sep 2019 10:01:47 -0400 Subject: [PATCH 78/82] v2: Dynamic completion for "helm repo" and "helm plugin" (#6265) * feat(helm): Completion for helm repo remove Signed-off-by: Marc Khouzam * feat(helm): Complete for helm plugin remove/update helm repo remove (will select from the names of configured repos) helm plugin remove (will select from names of installed plugins) helm plugin update (will select from names of installed plugins) Signed-off-by: Marc Khouzam * feat(helm): Completion for helm repo update Signed-off-by: Marc Khouzam --- cmd/helm/helm.go | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 2f394968f..20742836d 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -41,7 +41,7 @@ import ( const ( bashCompletionFunc = ` -__helm_override_flag_list=(--kubeconfig --kube-context --host --tiller-namespace) +__helm_override_flag_list=(--kubeconfig --kube-context --host --tiller-namespace --home) __helm_override_flags() { local ${__helm_override_flag_list[*]##*-} two_word_of of var @@ -80,6 +80,28 @@ __helm_list_releases() fi } +__helm_list_repos() +{ + __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" + local out oflags + oflags=$(__helm_override_flags) + __helm_debug "${FUNCNAME[0]}: __helm_override_flags are ${oflags}" + if out=$(helm repo list ${oflags} | tail +2 | cut -f1 2>/dev/null); then + COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) ) + fi +} + +__helm_list_plugins() +{ + __helm_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" + local out oflags + oflags=$(__helm_override_flags) + __helm_debug "${FUNCNAME[0]}: __helm_override_flags are ${oflags}" + if out=$(helm plugin list ${oflags} | tail +2 | cut -f1 2>/dev/null); then + COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) ) + fi +} + __helm_custom_func() { __helm_debug "${FUNCNAME[0]}: c is $c words[@] is ${words[@]}" @@ -89,6 +111,14 @@ __helm_custom_func() __helm_list_releases return ;; + helm_repo_remove | helm_repo_update) + __helm_list_repos + return + ;; + helm_plugin_remove | helm_plugin_update) + __helm_list_plugins + return + ;; *) ;; esac From eeff9079b84eeb67a0f0f7652c644c480aa2d045 Mon Sep 17 00:00:00 2001 From: Steven Cipriano Date: Thu, 5 Sep 2019 13:41:41 -0700 Subject: [PATCH 79/82] In get script, use specified path to helm binary for helm version check Signed-off-by: Steven Cipriano --- scripts/get | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/get b/scripts/get index ea2056ca6..3f645f807 100755 --- a/scripts/get +++ b/scripts/get @@ -94,7 +94,7 @@ checkDesiredVersion() { # if it needs to be changed. checkHelmInstalledVersion() { if [[ -f "${HELM_INSTALL_DIR}/${PROJECT_NAME}" ]]; then - local version=$(helm version -c | grep '^Client' | cut -d'"' -f2) + local version=$("${HELM_INSTALL_DIR}/${PROJECT_NAME}" version -c | grep '^Client' | cut -d'"' -f2) if [[ "$version" == "$TAG" ]]; then echo "Helm ${version} is already ${DESIRED_VERSION:-latest}" return 0 From b49f4269c5bdfee920b0d5fd7954513f5e17dad6 Mon Sep 17 00:00:00 2001 From: Xiang Dai <764524258@qq.com> Date: Wed, 21 Aug 2019 10:36:42 +0800 Subject: [PATCH 80/82] fix issue when dependency is URL Signed-off-by: Xiang Dai <764524258@qq.com> --- pkg/downloader/chart_downloader.go | 5 +++++ pkg/downloader/manager.go | 19 ++++++++++++++++--- pkg/downloader/manager_test.go | 16 ++++++++-------- pkg/resolver/resolver.go | 13 ++++++++++++- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go index 563188ec3..c2e9f6dc1 100644 --- a/pkg/downloader/chart_downloader.go +++ b/pkg/downloader/chart_downloader.go @@ -205,6 +205,11 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, ge } c.setCredentials(r) + // Skip if dependency not contain name + if len(r.Config.Name) == 0 { + return u, r.Client, nil + } + // Next, we need to load the index, and actually look up the chart. i, err := repo.LoadIndexFile(c.HelmHome.CacheIndex(r.Config.Name)) if err != nil { diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go index cca198916..6c6886e8a 100644 --- a/pkg/downloader/manager.go +++ b/pkg/downloader/manager.go @@ -233,7 +233,7 @@ func (m *Manager) downloadAll(deps []*chartutil.Dependency) error { // Any failure to resolve/download a chart should fail: // https://github.com/kubernetes/helm/issues/1439 - churl, username, password, err := findChartURL(dep.Name, dep.Version, dep.Repository, repos) + churl, username, password, err := m.findChartURL(dep.Name, dep.Version, dep.Repository, repos) if err != nil { saveError = fmt.Errorf("could not find %s: %s", churl, err) break @@ -403,9 +403,17 @@ func (m *Manager) getRepoNames(deps []*chartutil.Dependency) (map[string]string, } } if !found { - missing = append(missing, dd.Repository) + repository := dd.Repository + // Add if URL + _, err := url.ParseRequestURI(repository) + if err == nil { + reposMap[repository] = repository + continue + } + missing = append(missing, repository) } } + if len(missing) > 0 { errorMessage := fmt.Sprintf("no repository definition for %s. Please add them via 'helm repo add'", strings.Join(missing, ", ")) // It is common for people to try to enter "stable" as a repository instead of the actual URL. @@ -424,6 +432,7 @@ repository, use "https://kubernetes-charts.storage.googleapis.com/" or "@stable" } return nil, errors.New(errorMessage) } + return reposMap, nil } @@ -475,7 +484,7 @@ func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error { // repoURL is the repository to search // // If it finds a URL that is "relative", it will prepend the repoURL. -func findChartURL(name, version, repoURL string, repos map[string]*repo.ChartRepository) (url, username, password string, err error) { +func (m *Manager) findChartURL(name, version, repoURL string, repos map[string]*repo.ChartRepository) (url, username, password string, err error) { for _, cr := range repos { if urlutil.Equal(repoURL, cr.Config.URL) { var entry repo.ChartVersions @@ -497,6 +506,10 @@ func findChartURL(name, version, repoURL string, repos map[string]*repo.ChartRep return } } + url, err = repo.FindChartInRepoURL(repoURL, name, version, "", "", "", m.Getters) + if err == nil { + return + } err = fmt.Errorf("chart %s not found in %s", name, repoURL) return } diff --git a/pkg/downloader/manager_test.go b/pkg/downloader/manager_test.go index cb588394a..ef8b95071 100644 --- a/pkg/downloader/manager_test.go +++ b/pkg/downloader/manager_test.go @@ -78,7 +78,7 @@ func TestFindChartURL(t *testing.T) { version := "0.1.0" repoURL := "http://example.com/charts" - churl, username, password, err := findChartURL(name, version, repoURL, repos) + churl, username, password, err := m.findChartURL(name, version, repoURL, repos) if err != nil { t.Fatal(err) } @@ -106,13 +106,6 @@ func TestGetRepoNames(t *testing.T) { err bool expectedErr string }{ - { - name: "no repo definition failure", - req: []*chartutil.Dependency{ - {Name: "oedipus-rex", Repository: "http://example.com/test"}, - }, - err: true, - }, { name: "no repo definition failure -- stable repo", req: []*chartutil.Dependency{ @@ -128,6 +121,13 @@ func TestGetRepoNames(t *testing.T) { err: true, expectedErr: "no 'repository' field specified for dependency: \"dependency-missing-repository-field\"", }, + { + name: "dependency repository is url but not exist in repos", + req: []*chartutil.Dependency{ + {Name: "oedipus-rex", Repository: "http://example.com/test"}, + }, + expect: map[string]string{"http://example.com/test": "http://example.com/test"}, + }, { name: "no repo definition failure", req: []*chartutil.Dependency{ diff --git a/pkg/resolver/resolver.go b/pkg/resolver/resolver.go index 8177df2d3..516e9260f 100644 --- a/pkg/resolver/resolver.go +++ b/pkg/resolver/resolver.go @@ -71,7 +71,18 @@ func (r *Resolver) Resolve(reqs *chartutil.Requirements, repoNames map[string]st return nil, fmt.Errorf("dependency %q has an invalid version/constraint format: %s", d.Name, err) } - repoIndex, err := repo.LoadIndexFile(r.helmhome.CacheIndex(repoNames[d.Name])) + // repo does not exist in cache but has url info + cacheRepoName := repoNames[d.Name] + if cacheRepoName == "" && d.Repository != "" { + locked[i] = &chartutil.Dependency{ + Name: d.Name, + Repository: d.Repository, + Version: d.Version, + } + continue + } + + repoIndex, err := repo.LoadIndexFile(r.helmhome.CacheIndex(cacheRepoName)) if err != nil { return nil, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err) } From 8d8eceec92217a0eb3ad06a3e2b82e92f22b3c37 Mon Sep 17 00:00:00 2001 From: yuxiaobo Date: Tue, 10 Sep 2019 17:47:52 +0800 Subject: [PATCH 81/82] Grammar tweak Signed-off-by: yuxiaobo --- docs/chart_repository_sync_example.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chart_repository_sync_example.md b/docs/chart_repository_sync_example.md index 931275431..91215cb25 100644 --- a/docs/chart_repository_sync_example.md +++ b/docs/chart_repository_sync_example.md @@ -38,7 +38,7 @@ Building synchronization state... Starting synchronization Would copy file://fantastic-charts/alpine-0.1.0.tgz to gs://fantastic-charts/alpine-0.1.0.tgz Would copy file://fantastic-charts/index.yaml to gs://fantastic-charts/index.yaml -Are you sure you would like to continue with these changes?? [y/N]} y +Are you sure you would like to continue with these changes? [y/N]} y Building synchronization state... Starting synchronization Copying file://fantastic-charts/alpine-0.1.0.tgz [Content-Type=application/x-tar]... From 05d5ff4747cb810e61f88685285bcd8e73f073aa Mon Sep 17 00:00:00 2001 From: Xiang Dai <764524258@qq.com> Date: Tue, 10 Sep 2019 10:05:58 +0800 Subject: [PATCH 82/82] update test Signed-off-by: Xiang Dai <764524258@qq.com> --- pkg/resolver/resolver_test.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pkg/resolver/resolver_test.go b/pkg/resolver/resolver_test.go index 689ffbc32..f35e051fa 100644 --- a/pkg/resolver/resolver_test.go +++ b/pkg/resolver/resolver_test.go @@ -37,15 +37,6 @@ func TestResolve(t *testing.T) { }, err: true, }, - { - name: "cache index failure", - req: &chartutil.Requirements{ - Dependencies: []*chartutil.Dependency{ - {Name: "oedipus-rex", Repository: "http://example.com", Version: "1.0.0"}, - }, - }, - err: true, - }, { name: "chart not found failure", req: &chartutil.Requirements{