From fbe80437a499e6b5c7301588522b03dde593ce10 Mon Sep 17 00:00:00 2001 From: Justin Scott Date: Tue, 9 Jan 2018 00:51:03 -0800 Subject: [PATCH 001/221] fix(helm): fix importValues warnings from disabled charts ImportValues incorrectly processes charts that should be disabled. This patch excludes those charts. Closes #2620 --- pkg/chartutil/requirements.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/pkg/chartutil/requirements.go b/pkg/chartutil/requirements.go index ce761a6fc..546160b0c 100644 --- a/pkg/chartutil/requirements.go +++ b/pkg/chartutil/requirements.go @@ -394,6 +394,21 @@ func processImportValues(c *chart.Chart) error { b := make(map[string]interface{}, 0) // 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) + found := false + name := r.Name + for _, v := range c.Dependencies { + if v.Metadata.Name == r.Name { + found = true + } + if v.Metadata.Name == r.Alias { + found = true + name = r.Alias + } + } + if !found { + continue + } if len(r.ImportValues) > 0 { var outiv []interface{} for _, riv := range r.ImportValues { @@ -404,7 +419,7 @@ func processImportValues(c *chart.Chart) error { "parent": iv["parent"].(string), } outiv = append(outiv, nm) - s := r.Name + "." + nm["child"] + s := name + "." + nm["child"] // get child table vv, err := cvals.Table(s) if err != nil { @@ -420,7 +435,7 @@ func processImportValues(c *chart.Chart) error { "parent": ".", } outiv = append(outiv, nm) - s := r.Name + "." + nm["child"] + s := name + "." + nm["child"] vm, err := cvals.Table(s) if err != nil { log.Printf("Warning: ImportValues missing table: %v", err) From 3d05da010980fd93258d4f10ff4d0dbabe53dba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Na=CC=88gele?= Date: Mon, 22 Jan 2018 14:44:30 +0100 Subject: [PATCH 002/221] Fix pod recreation --- pkg/kube/client.go | 57 +++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index b1ff0de0f..2cb94cd23 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -428,40 +428,39 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, if err := target.Get(); err != nil { return fmt.Errorf("error trying to refresh resource information: %v", err) } - return nil - } - - // send patch to server - helper := resource.NewHelper(target.Client, target.Mapping) - - obj, err := helper.Patch(target.Namespace, target.Name, patchType, patch) - if err != nil { - kind := target.Mapping.GroupVersionKind.Kind - log.Printf("Cannot patch %s: %q (%v)", kind, target.Name, err) + } else { + // send patch to server + helper := resource.NewHelper(target.Client, target.Mapping) - if force { - // Attempt to delete... - if err := deleteResource(c, target); err != nil { + obj, err := helper.Patch(target.Namespace, target.Name, patchType, patch) + if err != nil { + kind := target.Mapping.GroupVersionKind.Kind + log.Printf("Cannot patch %s: %q (%v)", kind, target.Name, err) + + if force { + // Attempt to delete... + if err := deleteResource(c, target); err != nil { + return err + } + log.Printf("Deleted %s: %q", kind, target.Name) + + // ... and recreate + if err := createResource(target); err != nil { + return fmt.Errorf("Failed to recreate resource: %s", err) + } + log.Printf("Created a new %s called %q\n", kind, target.Name) + + // No need to refresh the target, as we recreated the resource based + // on it. In addition, it might not exist yet and a call to `Refresh` + // may fail. + } else { + log.Print("Use --force to force recreation of the resource") return err } - log.Printf("Deleted %s: %q", kind, target.Name) - - // ... and recreate - if err := createResource(target); err != nil { - return fmt.Errorf("Failed to recreate resource: %s", err) - } - log.Printf("Created a new %s called %q\n", kind, target.Name) - - // No need to refresh the target, as we recreated the resource based - // on it. In addition, it might not exist yet and a call to `Refresh` - // may fail. } else { - log.Print("Use --force to force recreation of the resource") - return err + // When patch succeeds without needing to recreate, refresh target. + target.Refresh(obj, true) } - } else { - // When patch succeeds without needing to recreate, refresh target. - target.Refresh(obj, true) } if !recreate { From 0ddfbaafb6e686f1a4c9490dfb66df8b29ccb592 Mon Sep 17 00:00:00 2001 From: Pure White Date: Wed, 24 Jan 2018 23:38:13 +0800 Subject: [PATCH 003/221] refactor prettyError, closes #3381 --- cmd/helm/helm.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 3810cfb8e..217764937 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -17,7 +17,6 @@ limitations under the License. package main // import "k8s.io/helm/cmd/helm" import ( - "errors" "fmt" "io/ioutil" "log" @@ -25,8 +24,8 @@ import ( "strings" "github.com/spf13/cobra" - "google.golang.org/grpc" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" @@ -209,13 +208,16 @@ func checkArgsLength(argsReceived int, requiredArgs ...string) error { // prettyError unwraps or rewrites certain errors to make them more user-friendly. func prettyError(err error) error { + // Add this check can prevent the object creation if err is nil. if err == nil { return nil } - // This is ridiculous. Why is 'grpc.rpcError' not exported? The least they - // could do is throw an interface on the lib that would let us get back - // the desc. Instead, we have to pass ALL errors through this. - return errors.New(grpc.ErrorDesc(err)) + // If it's grpc's error, make it more user-friendly. + if s, ok := status.FromError(err); ok { + return s.Err() + } + // Else return the original error. + return err } // configForContext creates a Kubernetes REST client configuration for a given kubeconfig context. From d77a60a4621479b0d8c42cdafebfdcf69b1b10e0 Mon Sep 17 00:00:00 2001 From: "jonathan.striebel" Date: Thu, 25 Jan 2018 15:52:48 +0100 Subject: [PATCH 004/221] change child-parent title & links to fix links --- docs/charts.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/charts.md b/docs/charts.md index 5627c8600..48d7cb231 100644 --- a/docs/charts.md +++ b/docs/charts.md @@ -325,7 +325,7 @@ tooling to introspect user-settable values. The keys containing the values to be imported can be specified in the parent chart's `requirements.yaml` file using a YAML list. Each item in the list is a key which is imported from the child chart's `exports` field. -To import values not contained in the `exports` key, use the [child/parent](#using-the-child/parent-format) format. +To import values not contained in the `exports` key, use the [child-parent](#using-the-child-parent-format) format. Examples of both formats are described below. ##### Using the exports format @@ -360,9 +360,9 @@ myint: 99 ``` Please note the parent key `data` is not contained in the parent's final values. If you need to specify the -parent key, use the 'child/parent' format. +parent key, use the 'child-parent' format. -##### Using the child/parent format +##### Using the child-parent format To access values that are not contained in the `exports` key of the child chart's values, you will need to specify the source key of the values to be imported (`child`) and the destination path in the parent chart's From 4947e5aaf8a5354cfada9816e837420ff7a75ca7 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Thu, 25 Jan 2018 23:16:44 -0800 Subject: [PATCH 005/221] fix helm init --upgrade logic --- cmd/helm/installer/install.go | 25 ++++-- cmd/helm/installer/install_test.go | 123 +++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 8 deletions(-) diff --git a/cmd/helm/installer/install.go b/cmd/helm/installer/install.go index f2c0d232d..230c7b39b 100644 --- a/cmd/helm/installer/install.go +++ b/cmd/helm/installer/install.go @@ -63,8 +63,8 @@ func Upgrade(client kubernetes.Interface, opts *Options) error { if err != nil { return err } - existingImage := obj.Spec.Template.Spec.Containers[0].Image - if !isNewerVersion(existingImage) && !opts.ForceUpgrade { + tillerImage := obj.Spec.Template.Spec.Containers[0].Image + if semverCompare(tillerImage) == -1 && !opts.ForceUpgrade { return errors.New("current Tiller version is newer, use --force-upgrade to downgrade") } obj.Spec.Template.Spec.Containers[0].Image = opts.selectImage() @@ -82,15 +82,24 @@ func Upgrade(client kubernetes.Interface, opts *Options) error { return err } -// isNewerVersion returns whether the current version is newer than the give image's version -func isNewerVersion(image string) bool { +// semverCompare returns whether the client's version is older, equal or newer than the given image's version. +func semverCompare(image string) int { split := strings.Split(image, ":") if len(split) < 2 { - // If we don't know the version, we consider the current version newer - return true + // If we don't know the version, we consider the client version newer. + return 1 } - imageVersion := split[1] - return semver.MustParse(version.Version).GreaterThan(semver.MustParse(imageVersion)) + tillerVersion, err := semver.NewVersion(split[1]) + if err != nil { + // same thing with unparsable tiller versions (e.g. canary releases). + return 1 + } + clientVersion, err := semver.NewVersion(version.Version) + if err != nil { + // aaaaaand same thing with unparsable helm versions (e.g. canary releases). + return 1 + } + return clientVersion.Compare(tillerVersion) } // createDeployment creates the Tiller Deployment resource. diff --git a/cmd/helm/installer/install_test.go b/cmd/helm/installer/install_test.go index 4a6f5f8eb..eaea05870 100644 --- a/cmd/helm/installer/install_test.go +++ b/cmd/helm/installer/install_test.go @@ -476,6 +476,129 @@ func TestUgrade_newerVersion(t *testing.T) { } } +func TestUpgrade_identical(t *testing.T) { + image := "gcr.io/kubernetes-helm/tiller:v2.0.0" + serviceAccount := "newServiceAccount" + existingDeployment, _ := deployment(&Options{ + Namespace: v1.NamespaceDefault, + ImageSpec: "imageToReplace:v2.0.0", + ServiceAccount: "serviceAccountToReplace", + UseCanary: false, + }) + existingService := service(v1.NamespaceDefault) + + fc := &fake.Clientset{} + fc.AddReactor("get", "deployments", func(action testcore.Action) (bool, runtime.Object, error) { + return true, existingDeployment, nil + }) + fc.AddReactor("update", "deployments", func(action testcore.Action) (bool, runtime.Object, error) { + obj := action.(testcore.UpdateAction).GetObject().(*v1beta1.Deployment) + i := obj.Spec.Template.Spec.Containers[0].Image + if i != image { + t.Errorf("expected image = '%s', got '%s'", image, i) + } + sa := obj.Spec.Template.Spec.ServiceAccountName + if sa != serviceAccount { + t.Errorf("expected serviceAccountName = '%s', got '%s'", serviceAccount, sa) + } + return true, obj, nil + }) + fc.AddReactor("get", "services", func(action testcore.Action) (bool, runtime.Object, error) { + return true, existingService, nil + }) + + opts := &Options{Namespace: v1.NamespaceDefault, ImageSpec: image, ServiceAccount: serviceAccount} + if err := Upgrade(fc, opts); err != nil { + t.Errorf("unexpected error: %#+v", err) + } + + if actions := fc.Actions(); len(actions) != 3 { + t.Errorf("unexpected actions: %v, expected 3 actions got %d", actions, len(actions)) + } +} + +func TestUpgrade_canaryClient(t *testing.T) { + image := "gcr.io/kubernetes-helm/tiller:canary" + serviceAccount := "newServiceAccount" + existingDeployment, _ := deployment(&Options{ + Namespace: v1.NamespaceDefault, + ImageSpec: "imageToReplace:v1.0.0", + ServiceAccount: "serviceAccountToReplace", + UseCanary: false, + }) + existingService := service(v1.NamespaceDefault) + + fc := &fake.Clientset{} + fc.AddReactor("get", "deployments", func(action testcore.Action) (bool, runtime.Object, error) { + return true, existingDeployment, nil + }) + fc.AddReactor("update", "deployments", func(action testcore.Action) (bool, runtime.Object, error) { + obj := action.(testcore.UpdateAction).GetObject().(*v1beta1.Deployment) + i := obj.Spec.Template.Spec.Containers[0].Image + if i != image { + t.Errorf("expected image = '%s', got '%s'", image, i) + } + sa := obj.Spec.Template.Spec.ServiceAccountName + if sa != serviceAccount { + t.Errorf("expected serviceAccountName = '%s', got '%s'", serviceAccount, sa) + } + return true, obj, nil + }) + fc.AddReactor("get", "services", func(action testcore.Action) (bool, runtime.Object, error) { + return true, existingService, nil + }) + + opts := &Options{Namespace: v1.NamespaceDefault, ImageSpec: image, ServiceAccount: serviceAccount} + if err := Upgrade(fc, opts); err != nil { + t.Errorf("unexpected error: %#+v", err) + } + + if actions := fc.Actions(); len(actions) != 3 { + t.Errorf("unexpected actions: %v, expected 3 actions got %d", actions, len(actions)) + } +} + +func TestUpgrade_canaryServer(t *testing.T) { + image := "gcr.io/kubernetes-helm/tiller:v2.0.0" + serviceAccount := "newServiceAccount" + existingDeployment, _ := deployment(&Options{ + Namespace: v1.NamespaceDefault, + ImageSpec: "imageToReplace:canary", + ServiceAccount: "serviceAccountToReplace", + UseCanary: false, + }) + existingService := service(v1.NamespaceDefault) + + fc := &fake.Clientset{} + fc.AddReactor("get", "deployments", func(action testcore.Action) (bool, runtime.Object, error) { + return true, existingDeployment, nil + }) + fc.AddReactor("update", "deployments", func(action testcore.Action) (bool, runtime.Object, error) { + obj := action.(testcore.UpdateAction).GetObject().(*v1beta1.Deployment) + i := obj.Spec.Template.Spec.Containers[0].Image + if i != image { + t.Errorf("expected image = '%s', got '%s'", image, i) + } + sa := obj.Spec.Template.Spec.ServiceAccountName + if sa != serviceAccount { + t.Errorf("expected serviceAccountName = '%s', got '%s'", serviceAccount, sa) + } + return true, obj, nil + }) + fc.AddReactor("get", "services", func(action testcore.Action) (bool, runtime.Object, error) { + return true, existingService, nil + }) + + opts := &Options{Namespace: v1.NamespaceDefault, ImageSpec: image, ServiceAccount: serviceAccount} + if err := Upgrade(fc, opts); err != nil { + t.Errorf("unexpected error: %#+v", err) + } + + if actions := fc.Actions(); len(actions) != 3 { + t.Errorf("unexpected actions: %v, expected 3 actions got %d", actions, len(actions)) + } +} + func tlsTestFile(t *testing.T, path string) string { const tlsTestDir = "../../../testdata" path = filepath.Join(tlsTestDir, path) From f13c4d28b5d4b93e2b9f2586d78657e43b192311 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Thu, 25 Jan 2018 23:32:42 -0800 Subject: [PATCH 006/221] Revert "feat(helm): adding kubeconfig flag" This reverts commit 371ff8f26deaf57556b35dd6c0378950ae07422e. --- cmd/helm/helm.go | 2 +- cmd/helm/install.go | 2 +- docs/helm/helm.md | 3 +-- docs/helm/helm_completion.md | 3 +-- docs/helm/helm_create.md | 3 +-- docs/helm/helm_delete.md | 3 +-- docs/helm/helm_dependency.md | 3 +-- docs/helm/helm_dependency_build.md | 3 +-- docs/helm/helm_dependency_list.md | 3 +-- docs/helm/helm_dependency_update.md | 3 +-- docs/helm/helm_fetch.md | 3 +-- docs/helm/helm_get.md | 3 +-- docs/helm/helm_get_hooks.md | 3 +-- docs/helm/helm_get_manifest.md | 3 +-- docs/helm/helm_get_values.md | 3 +-- docs/helm/helm_history.md | 3 +-- docs/helm/helm_home.md | 3 +-- docs/helm/helm_init.md | 3 +-- docs/helm/helm_inspect.md | 3 +-- docs/helm/helm_inspect_chart.md | 3 +-- docs/helm/helm_inspect_values.md | 3 +-- docs/helm/helm_install.md | 3 +-- docs/helm/helm_lint.md | 3 +-- docs/helm/helm_list.md | 3 +-- docs/helm/helm_package.md | 3 +-- docs/helm/helm_plugin.md | 3 +-- docs/helm/helm_plugin_install.md | 3 +-- docs/helm/helm_plugin_list.md | 3 +-- docs/helm/helm_plugin_remove.md | 3 +-- docs/helm/helm_plugin_update.md | 3 +-- docs/helm/helm_repo.md | 3 +-- docs/helm/helm_repo_add.md | 3 +-- docs/helm/helm_repo_index.md | 3 +-- docs/helm/helm_repo_list.md | 3 +-- docs/helm/helm_repo_remove.md | 3 +-- docs/helm/helm_repo_update.md | 3 +-- docs/helm/helm_reset.md | 3 +-- docs/helm/helm_rollback.md | 3 +-- docs/helm/helm_search.md | 3 +-- docs/helm/helm_serve.md | 3 +-- docs/helm/helm_status.md | 3 +-- docs/helm/helm_template.md | 3 +-- docs/helm/helm_test.md | 3 +-- docs/helm/helm_upgrade.md | 3 +-- docs/helm/helm_verify.md | 3 +-- docs/helm/helm_version.md | 3 +-- pkg/helm/environment/environment.go | 4 ---- pkg/kube/config.go | 7 +------ 48 files changed, 47 insertions(+), 100 deletions(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 3810cfb8e..fa916b1f2 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -220,7 +220,7 @@ func prettyError(err error) error { // configForContext creates a Kubernetes REST client configuration for a given kubeconfig context. func configForContext(context string) (*rest.Config, error) { - config, err := kube.GetConfig(context, settings.KubeConfig).ClientConfig() + config, err := kube.GetConfig(context).ClientConfig() if err != nil { return nil, fmt.Errorf("could not get Kubernetes config for context %q: %s", context, err) } diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 867c645bb..8f849a15b 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -460,7 +460,7 @@ func generateName(nameTemplate string) (string, error) { } func defaultNamespace() string { - if ns, _, err := kube.GetConfig(settings.KubeContext, settings.KubeConfig).Namespace(); err == nil { + if ns, _, err := kube.GetConfig(settings.KubeContext).Namespace(); err == nil { return ns } return "default" diff --git a/docs/helm/helm.md b/docs/helm/helm.md index caa4301a0..d3c63f56a 100644 --- a/docs/helm/helm.md +++ b/docs/helm/helm.md @@ -36,7 +36,6 @@ Environment: --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` @@ -68,4 +67,4 @@ Environment: * [helm verify](helm_verify.md) - verify that a chart at the given path has been signed and is valid * [helm version](helm_version.md) - print the client/server version information -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_completion.md b/docs/helm/helm_completion.md index 9fe91d52a..cef6a8631 100644 --- a/docs/helm/helm_completion.md +++ b/docs/helm/helm_completion.md @@ -28,11 +28,10 @@ helm completion SHELL --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_create.md b/docs/helm/helm_create.md index fa047ee23..636141661 100644 --- a/docs/helm/helm_create.md +++ b/docs/helm/helm_create.md @@ -47,11 +47,10 @@ helm create NAME --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_delete.md b/docs/helm/helm_delete.md index bf3adb6b2..26ac5fdac 100644 --- a/docs/helm/helm_delete.md +++ b/docs/helm/helm_delete.md @@ -38,11 +38,10 @@ helm delete [flags] RELEASE_NAME [...] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_dependency.md b/docs/helm/helm_dependency.md index 673c2c384..05b114b34 100644 --- a/docs/helm/helm_dependency.md +++ b/docs/helm/helm_dependency.md @@ -61,7 +61,6 @@ for this case. --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` @@ -71,4 +70,4 @@ for this case. * [helm dependency list](helm_dependency_list.md) - list the dependencies for the given chart * [helm dependency update](helm_dependency_update.md) - update charts/ based on the contents of requirements.yaml -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_dependency_build.md b/docs/helm/helm_dependency_build.md index 0c9d1f97b..70aae9a96 100644 --- a/docs/helm/helm_dependency_build.md +++ b/docs/helm/helm_dependency_build.md @@ -34,11 +34,10 @@ helm dependency build [flags] CHART --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm dependency](helm_dependency.md) - manage a chart's dependencies -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_dependency_list.md b/docs/helm/helm_dependency_list.md index a558356be..be5daec44 100644 --- a/docs/helm/helm_dependency_list.md +++ b/docs/helm/helm_dependency_list.md @@ -26,11 +26,10 @@ helm dependency list [flags] CHART --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm dependency](helm_dependency.md) - manage a chart's dependencies -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_dependency_update.md b/docs/helm/helm_dependency_update.md index 191a69644..94ddee3c5 100644 --- a/docs/helm/helm_dependency_update.md +++ b/docs/helm/helm_dependency_update.md @@ -39,11 +39,10 @@ helm dependency update [flags] CHART --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm dependency](helm_dependency.md) - manage a chart's dependencies -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_fetch.md b/docs/helm/helm_fetch.md index 5b4127c0a..9c8a4ec36 100644 --- a/docs/helm/helm_fetch.md +++ b/docs/helm/helm_fetch.md @@ -48,11 +48,10 @@ helm fetch [flags] [chart URL | repo/chartname] [...] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_get.md b/docs/helm/helm_get.md index ce6718b28..5b148b564 100644 --- a/docs/helm/helm_get.md +++ b/docs/helm/helm_get.md @@ -40,7 +40,6 @@ helm get [flags] RELEASE_NAME --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` @@ -50,4 +49,4 @@ helm get [flags] RELEASE_NAME * [helm get manifest](helm_get_manifest.md) - download the manifest for a named release * [helm get values](helm_get_values.md) - download the values file for a named release -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_get_hooks.md b/docs/helm/helm_get_hooks.md index a2fb36acd..c39c73888 100644 --- a/docs/helm/helm_get_hooks.md +++ b/docs/helm/helm_get_hooks.md @@ -33,11 +33,10 @@ helm get hooks [flags] RELEASE_NAME --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 15-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_get_manifest.md b/docs/helm/helm_get_manifest.md index 1cf712d9b..144f7bf87 100644 --- a/docs/helm/helm_get_manifest.md +++ b/docs/helm/helm_get_manifest.md @@ -35,11 +35,10 @@ helm get manifest [flags] RELEASE_NAME --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 15-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_get_values.md b/docs/helm/helm_get_values.md index 1e57a2303..eadc56a67 100644 --- a/docs/helm/helm_get_values.md +++ b/docs/helm/helm_get_values.md @@ -32,11 +32,10 @@ helm get values [flags] RELEASE_NAME --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 15-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_history.md b/docs/helm/helm_history.md index d9edd85c0..119e58b69 100755 --- a/docs/helm/helm_history.md +++ b/docs/helm/helm_history.md @@ -44,11 +44,10 @@ helm history [flags] RELEASE_NAME --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 10-Jan-2018 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_home.md b/docs/helm/helm_home.md index 069f6a162..855090a20 100644 --- a/docs/helm/helm_home.md +++ b/docs/helm/helm_home.md @@ -21,11 +21,10 @@ helm home --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_init.md b/docs/helm/helm_init.md index 5140a0621..856e9b565 100644 --- a/docs/helm/helm_init.md +++ b/docs/helm/helm_init.md @@ -63,11 +63,10 @@ helm init --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 9-Jan-2018 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_inspect.md b/docs/helm/helm_inspect.md index 7fc56cacc..006da7478 100644 --- a/docs/helm/helm_inspect.md +++ b/docs/helm/helm_inspect.md @@ -35,7 +35,6 @@ helm inspect [CHART] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` @@ -44,4 +43,4 @@ helm inspect [CHART] * [helm inspect chart](helm_inspect_chart.md) - shows inspect chart * [helm inspect values](helm_inspect_values.md) - shows inspect values -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_inspect_chart.md b/docs/helm/helm_inspect_chart.md index e1e88fbbe..37d0eb4af 100644 --- a/docs/helm/helm_inspect_chart.md +++ b/docs/helm/helm_inspect_chart.md @@ -33,11 +33,10 @@ helm inspect chart [CHART] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm inspect](helm_inspect.md) - inspect a chart -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_inspect_values.md b/docs/helm/helm_inspect_values.md index 348336b8f..2079849ff 100644 --- a/docs/helm/helm_inspect_values.md +++ b/docs/helm/helm_inspect_values.md @@ -33,11 +33,10 @@ helm inspect values [CHART] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm inspect](helm_inspect.md) - inspect a chart -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_install.md b/docs/helm/helm_install.md index f3a8ee06d..da9b91bb8 100644 --- a/docs/helm/helm_install.md +++ b/docs/helm/helm_install.md @@ -102,11 +102,10 @@ helm install [CHART] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 23-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_lint.md b/docs/helm/helm_lint.md index 8ab2d9e7d..8167a46cc 100644 --- a/docs/helm/helm_lint.md +++ b/docs/helm/helm_lint.md @@ -34,11 +34,10 @@ helm lint [flags] PATH --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_list.md b/docs/helm/helm_list.md index 733655cb8..1ba60b912 100755 --- a/docs/helm/helm_list.md +++ b/docs/helm/helm_list.md @@ -66,11 +66,10 @@ helm list [flags] [FILTER] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 10-Jan-2018 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_package.md b/docs/helm/helm_package.md index 71960f41e..85da8315e 100644 --- a/docs/helm/helm_package.md +++ b/docs/helm/helm_package.md @@ -40,11 +40,10 @@ helm package [flags] [CHART_PATH] [...] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 24-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_plugin.md b/docs/helm/helm_plugin.md index 5a636724c..f8e04f1a5 100644 --- a/docs/helm/helm_plugin.md +++ b/docs/helm/helm_plugin.md @@ -16,7 +16,6 @@ Manage client-side Helm plugins. --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` @@ -27,4 +26,4 @@ Manage client-side Helm plugins. * [helm plugin remove](helm_plugin_remove.md) - remove one or more Helm plugins * [helm plugin update](helm_plugin_update.md) - update one or more Helm plugins -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_plugin_install.md b/docs/helm/helm_plugin_install.md index f93378b7b..beb478845 100644 --- a/docs/helm/helm_plugin_install.md +++ b/docs/helm/helm_plugin_install.md @@ -29,11 +29,10 @@ helm plugin install [options] ... --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 20-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_plugin_list.md b/docs/helm/helm_plugin_list.md index 403ef1a6f..d363ae9b6 100644 --- a/docs/helm/helm_plugin_list.md +++ b/docs/helm/helm_plugin_list.md @@ -18,11 +18,10 @@ helm plugin list --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_plugin_remove.md b/docs/helm/helm_plugin_remove.md index 6c4530ce1..55f62514d 100644 --- a/docs/helm/helm_plugin_remove.md +++ b/docs/helm/helm_plugin_remove.md @@ -18,11 +18,10 @@ helm plugin remove ... --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_plugin_update.md b/docs/helm/helm_plugin_update.md index cbfe9ad5e..26a6ad270 100644 --- a/docs/helm/helm_plugin_update.md +++ b/docs/helm/helm_plugin_update.md @@ -18,11 +18,10 @@ helm plugin update ... --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_repo.md b/docs/helm/helm_repo.md index 3f184e875..a700f7aab 100644 --- a/docs/helm/helm_repo.md +++ b/docs/helm/helm_repo.md @@ -20,7 +20,6 @@ Example usage: --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` @@ -32,4 +31,4 @@ Example usage: * [helm repo remove](helm_repo_remove.md) - remove a chart repository * [helm repo update](helm_repo_update.md) - update information of available charts locally from chart repositories -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_repo_add.md b/docs/helm/helm_repo_add.md index c16797c63..7137c2c51 100644 --- a/docs/helm/helm_repo_add.md +++ b/docs/helm/helm_repo_add.md @@ -27,11 +27,10 @@ helm repo add [flags] [NAME] [URL] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_repo_index.md b/docs/helm/helm_repo_index.md index aece31367..7ddcf068f 100644 --- a/docs/helm/helm_repo_index.md +++ b/docs/helm/helm_repo_index.md @@ -34,11 +34,10 @@ helm repo index [flags] [DIR] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_repo_list.md b/docs/helm/helm_repo_list.md index 484ce3c68..2285a3c6e 100644 --- a/docs/helm/helm_repo_list.md +++ b/docs/helm/helm_repo_list.md @@ -18,11 +18,10 @@ helm repo list [flags] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_repo_remove.md b/docs/helm/helm_repo_remove.md index b34cee61c..d23980e73 100644 --- a/docs/helm/helm_repo_remove.md +++ b/docs/helm/helm_repo_remove.md @@ -18,11 +18,10 @@ helm repo remove [flags] [NAME] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_repo_update.md b/docs/helm/helm_repo_update.md index 0c9fb6efd..00dc6d9e2 100644 --- a/docs/helm/helm_repo_update.md +++ b/docs/helm/helm_repo_update.md @@ -24,11 +24,10 @@ helm repo update --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_reset.md b/docs/helm/helm_reset.md index dfb78c376..74a787bdc 100644 --- a/docs/helm/helm_reset.md +++ b/docs/helm/helm_reset.md @@ -34,11 +34,10 @@ helm reset --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_rollback.md b/docs/helm/helm_rollback.md index a2fedc559..3bd4af8bf 100644 --- a/docs/helm/helm_rollback.md +++ b/docs/helm/helm_rollback.md @@ -40,11 +40,10 @@ helm rollback [flags] [RELEASE] [REVISION] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_search.md b/docs/helm/helm_search.md index 1dc7e38ba..247b83f42 100644 --- a/docs/helm/helm_search.md +++ b/docs/helm/helm_search.md @@ -31,11 +31,10 @@ helm search [keyword] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_serve.md b/docs/helm/helm_serve.md index 4ce8a997a..163b24e76 100644 --- a/docs/helm/helm_serve.md +++ b/docs/helm/helm_serve.md @@ -39,11 +39,10 @@ helm serve --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_status.md b/docs/helm/helm_status.md index 52881896c..b878277ac 100644 --- a/docs/helm/helm_status.md +++ b/docs/helm/helm_status.md @@ -39,11 +39,10 @@ helm status [flags] RELEASE_NAME --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 12-Dec-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_template.md b/docs/helm/helm_template.md index f850fa4a8..347ba2ab4 100644 --- a/docs/helm/helm_template.md +++ b/docs/helm/helm_template.md @@ -43,11 +43,10 @@ helm template [flags] CHART --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 17-Jan-2018 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_test.md b/docs/helm/helm_test.md index b46d43e64..89436ed60 100644 --- a/docs/helm/helm_test.md +++ b/docs/helm/helm_test.md @@ -35,11 +35,10 @@ helm test [RELEASE] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_upgrade.md b/docs/helm/helm_upgrade.md index 5f4fde96c..290fe5921 100644 --- a/docs/helm/helm_upgrade.md +++ b/docs/helm/helm_upgrade.md @@ -70,11 +70,10 @@ helm upgrade [RELEASE] [CHART] --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_verify.md b/docs/helm/helm_verify.md index 74c3ee488..2c65b3092 100644 --- a/docs/helm/helm_verify.md +++ b/docs/helm/helm_verify.md @@ -33,11 +33,10 @@ helm verify [flags] PATH --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/docs/helm/helm_version.md b/docs/helm/helm_version.md index 1e46ceb18..18f9d261e 100644 --- a/docs/helm/helm_version.md +++ b/docs/helm/helm_version.md @@ -47,11 +47,10 @@ helm version --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --host string address of Tiller. Overrides $HELM_HOST --kube-context string name of the kubeconfig context to use - --kubeconfig string path to kubeconfig file. Overrides $KUBECONFIG --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 25-Jan-2018 diff --git a/pkg/helm/environment/environment.go b/pkg/helm/environment/environment.go index b8bcf0def..49d424b33 100644 --- a/pkg/helm/environment/environment.go +++ b/pkg/helm/environment/environment.go @@ -47,8 +47,6 @@ type EnvSettings struct { Debug bool // KubeContext is the name of the kubeconfig context. KubeContext string - // KubeConfig is the name of the kubeconfig file. - KubeConfig string } // AddFlags binds flags to the given flagset. @@ -56,7 +54,6 @@ func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) { fs.StringVar((*string)(&s.Home), "home", DefaultHelmHome, "location of your Helm config. Overrides $HELM_HOME") fs.StringVar(&s.TillerHost, "host", "", "address of Tiller. Overrides $HELM_HOST") fs.StringVar(&s.KubeContext, "kube-context", "", "name of the kubeconfig context to use") - fs.StringVar(&s.KubeConfig, "kubeconfig", "", "path to kubeconfig file. Overrides $KUBECONFIG") fs.BoolVar(&s.Debug, "debug", false, "enable verbose output") fs.StringVar(&s.TillerNamespace, "tiller-namespace", "kube-system", "namespace of Tiller") } @@ -81,7 +78,6 @@ var envMap = map[string]string{ "debug": "HELM_DEBUG", "home": "HELM_HOME", "host": "HELM_HOST", - "kubeconfig": "KUBECONFIG", "tiller-namespace": "TILLER_NAMESPACE", } diff --git a/pkg/kube/config.go b/pkg/kube/config.go index 541d4eba6..b6560486e 100644 --- a/pkg/kube/config.go +++ b/pkg/kube/config.go @@ -19,7 +19,7 @@ package kube // import "k8s.io/helm/pkg/kube" import "k8s.io/client-go/tools/clientcmd" // GetConfig returns a Kubernetes client config for a given context. -func GetConfig(context string, kubeconfig string) clientcmd.ClientConfig { +func GetConfig(context string) clientcmd.ClientConfig { rules := clientcmd.NewDefaultClientConfigLoadingRules() rules.DefaultClientConfig = &clientcmd.DefaultClientConfig @@ -28,10 +28,5 @@ func GetConfig(context string, kubeconfig string) clientcmd.ClientConfig { if context != "" { overrides.CurrentContext = context } - - if kubeconfig != "" { - rules.ExplicitPath = kubeconfig - } - return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(rules, overrides) } From 3c66183cb51eea000ad7120ba68b9b7e4fef26f8 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Fri, 26 Jan 2018 18:44:05 +0800 Subject: [PATCH 007/221] Fix typo --- docs/kubernetes_distros.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/kubernetes_distros.md b/docs/kubernetes_distros.md index ffba89384..04a86d0b4 100644 --- a/docs/kubernetes_distros.md +++ b/docs/kubernetes_distros.md @@ -42,4 +42,4 @@ Helm works straightforward on OpenShift Online, OpenShift Dedicated, OpenShift C ## Platform9 -Helm Client and Helm Server (Tiller) are pre-installed with [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/?utm_source=helm_distro_notes). Platform9 provides access to all official Helm charts through the App Catalog UI and native Kubernetes CLI. Additional repositories can be manually added. Further details are availble in this [Platform9 App Catalog article](https://platform9.com/support/deploying-kubernetes-apps-platform9-managed-kubernetes/?utm_source=helm_distro_notes). \ No newline at end of file +Helm Client and Helm Server (Tiller) are pre-installed with [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/?utm_source=helm_distro_notes). Platform9 provides access to all official Helm charts through the App Catalog UI and native Kubernetes CLI. Additional repositories can be manually added. Further details are available in this [Platform9 App Catalog article](https://platform9.com/support/deploying-kubernetes-apps-platform9-managed-kubernetes/?utm_source=helm_distro_notes). From ea520afd3e4d0eb3637a10b7443ca83bcaf340e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Na=CC=88gele?= Date: Sat, 27 Jan 2018 11:18:41 +0100 Subject: [PATCH 008/221] Fix 'getSelectorFromObject' --- pkg/kube/client.go | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 2cb94cd23..6b911c8a0 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -27,10 +27,12 @@ import ( "time" jsonpatch "github.com/evanphx/json-patch" - apps "k8s.io/api/apps/v1beta2" + appsv1 "k8s.io/api/apps/v1" + appsv1beta1 "k8s.io/api/apps/v1beta1" + appsv1beta2 "k8s.io/api/apps/v1beta2" batch "k8s.io/api/batch/v1" "k8s.io/api/core/v1" - "k8s.io/api/extensions/v1beta1" + extv1beta1 "k8s.io/api/extensions/v1beta1" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" @@ -507,18 +509,41 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, func getSelectorFromObject(obj runtime.Object) (map[string]string, error) { switch typed := obj.(type) { + case *v1.ReplicationController: return typed.Spec.Selector, nil - case *v1beta1.ReplicaSet: + + case *extv1beta1.ReplicaSet: + return typed.Spec.Selector.MatchLabels, nil + case *appsv1.ReplicaSet: + return typed.Spec.Selector.MatchLabels, nil + + case *extv1beta1.Deployment: + return typed.Spec.Selector.MatchLabels, nil + case *appsv1beta1.Deployment: return typed.Spec.Selector.MatchLabels, nil - case *v1beta1.Deployment: + case *appsv1beta2.Deployment: return typed.Spec.Selector.MatchLabels, nil - case *v1beta1.DaemonSet: + case *appsv1.Deployment: + return typed.Spec.Selector.MatchLabels, nil + + case *extv1beta1.DaemonSet: return typed.Spec.Selector.MatchLabels, nil + case *appsv1beta2.DaemonSet: + return typed.Spec.Selector.MatchLabels, nil + case *appsv1.DaemonSet: + return typed.Spec.Selector.MatchLabels, nil + case *batch.Job: return typed.Spec.Selector.MatchLabels, nil - case *apps.StatefulSet: + + case *appsv1beta1.StatefulSet: return typed.Spec.Selector.MatchLabels, nil + case *appsv1beta2.StatefulSet: + return typed.Spec.Selector.MatchLabels, nil + case *appsv1.StatefulSet: + return typed.Spec.Selector.MatchLabels, nil + default: return nil, fmt.Errorf("Unsupported kind when getting selector: %v", obj) } From d1b3523b2ba399f004571b60100e7fcb4611aa61 Mon Sep 17 00:00:00 2001 From: Oilbeater Date: Mon, 29 Jan 2018 16:51:16 +0800 Subject: [PATCH 009/221] Update Makefile Remove symbol table and debug info from go binary to reduce image size --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a5bdf1b8f..5801bcdbf 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ PKG := $(shell glide novendor) TAGS := TESTS := . TESTFLAGS := -LDFLAGS := +LDFLAGS := -w -s GOFLAGS := BINDIR := $(CURDIR)/bin BINARIES := helm tiller From 67c190af28a2ae5b530969b3a0319d648887b78d Mon Sep 17 00:00:00 2001 From: Arnaud Rinquin Date: Mon, 29 Jan 2018 14:42:40 -0800 Subject: [PATCH 010/221] doc(tips): Add an exception to tip about quoting integers Add a sentence to balance the advice about not quoting integers as it can cause headaches when applied to env variables. --- docs/charts_tips_and_tricks.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/charts_tips_and_tricks.md b/docs/charts_tips_and_tricks.md index b1df146db..f6b482963 100644 --- a/docs/charts_tips_and_tricks.md +++ b/docs/charts_tips_and_tricks.md @@ -52,6 +52,16 @@ many cases, cause parsing errors inside of Kubernetes. port: {{ .Values.Port }} ``` +This remark does not apply to env variables values which are expected to be string, even if they represent integers: + +``` +env: + -name: HOST + value: "http://host" + -name: PORT + value: "1234" +``` + ## Using the 'include' Function Go provides a way of including one template in another using a built-in From dddce02b942d13479afe44adebaa3aa992f75d0b Mon Sep 17 00:00:00 2001 From: lihuang Date: Mon, 5 Feb 2018 13:38:22 +0800 Subject: [PATCH 011/221] Update developers.md --- docs/developers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developers.md b/docs/developers.md index a84ce8722..5095bf1a0 100644 --- a/docs/developers.md +++ b/docs/developers.md @@ -27,7 +27,7 @@ packages. This will build both Helm and Tiller. `make bootstrap` will attempt to install certain tools if they are missing. -To run all of the tests (without running the tests for `vendor/`), run +To run all the tests (without running the tests for `vendor/`), run `make test`. To run Helm and Tiller locally, you can run `bin/helm` or `bin/tiller`. From db31b7a9daa02c0daa3e656e4e62eda5308057f9 Mon Sep 17 00:00:00 2001 From: liaoj Date: Mon, 5 Feb 2018 14:09:36 +0800 Subject: [PATCH 012/221] Update charts_tips_and_tricks.md typo error comand --> command --- docs/charts_tips_and_tricks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/charts_tips_and_tricks.md b/docs/charts_tips_and_tricks.md index b1df146db..2b4caa83b 100644 --- a/docs/charts_tips_and_tricks.md +++ b/docs/charts_tips_and_tricks.md @@ -234,7 +234,7 @@ update of that resource. ## Upgrade a release idempotently -In order to use the same command when installing and upgrading a release, use the following comand: +In order to use the same command when installing and upgrading a release, use the following command: ```shell helm upgrade --install --values ``` From 782b394e9799e875649219295e6ace6bd54ec39a Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Mon, 5 Feb 2018 07:17:46 -0500 Subject: [PATCH 013/221] Fix subchart2 example tag --- docs/charts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/charts.md b/docs/charts.md index a9f2cdf5b..a0c93697e 100644 --- a/docs/charts.md +++ b/docs/charts.md @@ -36,7 +36,7 @@ wordpress/ Helm reserves use of the `charts/` and `templates/` directories, and of the listed file names. Other files will be left as they are. -While the `charts` and `template` directories are optional there must be at least one chart dependency or template file for the chart to be valid. +While the `charts` and `templates` directories are optional there must be at least one chart dependency or template file for the chart to be valid. ## The Chart.yaml File @@ -276,7 +276,7 @@ dependencies: condition: subchart2.enabled,global.subchart2.enabled tags: - back-end - - subchart1 + - subchart2 ```` ```` From c316193a624e98c1ef4bba575088de0404989d92 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Mon, 5 Feb 2018 08:43:28 -0800 Subject: [PATCH 014/221] remove references to the term "master" --- docs/charts_tips_and_tricks.md | 2 +- docs/install_faq.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/charts_tips_and_tricks.md b/docs/charts_tips_and_tricks.md index 2b4caa83b..e77c86a9d 100644 --- a/docs/charts_tips_and_tricks.md +++ b/docs/charts_tips_and_tricks.md @@ -204,7 +204,7 @@ together in one GitHub repository. **Deis's [Workflow](https://github.com/deis/workflow/tree/master/charts/workflow):** This chart exposes the entire Deis PaaS system with one chart. But it's different -from the SAP chart in that this master chart is built from each component, and +from the SAP chart in that this umbrella chart is built from each component, and each component is tracked in a different Git repository. Check out the `requirements.yaml` file to see how this chart is composed by their CI/CD pipeline. diff --git a/docs/install_faq.md b/docs/install_faq.md index 4a344c2ee..ff9ee89e6 100644 --- a/docs/install_faq.md +++ b/docs/install_faq.md @@ -106,12 +106,12 @@ Error: Error forwarding ports: error upgrading connection: dial tcp: lookup kube A: We have seen this issue with Ubuntu and Kubeadm in multi-node clusters. The issue is that the nodes expect certain DNS records to be obtainable via global DNS. Until this is resolved upstream, you can work around the issue as -follows: +follows. On each of the control plane nodes: -1) Add entries to `/etc/hosts` on the master mapping your hostnames to their public IPs -2) Install `dnsmasq` on the master (e.g. `apt install -y dnsmasq`) -3) Kill the k8s api server container on master (kubelet will recreate it) -4) Then `systemctl restart docker` (or reboot the master) for it to pick up the /etc/resolv.conf changes +1) Add entries to `/etc/hosts`, mapping your hostnames to their public IPs +2) Install `dnsmasq` (e.g. `apt install -y dnsmasq`) +3) Remove the k8s api server container (kubelet will recreate it) +4) Then `systemctl restart docker` (or reboot the node) for it to pick up the /etc/resolv.conf changes See this issue for more information: https://github.com/kubernetes/helm/issues/1455 From e6137ff05fd6d6e736a108cf91f5752e8669b268 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Mon, 5 Feb 2018 15:31:15 -0500 Subject: [PATCH 015/221] fix(api-machinery): Fixes patching for unstructured objects CRDs and other objects seen as unstructured cannot use strategic merge patching. It has never been supported on CRDs. Previously, cases like unstructured objects could have caused an unregistered error. This is no longer the case. This change explicitly looks for unstructured objects and handles those using json merge patching. Closes #3382 --- pkg/kube/client.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 6b911c8a0..cd5227dd7 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -399,14 +399,25 @@ func createPatch(mapping *meta.RESTMapping, target, current runtime.Object) ([]b return nil, types.StrategicMergePatchType, fmt.Errorf("serializing target configuration: %s", err) } + // While different objects need different merge types, the parent function + // that calls this does not try to create a patch when the data (first + // returned object) is nil. We can skip calculating the the merge type as + // the returned merge type is ignored. if apiequality.Semantic.DeepEqual(oldData, newData) { return nil, types.StrategicMergePatchType, nil } // Get a versioned object versionedObject, err := mapping.ConvertToVersion(target, mapping.GroupVersionKind.GroupVersion()) + + // Unstructured objects, such as CRDs, may not have an 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. + _, isUnstructured := versionedObject.(runtime.Unstructured) + switch { - case runtime.IsNotRegisteredError(err): + case runtime.IsNotRegisteredError(err), isUnstructured: // fall back to generic JSON merge patch patch, err := jsonpatch.CreateMergePatch(oldData, newData) return patch, types.MergePatchType, err From bf8bc42cfc6bfe78d62a070c093e040c9bbe7338 Mon Sep 17 00:00:00 2001 From: lihuang Date: Tue, 6 Feb 2018 10:27:42 +0800 Subject: [PATCH 016/221] Update tiller_ssl.md --- docs/tiller_ssl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tiller_ssl.md b/docs/tiller_ssl.md index 71ddd8080..db1603068 100644 --- a/docs/tiller_ssl.md +++ b/docs/tiller_ssl.md @@ -200,7 +200,7 @@ If you want to customize the manifest, you can save that output to a file and th use `kubectl create` to load it into your cluster. > We strongly recommend enabling RBAC on your cluster and adding [service accounts](rbac.md) -> with RBACS. +> with RBAC. Otherwise, you can remove the `--dry-run` and `--debug` flags. We also recommend putting Tiller in a non-system namespace (`--tiller-namespace=something`) and enable From 614cd9dfe7413a3b8624311bebaf8e8229b05e3f Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Wed, 7 Feb 2018 12:00:13 -0500 Subject: [PATCH 017/221] fix(grpc): Fixes issue where message sending limited to 4mb Between grpc 1.2.x and 1.7.x there was an API change. The previous MaxMsgSize is now a wrapper around MaxRecvMsgSize. This change now sets the MaxRecvMsgSize and MaxSendMsgSize which need to be set independently. --- pkg/tiller/server.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/tiller/server.go b/pkg/tiller/server.go index 57826578e..95276018e 100644 --- a/pkg/tiller/server.go +++ b/pkg/tiller/server.go @@ -36,7 +36,8 @@ var maxMsgSize = 1024 * 1024 * 20 // DefaultServerOpts returns the set of default grpc ServerOption's that Tiller requires. func DefaultServerOpts() []grpc.ServerOption { return []grpc.ServerOption{ - grpc.MaxMsgSize(maxMsgSize), + grpc.MaxRecvMsgSize(maxMsgSize), + grpc.MaxSendMsgSize(maxMsgSize), grpc.UnaryInterceptor(newUnaryInterceptor()), grpc.StreamInterceptor(newStreamInterceptor()), } From b02c6ffb910601dcf8f79d3af3d5c025b0380db4 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Thu, 8 Feb 2018 13:20:37 -0800 Subject: [PATCH 018/221] use an underscore for release_checklist.md Brings it in line with the rest of the documentation in docs/ --- docs/{release-checklist.md => release_checklist.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{release-checklist.md => release_checklist.md} (100%) diff --git a/docs/release-checklist.md b/docs/release_checklist.md similarity index 100% rename from docs/release-checklist.md rename to docs/release_checklist.md From 244b1b152865c3f7d86f38a16d4dc9ce2a574bd2 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Thu, 8 Feb 2018 16:18:42 -0500 Subject: [PATCH 019/221] fix(helm): fix the build-time golint warning on 'cmd/helm/install.go' When building helm, golint no longer generates the following warning: cmd/helm/install.go:502:9:warning: if block ends with a return statement, so drop this else and outdent its block (golint) Signed-off-by: Arash Deshmeh --- cmd/helm/install.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 8f849a15b..55ddd8141 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -499,12 +499,12 @@ func readFile(filePath string) ([]byte, error) { if err != nil { return ioutil.ReadFile(filePath) - } else { - getter, err := getterConstructor(filePath, "", "", "") - if err != nil { - return []byte{}, err - } - data, err := getter.Get(filePath) - return data.Bytes(), err } + + getter, err := getterConstructor(filePath, "", "", "") + if err != nil { + return []byte{}, err + } + data, err := getter.Get(filePath) + return data.Bytes(), err } From 0764d95a03df6801f38e2b625f9b69b5313d1c73 Mon Sep 17 00:00:00 2001 From: oilbeater Date: Wed, 7 Feb 2018 18:02:36 +0800 Subject: [PATCH 020/221] defer in loop may cause resource leak defer statement executes only when function return, and the resource still be hold during loop. Release the resource manually when not needed. --- pkg/plugin/installer/http_installer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/plugin/installer/http_installer.go b/pkg/plugin/installer/http_installer.go index 203f038f2..91d497651 100644 --- a/pkg/plugin/installer/http_installer.go +++ b/pkg/plugin/installer/http_installer.go @@ -193,10 +193,11 @@ func (g *TarGzExtractor) Extract(buffer *bytes.Buffer, targetDir string) error { if err != nil { return err } - defer outFile.Close() if _, err := io.Copy(outFile, tarReader); err != nil { + outFile.Close() return err } + outFile.Close() default: return fmt.Errorf("unknown type: %b in %s", header.Typeflag, header.Name) } From 588f7a8443384dc7c83d8d2d802c970af3314f02 Mon Sep 17 00:00:00 2001 From: Ben Langfeld Date: Fri, 9 Feb 2018 10:31:19 -0200 Subject: [PATCH 021/221] Tiller should only enforce what we expect from Helm https://github.com/kubernetes/helm/pull/3183 added a keepalive to the Helm client of 30s period, while Tiller was never configured to permit this, keeping the default minimum keepalive period of 5 minutes, disconnecting any clients which ping more regularly than this. This commit enforces a minimum that is lower than what Helm is configured for, preventing these disconnections, and thus fixes #3409. --- cmd/tiller/tiller.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/tiller/tiller.go b/cmd/tiller/tiller.go index 96eeddacb..185bf4b6c 100644 --- a/cmd/tiller/tiller.go +++ b/cmd/tiller/tiller.go @@ -161,6 +161,9 @@ func start() { MaxConnectionIdle: 10 * time.Minute, // If needed, we can configure the max connection age })) + opts = append(opts, grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{ + MinTime: time.Duration(20) * time.Second, // For compatibility with the client keepalive.ClientParameters + })) } rootServer = tiller.NewServer(opts...) From 3b22ecd53b2df89e1d0dc625c7fd569450ef13d8 Mon Sep 17 00:00:00 2001 From: Ben Langfeld Date: Fri, 9 Feb 2018 11:11:05 -0200 Subject: [PATCH 022/221] Keepalive config should be independent of TLS --- cmd/tiller/tiller.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/cmd/tiller/tiller.go b/cmd/tiller/tiller.go index 185bf4b6c..e0c10cb29 100644 --- a/cmd/tiller/tiller.go +++ b/cmd/tiller/tiller.go @@ -157,15 +157,16 @@ func start() { logger.Fatalf("Could not create server TLS configuration: %v", err) } opts = append(opts, grpc.Creds(credentials.NewTLS(cfg))) - opts = append(opts, grpc.KeepaliveParams(keepalive.ServerParameters{ - MaxConnectionIdle: 10 * time.Minute, - // If needed, we can configure the max connection age - })) - opts = append(opts, grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{ - MinTime: time.Duration(20) * time.Second, // For compatibility with the client keepalive.ClientParameters - })) } + opts = append(opts, grpc.KeepaliveParams(keepalive.ServerParameters{ + MaxConnectionIdle: 10 * time.Minute, + // If needed, we can configure the max connection age + })) + opts = append(opts, grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{ + MinTime: time.Duration(20) * time.Second, // For compatibility with the client keepalive.ClientParameters + })) + rootServer = tiller.NewServer(opts...) lstn, err := net.Listen("tcp", *grpcAddr) From 084a2bb945ef2c6fcb3a97cb3ee00210a2f0fe5d Mon Sep 17 00:00:00 2001 From: Justin Scott Date: Thu, 8 Feb 2018 16:46:38 -0800 Subject: [PATCH 023/221] fix(helm): update helm reset --force tip for clarity Updates helm reset error message to clarify that --force will not remove releases. Closes #3394 --- cmd/helm/reset.go | 4 ++-- cmd/helm/reset_test.go | 2 +- docs/helm/helm_reset.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/helm/reset.go b/cmd/helm/reset.go index 707c3d0be..623776729 100644 --- a/cmd/helm/reset.go +++ b/cmd/helm/reset.go @@ -77,7 +77,7 @@ func newResetCmd(client helm.Interface, out io.Writer) *cobra.Command { } f := cmd.Flags() - f.BoolVarP(&d.force, "force", "f", false, "forces Tiller uninstall even if there are releases installed, or if Tiller is not in ready state") + f.BoolVarP(&d.force, "force", "f", false, "forces Tiller uninstall even if there are releases installed, or if Tiller is not in ready state. Releases are not deleted.)") f.BoolVar(&d.removeHelmHome, "remove-helm-home", false, "if set deletes $HELM_HOME") return cmd @@ -101,7 +101,7 @@ func (d *resetCmd) run() error { } if !d.force && res != nil && len(res.Releases) > 0 { - return fmt.Errorf("there are still %d deployed releases (Tip: use --force)", len(res.Releases)) + return fmt.Errorf("there are still %d deployed releases (Tip: use --force to remove Tiller. Releases will not be deleted.)", len(res.Releases)) } if err := installer.Uninstall(d.kubeClient, &installer.Options{Namespace: d.namespace}); err != nil { diff --git a/cmd/helm/reset_test.go b/cmd/helm/reset_test.go index a68f29545..458736a63 100644 --- a/cmd/helm/reset_test.go +++ b/cmd/helm/reset_test.go @@ -121,7 +121,7 @@ func TestReset_deployedReleases(t *testing.T) { namespace: core.NamespaceDefault, } err = cmd.run() - expected := "there are still 1 deployed releases (Tip: use --force)" + expected := "there are still 1 deployed releases (Tip: use --force to remove Tiller. Releases will not be deleted.)" if !strings.Contains(err.Error(), expected) { t.Errorf("unexpected error: %v", err) } diff --git a/docs/helm/helm_reset.md b/docs/helm/helm_reset.md index 74a787bdc..f6707b8bd 100644 --- a/docs/helm/helm_reset.md +++ b/docs/helm/helm_reset.md @@ -18,7 +18,7 @@ helm reset ### Options ``` - -f, --force forces Tiller uninstall even if there are releases installed, or if Tiller is not in ready state + -f, --force forces Tiller uninstall even if there are releases installed, or if Tiller is not in ready state. Releases are not deleted.) --remove-helm-home if set deletes $HELM_HOME --tls enable TLS for request --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") @@ -40,4 +40,4 @@ helm reset ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Feb-2018 From f7e078ca29d4b063f49e9dffda8412a2a3de1085 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Fri, 9 Feb 2018 13:53:38 -0800 Subject: [PATCH 024/221] bump docker to 17.11.0-ce --- .circleci/config.yml | 3 ++- .circleci/deploy.sh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 35e643a04..477c72f59 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,7 +9,8 @@ jobs: PROJECT_NAME: "kubernetes-helm" steps: - checkout - - setup_remote_docker + - setup_remote_docker: + version: 17.11.0-ce - restore_cache: keys: - glide-{{ checksum "glide.yaml" }}-{{ checksum "glide.lock" }} diff --git a/.circleci/deploy.sh b/.circleci/deploy.sh index 6a3b3d0a6..7f2ca7122 100755 --- a/.circleci/deploy.sh +++ b/.circleci/deploy.sh @@ -34,7 +34,7 @@ else fi echo "Install docker client" -VER="17.03.0-ce" +VER="17.11.0-ce" curl -L -o /tmp/docker-$VER.tgz https://get.docker.com/builds/Linux/x86_64/docker-$VER.tgz tar -xz -C /tmp -f /tmp/docker-$VER.tgz mv /tmp/docker/* /usr/bin From 757db3a062fa3554daa8b53f28580817d75061fe Mon Sep 17 00:00:00 2001 From: oilbeater Date: Sat, 10 Feb 2018 16:58:39 +0800 Subject: [PATCH 025/221] defer in loop may cause resource leak --- pkg/chartutil/expand.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/chartutil/expand.go b/pkg/chartutil/expand.go index ae28f8147..126e14e80 100644 --- a/pkg/chartutil/expand.go +++ b/pkg/chartutil/expand.go @@ -63,11 +63,12 @@ func Expand(dir string, r io.Reader) error { if err != nil { return err } - defer file.Close() _, err = io.Copy(file, tr) if err != nil { + file.Close() return err } + file.Close() } return nil } From 0d12288e46fb21f57cf8974c8b9df0c80a4c529a Mon Sep 17 00:00:00 2001 From: Jonathan Hall Date: Sat, 10 Feb 2018 14:29:28 +0100 Subject: [PATCH 026/221] Grammar fixes and clarifications --- docs/securing_installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/securing_installation.md b/docs/securing_installation.md index 38350a922..2db2bcfb4 100644 --- a/docs/securing_installation.md +++ b/docs/securing_installation.md @@ -52,7 +52,7 @@ This situation may change in the future. While the community has several methods In the default installation the gRPC endpoint that Tiller offers is available inside the cluster (not external to the cluster) without authentication configuration applied. Without applying authentication, any process in the cluster can use the gRPC endpoint to perform operations inside the cluster. In a local or secured private cluster, this enables rapid usage and is normal. (When running outside the cluster, Helm authenticates through the Kubernetes API server to reach Tiller, leveraging existing Kubernetes authentication support.) -Shared and production clusters -- for the most part -- should use Helm 2.7.2 at a minimum and configure TLS for each the Tiller gRPC endpoint to ensure that within the cluster usage of gRPC endpoints is only for the properly authenticated identity for that endpoint. Doing so enables any number of Tiller instances to be deployed in any number of namespaces and yet no unauthenticated usage of any gRPC endpoint is possible. Finally, usage of Helm `init` with the `--tiller-tls-verify` option to install Tiller with TLS enabled and to verify remote certificates, and other Helm commands should use the `--tls` with all other commands. +Shared and production clusters -- for the most part -- should use Helm 2.7.2 at a minimum and configure TLS for each Tiller gRPC endpoint to ensure that within the cluster usage of gRPC endpoints is only for the properly authenticated identity for that endpoint. Doing so enables any number of Tiller instances to be deployed in any number of namespaces and yet no unauthenticated usage of any gRPC endpoint is possible. Finally, usa Helm `init` with the `--tiller-tls-verify` option to install Tiller with TLS enabled and to verify remote certificates, and all other Helm commands should use the `--tls` option. For more information about the proper steps to configure Tiller and use Helm properly with TLS configured, see [Using SSL between Helm and Tiller](tiller_ssl.md). From ffc76861fe2e97ec63f36575bb2b3898a8b3a11d Mon Sep 17 00:00:00 2001 From: Jonathan Hall Date: Sat, 10 Feb 2018 14:39:14 +0100 Subject: [PATCH 027/221] Fix bash example --- docs/securing_installation.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/securing_installation.md b/docs/securing_installation.md index 2db2bcfb4..2233620af 100644 --- a/docs/securing_installation.md +++ b/docs/securing_installation.md @@ -91,13 +91,13 @@ The following guidelines reiterate the Best Practices for securing Helm and Till If these steps are followed, an example `helm init` command might look something like this: ```bash -$ helm init \ -–tiller-tls \ -–tiller-tls-verify \ -–tiller-tls-ca-cert=ca.pem \ -–tiller-tls-cert=cert.pem \ -–tiller-tls-key=key.pem \ -–service-account=accountname +$ helm init \ +--tiller-tls \ +--tiller-tls-verify \ +--tiller-tls-ca-cert=ca.pem \ +--tiller-tls-cert=cert.pem \ +--tiller-tls-key=key.pem \ +--service-account=accountname ``` This command will start Tiller with both strong authentication over gRPC, and a service account to which RBAC policies have been applied. From cff4ea416ebe54542c26ec9ac6c4ac659c97d887 Mon Sep 17 00:00:00 2001 From: Sunny Date: Tue, 25 Jul 2017 19:49:23 +0530 Subject: [PATCH 028/221] feat(helm): add --template flag to `helm version` `helm version --template` prints the client and server version info in the provided template format. --- cmd/helm/version.go | 22 ++++++++++++++++++---- cmd/helm/version_test.go | 1 + docs/helm/helm_version.md | 3 ++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/cmd/helm/version.go b/cmd/helm/version.go index 69e0f3905..8eaff1ca9 100644 --- a/cmd/helm/version.go +++ b/cmd/helm/version.go @@ -55,6 +55,7 @@ type versionCmd struct { showClient bool showServer bool short bool + template string } func newVersionCmd(c helm.Interface, out io.Writer) *cobra.Command { @@ -85,18 +86,26 @@ func newVersionCmd(c helm.Interface, out io.Writer) *cobra.Command { f.BoolVarP(&version.showClient, "client", "c", false, "client version only") f.BoolVarP(&version.showServer, "server", "s", false, "server version only") f.BoolVar(&version.short, "short", false, "print the version number") + f.StringVar(&version.template, "template", "", "template for version string format") return cmd } func (v *versionCmd) run() error { + // Store map data for template rendering + data := map[string]interface{}{} + if v.showClient { cv := version.GetVersionProto() - fmt.Fprintf(v.out, "Client: %s\n", formatVersion(cv, v.short)) + if v.template != "" { + data["Client"] = cv + } else { + fmt.Fprintf(v.out, "Client: %s\n", formatVersion(cv, v.short)) + } } if !v.showServer { - return nil + return tpl(v.template, data, v.out) } if settings.Debug { @@ -115,8 +124,13 @@ func (v *versionCmd) run() error { debug("%s", err) return errors.New("cannot connect to Tiller") } - fmt.Fprintf(v.out, "Server: %s\n", formatVersion(resp.Version, v.short)) - return nil + + if v.template != "" { + data["Server"] = resp.Version + } else { + fmt.Fprintf(v.out, "Server: %s\n", formatVersion(resp.Version, v.short)) + } + return tpl(v.template, data, v.out) } func getK8sVersion() (*apiVersion.Info, error) { diff --git a/cmd/helm/version_test.go b/cmd/helm/version_test.go index 475200085..dbc40f401 100644 --- a/cmd/helm/version_test.go +++ b/cmd/helm/version_test.go @@ -38,6 +38,7 @@ func TestVersion(t *testing.T) { {"default", true, true, []string{}, false}, {"client", true, false, []string{"-c"}, false}, {"server", false, true, []string{"-s"}, false}, + {"template", true, true, []string{"--template='{{ .Client.SemVer }} {{ .Server.SemVer }}'"}, false}, } settings.TillerHost = "fake-localhost" diff --git a/docs/helm/helm_version.md b/docs/helm/helm_version.md index 18f9d261e..39b4adfab 100644 --- a/docs/helm/helm_version.md +++ b/docs/helm/helm_version.md @@ -33,6 +33,7 @@ helm version -c, --client client version only -s, --server server version only --short print the version number + --template string template for version string format --tls enable TLS for request --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") @@ -53,4 +54,4 @@ helm version ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 11-Feb-2018 From a59d2125123d9d829e99823e1f969309841fefd8 Mon Sep 17 00:00:00 2001 From: Thibaut Rousseau Date: Mon, 12 Feb 2018 00:33:28 +0100 Subject: [PATCH 029/221] docs: Fix FromJson comment --- pkg/chartutil/files.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go index 687a9a8d6..a711a3366 100644 --- a/pkg/chartutil/files.go +++ b/pkg/chartutil/files.go @@ -220,10 +220,10 @@ func ToJson(v interface{}) string { return string(data) } -// FromJson converts a YAML document into a map[string]interface{}. +// FromJson converts a JSON document into a map[string]interface{}. // // This is not a general-purpose JSON parser, and will not parse all valid -// YAML documents. Additionally, because its intended use is within templates +// JSON documents. Additionally, because its intended use is within templates // it tolerates errors. It will insert the returned error message string into // m["Error"] in the returned map. func FromJson(str string) map[string]interface{} { From 76a40fc573120cca95042a0385dc97701b98c228 Mon Sep 17 00:00:00 2001 From: yank1 Date: Mon, 12 Feb 2018 19:08:39 +0800 Subject: [PATCH 030/221] fix a typo in client --- pkg/helm/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/helm/client.go b/pkg/helm/client.go index a5d44bc09..83c97f9a8 100644 --- a/pkg/helm/client.go +++ b/pkg/helm/client.go @@ -293,7 +293,7 @@ func (h *Client) RunReleaseTest(rlsName string, opts ...ReleaseTestOption) (<-ch return h.test(ctx, req) } -// PingTiller pings the Tiller pod and ensure's that it is up and runnning +// PingTiller pings the Tiller pod and ensure's that it is up and running func (h *Client) PingTiller() error { ctx := NewContext() return h.ping(ctx) From 50cba63c5c3054f10d09b493b010ac4ee82441ae Mon Sep 17 00:00:00 2001 From: Yann Coleu Date: Tue, 13 Feb 2018 12:34:59 +0100 Subject: [PATCH 031/221] fix occurences typo in charts.md --- docs/charts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/charts.md b/docs/charts.md index 00e0144f3..5cbdb79ad 100644 --- a/docs/charts.md +++ b/docs/charts.md @@ -849,7 +849,7 @@ considerations in mind: - The `Chart.yaml` will be overwritten by the generator. - Users will expect to modify such a chart's contents, so documentation should indicate how users can do so. -- All occurances of `` will be replaced with the specified chart +- All occurences of `` will be replaced with the specified chart name so that starter charts can be used as templates. Currently the only way to add a chart to `$HELM_HOME/starters` is to manually From a9ba3aa89777d651b4515b53f7cae98637447503 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Tue, 13 Feb 2018 11:29:23 -0500 Subject: [PATCH 032/221] fix(helm): fix the bug in test code 'cmd/helm/create_test.go' that leaves behind temp directories during build The build process no longer leaves behind 'helm-create-*' temp directories. Signed-off-by: Arash Deshmeh --- cmd/helm/create_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/helm/create_test.go b/cmd/helm/create_test.go index afaed6483..cb7b1d387 100644 --- a/cmd/helm/create_test.go +++ b/cmd/helm/create_test.go @@ -33,7 +33,7 @@ func TestCreateCmd(t *testing.T) { if err != nil { t.Fatal(err) } - defer os.Remove(tdir) + defer os.RemoveAll(tdir) // CD into it pwd, err := os.Getwd() @@ -79,7 +79,7 @@ func TestCreateStarterCmd(t *testing.T) { if err != nil { t.Fatal(err) } - defer os.Remove(tdir) + defer os.RemoveAll(tdir) thome, err := tempHelmHome(t) if err != nil { From d65f8b532fd0c9bf622ff1ecb3f1aba4d43d8b7d Mon Sep 17 00:00:00 2001 From: Jason Murray Date: Wed, 14 Feb 2018 08:47:55 +0100 Subject: [PATCH 033/221] Typo once/one --- docs/chart_template_guide/subcharts_and_globals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chart_template_guide/subcharts_and_globals.md b/docs/chart_template_guide/subcharts_and_globals.md index 26e9a60cb..33274effe 100644 --- a/docs/chart_template_guide/subcharts_and_globals.md +++ b/docs/chart_template_guide/subcharts_and_globals.md @@ -83,7 +83,7 @@ mysubchart: dessert: ice cream ``` -Note the last two lines. Any directives inside of the `mysubchart` section will be sent to the `mysubchart` chart. So if we run `helm install --dry-run --debug mychart`, once of the things we will see is the `mysubchart` ConfigMap: +Note the last two lines. Any directives inside of the `mysubchart` section will be sent to the `mysubchart` chart. So if we run `helm install --dry-run --debug mychart`, one of the things we will see is the `mysubchart` ConfigMap: ```yaml # Source: mychart/charts/mysubchart/templates/configmap.yaml From c78af5483c895fc4ccc204c350ed47b5da48fc17 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Wed, 14 Feb 2018 10:42:39 -0500 Subject: [PATCH 034/221] fix(helm): fix the implicit dependency of TestSetAppVersion test on previous tests, due to helm home, by explicitly creating a temporary helm directory for the test. Signed-off-by: Arash Deshmeh --- cmd/helm/package_test.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/cmd/helm/package_test.go b/cmd/helm/package_test.go index d338c29cd..4404586e0 100644 --- a/cmd/helm/package_test.go +++ b/cmd/helm/package_test.go @@ -205,7 +205,19 @@ func TestSetAppVersion(t *testing.T) { var ch *chart.Chart expectedAppVersion := "app-version-foo" tmp, _ := ioutil.TempDir("", "helm-package-app-version-") - defer os.RemoveAll(tmp) + + thome, err := tempHelmHome(t) + if err != nil { + t.Fatal(err) + } + cleanup := resetEnv() + defer func() { + os.RemoveAll(tmp) + os.RemoveAll(thome.String()) + cleanup() + }() + + settings.Home = helmpath.Home(thome) c := newPackageCmd(&bytes.Buffer{}) flags := map[string]string{ @@ -213,7 +225,7 @@ func TestSetAppVersion(t *testing.T) { "app-version": expectedAppVersion, } setFlags(c, flags) - err := c.RunE(c, []string{"testdata/testcharts/alpine"}) + err = c.RunE(c, []string{"testdata/testcharts/alpine"}) if err != nil { t.Errorf("unexpected error %q", err) } From d216fd0d7d272aab95767d9ecec25755a60d4f9e Mon Sep 17 00:00:00 2001 From: Michelle Noorali Date: Thu, 15 Feb 2018 12:25:51 -0500 Subject: [PATCH 035/221] chore(README): add ref to helm mailing list --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 547839e24..6aee432aa 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,9 @@ You can reach the Helm community and developers via the following channels: - #helm-users - #helm-dev - #charts -- Mailing List: https://groups.google.com/forum/#!forum/kubernetes-sig-apps +- Mailing Lists: + - [Helm Mailing List](https://lists.cncf.io/g/cncf-kubernetes-helm) + - [Kubernetes SIG Apps Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-apps) - Developer Call: Thursdays at 9:30-10:00 Pacific. [https://zoom.us/j/4526666954](https://zoom.us/j/4526666954) ### Code of conduct From abd33764e8738e9d46b6ec9dc5d7f73f1eeee675 Mon Sep 17 00:00:00 2001 From: Liam White Date: Fri, 16 Feb 2018 10:44:47 +0000 Subject: [PATCH 036/221] Fix linting bug with charts containing more than one hyphen --- cmd/helm/lint.go | 6 +++++- cmd/helm/lint_test.go | 19 +++++++++++++----- .../compressedchart-with-hyphens-0.1.0.tgz | Bin 0 -> 548 bytes 3 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 cmd/helm/testdata/testcharts/compressedchart-with-hyphens-0.1.0.tgz diff --git a/cmd/helm/lint.go b/cmd/helm/lint.go index f529f8ce5..29eea1a88 100644 --- a/cmd/helm/lint.go +++ b/cmd/helm/lint.go @@ -149,7 +149,11 @@ func lintChart(path string, vals []byte, namespace string, strict bool) (support return linter, err } - base := strings.Split(filepath.Base(path), "-")[0] + lastHyphenIndex := strings.LastIndex(filepath.Base(path), "-") + if lastHyphenIndex <= 0 { + return linter, fmt.Errorf("unable to parse chart archive %q, missing '-'", filepath.Base(path)) + } + base := filepath.Base(path)[:lastHyphenIndex] chartPath = filepath.Join(tempDir, base) } else { chartPath = path diff --git a/cmd/helm/lint_test.go b/cmd/helm/lint_test.go index e52bdc056..7f045153c 100644 --- a/cmd/helm/lint_test.go +++ b/cmd/helm/lint_test.go @@ -21,11 +21,13 @@ import ( ) var ( - values = []byte{} - namespace = "testNamespace" - strict = false - archivedChartPath = "testdata/testcharts/compressedchart-0.1.0.tgz" - chartDirPath = "testdata/testcharts/decompressedchart/" + values = []byte{} + namespace = "testNamespace" + strict = false + archivedChartPath = "testdata/testcharts/compressedchart-0.1.0.tgz" + archivedChartPathWithHyphens = "testdata/testcharts/compressedchart-with-hyphens-0.1.0.tgz" + invalidArchivedChartPath = "testdata/testcharts/invalidcompressedchart0.1.0.tgz" + chartDirPath = "testdata/testcharts/decompressedchart/" ) func TestLintChart(t *testing.T) { @@ -37,4 +39,11 @@ func TestLintChart(t *testing.T) { t.Errorf("%s", err) } + if _, err := lintChart(archivedChartPathWithHyphens, values, namespace, strict); err != nil { + t.Errorf("%s", err) + } + + if _, err := lintChart(invalidArchivedChartPath, values, namespace, strict); err == nil { + t.Errorf("Expected a chart parsing error") + } } diff --git a/cmd/helm/testdata/testcharts/compressedchart-with-hyphens-0.1.0.tgz b/cmd/helm/testdata/testcharts/compressedchart-with-hyphens-0.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..379210a92c1795429d2c4baae389f1e971f26824 GIT binary patch literal 548 zcmV+<0^9u`iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PL4fi`y^|#dG$jc->rDXjD0A64=|)92WW)wwIoYVoz*QSrU?* zG;H^~7dcDXrjTqgP3fZFMMBsbi zPWu0B_M89nr2n%p#E0nPPIpGV%QZGNX)If*N~tSYQG5|qH0t|nfN!leE_nEwltQJ< z5{(E&Ep_!Aj+6*;9W6i9KdlR0WlY0RR8Xa#gbc6aWCh@%&~0 literal 0 HcmV?d00001 From fbe17d277e5e4260edea47c9ede97dadab78be7c Mon Sep 17 00:00:00 2001 From: Frederik Carlier Date: Fri, 16 Feb 2018 14:32:01 +0100 Subject: [PATCH 037/221] Fix typo --- _proto/hapi/services/tiller.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_proto/hapi/services/tiller.proto b/_proto/hapi/services/tiller.proto index 1fb6a86e9..5897676ab 100644 --- a/_proto/hapi/services/tiller.proto +++ b/_proto/hapi/services/tiller.proto @@ -165,7 +165,7 @@ message GetReleaseStatusResponse { // Info contains information about the release. hapi.release.Info info = 2; - // Namesapce the release was released into + // Namespace the release was released into string namespace = 3; } From 8530f1bc22cdd06c73c8f84a1c8652be49b1b5fd Mon Sep 17 00:00:00 2001 From: Frederik Carlier Date: Fri, 16 Feb 2018 16:22:24 +0100 Subject: [PATCH 038/221] Add a reference to Helm.NET --- docs/related.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/related.md b/docs/related.md index 1a13fd5e3..826c2c3aa 100644 --- a/docs/related.md +++ b/docs/related.md @@ -62,6 +62,7 @@ Tools layered on top of Helm or Tiller. - [Helm Chart Publisher](https://github.com/luizbafilho/helm-chart-publisher) - HTTP API for publishing Helm Charts in an easy way - [Armada](https://github.com/att-comdev/armada) - Manage prefixed releases throughout various Kubernetes namespaces, and removes completed jobs for complex deployments. Used by the [Openstack-Helm](https://github.com/openstack/openstack-helm) team. - [ChartMuseum](https://github.com/chartmuseum/chartmuseum) - Helm Chart Repository with support for Amazon S3 and Google Cloud Storage +- [Helm.NET](https://github.com/qmfrederik/helm) - A .NET client for Tiller's API ## Helm Included From c1020106d722704b3360444646d874e4128312fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stevo=20Slavi=C4=87?= Date: Fri, 16 Feb 2018 22:24:46 +0100 Subject: [PATCH 039/221] Update download links to 2.8.1 binaries --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6aee432aa..039f34b38 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,10 @@ Think of it like apt/yum/homebrew for Kubernetes. Binary downloads of the Helm client can be found at the following links: -- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-darwin-amd64.tar.gz) -- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-linux-amd64.tar.gz) -- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-linux-386.tar.gz) -- [Windows](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-windows-amd64.tar.gz) +- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.1-darwin-amd64.tar.gz) +- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.1-linux-amd64.tar.gz) +- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.1-linux-386.tar.gz) +- [Windows](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.1-windows-amd64.tar.gz) Unpack the `helm` binary and add it to your PATH and you are good to go! macOS/[homebrew](https://brew.sh/) users can also use `brew install kubernetes-helm`. From 4fcf69bc5287f6ca6090655ef8b8bb8087d6fa8a Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Fri, 16 Feb 2018 16:30:42 -0500 Subject: [PATCH 040/221] fix(helm): fix the output leak to stdout during build by tests under pkg/releasetesting, by redirecting output from mock clients. Signed-off-by: Arash Deshmeh --- pkg/releasetesting/environment_test.go | 8 ++++---- pkg/releasetesting/test_suite_test.go | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/releasetesting/environment_test.go b/pkg/releasetesting/environment_test.go index 29ca93d09..0199b74eb 100644 --- a/pkg/releasetesting/environment_test.go +++ b/pkg/releasetesting/environment_test.go @@ -20,7 +20,7 @@ import ( "bytes" "errors" "io" - "os" + "io/ioutil" "testing" "k8s.io/helm/pkg/proto/hapi/release" @@ -145,7 +145,7 @@ type getFailingKubeClient struct { func newGetFailingKubeClient() *getFailingKubeClient { return &getFailingKubeClient{ - PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: os.Stdout}, + PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: ioutil.Discard}, } } @@ -159,7 +159,7 @@ type deleteFailingKubeClient struct { func newDeleteFailingKubeClient() *deleteFailingKubeClient { return &deleteFailingKubeClient{ - PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: os.Stdout}, + PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: ioutil.Discard}, } } @@ -173,7 +173,7 @@ type createFailingKubeClient struct { func newCreateFailingKubeClient() *createFailingKubeClient { return &createFailingKubeClient{ - PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: os.Stdout}, + PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: ioutil.Discard}, } } diff --git a/pkg/releasetesting/test_suite_test.go b/pkg/releasetesting/test_suite_test.go index d83cd2666..e6cc8bcf5 100644 --- a/pkg/releasetesting/test_suite_test.go +++ b/pkg/releasetesting/test_suite_test.go @@ -18,7 +18,7 @@ package releasetesting import ( "io" - "os" + "io/ioutil" "testing" "time" @@ -320,7 +320,7 @@ type podSucceededKubeClient struct { func newPodSucceededKubeClient() *podSucceededKubeClient { return &podSucceededKubeClient{ - PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: os.Stdout}, + PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: ioutil.Discard}, } } @@ -334,7 +334,7 @@ type podFailedKubeClient struct { func newPodFailedKubeClient() *podFailedKubeClient { return &podFailedKubeClient{ - PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: os.Stdout}, + PrintingKubeClient: tillerEnv.PrintingKubeClient{Out: ioutil.Discard}, } } From 4cc95d2c2f8ecfa08d252b8ecc499ad05df63579 Mon Sep 17 00:00:00 2001 From: Mueed Chaudhry Date: Fri, 16 Feb 2018 14:26:25 -0500 Subject: [PATCH 041/221] update docs to demonstrate best practices in regards to named templates --- docs/chart_template_guide/named_templates.md | 47 ++++++++++---------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/docs/chart_template_guide/named_templates.md b/docs/chart_template_guide/named_templates.md index 1dc9c7618..042842427 100644 --- a/docs/chart_template_guide/named_templates.md +++ b/docs/chart_template_guide/named_templates.md @@ -4,15 +4,19 @@ It is time to move beyond one template, and begin to create others. In this sect In the "Flow Control" section we introduced three actions for declaring and managing templates: `define`, `template`, and `block`. In this section, we'll cover those three actions, and also introduce a special-purpose `include` function that works similarly to the `template` action. +An important detail to keep in mind when naming templates: **template names are global**. If you declare two templates with the same name, whichever one is loaded last will be the one used. Because templates in subcharts are compiled together with top-level templates, you should be careful to name your templates with _chart-specific names_. + +One popular naming convention is to prefix each defined template with the name of the chart: `{{ define "mychart.labels" }}`. By using the specific chart name as a prefix we can avoid any conflicts that may arise due to two different charts that implement templates of the same name. + ## Partials and `_` files So far, we've used one file, and that one file has contained a single template. But Helm's template language allows you to create named embedded templates, that can be accessed by name elsewhere. Before we get to the nuts-and-bolts of writing those templates, there is file naming convention that deserves mention: -- Most files in `templates/` are treated as if they contain Kubernetes manifests -- The `NOTES.txt` is one exception -- But files whose name begins with an underscore (`_`) are assumed to _not_ have a manifest inside. These files are not rendered to Kubernetes object definitions, but are available everywhere within other chart templates for use. +* Most files in `templates/` are treated as if they contain Kubernetes manifests +* The `NOTES.txt` is one exception +* But files whose name begins with an underscore (`_`) are assumed to _not_ have a manifest inside. These files are not rendered to Kubernetes object definitions, but are available everywhere within other chart templates for use. These files are used to store partials and helpers. In fact, when we first created `mychart`, we saw a file called `_helpers.tpl`. That file is the default location for template partials. @@ -21,7 +25,7 @@ These files are used to store partials and helpers. In fact, when we first creat The `define` action allows us to create a named template inside of a template file. Its syntax goes like this: ```yaml -{{ define "MY_NAME" }} +{{ define "MY.NAME" }} # body of template here {{ end }} ``` @@ -29,7 +33,7 @@ The `define` action allows us to create a named template inside of a template fi For example, we can define a template to encapsulate a Kubernetes block of labels: ```yaml -{{- define "my_labels" }} +{{- define "mychart.labels" }} labels: generator: helm date: {{ now | htmlDate }} @@ -39,7 +43,7 @@ For example, we can define a template to encapsulate a Kubernetes block of label Now we can embed this template inside of our existing ConfigMap, and then include it with the `template` action: ```yaml -{{- define "my_labels" }} +{{- define "mychart.labels" }} labels: generator: helm date: {{ now | htmlDate }} @@ -48,7 +52,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ .Release.Name }}-configmap - {{- template "my_labels" }} + {{- template "mychart.labels" }} data: myvalue: "Hello World" {{- range $key, $val := .Values.favorite }} @@ -56,7 +60,7 @@ data: {{- end }} ``` -When the template engine reads this file, it will store away the reference to `my_labels` until `template "my_labels"` is called. Then it will render that template inline. So the result will look like this: +When the template engine reads this file, it will store away the reference to `mychart.labels` until `template "mychart.labels"` is called. Then it will render that template inline. So the result will look like this: ```yaml # Source: mychart/templates/configmap.yaml @@ -77,7 +81,7 @@ Conventionally, Helm charts put these templates inside of a partials file, usual ```yaml {{/* Generate basic labels */}} -{{- define "my_labels" }} +{{- define "mychart.labels" }} labels: generator: helm date: {{ now | htmlDate }} @@ -93,7 +97,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ .Release.Name }}-configmap - {{- template "my_labels" }} + {{- template "mychart.labels" }} data: myvalue: "Hello World" {{- range $key, $val := .Values.favorite }} @@ -101,9 +105,7 @@ data: {{- end }} ``` -There is one _really important detail_ to keep in mind when naming templates: **template names are global**. If you declare two templates with the same name, whichever one is loaded last will be the one used. Because templates in subcharts are compiled together with top-level templates, you should be careful to name your templates with chart-specific names. - -One popular naming convention is to prefix each defined template with the name of the chart: `{{ define "mychart.labels" }}` or `{{ define "mychart_labels" }}`. +As mentioned above, **template names are global**. As a result of this, if two templates are declared with the same name the last occurance will be the one that is used. Since templates in subcharts are compiled together with top-level templates, it is best to name your templates with _chart specific names_. A popular naming convention is to prefix each defined template with the name of the chart: `{{ define "mychart.labels" }}`. ## Setting the scope of a template @@ -111,7 +113,7 @@ In the template we defined above, we did not use any objects. We just used funct ```yaml {{/* Generate basic labels */}} -{{- define "my_labels" }} +{{- define "mychart.labels" }} labels: generator: helm date: {{ now | htmlDate }} @@ -138,7 +140,7 @@ metadata: What happened to the name and version? They weren't in the scope for our defined template. When a named template (created with `define`) is rendered, it will receive the scope passed in by the `template` call. In our example, we included the template like this: ```yaml -{{- template "my_labels" }} +{{- template "mychart.labels" }} ``` No scope was passed in, so within the template we cannot access anything in `.`. This is easy enough to fix, though. We simply pass a scope to the template: @@ -148,7 +150,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ .Release.Name }}-configmap - {{- template "my_labels" . }} + {{- template "mychart.labels" . }} ``` Note that we pass `.` at the end of the `template` call. We could just as easily pass `.Values` or `.Values.favorite` or whatever scope we want. But what we want is the top-level scope. @@ -174,8 +176,8 @@ Now `{{ .Chart.Name }}` resolves to `mychart`, and `{{ .Chart.Version }}` resolv Say we've defined a simple template that looks like this: -``` -{{- define "mychart_app" -}} +```yaml +{{- define "mychart.app" -}} app_name: {{ .Chart.Name }} app_version: "{{ .Chart.Version }}+{{ .Release.Time.Seconds }}" {{- end -}} @@ -189,14 +191,13 @@ kind: ConfigMap metadata: name: {{ .Release.Name }}-configmap labels: - {{ template "mychart_app" .}} + {{ template "mychart.app" .}} data: myvalue: "Hello World" {{- range $key, $val := .Values.favorite }} {{ $key }}: {{ $val | quote }} {{- end }} - {{ template "mychart_app" . }} - +{{ template "mychart.app" . }} ``` The output will not be what we expect: @@ -230,13 +231,13 @@ kind: ConfigMap metadata: name: {{ .Release.Name }}-configmap labels: -{{ include "mychart_app" . | indent 4 }} +{{ include "mychart.app" . | indent 4 }} data: myvalue: "Hello World" {{- range $key, $val := .Values.favorite }} {{ $key }}: {{ $val | quote }} {{- end }} -{{ include "mychart_app" . | indent 2 }} +{{ include "mychart.app" . | indent 2 }} ``` Now the produced YAML is correctly indented for each section: From 0d758cfd410f66c8ae60049ee7ead6a910a42f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Bergstr=C3=B6m?= Date: Thu, 15 Feb 2018 14:31:18 +0100 Subject: [PATCH 042/221] Mute upgrade --install default namespace warning Initialize empty selection like in the install command to prevent: WARNING: Namespace doesn't match with previous --- cmd/helm/upgrade.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 7a7dfb0f6..7fca5af68 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -154,9 +154,15 @@ func (u *upgradeCmd) run() error { releaseHistory, err := u.client.ReleaseHistory(u.release, helm.WithMaxHistory(1)) if err == nil { + if u.namespace == "" { + u.namespace = defaultNamespace() + } previousReleaseNamespace := releaseHistory.Releases[0].Namespace if previousReleaseNamespace != u.namespace { - fmt.Fprintf(u.out, "WARNING: Namespace doesn't match with previous. Release will be deployed to %s\n", previousReleaseNamespace) + fmt.Fprintf(u.out, + "WARNING: Namespace %q doesn't match with previous. Release will be deployed to %s\n", + u.namespace, previousReleaseNamespace, + ) } } From 98e5006ecfefe7c1b1ab10c9e9e906407101ded1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Bergstr=C3=B6m?= Date: Thu, 15 Feb 2018 14:02:14 +0100 Subject: [PATCH 043/221] Bump client side grpc max msg size Set it to match the server side, or the default limit of 4MB will still apply when upgrading charts. Fixes #3512 --- pkg/helm/client.go | 5 +++++ pkg/tiller/server.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/helm/client.go b/pkg/helm/client.go index 83c97f9a8..f5dc5a001 100644 --- a/pkg/helm/client.go +++ b/pkg/helm/client.go @@ -30,6 +30,10 @@ import ( rls "k8s.io/helm/pkg/proto/hapi/services" ) +// maxMsgSize use 20MB as the default message size limit. +// grpc library default is 4MB +const maxMsgSize = 1024 * 1024 * 20 + // Client manages client side of the Helm-Tiller protocol. type Client struct { opts options @@ -310,6 +314,7 @@ func (h *Client) connect(ctx context.Context) (conn *grpc.ClientConn, err error) // getting closed by upstreams Time: time.Duration(30) * time.Second, }), + grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(maxMsgSize)), } switch { case h.opts.useTLS: diff --git a/pkg/tiller/server.go b/pkg/tiller/server.go index 95276018e..818cfd47a 100644 --- a/pkg/tiller/server.go +++ b/pkg/tiller/server.go @@ -31,7 +31,7 @@ import ( // maxMsgSize use 20MB as the default message size limit. // grpc library default is 4MB -var maxMsgSize = 1024 * 1024 * 20 +const maxMsgSize = 1024 * 1024 * 20 // DefaultServerOpts returns the set of default grpc ServerOption's that Tiller requires. func DefaultServerOpts() []grpc.ServerOption { From 9bac0a4c30d1eb879acdd68617336834b48937c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Bergstr=C3=B6m?= Date: Thu, 15 Feb 2018 14:19:09 +0100 Subject: [PATCH 044/221] Update deprecated grpc dial timeout The docs say: use DialContext instead. --- pkg/helm/client.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/helm/client.go b/pkg/helm/client.go index f5dc5a001..c7ef4d89e 100644 --- a/pkg/helm/client.go +++ b/pkg/helm/client.go @@ -307,7 +307,6 @@ func (h *Client) PingTiller() error { // are constructed here. func (h *Client) connect(ctx context.Context) (conn *grpc.ClientConn, err error) { opts := []grpc.DialOption{ - grpc.WithTimeout(5 * time.Second), grpc.WithBlock(), grpc.WithKeepaliveParams(keepalive.ClientParameters{ // Send keepalive every 30 seconds to prevent the connection from @@ -322,7 +321,9 @@ func (h *Client) connect(ctx context.Context) (conn *grpc.ClientConn, err error) default: opts = append(opts, grpc.WithInsecure()) } - if conn, err = grpc.Dial(h.opts.host, opts...); err != nil { + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + if conn, err = grpc.DialContext(ctx, h.opts.host, opts...); err != nil { return nil, err } return conn, nil From 5b25eef9e260f2658914c5b9de27d8f69efcc2a3 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Mon, 19 Feb 2018 12:54:45 -0500 Subject: [PATCH 045/221] fix(helm): fix the bug in test code under pkg/tiller that leaks output to stdout during build Signed-off-by: Arash Deshmeh --- pkg/tiller/release_server_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index ce95acc8f..d71e34bee 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -19,6 +19,7 @@ package tiller import ( "errors" "io" + "io/ioutil" "os" "regexp" "testing" @@ -284,7 +285,7 @@ func releaseWithKeepStub(rlsName string) *release.Release { func MockEnvironment() *environment.Environment { e := environment.New() e.Releases = storage.Init(driver.NewMemory()) - e.KubeClient = &environment.PrintingKubeClient{Out: os.Stdout} + e.KubeClient = &environment.PrintingKubeClient{Out: ioutil.Discard} return e } @@ -305,7 +306,7 @@ func (u *updateFailingKubeClient) Update(namespace string, originalReader, modif func newHookFailingKubeClient() *hookFailingKubeClient { return &hookFailingKubeClient{ - PrintingKubeClient: environment.PrintingKubeClient{Out: os.Stdout}, + PrintingKubeClient: environment.PrintingKubeClient{Out: ioutil.Discard}, } } From 55cc23cb0168d527ba60de359e38c5717cf2577d Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Tue, 20 Feb 2018 11:45:46 -0500 Subject: [PATCH 046/221] fix(helm): fix the bug in tests under cmd/helm that leaves behind temporary directories named "repo-test-*" during build. Signed-off-by: Arash Deshmeh --- cmd/helm/repo_add_test.go | 4 ++-- cmd/helm/repo_remove_test.go | 2 +- cmd/helm/repo_update_test.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index 2e36decbf..1f49e45ea 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -36,7 +36,7 @@ func TestRepoAddCmd(t *testing.T) { cleanup := resetEnv() defer func() { srv.Stop() - os.Remove(thome.String()) + os.RemoveAll(thome.String()) cleanup() }() if err := ensureTestHome(thome, t); err != nil { @@ -72,7 +72,7 @@ func TestRepoAdd(t *testing.T) { hh := thome defer func() { ts.Stop() - os.Remove(thome.String()) + os.RemoveAll(thome.String()) cleanup() }() if err := ensureTestHome(hh, t); err != nil { diff --git a/cmd/helm/repo_remove_test.go b/cmd/helm/repo_remove_test.go index 84244ae98..63082b42e 100644 --- a/cmd/helm/repo_remove_test.go +++ b/cmd/helm/repo_remove_test.go @@ -37,7 +37,7 @@ func TestRepoRemove(t *testing.T) { cleanup := resetEnv() defer func() { ts.Stop() - os.Remove(thome.String()) + os.RemoveAll(thome.String()) cleanup() }() if err := ensureTestHome(hh, t); err != nil { diff --git a/cmd/helm/repo_update_test.go b/cmd/helm/repo_update_test.go index 0d0a31350..e6f2af32f 100644 --- a/cmd/helm/repo_update_test.go +++ b/cmd/helm/repo_update_test.go @@ -75,7 +75,7 @@ func TestUpdateCharts(t *testing.T) { cleanup := resetEnv() defer func() { ts.Stop() - os.Remove(thome.String()) + os.RemoveAll(thome.String()) cleanup() }() if err := ensureTestHome(hh, t); err != nil { From ed0a7462d8ca3a40659f1ccf6462929b5313545d Mon Sep 17 00:00:00 2001 From: EJ Etherington Date: Tue, 20 Feb 2018 08:46:44 -0800 Subject: [PATCH 047/221] Added ReactiveOps Autohelm to the related tools list --- docs/related.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/related.md b/docs/related.md index 826c2c3aa..a753a123c 100644 --- a/docs/related.md +++ b/docs/related.md @@ -55,6 +55,7 @@ Tools layered on top of Helm or Tiller. - [Landscaper](https://github.com/Eneco/landscaper/) - "Landscaper takes a set of Helm Chart references with values (a desired state), and realizes this in a Kubernetes cluster." - [Rudder](https://github.com/AcalephStorage/rudder) - RESTful (JSON) proxy for Tiller's API - [Helmfile](https://github.com/roboll/helmfile) - Helmfile is a declarative spec for deploying helm charts +- [Autohelm](https://github.com/reactiveops/autohelm) - Autohelm is _another_ simple declarative spec for deploying helm charts. Written in python and supports git urls as a source for helm charts. - [Schelm](https://github.com/databus23/schelm) - Render a Helm manifest to a directory - [Drone.io Helm Plugin](http://plugins.drone.io/ipedrazas/drone-helm/) - Run Helm inside of the Drone CI/CD system - [Cog](https://github.com/ohaiwalt/cog-helm) - Helm chart to deploy Cog on Kubernetes From df041c4b19d4007256123bfba57c56355086c934 Mon Sep 17 00:00:00 2001 From: Radu Matei Date: Tue, 20 Feb 2018 20:23:09 +0200 Subject: [PATCH 048/221] Fix minor typo --- pkg/helm/option.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/helm/option.go b/pkg/helm/option.go index 4f6924db2..a8770a488 100644 --- a/pkg/helm/option.go +++ b/pkg/helm/option.go @@ -375,7 +375,7 @@ func UpgradeForce(force bool) UpdateOption { type ContentOption func(*options) // ContentReleaseVersion will instruct Tiller to retrieve the content -// of a paritcular version of a release. +// of a particular version of a release. func ContentReleaseVersion(version int32) ContentOption { return func(opts *options) { opts.contentReq.Version = version From d0883dd8138947772239c25e212926d1afb1fcef Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Tue, 20 Feb 2018 22:11:29 -0800 Subject: [PATCH 049/221] docs(related): add helm-local plugin (#3547) --- docs/related.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/related.md b/docs/related.md index a753a123c..41b5c8f33 100644 --- a/docs/related.md +++ b/docs/related.md @@ -33,6 +33,7 @@ or [pull request](https://github.com/kubernetes/helm/pulls). - [helm-env](https://github.com/adamreese/helm-env) - Plugin to show current environment - [helm-last](https://github.com/adamreese/helm-last) - Plugin to show the latest release - [helm-nuke](https://github.com/adamreese/helm-nuke) - Plugin to destroy all releases +- [helm-local](https://github.com/adamreese/helm-local) - Plugin to run Tiller as a local daemon - [App Registry](https://github.com/app-registry/helm-plugin) - Plugin to manage charts via the [App Registry specification](https://github.com/app-registry/spec) - [helm-secrets](https://github.com/futuresimple/helm-secrets) - Plugin to manage and store secrets safely - [helm-edit](https://github.com/mstrzele/helm-edit) - Plugin for editing release's values @@ -55,7 +56,7 @@ Tools layered on top of Helm or Tiller. - [Landscaper](https://github.com/Eneco/landscaper/) - "Landscaper takes a set of Helm Chart references with values (a desired state), and realizes this in a Kubernetes cluster." - [Rudder](https://github.com/AcalephStorage/rudder) - RESTful (JSON) proxy for Tiller's API - [Helmfile](https://github.com/roboll/helmfile) - Helmfile is a declarative spec for deploying helm charts -- [Autohelm](https://github.com/reactiveops/autohelm) - Autohelm is _another_ simple declarative spec for deploying helm charts. Written in python and supports git urls as a source for helm charts. +- [Autohelm](https://github.com/reactiveops/autohelm) - Autohelm is _another_ simple declarative spec for deploying helm charts. Written in python and supports git urls as a source for helm charts. - [Schelm](https://github.com/databus23/schelm) - Render a Helm manifest to a directory - [Drone.io Helm Plugin](http://plugins.drone.io/ipedrazas/drone-helm/) - Run Helm inside of the Drone CI/CD system - [Cog](https://github.com/ohaiwalt/cog-helm) - Helm chart to deploy Cog on Kubernetes From 64b7d060baa92150f8a45cdff644a6cadc34ddb5 Mon Sep 17 00:00:00 2001 From: Mauricio Scheffer Date: Fri, 23 Feb 2018 14:32:46 +0000 Subject: [PATCH 050/221] Fix link to Slack --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 039f34b38..01927aff3 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ The [Helm roadmap uses Github milestones](https://github.com/kubernetes/helm/mil You can reach the Helm community and developers via the following channels: -- [Kubernetes Slack](https://slack.k8s.io): +- [Kubernetes Slack](http://slack.k8s.io): - #helm-users - #helm-dev - #charts From 5b77335415dc98c087a63bcd36c1d2db5ebf7dba Mon Sep 17 00:00:00 2001 From: Jean-Philippe Courson Date: Sat, 24 Feb 2018 17:12:37 +0000 Subject: [PATCH 051/221] Create missing directories when saving files in chartutil.SaveDir --- pkg/chartutil/save.go | 6 ++++++ pkg/chartutil/save_test.go | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/pkg/chartutil/save.go b/pkg/chartutil/save.go index b89917d96..bff32dde5 100644 --- a/pkg/chartutil/save.go +++ b/pkg/chartutil/save.go @@ -70,6 +70,12 @@ func SaveDir(c *chart.Chart, dest string) error { // Save files for _, f := range c.Files { n := filepath.Join(outdir, f.TypeUrl) + + d := filepath.Dir(n) + if err := os.MkdirAll(d, 0755); err != nil { + return err + } + if err := ioutil.WriteFile(n, f.Value, 0755); err != nil { return err } diff --git a/pkg/chartutil/save_test.go b/pkg/chartutil/save_test.go index 566999ff7..5e1564299 100644 --- a/pkg/chartutil/save_test.go +++ b/pkg/chartutil/save_test.go @@ -22,6 +22,7 @@ import ( "strings" "testing" + "github.com/golang/protobuf/ptypes/any" "k8s.io/helm/pkg/proto/hapi/chart" ) @@ -40,6 +41,9 @@ func TestSave(t *testing.T) { Values: &chart.Config{ Raw: "ship: Pequod", }, + Files: []*any.Any{ + {TypeUrl: "scheherazade/shahryar.txt", Value: []byte("1,001 Nights")}, + }, } where, err := Save(c, tmp) @@ -64,6 +68,9 @@ func TestSave(t *testing.T) { if c2.Values.Raw != c.Values.Raw { t.Fatal("Values data did not match") } + if len(c2.Files) != 1 || c2.Files[0].TypeUrl != "scheherazade/shahryar.txt" { + t.Fatal("Files data did not match") + } } func TestSaveDir(t *testing.T) { @@ -81,6 +88,9 @@ func TestSaveDir(t *testing.T) { Values: &chart.Config{ Raw: "ship: Pequod", }, + Files: []*any.Any{ + {TypeUrl: "scheherazade/shahryar.txt", Value: []byte("1,001 Nights")}, + }, } if err := SaveDir(c, tmp); err != nil { @@ -98,4 +108,7 @@ func TestSaveDir(t *testing.T) { if c2.Values.Raw != c.Values.Raw { t.Fatal("Values data did not match") } + if len(c2.Files) != 1 || c2.Files[0].TypeUrl != "scheherazade/shahryar.txt" { + t.Fatal("Files data did not match") + } } From c314e2e2f1a3ef1d54daea24c66bed215c9be152 Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Mon, 26 Feb 2018 15:44:32 -0800 Subject: [PATCH 052/221] fix(plugins): support newer git (#3571) Newer gits don't like checking out an empty string. ``` empty string is not a valid pathspec. please use . instead if you meant to match all paths ``` --- pkg/plugin/installer/vcs_installer.go | 7 +++--- pkg/plugin/installer/vcs_installer_test.go | 26 +++++++++++----------- pkg/storage/driver/records_test.go | 2 +- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/pkg/plugin/installer/vcs_installer.go b/pkg/plugin/installer/vcs_installer.go index d2ba3aa31..0a373a971 100644 --- a/pkg/plugin/installer/vcs_installer.go +++ b/pkg/plugin/installer/vcs_installer.go @@ -78,9 +78,10 @@ func (i *VCSInstaller) Install() error { if err != nil { return err } - - if err := i.setVersion(i.Repo, ref); err != nil { - return err + if ref != "" { + if err := i.setVersion(i.Repo, ref); err != nil { + return err + } } if !isPlugin(i.Repo.LocalPath()) { diff --git a/pkg/plugin/installer/vcs_installer_test.go b/pkg/plugin/installer/vcs_installer_test.go index 4abfc4c09..453899543 100644 --- a/pkg/plugin/installer/vcs_installer_test.go +++ b/pkg/plugin/installer/vcs_installer_test.go @@ -69,20 +69,20 @@ func TestVCSInstaller(t *testing.T) { i, err := NewForSource(source, "~0.1.0", home) if err != nil { - t.Errorf("unexpected error: %s", err) + t.Fatalf("unexpected error: %s", err) } // ensure a VCSInstaller was returned vcsInstaller, ok := i.(*VCSInstaller) if !ok { - t.Error("expected a VCSInstaller") + t.Fatal("expected a VCSInstaller") } // set the testRepo in the VCSInstaller vcsInstaller.Repo = repo if err := Install(i); err != nil { - t.Error(err) + t.Fatal(err) } if repo.current != "0.1.1" { t.Errorf("expected version '0.1.1', got %q", repo.current) @@ -123,13 +123,13 @@ func TestVCSInstallerNonExistentVersion(t *testing.T) { i, err := NewForSource(source, version, home) if err != nil { - t.Errorf("unexpected error: %s", err) + t.Fatalf("unexpected error: %s", err) } // ensure a VCSInstaller was returned _, ok := i.(*VCSInstaller) if !ok { - t.Error("expected a VCSInstaller") + t.Fatal("expected a VCSInstaller") } if err := Install(i); err == nil { @@ -155,40 +155,40 @@ func TestVCSInstallerUpdate(t *testing.T) { i, err := NewForSource(source, "", home) if err != nil { - t.Errorf("unexpected error: %s", err) + t.Fatalf("unexpected error: %s", err) } // ensure a VCSInstaller was returned _, ok := i.(*VCSInstaller) if !ok { - t.Error("expected a VCSInstaller") + t.Fatal("expected a VCSInstaller") } if err := Update(i); err == nil { - t.Error("expected error for plugin does not exist, got none") + t.Fatal("expected error for plugin does not exist, got none") } else if err.Error() != "plugin does not exist" { - t.Errorf("expected error for plugin does not exist, got (%v)", err) + t.Fatalf("expected error for plugin does not exist, got (%v)", err) } // Install plugin before update if err := Install(i); err != nil { - t.Error(err) + t.Fatal(err) } // Test FindSource method for positive result pluginInfo, err := FindSource(i.Path(), home) if err != nil { - t.Error(err) + t.Fatal(err) } repoRemote := pluginInfo.(*VCSInstaller).Repo.Remote() if repoRemote != source { - t.Errorf("invalid source found, expected %q got %q", source, repoRemote) + t.Fatalf("invalid source found, expected %q got %q", source, repoRemote) } // Update plugin if err := Update(i); err != nil { - t.Error(err) + t.Fatal(err) } // Test update failure diff --git a/pkg/storage/driver/records_test.go b/pkg/storage/driver/records_test.go index 607f7c139..79380afb8 100644 --- a/pkg/storage/driver/records_test.go +++ b/pkg/storage/driver/records_test.go @@ -78,7 +78,7 @@ func TestRecordsRemove(t *testing.T) { for _, tt := range tests { if r := rs.Remove(tt.key); r == nil { if !tt.ok { - t.Fatalf("Failed to %q (key = %s). Expected nil, got %s", + t.Fatalf("Failed to %q (key = %s). Expected nil, got %v", tt.desc, tt.key, r, From fa611fe2853f3393c7c2d902b8dabc72c88d63df Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Mon, 26 Feb 2018 15:49:07 -0800 Subject: [PATCH 053/221] fix(plugins): support installing plugins by relative path (#3568) Support installing plugins by relative path ``` helm plugins install . ``` --- pkg/plugin/installer/installer.go | 2 +- pkg/plugin/installer/local_installer.go | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pkg/plugin/installer/installer.go b/pkg/plugin/installer/installer.go index 10433f4cd..02aee9f46 100644 --- a/pkg/plugin/installer/installer.go +++ b/pkg/plugin/installer/installer.go @@ -21,9 +21,9 @@ import ( "os" "path" "path/filepath" + "strings" "k8s.io/helm/pkg/helm/helmpath" - "strings" ) // ErrMissingMetadata indicates that plugin.yaml is missing. diff --git a/pkg/plugin/installer/local_installer.go b/pkg/plugin/installer/local_installer.go index 18011f8de..3cf6bb422 100644 --- a/pkg/plugin/installer/local_installer.go +++ b/pkg/plugin/installer/local_installer.go @@ -16,6 +16,7 @@ limitations under the License. package installer // import "k8s.io/helm/pkg/plugin/installer" import ( + "fmt" "path/filepath" "k8s.io/helm/pkg/helm/helmpath" @@ -28,8 +29,12 @@ type LocalInstaller struct { // NewLocalInstaller creates a new LocalInstaller. func NewLocalInstaller(source string, home helmpath.Home) (*LocalInstaller, error) { + src, err := filepath.Abs(source) + if err != nil { + return nil, fmt.Errorf("unable to get absolute path to plugin: %v", err) + } i := &LocalInstaller{ - base: newBase(source, home), + base: newBase(src, home), } return i, nil } @@ -41,11 +46,7 @@ func (i *LocalInstaller) Install() error { if !isPlugin(i.Source) { return ErrMissingMetadata } - src, err := filepath.Abs(i.Source) - if err != nil { - return err - } - return i.link(src) + return i.link(i.Source) } // Update updates a local repository From a78336ad355515f3142a06f3cc18acf46faf924f Mon Sep 17 00:00:00 2001 From: Lukas Eichler Date: Tue, 27 Feb 2018 09:16:02 +0100 Subject: [PATCH 054/221] docs(helm): Added kubeVersion to documentation. docs(helm): Added kubeVersion to documentation and examples. Adjusted wording for the Chart.kubeVersion description Removing redundant wording for Chart.kubeVersion description --- docs/charts.md | 1 + docs/examples/nginx/Chart.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/charts.md b/docs/charts.md index 00e0144f3..91ead584f 100644 --- a/docs/charts.md +++ b/docs/charts.md @@ -45,6 +45,7 @@ The `Chart.yaml` file is required for a chart. It contains the following fields: ```yaml name: The name of the chart (required) version: A SemVer 2 version (required) +kubeVersion: A SemVer range of compatible Kubernetes versions (optional) description: A single-sentence description of this project (optional) keywords: - A list of keywords about this project (optional) diff --git a/docs/examples/nginx/Chart.yaml b/docs/examples/nginx/Chart.yaml index 6ca92998d..f6e2de338 100644 --- a/docs/examples/nginx/Chart.yaml +++ b/docs/examples/nginx/Chart.yaml @@ -1,6 +1,7 @@ name: nginx description: A basic NGINX HTTP server version: 0.1.0 +kubeVersion: >= 1.2.0 keywords: - http - nginx From 5f1a21bc321b326f3fab87b71bdc12bcd7125441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Bergstr=C3=B6m?= Date: Tue, 27 Feb 2018 19:25:40 +0100 Subject: [PATCH 055/221] fix(tiller): Supersede multiple deployments (#3539) * add test for rolling back from a FAILED deployment * Update naming of release variables Use same naming as the rest of the file. * Update rollback test - Add logging - Verify other release names not changed * fix(tiller): Supersede multiple deployments There are cases when multiple revisions of a release has been marked with DEPLOYED status. This makes sure any previous deployment will be set to SUPERSEDED when doing rollbacks. Closes #2941 #3513 #3275 --- pkg/storage/storage.go | 24 +++++++++++---- pkg/tiller/release_rollback.go | 46 +++++++++++++++++------------ pkg/tiller/release_rollback_test.go | 31 +++++++++++++++++-- pkg/tiller/release_server.go | 1 + 4 files changed, 76 insertions(+), 26 deletions(-) diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index 4ac5dbf4f..f76eb09f4 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -98,7 +98,7 @@ func (s *Storage) ListDeployed() ([]*rspb.Release, error) { }) } -// ListFilterAll returns the set of releases satisfying satisfying the predicate +// ListFilterAll returns the set of releases satisfying the predicate // (filter0 && filter1 && ... && filterN), i.e. a Release is included in the results // if and only if all filters return true. func (s *Storage) ListFilterAll(fns ...relutil.FilterFunc) ([]*rspb.Release, error) { @@ -108,7 +108,7 @@ func (s *Storage) ListFilterAll(fns ...relutil.FilterFunc) ([]*rspb.Release, err }) } -// ListFilterAny returns the set of releases satisfying satisfying the predicate +// ListFilterAny returns the set of releases satisfying the predicate // (filter0 || filter1 || ... || filterN), i.e. a Release is included in the results // if at least one of the filters returns true. func (s *Storage) ListFilterAny(fns ...relutil.FilterFunc) ([]*rspb.Release, error) { @@ -118,10 +118,24 @@ func (s *Storage) ListFilterAny(fns ...relutil.FilterFunc) ([]*rspb.Release, err }) } -// Deployed returns the deployed release with the provided release name, or +// Deployed returns the last deployed release with the provided release name, or // returns ErrReleaseNotFound if not found. func (s *Storage) Deployed(name string) (*rspb.Release, error) { - s.Log("getting deployed release from %q history", name) + ls, err := s.DeployedAll(name) + if err != nil { + if strings.Contains(err.Error(), "not found") { + return nil, fmt.Errorf("%q has no deployed releases", name) + } + return nil, err + } + + return ls[0], err +} + +// DeployedAll returns all deployed releases with the provided name, or +// returns ErrReleaseNotFound if not found. +func (s *Storage) DeployedAll(name string) ([]*rspb.Release, error) { + s.Log("getting deployed releases from %q history", name) ls, err := s.Driver.Query(map[string]string{ "NAME": name, @@ -129,7 +143,7 @@ func (s *Storage) Deployed(name string) (*rspb.Release, error) { "STATUS": "DEPLOYED", }) if err == nil { - return ls[0], nil + return ls, nil } if strings.Contains(err.Error(), "not found") { return nil, fmt.Errorf("%q has no deployed releases", name) diff --git a/pkg/tiller/release_rollback.go b/pkg/tiller/release_rollback.go index e8b6435b5..fe9a6a032 100644 --- a/pkg/tiller/release_rollback.go +++ b/pkg/tiller/release_rollback.go @@ -69,46 +69,46 @@ func (s *ReleaseServer) prepareRollback(req *services.RollbackReleaseRequest) (* return nil, nil, errInvalidRevision } - crls, err := s.env.Releases.Last(req.Name) + currentRelease, err := s.env.Releases.Last(req.Name) if err != nil { return nil, nil, err } - rbv := req.Version + previousVersion := req.Version if req.Version == 0 { - rbv = crls.Version - 1 + previousVersion = currentRelease.Version - 1 } - s.Log("rolling back %s (current: v%d, target: v%d)", req.Name, crls.Version, rbv) + s.Log("rolling back %s (current: v%d, target: v%d)", req.Name, currentRelease.Version, previousVersion) - prls, err := s.env.Releases.Get(req.Name, rbv) + previousRelease, err := s.env.Releases.Get(req.Name, previousVersion) if err != nil { return nil, nil, err } // Store a new release object with previous release's configuration - target := &release.Release{ + targetRelease := &release.Release{ Name: req.Name, - Namespace: crls.Namespace, - Chart: prls.Chart, - Config: prls.Config, + Namespace: currentRelease.Namespace, + Chart: previousRelease.Chart, + Config: previousRelease.Config, Info: &release.Info{ - FirstDeployed: crls.Info.FirstDeployed, + FirstDeployed: currentRelease.Info.FirstDeployed, LastDeployed: timeconv.Now(), Status: &release.Status{ Code: release.Status_PENDING_ROLLBACK, - Notes: prls.Info.Status.Notes, + Notes: previousRelease.Info.Status.Notes, }, - // Because we lose the reference to rbv elsewhere, we set the + // Because we lose the reference to previous version elsewhere, we set the // message here, and only override it later if we experience failure. - Description: fmt.Sprintf("Rollback to %d", rbv), + Description: fmt.Sprintf("Rollback to %d", previousVersion), }, - Version: crls.Version + 1, - Manifest: prls.Manifest, - Hooks: prls.Hooks, + Version: currentRelease.Version + 1, + Manifest: previousRelease.Manifest, + Hooks: previousRelease.Hooks, } - return crls, target, nil + return currentRelease, targetRelease, nil } func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.Release, req *services.RollbackReleaseRequest) (*services.RollbackReleaseResponse, error) { @@ -146,8 +146,16 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R } } - currentRelease.Info.Status.Code = release.Status_SUPERSEDED - s.recordRelease(currentRelease, true) + deployed, err := s.env.Releases.DeployedAll(currentRelease.Name) + if err != nil { + return nil, err + } + // Supersede all previous deployments, see issue #2941. + for _, r := range deployed { + s.Log("superseding previous deployment %d", r.Version) + r.Info.Status.Code = release.Status_SUPERSEDED + s.recordRelease(r, true) + } targetRelease.Info.Status.Code = release.Status_DEPLOYED diff --git a/pkg/tiller/release_rollback_test.go b/pkg/tiller/release_rollback_test.go index aa3a764f6..b73501a36 100644 --- a/pkg/tiller/release_rollback_test.go +++ b/pkg/tiller/release_rollback_test.go @@ -139,11 +139,22 @@ func TestRollbackRelease(t *testing.T) { func TestRollbackWithReleaseVersion(t *testing.T) { c := helm.NewContext() rs := rsFixture() + rs.Log = t.Logf + rs.env.Releases.Log = t.Logf + rel2 := releaseStub() + rel2.Name = "other" + rs.env.Releases.Create(rel2) rel := releaseStub() rs.env.Releases.Create(rel) - upgradedRel := upgradeReleaseVersion(rel) + v2 := upgradeReleaseVersion(rel) rs.env.Releases.Update(rel) - rs.env.Releases.Create(upgradedRel) + rs.env.Releases.Create(v2) + v3 := upgradeReleaseVersion(v2) + // retain the original release as DEPLOYED while the update should fail + v2.Info.Status.Code = release.Status_DEPLOYED + v3.Info.Status.Code = release.Status_FAILED + rs.env.Releases.Update(v2) + rs.env.Releases.Create(v3) req := &services.RollbackReleaseRequest{ Name: rel.Name, @@ -155,6 +166,22 @@ func TestRollbackWithReleaseVersion(t *testing.T) { if err != nil { t.Fatalf("Failed rollback: %s", err) } + // check that v2 is now in a SUPERSEDED state + oldRel, err := rs.env.Releases.Get(rel.Name, 2) + if err != nil { + t.Fatalf("Failed to retrieve v1: %s", err) + } + if oldRel.Info.Status.Code != release.Status_SUPERSEDED { + t.Errorf("Expected v2 to be in a SUPERSEDED state, got %q", oldRel.Info.Status.Code) + } + // make sure we didn't update some other deployments. + otherRel, err := rs.env.Releases.Get(rel2.Name, 1) + if err != nil { + t.Fatalf("Failed to retrieve other v1: %s", err) + } + if otherRel.Info.Status.Code != release.Status_DEPLOYED { + t.Errorf("Expected other deployed release to stay untouched, got %q", otherRel.Info.Status.Code) + } } func TestRollbackReleaseNoHooks(t *testing.T) { diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index 31a043030..a96c64938 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -316,6 +316,7 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values return hooks, b, notes, nil } +// recordRelease with an update operation in case reuse has been set. func (s *ReleaseServer) recordRelease(r *release.Release, reuse bool) { if reuse { if err := s.env.Releases.Update(r); err != nil { From 286c902572a209d1a827b32ce794c721fcf21e44 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 27 Feb 2018 13:48:34 -0800 Subject: [PATCH 056/221] fix(circle): fix download link to download.docker.com Docker stopped releasing binaries to get.docker.com as of 17.03.0-ce. They are all hosted at download.docker.com now. I also had to downgrade docker to 17.09.0-ce because that's the only version that both download.docker.com and CircleCI support. https://download.docker.com/linux/static/stable/x86_64/ https://circleci.com/docs/2.0/building-docker-images/#docker-version --- .circleci/config.yml | 2 +- .circleci/deploy.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 477c72f59..f3c8feead 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,7 +10,7 @@ jobs: steps: - checkout - setup_remote_docker: - version: 17.11.0-ce + version: 17.09.0-ce - restore_cache: keys: - glide-{{ checksum "glide.yaml" }}-{{ checksum "glide.lock" }} diff --git a/.circleci/deploy.sh b/.circleci/deploy.sh index 7f2ca7122..d29a353ee 100755 --- a/.circleci/deploy.sh +++ b/.circleci/deploy.sh @@ -34,8 +34,8 @@ else fi echo "Install docker client" -VER="17.11.0-ce" -curl -L -o /tmp/docker-$VER.tgz https://get.docker.com/builds/Linux/x86_64/docker-$VER.tgz +VER="17.09.0-ce" +curl -L -o /tmp/docker-$VER.tgz https://download.docker.com/linux/static/stable/x86_64/docker-$VER.tgz tar -xz -C /tmp -f /tmp/docker-$VER.tgz mv /tmp/docker/* /usr/bin From cc7ee84998b746e14ec0e24570c8eede26d2901b Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 27 Feb 2018 15:15:10 -0800 Subject: [PATCH 057/221] remove deprecated -e flag to `docker login` --- .circleci/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/deploy.sh b/.circleci/deploy.sh index d29a353ee..6ad91109d 100755 --- a/.circleci/deploy.sh +++ b/.circleci/deploy.sh @@ -48,7 +48,7 @@ echo "Configuring gcloud authentication" echo "${GCLOUD_SERVICE_KEY}" | base64 --decode > "${HOME}/gcloud-service-key.json" ${HOME}/google-cloud-sdk/bin/gcloud auth activate-service-account --key-file "${HOME}/gcloud-service-key.json" ${HOME}/google-cloud-sdk/bin/gcloud config set project "${PROJECT_NAME}" -docker login -e 1234@5678.com -u _json_key -p "$(cat ${HOME}/gcloud-service-key.json)" https://gcr.io +docker login -u _json_key -p "$(cat ${HOME}/gcloud-service-key.json)" https://gcr.io echo "Building the tiller image" make docker-build VERSION="${VERSION}" From 829fe51f1ecfe3bacdd4670b3c09f10335ad82e2 Mon Sep 17 00:00:00 2001 From: James Munnelly Date: Wed, 28 Feb 2018 16:00:35 +0000 Subject: [PATCH 058/221] Add link to securing helm docs in 'helm init' text --- cmd/helm/init.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/helm/init.go b/cmd/helm/init.go index c8753874f..cccd8a83d 100644 --- a/cmd/helm/init.go +++ b/cmd/helm/init.go @@ -310,7 +310,9 @@ func (i *initCmd) run() error { if err := i.ping(); err != nil { return err } - fmt.Fprintln(i.out, "\nTiller (the Helm server-side component) has been installed into your Kubernetes Cluster.") + fmt.Fprintln(i.out, "\nTiller (the Helm server-side component) has been installed into your Kubernetes Cluster.\n\n"+ + "Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.\n"+ + "For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation") } } else { fmt.Fprintln(i.out, "Not installing Tiller due to 'client-only' flag having been set") From e4305233e441e0601ae80cc985052ad30eb2590d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Bergstr=C3=B6m?= Date: Fri, 2 Mar 2018 12:56:34 +0100 Subject: [PATCH 059/221] Add helm-hashtag plugin https://github.com/balboah/helm-hashtag --- docs/related.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/related.md b/docs/related.md index 41b5c8f33..5bccaa26f 100644 --- a/docs/related.md +++ b/docs/related.md @@ -41,6 +41,7 @@ or [pull request](https://github.com/kubernetes/helm/pulls). - [helm-github](https://github.com/sagansystems/helm-github) - Plugin to install Helm Charts from Github repositories - [helm-monitor](https://github.com/ContainerSolutions/helm-monitor) - Plugin to monitor a release and rollback based on Prometheus/ElasticSearch query - [helm-k8comp](https://github.com/cststack/k8comp) - Plugin to create Helm Charts from hiera using k8comp +- [helm-hashtag](https://github.com/balboah/helm-hashtag) - Plugin for tracking docker tag hash digests as values We also encourage GitHub authors to use the [helm-plugin](https://github.com/search?q=topic%3Ahelm-plugin&type=Repositories) tag on their plugin repositories. From df61fb84d8db9a3be6b76f461c32c6fb6680e368 Mon Sep 17 00:00:00 2001 From: Sami Alajrami Date: Fri, 2 Mar 2018 13:14:05 +0100 Subject: [PATCH 060/221] adding Helmsman in docs/related.md --- docs/related.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/related.md b/docs/related.md index 41b5c8f33..4623aa3f2 100644 --- a/docs/related.md +++ b/docs/related.md @@ -57,6 +57,7 @@ Tools layered on top of Helm or Tiller. - [Rudder](https://github.com/AcalephStorage/rudder) - RESTful (JSON) proxy for Tiller's API - [Helmfile](https://github.com/roboll/helmfile) - Helmfile is a declarative spec for deploying helm charts - [Autohelm](https://github.com/reactiveops/autohelm) - Autohelm is _another_ simple declarative spec for deploying helm charts. Written in python and supports git urls as a source for helm charts. +- [Helmsman](https://github.com/Praqma/helmsman) - Helmsman is a helm-charts-as-code tool which enables installing/upgrading/protecting/moving/deleting releases from version controlled desired state files (described in a simple TOML format). - [Schelm](https://github.com/databus23/schelm) - Render a Helm manifest to a directory - [Drone.io Helm Plugin](http://plugins.drone.io/ipedrazas/drone-helm/) - Run Helm inside of the Drone CI/CD system - [Cog](https://github.com/ohaiwalt/cog-helm) - Helm chart to deploy Cog on Kubernetes From 81e09ff14c0b45c1c9cbe9a72a0a61156d5a7981 Mon Sep 17 00:00:00 2001 From: Ryan Payton Date: Thu, 7 Sep 2017 12:57:23 -0700 Subject: [PATCH 061/221] updating DownloadIndexFile function call to pass in HELM_HOME --- cmd/helm/init.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/helm/init.go b/cmd/helm/init.go index c8753874f..c0a7f6fcf 100644 --- a/cmd/helm/init.go +++ b/cmd/helm/init.go @@ -362,7 +362,7 @@ func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) err if fi, err := os.Stat(repoFile); err != nil { fmt.Fprintf(out, "Creating %s \n", repoFile) f := repo.NewRepoFile() - sr, err := initStableRepo(home.CacheIndex(stableRepository), out, skipRefresh) + sr, err := initStableRepo(home.CacheIndex(stableRepository), out, skipRefresh, home) if err != nil { return err } @@ -381,7 +381,7 @@ func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) err return nil } -func initStableRepo(cacheFile string, out io.Writer, skipRefresh bool) (*repo.Entry, error) { +func initStableRepo(cacheFile string, out io.Writer, skipRefresh bool, home helmpath.Home) (*repo.Entry, error) { fmt.Fprintf(out, "Adding %s repo with URL: %s \n", stableRepository, stableRepositoryURL) c := repo.Entry{ Name: stableRepository, From dc7e465705c6b5a7f387b4833a86e5459bd6a8cd Mon Sep 17 00:00:00 2001 From: "Christopher A. Stelma" Date: Thu, 1 Mar 2018 14:52:11 -0800 Subject: [PATCH 062/221] pass home down through createLink --- cmd/helm/init.go | 8 +++++--- cmd/helm/init_unix.go | 6 ++++-- cmd/helm/init_windows.go | 6 ++++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/cmd/helm/init.go b/cmd/helm/init.go index c0a7f6fcf..9fbd5fc89 100644 --- a/cmd/helm/init.go +++ b/cmd/helm/init.go @@ -366,7 +366,7 @@ func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) err if err != nil { return err } - lr, err := initLocalRepo(home.LocalRepository(localRepositoryIndexFile), home.CacheIndex("local"), out) + lr, err := initLocalRepo(home.LocalRepository(localRepositoryIndexFile), home.CacheIndex("local"), out, home) if err != nil { return err } @@ -406,7 +406,7 @@ func initStableRepo(cacheFile string, out io.Writer, skipRefresh bool, home helm return &c, nil } -func initLocalRepo(indexFile, cacheFile string, out io.Writer) (*repo.Entry, error) { +func initLocalRepo(indexFile, cacheFile string, out io.Writer, home helmpath.Home) (*repo.Entry, error) { if fi, err := os.Stat(indexFile); err != nil { fmt.Fprintf(out, "Adding %s repo with URL: %s \n", localRepository, localRepositoryURL) i := repo.NewIndexFile() @@ -415,7 +415,9 @@ func initLocalRepo(indexFile, cacheFile string, out io.Writer) (*repo.Entry, err } //TODO: take this out and replace with helm update functionality - createLink(indexFile, cacheFile) + if err := createLink(indexFile, cacheFile, home); err != nil { + return nil, err + } } else if fi.IsDir() { return nil, fmt.Errorf("%s must be a file, not a directory", indexFile) } diff --git a/cmd/helm/init_unix.go b/cmd/helm/init_unix.go index ff6260434..1117dd487 100644 --- a/cmd/helm/init_unix.go +++ b/cmd/helm/init_unix.go @@ -20,8 +20,10 @@ package main import ( "os" + + "k8s.io/helm/pkg/helm/helmpath" ) -func createLink(indexFile, cacheFile string) { - os.Symlink(indexFile, cacheFile) +func createLink(indexFile, cacheFile string, home helmpath.Home) error { + return os.Symlink(indexFile, cacheFile) } diff --git a/cmd/helm/init_windows.go b/cmd/helm/init_windows.go index 73ae6c6de..be17bccda 100644 --- a/cmd/helm/init_windows.go +++ b/cmd/helm/init_windows.go @@ -20,8 +20,10 @@ package main import ( "os" + + "k8s.io/helm/pkg/helm/helmpath" ) -func createLink(indexFile, cacheFile string) { - os.Link(indexFile, cacheFile) +func createLink(indexFile, cacheFile string, home helmpath.Home) error { + return os.Link(indexFile, cacheFile) } From 8a7390342bd17a577cfed1fc66c73610447200e3 Mon Sep 17 00:00:00 2001 From: Evans Castonguay Date: Sun, 4 Mar 2018 10:06:35 -0500 Subject: [PATCH 063/221] Add instruction to support new GnuGP version The latest GnuGP tool (https://gnupg.org/download/) is now storing keyring in a new format file 'kbx' instead of 'gpg' which make the current documentation incomplete for a new user. The propose pull request consists of adding documentation to explain how to generate a gpg using the latest GnuGP tool --- docs/provenance.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/provenance.md b/docs/provenance.md index 1f1361513..fd7552657 100644 --- a/docs/provenance.md +++ b/docs/provenance.md @@ -52,6 +52,12 @@ $ helm package --sign --key 'helm signing key' --keyring path/to/keyring.secret **TIP:** for GnuPG users, your secret keyring is in `~/.gnupg/secring.gpg`. You can use `gpg --list-secret-keys` to list the keys you have. +**Warning:** the latest GnuPG version store your secret keyring using a new format 'kbx' on the default location '~/.gnupg/pubring.kbx'. Please use the following command to convert your keyring to the legacy gpg format: + +``` +$ gpg --export-secret-keys >~/.gnupg/secring.gpg +``` + At this point, you should see both `mychart-0.1.0.tgz` and `mychart-0.1.0.tgz.prov`. Both files should eventually be uploaded to your desired chart repository. From f78aaa8715f916de4c09f3796b8b414b836323bd Mon Sep 17 00:00:00 2001 From: Itay Shakury Date: Mon, 5 Mar 2018 22:42:01 +0200 Subject: [PATCH 064/221] added Codefresh --- docs/related.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/related.md b/docs/related.md index 7a8b3a70e..6fbdf7df3 100644 --- a/docs/related.md +++ b/docs/related.md @@ -67,6 +67,7 @@ Tools layered on top of Helm or Tiller. - [Armada](https://github.com/att-comdev/armada) - Manage prefixed releases throughout various Kubernetes namespaces, and removes completed jobs for complex deployments. Used by the [Openstack-Helm](https://github.com/openstack/openstack-helm) team. - [ChartMuseum](https://github.com/chartmuseum/chartmuseum) - Helm Chart Repository with support for Amazon S3 and Google Cloud Storage - [Helm.NET](https://github.com/qmfrederik/helm) - A .NET client for Tiller's API +- [Codefresh](https://codefresh.io) - Kubernetes native CI/CD and management platform with UI dashboards for managing Helm charts and releases ## Helm Included From 2f252e95242849123fa7826748cbfd050fde870c Mon Sep 17 00:00:00 2001 From: Yaroslav Molochko Date: Tue, 6 Mar 2018 02:21:17 +0200 Subject: [PATCH 065/221] Add --replicas option for HA fixes #2334 --- cmd/helm/init.go | 3 +++ cmd/helm/installer/install.go | 1 + cmd/helm/installer/install_test.go | 27 +++++++++++++++++++++++++++ cmd/helm/installer/options.go | 13 +++++++++++++ docs/helm/helm_init.md | 3 ++- 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/cmd/helm/init.go b/cmd/helm/init.go index cccd8a83d..49adfc2c3 100644 --- a/cmd/helm/init.go +++ b/cmd/helm/init.go @@ -86,6 +86,7 @@ type initCmd struct { kubeClient kubernetes.Interface serviceAccount string maxHistory int + replicas int wait bool } @@ -130,6 +131,7 @@ func newInitCmd(out io.Writer) *cobra.Command { f.BoolVar(&i.opts.EnableHostNetwork, "net-host", false, "install Tiller with net=host") f.StringVar(&i.serviceAccount, "service-account", "", "name of service account") f.IntVar(&i.maxHistory, "history-max", 0, "limit the maximum number of revisions saved per release. Use 0 for no limit.") + f.IntVar(&i.replicas, "replicas", 1, "amount of tiller instances to run on the cluster") f.StringVar(&i.opts.NodeSelectors, "node-selectors", "", "labels to specify the node on which Tiller is installed (app=tiller,helm=rocks)") f.VarP(&i.opts.Output, "output", "o", "skip installation and output Tiller's manifest in specified format (json or yaml)") @@ -175,6 +177,7 @@ func (i *initCmd) run() error { i.opts.ForceUpgrade = i.forceUpgrade i.opts.ServiceAccount = i.serviceAccount i.opts.MaxHistory = i.maxHistory + i.opts.Replicas = i.replicas writeYAMLManifest := func(apiVersion, kind, body string, first, last bool) error { w := i.out diff --git a/cmd/helm/installer/install.go b/cmd/helm/installer/install.go index 230c7b39b..fc81fa26b 100644 --- a/cmd/helm/installer/install.go +++ b/cmd/helm/installer/install.go @@ -183,6 +183,7 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) { Labels: labels, }, Spec: v1beta1.DeploymentSpec{ + Replicas: opts.getReplicas(), Template: v1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: labels, diff --git a/cmd/helm/installer/install_test.go b/cmd/helm/installer/install_test.go index eaea05870..dbb7143e3 100644 --- a/cmd/helm/installer/install_test.go +++ b/cmd/helm/installer/install_test.go @@ -211,6 +211,10 @@ func TestInstall(t *testing.T) { if ports != 2 { t.Errorf("expected ports = 2, got '%d'", ports) } + replicas := obj.Spec.Replicas + if int(*replicas) != 1 { + t.Errorf("expected replicas = 1, got '%d'", replicas) + } return true, obj, nil }) fc.AddReactor("create", "services", func(action testcore.Action) (bool, runtime.Object, error) { @@ -236,6 +240,29 @@ func TestInstall(t *testing.T) { } } +func TestInstallHA(t *testing.T) { + image := "gcr.io/kubernetes-helm/tiller:v2.0.0" + + fc := &fake.Clientset{} + fc.AddReactor("create", "deployments", func(action testcore.Action) (bool, runtime.Object, error) { + obj := action.(testcore.CreateAction).GetObject().(*v1beta1.Deployment) + replicas := obj.Spec.Replicas + if int(*replicas) != 2 { + t.Errorf("expected replicas = 2, got '%d'", replicas) + } + return true, obj, nil + }) + + opts := &Options{ + Namespace: v1.NamespaceDefault, + ImageSpec: image, + Replicas: 2, + } + if err := Install(fc, opts); err != nil { + t.Errorf("unexpected error: %#+v", err) + } +} + func TestInstall_WithTLS(t *testing.T) { image := "gcr.io/kubernetes-helm/tiller:v2.0.0" name := "tiller-secret" diff --git a/cmd/helm/installer/options.go b/cmd/helm/installer/options.go index edff2740f..13cf43dcc 100644 --- a/cmd/helm/installer/options.go +++ b/cmd/helm/installer/options.go @@ -81,6 +81,11 @@ type Options struct { // Less than or equal to zero means no limit. MaxHistory int + // Replicas sets the amount of Tiller replicas to start + // + // Less than or equals to 1 means 1. + Replicas int + // NodeSelectors determine which nodes Tiller can land on. NodeSelectors string @@ -109,6 +114,14 @@ func (opts *Options) pullPolicy() v1.PullPolicy { return v1.PullIfNotPresent } +func (opts *Options) getReplicas() *int32 { + replicas := int32(1) + if opts.Replicas > 1 { + replicas = int32(opts.Replicas) + } + return &replicas +} + func (opts *Options) tls() bool { return opts.EnableTLS || opts.VerifyTLS } // valuesMap returns user set values in map format diff --git a/docs/helm/helm_init.md b/docs/helm/helm_init.md index 856e9b565..5ed24e60d 100644 --- a/docs/helm/helm_init.md +++ b/docs/helm/helm_init.md @@ -43,6 +43,7 @@ helm init --node-selectors string labels to specify the node on which Tiller is installed (app=tiller,helm=rocks) -o, --output OutputFormat skip installation and output Tiller's manifest in specified format (json or yaml) --override stringArray override values for the Tiller Deployment manifest (can specify multiple or separate values with commas: key1=val1,key2=val2) + --replicas int amount of tiller instances to run on the cluster (default 1) --service-account string name of service account --skip-refresh do not refresh (download) the local repository cache --stable-repo-url string URL for stable repository (default "https://kubernetes-charts.storage.googleapis.com") @@ -69,4 +70,4 @@ helm init ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 6-Mar-2018 From 363e5bcdf8e486dda871f19e3fc0c24f27762d25 Mon Sep 17 00:00:00 2001 From: Chen Zhiwei Date: Mon, 5 Mar 2018 15:01:35 +0800 Subject: [PATCH 066/221] Change helm update to helm upgrade --- docs/chart_template_guide/values_files.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chart_template_guide/values_files.md b/docs/chart_template_guide/values_files.md index 31b34175a..32a178735 100644 --- a/docs/chart_template_guide/values_files.md +++ b/docs/chart_template_guide/values_files.md @@ -4,7 +4,7 @@ In the previous section we looked at the built-in objects that Helm templates of - The `values.yaml` file in the chart - If this is a subchart, the `values.yaml` file of a parent chart -- A values file if passed into `helm install` or `helm update` with the `-f` flag (`helm install -f myvals.yaml ./mychart`) +- A values file if passed into `helm install` or `helm upgrade` with the `-f` flag (`helm install -f myvals.yaml ./mychart`) - Individual parameters passed with `--set` (such as `helm install --set foo=bar ./mychart`) The list above is in order of specificity: `values.yaml` is the default, which can be overridden by a parent chart's `values.yaml`, which can in turn be overridden by a user-supplied values file, which can in turn be overridden by `--set` parameters. From d8489901224c8279b724c84c0f17df67a9d5aaf2 Mon Sep 17 00:00:00 2001 From: Morgan Parry Date: Tue, 6 Mar 2018 11:06:50 +0000 Subject: [PATCH 067/221] fix(helm): Don't crash in search if upper case chars are encountered. Closes #3088 --- cmd/helm/search/search.go | 10 +++++----- cmd/helm/search/search_test.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/helm/search/search.go b/cmd/helm/search/search.go index a24208a4b..6c4cb4aa4 100644 --- a/cmd/helm/search/search.go +++ b/cmd/helm/search/search.go @@ -146,11 +146,11 @@ func (i *Index) SearchLiteral(term string, threshold int) []*Result { term = strings.ToLower(term) buf := []*Result{} for k, v := range i.lines { - k = strings.ToLower(k) - v = strings.ToLower(v) - res := strings.Index(v, term) - if score := i.calcScore(res, v); res != -1 && score < threshold { - parts := strings.Split(k, verSep) // Remove version, if it is there. + lk := strings.ToLower(k) + lv := strings.ToLower(v) + res := strings.Index(lv, term) + if score := i.calcScore(res, lv); res != -1 && score < threshold { + parts := strings.Split(lk, verSep) // Remove version, if it is there. buf = append(buf, &Result{Name: parts[0], Score: score, Chart: i.charts[k]}) } } diff --git a/cmd/helm/search/search_test.go b/cmd/helm/search/search_test.go index 949cf7be7..574f55448 100644 --- a/cmd/helm/search/search_test.go +++ b/cmd/helm/search/search_test.go @@ -91,10 +91,10 @@ var indexfileEntries = map[string]repo.ChartVersions{ }, }, { - URLs: []string{"http://example.com/charts/santa-maria-1.2.2.tgz"}, + URLs: []string{"http://example.com/charts/santa-maria-1.2.2-rc-1.tgz"}, Metadata: &chart.Metadata{ Name: "santa-maria", - Version: "1.2.2", + Version: "1.2.2-RC-1", Description: "Three boat", }, }, From c6f7e54267c6509c62d0e01b2fc8a0b004b305a3 Mon Sep 17 00:00:00 2001 From: Evans Castonguay Date: Tue, 6 Mar 2018 14:47:55 -0500 Subject: [PATCH 068/221] update the documentation to refere to GnuPG v2 update the documentation to refere to GnuPG v2 instead of latest GnuPG --- docs/provenance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/provenance.md b/docs/provenance.md index fd7552657..1eb69f8f3 100644 --- a/docs/provenance.md +++ b/docs/provenance.md @@ -52,7 +52,7 @@ $ helm package --sign --key 'helm signing key' --keyring path/to/keyring.secret **TIP:** for GnuPG users, your secret keyring is in `~/.gnupg/secring.gpg`. You can use `gpg --list-secret-keys` to list the keys you have. -**Warning:** the latest GnuPG version store your secret keyring using a new format 'kbx' on the default location '~/.gnupg/pubring.kbx'. Please use the following command to convert your keyring to the legacy gpg format: +**Warning:** the GnuPG v2 store your secret keyring using a new format 'kbx' on the default location '~/.gnupg/pubring.kbx'. Please use the following command to convert your keyring to the legacy gpg format: ``` $ gpg --export-secret-keys >~/.gnupg/secring.gpg From da989dc275a92fd48343263baf99231b310ce9ac Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Wed, 14 Feb 2018 09:09:35 -0500 Subject: [PATCH 069/221] fix(helm): fix the bug in test code 'cmd/helm/init_test.go' and 'cmd/helm/repo_update_test.go' that leave behind temporary helm home directories during build. With this fix, the build process no longer leaves behind 'helm_home-*' temp directories. Signed-off-by: Arash Deshmeh --- cmd/helm/init_test.go | 8 ++++---- cmd/helm/repo_update_test.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/helm/init_test.go b/cmd/helm/init_test.go index 4513315b7..6a5767fca 100644 --- a/cmd/helm/init_test.go +++ b/cmd/helm/init_test.go @@ -46,7 +46,7 @@ func TestInitCmd(t *testing.T) { if err != nil { t.Fatal(err) } - defer os.Remove(home) + defer os.RemoveAll(home) var buf bytes.Buffer fc := fake.NewSimpleClientset() @@ -80,7 +80,7 @@ func TestInitCmd_exists(t *testing.T) { if err != nil { t.Fatal(err) } - defer os.Remove(home) + defer os.RemoveAll(home) var buf bytes.Buffer fc := fake.NewSimpleClientset(&v1beta1.Deployment{ @@ -113,7 +113,7 @@ func TestInitCmd_clientOnly(t *testing.T) { if err != nil { t.Fatal(err) } - defer os.Remove(home) + defer os.RemoveAll(home) var buf bytes.Buffer fc := fake.NewSimpleClientset() @@ -184,7 +184,7 @@ func TestEnsureHome(t *testing.T) { if err != nil { t.Fatal(err) } - defer os.Remove(home) + defer os.RemoveAll(home) b := bytes.NewBuffer(nil) hh := helmpath.Home(home) diff --git a/cmd/helm/repo_update_test.go b/cmd/helm/repo_update_test.go index e6f2af32f..68f964f32 100644 --- a/cmd/helm/repo_update_test.go +++ b/cmd/helm/repo_update_test.go @@ -37,7 +37,7 @@ func TestUpdateCmd(t *testing.T) { cleanup := resetEnv() defer func() { - os.Remove(thome.String()) + os.RemoveAll(thome.String()) cleanup() }() From 3058644f364f5fbce596aac1fc0edd718b504f5b Mon Sep 17 00:00:00 2001 From: bryangunn <30510064+bryangunn@users.noreply.github.com> Date: Tue, 6 Mar 2018 15:51:28 -0500 Subject: [PATCH 070/221] Fixed bad link to Issues page The link to the issues page was giving a 404 due to a malformed URL. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c98d49a05..6247f7b21 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ The Kubernetes Helm project accepts contributions via GitHub pull requests. This ## Reporting a Security Issue Most of the time, when you find a bug in Helm, it should be reported -using [GitHub issues](github.com/kubernetes/helm/issues). However, if +using [GitHub issues](https://github.com/kubernetes/helm/issues). However, if you are reporting a _security vulnerability_, please email a report to [helm-security@deis.com](mailto:helm-security@deis.com). This will give us a chance to try to fix the issue before it is exploited in the wild. From 01b404b68e4be94fe7776fc51cd65c155308a5fa Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 6 Mar 2018 15:57:26 -0800 Subject: [PATCH 071/221] fix kubeVersion example --- docs/examples/nginx/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/nginx/Chart.yaml b/docs/examples/nginx/Chart.yaml index f6e2de338..807455210 100644 --- a/docs/examples/nginx/Chart.yaml +++ b/docs/examples/nginx/Chart.yaml @@ -1,7 +1,7 @@ name: nginx description: A basic NGINX HTTP server version: 0.1.0 -kubeVersion: >= 1.2.0 +kubeVersion: ">=1.2.0" keywords: - http - nginx From e73c82f51ea839b28c33ca31daa21c8ba7c1cc4f Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Wed, 7 Mar 2018 09:55:41 -0800 Subject: [PATCH 072/221] bump go to 1.10 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f3c8feead..df9786d82 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,7 +4,7 @@ jobs: working_directory: /go/src/k8s.io/helm parallelism: 3 docker: - - image: golang:1.8 + - image: golang:1.10 environment: PROJECT_NAME: "kubernetes-helm" steps: From bf7e755ef39c436e16681df97334d67c6a63cfa3 Mon Sep 17 00:00:00 2001 From: Greg Burton Date: Wed, 7 Mar 2018 15:40:31 -0800 Subject: [PATCH 073/221] Respect env proxy settings when using custom Transport --- pkg/getter/httpgetter.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/getter/httpgetter.go b/pkg/getter/httpgetter.go index 5a2146ec6..c86b96458 100644 --- a/pkg/getter/httpgetter.go +++ b/pkg/getter/httpgetter.go @@ -76,6 +76,7 @@ func newHTTPGetter(URL, CertFile, KeyFile, CAFile string) (Getter, error) { client.client = &http.Client{ Transport: &http.Transport{ TLSClientConfig: tlsConf, + Proxy: http.ProxyFromEnvironment, }, } } else { From 75ccc353eb12884ebf2f8c653cee7730cc397f67 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Thu, 8 Mar 2018 15:30:42 -0500 Subject: [PATCH 074/221] fix(helm): remove duplicate test code from cmd/helm/list_test. Closes #3637 Signed-off-by: Arash Deshmeh --- cmd/helm/list_test.go | 82 ++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 51 deletions(-) diff --git a/cmd/helm/list_test.go b/cmd/helm/list_test.go index 6e3321664..d853fa6b1 100644 --- a/cmd/helm/list_test.go +++ b/cmd/helm/list_test.go @@ -17,50 +17,44 @@ limitations under the License. package main import ( - "bytes" - "regexp" + "io" "testing" + "github.com/spf13/cobra" + "k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/proto/hapi/release" ) func TestListCmd(t *testing.T) { - tests := []struct { - name string - args []string - resp []*release.Release - expected string - err bool - }{ + tests := []releaseCase{ { name: "with a release", - resp: []*release.Release{ + rels: []*release.Release{ helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}), }, expected: "thomas-guide", }, { name: "list", - args: []string{}, - resp: []*release.Release{ + rels: []*release.Release{ helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas"}), }, expected: "NAME \tREVISION\tUPDATED \tSTATUS \tCHART \tNAMESPACE\natlas\t1 \t(.*)\tDEPLOYED\tfoo-0.1.0-beta.1\tdefault \n", }, { - name: "list, one deployed, one failed", - args: []string{"-q"}, - resp: []*release.Release{ + name: "list, one deployed, one failed", + flags: []string{"-q"}, + rels: []*release.Release{ helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_FAILED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), }, expected: "thomas-guide\natlas-guide", }, { - name: "with a release, multiple flags", - args: []string{"--deleted", "--deployed", "--failed", "-q"}, - resp: []*release.Release{ + name: "with a release, multiple flags", + flags: []string{"--deleted", "--deployed", "--failed", "-q"}, + rels: []*release.Release{ helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), }, @@ -69,9 +63,9 @@ func TestListCmd(t *testing.T) { expected: "thomas-guide\natlas-guide", }, { - name: "with a release, multiple flags", - args: []string{"--all", "-q"}, - resp: []*release.Release{ + name: "with a release, multiple flags", + flags: []string{"--all", "-q"}, + rels: []*release.Release{ helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), }, @@ -79,9 +73,9 @@ func TestListCmd(t *testing.T) { expected: "thomas-guide\natlas-guide", }, { - name: "with a release, multiple flags, deleting", - args: []string{"--all", "-q"}, - resp: []*release.Release{ + name: "with a release, multiple flags, deleting", + flags: []string{"--all", "-q"}, + rels: []*release.Release{ helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETING}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), }, @@ -89,9 +83,9 @@ func TestListCmd(t *testing.T) { expected: "thomas-guide\natlas-guide", }, { - name: "namespace defined, multiple flags", - args: []string{"--all", "-q", "--namespace test123"}, - resp: []*release.Release{ + name: "namespace defined, multiple flags", + flags: []string{"--all", "-q", "--namespace test123"}, + rels: []*release.Release{ helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Namespace: "test123"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Namespace: "test321"}), }, @@ -99,18 +93,18 @@ func TestListCmd(t *testing.T) { expected: "thomas-guide", }, { - name: "with a pending release, multiple flags", - args: []string{"--all", "-q"}, - resp: []*release.Release{ + name: "with a pending release, multiple flags", + flags: []string{"--all", "-q"}, + rels: []*release.Release{ helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_PENDING_INSTALL}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), }, expected: "thomas-guide\natlas-guide", }, { - name: "with a pending release, pending flag", - args: []string{"--pending", "-q"}, - resp: []*release.Release{ + name: "with a pending release, pending flag", + flags: []string{"--pending", "-q"}, + rels: []*release.Release{ helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_PENDING_INSTALL}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "wild-idea", StatusCode: release.Status_PENDING_UPGRADE}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-maps", StatusCode: release.Status_PENDING_ROLLBACK}), @@ -120,7 +114,7 @@ func TestListCmd(t *testing.T) { }, { name: "with old releases", - resp: []*release.Release{ + rels: []*release.Release{ helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_FAILED}), }, @@ -128,21 +122,7 @@ func TestListCmd(t *testing.T) { }, } - var buf bytes.Buffer - for _, tt := range tests { - c := &helm.FakeClient{ - Rels: tt.resp, - } - cmd := newListCmd(c, &buf) - cmd.ParseFlags(tt.args) - err := cmd.RunE(cmd, tt.args) - if (err != nil) != tt.err { - t.Errorf("%q. expected error: %v, got %v", tt.name, tt.err, err) - } - re := regexp.MustCompile(tt.expected) - if !re.Match(buf.Bytes()) { - t.Errorf("%q. expected\n%q\ngot\n%q", tt.name, tt.expected, buf.String()) - } - buf.Reset() - } + runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { + return newListCmd(c, out) + }) } From a66a39a171fa453f6515cbe23d7d2715cba9cc81 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 6 Mar 2018 11:49:08 -0800 Subject: [PATCH 075/221] fix helm init --wait --- cmd/helm/delete.go | 2 +- cmd/helm/get.go | 2 +- cmd/helm/get_hooks.go | 2 +- cmd/helm/get_manifest.go | 2 +- cmd/helm/get_values.go | 2 +- cmd/helm/helm.go | 4 +- cmd/helm/history.go | 2 +- cmd/helm/init.go | 52 ++++++++++++++++++-- cmd/helm/install.go | 2 +- cmd/helm/list.go | 2 +- cmd/helm/load_plugins.go | 2 +- cmd/helm/release_testing.go | 2 +- cmd/helm/reset.go | 2 +- cmd/helm/rollback.go | 2 +- cmd/helm/status.go | 2 +- cmd/helm/upgrade.go | 2 +- cmd/helm/version.go | 2 +- cmd/tiller/tiller.go | 8 +++ docs/helm/helm.md | 13 ++--- docs/helm/helm_completion.md | 13 ++--- docs/helm/helm_create.md | 13 ++--- docs/helm/helm_delete.md | 13 ++--- docs/helm/helm_dependency.md | 13 ++--- docs/helm/helm_dependency_build.md | 13 ++--- docs/helm/helm_dependency_list.md | 13 ++--- docs/helm/helm_dependency_update.md | 13 ++--- docs/helm/helm_fetch.md | 13 ++--- docs/helm/helm_get.md | 13 ++--- docs/helm/helm_get_hooks.md | 13 ++--- docs/helm/helm_get_manifest.md | 13 ++--- docs/helm/helm_get_values.md | 13 ++--- docs/helm/helm_history.md | 13 ++--- docs/helm/helm_home.md | 13 ++--- docs/helm/helm_init.md | 13 ++--- docs/helm/helm_inspect.md | 13 ++--- docs/helm/helm_inspect_chart.md | 13 ++--- docs/helm/helm_inspect_values.md | 13 ++--- docs/helm/helm_install.md | 13 ++--- docs/helm/helm_lint.md | 13 ++--- docs/helm/helm_list.md | 13 ++--- docs/helm/helm_package.md | 13 ++--- docs/helm/helm_plugin.md | 13 ++--- docs/helm/helm_plugin_install.md | 13 ++--- docs/helm/helm_plugin_list.md | 13 ++--- docs/helm/helm_plugin_remove.md | 13 ++--- docs/helm/helm_plugin_update.md | 13 ++--- docs/helm/helm_repo.md | 13 ++--- docs/helm/helm_repo_add.md | 13 ++--- docs/helm/helm_repo_index.md | 13 ++--- docs/helm/helm_repo_list.md | 13 ++--- docs/helm/helm_repo_remove.md | 13 ++--- docs/helm/helm_repo_update.md | 13 ++--- docs/helm/helm_reset.md | 13 ++--- docs/helm/helm_rollback.md | 13 ++--- docs/helm/helm_search.md | 13 ++--- docs/helm/helm_serve.md | 13 ++--- docs/helm/helm_status.md | 13 ++--- docs/helm/helm_template.md | 13 ++--- docs/helm/helm_test.md | 13 ++--- docs/helm/helm_upgrade.md | 13 ++--- docs/helm/helm_verify.md | 13 ++--- docs/helm/helm_version.md | 13 ++--- pkg/helm/client.go | 19 +++++-- pkg/helm/environment/environment.go | 3 ++ pkg/helm/option.go | 10 ++++ pkg/helm/portforwarder/portforwarder.go | 7 +-- pkg/helm/portforwarder/portforwarder_test.go | 2 +- 67 files changed, 416 insertions(+), 291 deletions(-) diff --git a/cmd/helm/delete.go b/cmd/helm/delete.go index 05c845344..e0ac8c4f6 100755 --- a/cmd/helm/delete.go +++ b/cmd/helm/delete.go @@ -57,7 +57,7 @@ func newDeleteCmd(c helm.Interface, out io.Writer) *cobra.Command { SuggestFor: []string{"remove", "rm"}, Short: "given a release name, delete the release from Kubernetes", Long: deleteDesc, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return errors.New("command 'delete' requires a release name") diff --git a/cmd/helm/get.go b/cmd/helm/get.go index 477f730d5..a2eb1d137 100644 --- a/cmd/helm/get.go +++ b/cmd/helm/get.go @@ -57,7 +57,7 @@ func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command { Use: "get [flags] RELEASE_NAME", Short: "download a named release", Long: getHelp, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return errReleaseRequired diff --git a/cmd/helm/get_hooks.go b/cmd/helm/get_hooks.go index ea57838af..1b6f2f8fe 100644 --- a/cmd/helm/get_hooks.go +++ b/cmd/helm/get_hooks.go @@ -47,7 +47,7 @@ func newGetHooksCmd(client helm.Interface, out io.Writer) *cobra.Command { Use: "hooks [flags] RELEASE_NAME", Short: "download all hooks for a named release", Long: getHooksHelp, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return errReleaseRequired diff --git a/cmd/helm/get_manifest.go b/cmd/helm/get_manifest.go index 773d8003b..1c42830f0 100644 --- a/cmd/helm/get_manifest.go +++ b/cmd/helm/get_manifest.go @@ -49,7 +49,7 @@ func newGetManifestCmd(client helm.Interface, out io.Writer) *cobra.Command { Use: "manifest [flags] RELEASE_NAME", Short: "download the manifest for a named release", Long: getManifestHelp, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return errReleaseRequired diff --git a/cmd/helm/get_values.go b/cmd/helm/get_values.go index 592f6fe61..b6ce648e5 100644 --- a/cmd/helm/get_values.go +++ b/cmd/helm/get_values.go @@ -47,7 +47,7 @@ func newGetValuesCmd(client helm.Interface, out io.Writer) *cobra.Command { Use: "values [flags] RELEASE_NAME", Short: "download the values file for a named release", Long: getValuesHelp, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return errReleaseRequired diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 4a0d10fe6..497565209 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -165,7 +165,7 @@ func markDeprecated(cmd *cobra.Command, notice string) *cobra.Command { return cmd } -func setupConnection(c *cobra.Command, args []string) error { +func setupConnection() error { if settings.TillerHost == "" { config, client, err := getKubeClient(settings.KubeContext) if err != nil { @@ -266,7 +266,7 @@ func ensureHelmClient(h helm.Interface) helm.Interface { } func newClient() helm.Interface { - options := []helm.Option{helm.Host(settings.TillerHost)} + options := []helm.Option{helm.Host(settings.TillerHost), helm.ConnectTimeout(settings.TillerConnectionTimeout)} if tlsVerify || tlsEnable { if tlsCaCertFile == "" { diff --git a/cmd/helm/history.go b/cmd/helm/history.go index 0637eca64..659c39e81 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -61,7 +61,7 @@ func newHistoryCmd(c helm.Interface, w io.Writer) *cobra.Command { Long: historyHelp, Short: "fetch release history", Aliases: []string{"hist"}, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { switch { case len(args) == 0: diff --git a/cmd/helm/init.go b/cmd/helm/init.go index 49adfc2c3..6c9cacf3b 100644 --- a/cmd/helm/init.go +++ b/cmd/helm/init.go @@ -23,6 +23,7 @@ import ( "fmt" "io" "os" + "time" "github.com/spf13/cobra" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -33,6 +34,7 @@ import ( "k8s.io/helm/pkg/getter" "k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm/helmpath" + "k8s.io/helm/pkg/helm/portforwarder" "k8s.io/helm/pkg/repo" ) @@ -310,13 +312,13 @@ func (i *initCmd) run() error { "(Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)") } } else { - if err := i.ping(); err != nil { - return err - } fmt.Fprintln(i.out, "\nTiller (the Helm server-side component) has been installed into your Kubernetes Cluster.\n\n"+ "Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.\n"+ "For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation") } + if err := i.ping(); err != nil { + return err + } } else { fmt.Fprintln(i.out, "Not installing Tiller due to 'client-only' flag having been set") } @@ -327,6 +329,19 @@ func (i *initCmd) run() error { func (i *initCmd) ping() error { if i.wait { + _, kubeClient, err := getKubeClient(settings.KubeContext) + if err != nil { + return err + } + if !watchTillerUntilReady(settings.TillerNamespace, kubeClient, settings.TillerConnectionTimeout) { + return fmt.Errorf("tiller was not found. polling deadline exceeded") + } + + // establish a connection to Tiller now that we've effectively guaranteed it's available + if err := setupConnection(); err != nil { + return err + } + i.client = newClient() if err := i.client.PingTiller(); err != nil { return fmt.Errorf("could not ping Tiller: %s", err) } @@ -443,3 +458,34 @@ func ensureRepoFileFormat(file string, out io.Writer) error { return nil } + +// watchTillerUntilReady waits for the tiller pod to become available. This is useful in situations where we +// want to wait before we call New(). +// +// Returns true if it exists. If the timeout was reached and it could not find the pod, it returns false. +func watchTillerUntilReady(namespace string, client kubernetes.Interface, timeout int64) bool { + deadlinePollingChan := time.NewTimer(time.Duration(timeout) * time.Second).C + checkTillerPodTicker := time.NewTicker(500 * time.Millisecond) + doneChan := make(chan bool) + + defer checkTillerPodTicker.Stop() + + go func() { + for range checkTillerPodTicker.C { + _, err := portforwarder.GetTillerPodName(client.CoreV1(), namespace) + if err == nil { + doneChan <- true + break + } + } + }() + + for { + select { + case <-deadlinePollingChan: + return false + case <-doneChan: + return true + } + } +} diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 55ddd8141..da1ee52d7 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -153,7 +153,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command { Use: "install [CHART]", Short: "install a chart archive", Long: installDesc, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { if err := checkArgsLength(len(args), "chart name"); err != nil { return err diff --git a/cmd/helm/list.go b/cmd/helm/list.go index bf543df5e..0219d60f2 100644 --- a/cmd/helm/list.go +++ b/cmd/helm/list.go @@ -88,7 +88,7 @@ func newListCmd(client helm.Interface, out io.Writer) *cobra.Command { Short: "list releases", Long: listHelp, Aliases: []string{"ls"}, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { if len(args) > 0 { list.filter = strings.Join(args, " ") diff --git a/cmd/helm/load_plugins.go b/cmd/helm/load_plugins.go index 2994126cb..ef24e7883 100644 --- a/cmd/helm/load_plugins.go +++ b/cmd/helm/load_plugins.go @@ -103,7 +103,7 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) { if _, err := processParent(cmd, args); err != nil { return err } - return setupConnection(cmd, args) + return setupConnection() } } diff --git a/cmd/helm/release_testing.go b/cmd/helm/release_testing.go index 09a6330c6..bdfa87a60 100644 --- a/cmd/helm/release_testing.go +++ b/cmd/helm/release_testing.go @@ -51,7 +51,7 @@ func newReleaseTestCmd(c helm.Interface, out io.Writer) *cobra.Command { Use: "test [RELEASE]", Short: "test a release", Long: releaseTestDesc, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { if err := checkArgsLength(len(args), "release name"); err != nil { return err diff --git a/cmd/helm/reset.go b/cmd/helm/reset.go index 623776729..9d3e17e03 100644 --- a/cmd/helm/reset.go +++ b/cmd/helm/reset.go @@ -58,7 +58,7 @@ func newResetCmd(client helm.Interface, out io.Writer) *cobra.Command { Short: "uninstalls Tiller from a cluster", Long: resetDesc, PreRunE: func(cmd *cobra.Command, args []string) error { - if err := setupConnection(cmd, args); !d.force && err != nil { + if err := setupConnection(); !d.force && err != nil { return err } return nil diff --git a/cmd/helm/rollback.go b/cmd/helm/rollback.go index c55707f7c..889b6ae28 100644 --- a/cmd/helm/rollback.go +++ b/cmd/helm/rollback.go @@ -57,7 +57,7 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command { Use: "rollback [flags] [RELEASE] [REVISION]", Short: "roll back a release to a previous revision", Long: rollbackDesc, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { if err := checkArgsLength(len(args), "release name", "revision number"); err != nil { return err diff --git a/cmd/helm/status.go b/cmd/helm/status.go index 12cfcd59e..b73b6f56e 100644 --- a/cmd/helm/status.go +++ b/cmd/helm/status.go @@ -63,7 +63,7 @@ func newStatusCmd(client helm.Interface, out io.Writer) *cobra.Command { Use: "status [flags] RELEASE_NAME", Short: "displays the status of the named release", Long: statusHelp, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return errReleaseRequired diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 7fca5af68..d08dd62ef 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -91,7 +91,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command { Use: "upgrade [RELEASE] [CHART]", Short: "upgrade a release", Long: upgradeDesc, - PreRunE: setupConnection, + PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() }, RunE: func(cmd *cobra.Command, args []string) error { if err := checkArgsLength(len(args), "release name", "chart path"); err != nil { return err diff --git a/cmd/helm/version.go b/cmd/helm/version.go index 8eaff1ca9..d541067a0 100644 --- a/cmd/helm/version.go +++ b/cmd/helm/version.go @@ -76,7 +76,7 @@ func newVersionCmd(c helm.Interface, out io.Writer) *cobra.Command { if version.showServer { // We do this manually instead of in PreRun because we only // need a tunnel if server version is requested. - setupConnection(cmd, args) + setupConnection() } version.client = ensureHelmClient(version.client) return version.run() diff --git a/cmd/tiller/tiller.go b/cmd/tiller/tiller.go index e0c10cb29..5d2db3816 100644 --- a/cmd/tiller/tiller.go +++ b/cmd/tiller/tiller.go @@ -33,6 +33,8 @@ import ( goprom "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/health" + healthpb "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/keepalive" "k8s.io/helm/pkg/kube" @@ -113,6 +115,9 @@ func main() { func start() { + healthSrv := health.NewServer() + healthSrv.SetServingStatus("Tiller", healthpb.HealthCheckResponse_NOT_SERVING) + clientset, err := kube.New(nil).ClientSet() if err != nil { logger.Fatalf("Cannot initialize Kubernetes connection: %s", err) @@ -168,6 +173,7 @@ func start() { })) rootServer = tiller.NewServer(opts...) + healthpb.RegisterHealthServer(rootServer, healthSrv) lstn, err := net.Listen("tcp", *grpcAddr) if err != nil { @@ -207,6 +213,8 @@ func start() { } }() + healthSrv.SetServingStatus("Tiller", healthpb.HealthCheckResponse_SERVING) + select { case err := <-srvErrCh: logger.Fatalf("Server died: %s", err) diff --git a/docs/helm/helm.md b/docs/helm/helm.md index d3c63f56a..f470e84b2 100644 --- a/docs/helm/helm.md +++ b/docs/helm/helm.md @@ -32,11 +32,12 @@ Environment: ### Options ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO @@ -67,4 +68,4 @@ Environment: * [helm verify](helm_verify.md) - verify that a chart at the given path has been signed and is valid * [helm version](helm_version.md) - print the client/server version information -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_completion.md b/docs/helm/helm_completion.md index cef6a8631..994205d88 100644 --- a/docs/helm/helm_completion.md +++ b/docs/helm/helm_completion.md @@ -24,14 +24,15 @@ helm completion SHELL ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_create.md b/docs/helm/helm_create.md index 636141661..6e0f3de78 100644 --- a/docs/helm/helm_create.md +++ b/docs/helm/helm_create.md @@ -43,14 +43,15 @@ helm create NAME ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_delete.md b/docs/helm/helm_delete.md index 26ac5fdac..5d41cd7ea 100644 --- a/docs/helm/helm_delete.md +++ b/docs/helm/helm_delete.md @@ -34,14 +34,15 @@ helm delete [flags] RELEASE_NAME [...] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_dependency.md b/docs/helm/helm_dependency.md index 05b114b34..34d49e20a 100644 --- a/docs/helm/helm_dependency.md +++ b/docs/helm/helm_dependency.md @@ -57,11 +57,12 @@ for this case. ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO @@ -70,4 +71,4 @@ for this case. * [helm dependency list](helm_dependency_list.md) - list the dependencies for the given chart * [helm dependency update](helm_dependency_update.md) - update charts/ based on the contents of requirements.yaml -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_dependency_build.md b/docs/helm/helm_dependency_build.md index 70aae9a96..0413a9a85 100644 --- a/docs/helm/helm_dependency_build.md +++ b/docs/helm/helm_dependency_build.md @@ -30,14 +30,15 @@ helm dependency build [flags] CHART ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm dependency](helm_dependency.md) - manage a chart's dependencies -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_dependency_list.md b/docs/helm/helm_dependency_list.md index be5daec44..b4343081c 100644 --- a/docs/helm/helm_dependency_list.md +++ b/docs/helm/helm_dependency_list.md @@ -22,14 +22,15 @@ helm dependency list [flags] CHART ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm dependency](helm_dependency.md) - manage a chart's dependencies -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_dependency_update.md b/docs/helm/helm_dependency_update.md index 94ddee3c5..3c90ff779 100644 --- a/docs/helm/helm_dependency_update.md +++ b/docs/helm/helm_dependency_update.md @@ -35,14 +35,15 @@ helm dependency update [flags] CHART ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm dependency](helm_dependency.md) - manage a chart's dependencies -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_fetch.md b/docs/helm/helm_fetch.md index 9c8a4ec36..3bc3334a0 100644 --- a/docs/helm/helm_fetch.md +++ b/docs/helm/helm_fetch.md @@ -44,14 +44,15 @@ helm fetch [flags] [chart URL | repo/chartname] [...] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_get.md b/docs/helm/helm_get.md index 5b148b564..9cd70e520 100644 --- a/docs/helm/helm_get.md +++ b/docs/helm/helm_get.md @@ -36,11 +36,12 @@ helm get [flags] RELEASE_NAME ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO @@ -49,4 +50,4 @@ helm get [flags] RELEASE_NAME * [helm get manifest](helm_get_manifest.md) - download the manifest for a named release * [helm get values](helm_get_values.md) - download the values file for a named release -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_get_hooks.md b/docs/helm/helm_get_hooks.md index c39c73888..85fa5d04b 100644 --- a/docs/helm/helm_get_hooks.md +++ b/docs/helm/helm_get_hooks.md @@ -29,14 +29,15 @@ helm get hooks [flags] RELEASE_NAME ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_get_manifest.md b/docs/helm/helm_get_manifest.md index 144f7bf87..a00c1be56 100644 --- a/docs/helm/helm_get_manifest.md +++ b/docs/helm/helm_get_manifest.md @@ -31,14 +31,15 @@ helm get manifest [flags] RELEASE_NAME ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_get_values.md b/docs/helm/helm_get_values.md index eadc56a67..d8944b475 100644 --- a/docs/helm/helm_get_values.md +++ b/docs/helm/helm_get_values.md @@ -28,14 +28,15 @@ helm get values [flags] RELEASE_NAME ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_history.md b/docs/helm/helm_history.md index 119e58b69..81c720021 100755 --- a/docs/helm/helm_history.md +++ b/docs/helm/helm_history.md @@ -40,14 +40,15 @@ helm history [flags] RELEASE_NAME ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_home.md b/docs/helm/helm_home.md index 855090a20..bdccd756f 100644 --- a/docs/helm/helm_home.md +++ b/docs/helm/helm_home.md @@ -17,14 +17,15 @@ helm home ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_init.md b/docs/helm/helm_init.md index 5ed24e60d..5374488af 100644 --- a/docs/helm/helm_init.md +++ b/docs/helm/helm_init.md @@ -60,14 +60,15 @@ helm init ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 6-Mar-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_inspect.md b/docs/helm/helm_inspect.md index 006da7478..df122f763 100644 --- a/docs/helm/helm_inspect.md +++ b/docs/helm/helm_inspect.md @@ -31,11 +31,12 @@ helm inspect [CHART] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO @@ -43,4 +44,4 @@ helm inspect [CHART] * [helm inspect chart](helm_inspect_chart.md) - shows inspect chart * [helm inspect values](helm_inspect_values.md) - shows inspect values -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_inspect_chart.md b/docs/helm/helm_inspect_chart.md index 37d0eb4af..bfa6061c8 100644 --- a/docs/helm/helm_inspect_chart.md +++ b/docs/helm/helm_inspect_chart.md @@ -29,14 +29,15 @@ helm inspect chart [CHART] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm inspect](helm_inspect.md) - inspect a chart -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_inspect_values.md b/docs/helm/helm_inspect_values.md index 2079849ff..fbf8660c2 100644 --- a/docs/helm/helm_inspect_values.md +++ b/docs/helm/helm_inspect_values.md @@ -29,14 +29,15 @@ helm inspect values [CHART] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm inspect](helm_inspect.md) - inspect a chart -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_install.md b/docs/helm/helm_install.md index da9b91bb8..406416dc8 100644 --- a/docs/helm/helm_install.md +++ b/docs/helm/helm_install.md @@ -98,14 +98,15 @@ helm install [CHART] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_lint.md b/docs/helm/helm_lint.md index 8167a46cc..da3cdf945 100644 --- a/docs/helm/helm_lint.md +++ b/docs/helm/helm_lint.md @@ -30,14 +30,15 @@ helm lint [flags] PATH ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_list.md b/docs/helm/helm_list.md index 1ba60b912..1d5bf7ea2 100755 --- a/docs/helm/helm_list.md +++ b/docs/helm/helm_list.md @@ -62,14 +62,15 @@ helm list [flags] [FILTER] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_package.md b/docs/helm/helm_package.md index 85da8315e..c51aa7032 100644 --- a/docs/helm/helm_package.md +++ b/docs/helm/helm_package.md @@ -36,14 +36,15 @@ helm package [flags] [CHART_PATH] [...] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_plugin.md b/docs/helm/helm_plugin.md index f8e04f1a5..cc42aa4dc 100644 --- a/docs/helm/helm_plugin.md +++ b/docs/helm/helm_plugin.md @@ -12,11 +12,12 @@ Manage client-side Helm plugins. ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO @@ -26,4 +27,4 @@ Manage client-side Helm plugins. * [helm plugin remove](helm_plugin_remove.md) - remove one or more Helm plugins * [helm plugin update](helm_plugin_update.md) - update one or more Helm plugins -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_plugin_install.md b/docs/helm/helm_plugin_install.md index beb478845..196ca97dd 100644 --- a/docs/helm/helm_plugin_install.md +++ b/docs/helm/helm_plugin_install.md @@ -25,14 +25,15 @@ helm plugin install [options] ... ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_plugin_list.md b/docs/helm/helm_plugin_list.md index d363ae9b6..ddfd04ee6 100644 --- a/docs/helm/helm_plugin_list.md +++ b/docs/helm/helm_plugin_list.md @@ -14,14 +14,15 @@ helm plugin list ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_plugin_remove.md b/docs/helm/helm_plugin_remove.md index 55f62514d..8543a367a 100644 --- a/docs/helm/helm_plugin_remove.md +++ b/docs/helm/helm_plugin_remove.md @@ -14,14 +14,15 @@ helm plugin remove ... ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_plugin_update.md b/docs/helm/helm_plugin_update.md index 26a6ad270..9e5e205f0 100644 --- a/docs/helm/helm_plugin_update.md +++ b/docs/helm/helm_plugin_update.md @@ -14,14 +14,15 @@ helm plugin update ... ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_repo.md b/docs/helm/helm_repo.md index a700f7aab..4109ceca4 100644 --- a/docs/helm/helm_repo.md +++ b/docs/helm/helm_repo.md @@ -16,11 +16,12 @@ Example usage: ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO @@ -31,4 +32,4 @@ Example usage: * [helm repo remove](helm_repo_remove.md) - remove a chart repository * [helm repo update](helm_repo_update.md) - update information of available charts locally from chart repositories -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_repo_add.md b/docs/helm/helm_repo_add.md index 7137c2c51..f0dfcbd5d 100644 --- a/docs/helm/helm_repo_add.md +++ b/docs/helm/helm_repo_add.md @@ -23,14 +23,15 @@ helm repo add [flags] [NAME] [URL] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_repo_index.md b/docs/helm/helm_repo_index.md index 7ddcf068f..14b412b29 100644 --- a/docs/helm/helm_repo_index.md +++ b/docs/helm/helm_repo_index.md @@ -30,14 +30,15 @@ helm repo index [flags] [DIR] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_repo_list.md b/docs/helm/helm_repo_list.md index 2285a3c6e..858ef957f 100644 --- a/docs/helm/helm_repo_list.md +++ b/docs/helm/helm_repo_list.md @@ -14,14 +14,15 @@ helm repo list [flags] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_repo_remove.md b/docs/helm/helm_repo_remove.md index d23980e73..801bc3c3f 100644 --- a/docs/helm/helm_repo_remove.md +++ b/docs/helm/helm_repo_remove.md @@ -14,14 +14,15 @@ helm repo remove [flags] [NAME] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_repo_update.md b/docs/helm/helm_repo_update.md index 00dc6d9e2..897ed24b7 100644 --- a/docs/helm/helm_repo_update.md +++ b/docs/helm/helm_repo_update.md @@ -20,14 +20,15 @@ helm repo update ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_reset.md b/docs/helm/helm_reset.md index f6707b8bd..ed68b1b84 100644 --- a/docs/helm/helm_reset.md +++ b/docs/helm/helm_reset.md @@ -30,14 +30,15 @@ helm reset ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 8-Feb-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_rollback.md b/docs/helm/helm_rollback.md index 3bd4af8bf..4b6dcbbb2 100644 --- a/docs/helm/helm_rollback.md +++ b/docs/helm/helm_rollback.md @@ -36,14 +36,15 @@ helm rollback [flags] [RELEASE] [REVISION] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_search.md b/docs/helm/helm_search.md index 247b83f42..f59814b9a 100644 --- a/docs/helm/helm_search.md +++ b/docs/helm/helm_search.md @@ -27,14 +27,15 @@ helm search [keyword] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_serve.md b/docs/helm/helm_serve.md index 163b24e76..90ebb6da9 100644 --- a/docs/helm/helm_serve.md +++ b/docs/helm/helm_serve.md @@ -35,14 +35,15 @@ helm serve ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_status.md b/docs/helm/helm_status.md index b878277ac..02ec0ad66 100644 --- a/docs/helm/helm_status.md +++ b/docs/helm/helm_status.md @@ -35,14 +35,15 @@ helm status [flags] RELEASE_NAME ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_template.md b/docs/helm/helm_template.md index 347ba2ab4..126adb02f 100644 --- a/docs/helm/helm_template.md +++ b/docs/helm/helm_template.md @@ -39,14 +39,15 @@ helm template [flags] CHART ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_test.md b/docs/helm/helm_test.md index 89436ed60..062244e73 100644 --- a/docs/helm/helm_test.md +++ b/docs/helm/helm_test.md @@ -31,14 +31,15 @@ helm test [RELEASE] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_upgrade.md b/docs/helm/helm_upgrade.md index 290fe5921..5ed128958 100644 --- a/docs/helm/helm_upgrade.md +++ b/docs/helm/helm_upgrade.md @@ -66,14 +66,15 @@ helm upgrade [RELEASE] [CHART] ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_verify.md b/docs/helm/helm_verify.md index 2c65b3092..bc5343937 100644 --- a/docs/helm/helm_verify.md +++ b/docs/helm/helm_verify.md @@ -29,14 +29,15 @@ helm verify [flags] PATH ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 25-Jan-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_version.md b/docs/helm/helm_version.md index 39b4adfab..1f48cceba 100644 --- a/docs/helm/helm_version.md +++ b/docs/helm/helm_version.md @@ -44,14 +44,15 @@ helm version ### Options inherited from parent commands ``` - --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default "kube-system") + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") ``` ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 11-Feb-2018 +###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/pkg/helm/client.go b/pkg/helm/client.go index c7ef4d89e..372613b2a 100644 --- a/pkg/helm/client.go +++ b/pkg/helm/client.go @@ -17,6 +17,7 @@ limitations under the License. package helm // import "k8s.io/helm/pkg/helm" import ( + "fmt" "io" "time" @@ -25,6 +26,7 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/keepalive" + healthpb "google.golang.org/grpc/health/grpc_health_v1" "k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/proto/hapi/chart" rls "k8s.io/helm/pkg/proto/hapi/services" @@ -321,7 +323,7 @@ func (h *Client) connect(ctx context.Context) (conn *grpc.ClientConn, err error) default: opts = append(opts, grpc.WithInsecure()) } - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + ctx, cancel := context.WithTimeout(ctx, h.opts.connectTimeout) defer cancel() if conn, err = grpc.DialContext(ctx, h.opts.host, opts...); err != nil { return nil, err @@ -488,6 +490,17 @@ func (h *Client) ping(ctx context.Context) error { } defer c.Close() - rlc := rls.NewReleaseServiceClient(c) - return rlc.PingTiller(ctx) + healthClient := healthpb.NewHealthClient(c) + resp, err := healthClient.Check(ctx, &healthpb.HealthCheckRequest{Service: "Tiller"}) + if err != nil { + return err + } + switch resp.GetStatus() { + case healthpb.HealthCheckResponse_SERVING: + return nil + case healthpb.HealthCheckResponse_NOT_SERVING: + return fmt.Errorf("tiller is not serving requests at this time, Please try again later") + default: + return fmt.Errorf("tiller healthcheck returned an unknown status") + } } diff --git a/pkg/helm/environment/environment.go b/pkg/helm/environment/environment.go index 49d424b33..2980e6dc9 100644 --- a/pkg/helm/environment/environment.go +++ b/pkg/helm/environment/environment.go @@ -39,6 +39,8 @@ var DefaultHelmHome = filepath.Join(homedir.HomeDir(), ".helm") type EnvSettings struct { // TillerHost is the host and port of Tiller. TillerHost string + // TillerConnectionTimeout is the duration (in seconds) helm will wait to establish a connection to tiller. + TillerConnectionTimeout int64 // TillerNamespace is the namespace in which Tiller runs. TillerNamespace string // Home is the local path to the Helm home directory. @@ -56,6 +58,7 @@ func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&s.KubeContext, "kube-context", "", "name of the kubeconfig context to use") fs.BoolVar(&s.Debug, "debug", false, "enable verbose output") fs.StringVar(&s.TillerNamespace, "tiller-namespace", "kube-system", "namespace of Tiller") + fs.Int64Var(&s.TillerConnectionTimeout, "tiller-connection-timeout", int64(300), "the duration (in seconds) Helm will wait to establish a connection to tiller") } // Init sets values from the environment. diff --git a/pkg/helm/option.go b/pkg/helm/option.go index a8770a488..3381e3f80 100644 --- a/pkg/helm/option.go +++ b/pkg/helm/option.go @@ -18,6 +18,7 @@ package helm import ( "crypto/tls" + "time" "github.com/golang/protobuf/proto" "golang.org/x/net/context" @@ -78,6 +79,8 @@ type options struct { reuseValues bool // release test options are applied directly to the test release history request testReq rls.TestReleaseRequest + // connectTimeout specifies the time duration Helm will wait to establish a connection to tiller + connectTimeout time.Duration } // Host specifies the host address of the Tiller release server, (default = ":44134"). @@ -180,6 +183,13 @@ func ReleaseName(name string) InstallOption { } } +// ConnectTimeout specifies the duration (in seconds) Helm will wait to establish a connection to tiller +func ConnectTimeout(timeout int64) Option { + return func(opts *options) { + opts.connectTimeout = time.Duration(timeout) * time.Second + } +} + // InstallTimeout specifies the number of seconds before kubernetes calls timeout func InstallTimeout(timeout int64) InstallOption { return func(opts *options) { diff --git a/pkg/helm/portforwarder/portforwarder.go b/pkg/helm/portforwarder/portforwarder.go index 07e692e9a..878610d5f 100644 --- a/pkg/helm/portforwarder/portforwarder.go +++ b/pkg/helm/portforwarder/portforwarder.go @@ -30,12 +30,12 @@ import ( ) var ( - tillerPodLabels labels.Set = labels.Set{"app": "helm", "name": "tiller"} + tillerPodLabels = labels.Set{"app": "helm", "name": "tiller"} ) // New creates a new and initialized tunnel. func New(namespace string, client kubernetes.Interface, config *rest.Config) (*kube.Tunnel, error) { - podName, err := getTillerPodName(client.CoreV1(), namespace) + podName, err := GetTillerPodName(client.CoreV1(), namespace) if err != nil { return nil, err } @@ -44,7 +44,8 @@ func New(namespace string, client kubernetes.Interface, config *rest.Config) (*k return t, t.ForwardPort() } -func getTillerPodName(client corev1.PodsGetter, namespace string) (string, error) { +// GetTillerPodName fetches the name of tiller pod running in the given namespace. +func GetTillerPodName(client corev1.PodsGetter, namespace string) (string, error) { selector := tillerPodLabels.AsSelector() pod, err := getFirstRunningPod(client, namespace, selector) if err != nil { diff --git a/pkg/helm/portforwarder/portforwarder_test.go b/pkg/helm/portforwarder/portforwarder_test.go index b9e90afa8..e4c148991 100644 --- a/pkg/helm/portforwarder/portforwarder_test.go +++ b/pkg/helm/portforwarder/portforwarder_test.go @@ -76,7 +76,7 @@ func TestGetFirstPod(t *testing.T) { for _, tt := range tests { client := fake.NewSimpleClientset(&v1.PodList{Items: tt.pods}) - name, err := getTillerPodName(client.Core(), v1.NamespaceDefault) + name, err := GetTillerPodName(client.Core(), v1.NamespaceDefault) if (err != nil) != tt.err { t.Errorf("%q. expected error: %v, got %v", tt.name, tt.err, err) } From 250d25fdceaf5546f29228f3711cedd8d6776fcd Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Thu, 8 Mar 2018 12:14:50 -0800 Subject: [PATCH 076/221] fix protoc k8s.io/kubernetes bumped protobuf to 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9 --- glide.lock | 10 +++-- glide.yaml | 4 +- pkg/proto/hapi/chart/metadata.pb.go | 59 ++++++++++++++-------------- pkg/proto/hapi/release/hook.pb.go | 10 +++++ pkg/proto/hapi/services/tiller.pb.go | 20 +--------- 5 files changed, 49 insertions(+), 54 deletions(-) diff --git a/glide.lock b/glide.lock index e14766948..1ccdae61c 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: c4a1f6e380baf38d371d428fa5c8f7b2363663d811c728e982300692287a58e4 -updated: 2018-02-02T20:15:49.706602Z +hash: d93f565214b112cf8560e9cd2da2f3ab7852a1f19544569fc112bd4fb2d1d506 +updated: 2018-03-08T14:06:06.497394911-08:00 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -147,7 +147,7 @@ imports: - name: github.com/go-openapi/swag version: f3f9494671f93fcff853e3c6e9e948b3eb71e590 - name: github.com/gobwas/glob - version: bea32b9cd2d6f55753d94a28e959b13f0244797a + version: 5ccd90ef52e1e632236f7326478d4faa74f99438 subpackages: - compiler - match @@ -168,7 +168,7 @@ imports: subpackages: - lru - name: github.com/golang/protobuf - version: 4bd1920723d7b7c925de087aa32e2187708897f7 + version: 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9 subpackages: - proto - ptypes @@ -378,6 +378,8 @@ imports: - credentials - grpclb/grpc_lb_v1/messages - grpclog + - health + - health/grpc_health_v1 - internal - keepalive - metadata diff --git a/glide.yaml b/glide.yaml index 81bb8ebe1..7d0fce978 100644 --- a/glide.yaml +++ b/glide.yaml @@ -19,7 +19,7 @@ import: version: ~1.3.1 - package: github.com/technosophos/moniker - package: github.com/golang/protobuf - version: 4bd1920723d7b7c925de087aa32e2187708897f7 + version: 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9 subpackages: - proto - ptypes/any @@ -53,7 +53,7 @@ import: vcs: git - package: k8s.io/kubernetes - version: ~1.9.2 + version: 1.9.2 - package: k8s.io/client-go version: ~6.0.0 - package: k8s.io/api diff --git a/pkg/proto/hapi/chart/metadata.pb.go b/pkg/proto/hapi/chart/metadata.pb.go index 49a4aa0ac..9daeaa9e5 100644 --- a/pkg/proto/hapi/chart/metadata.pb.go +++ b/pkg/proto/hapi/chart/metadata.pb.go @@ -107,7 +107,7 @@ type Metadata struct { // Annotations are additional mappings uninterpreted by Tiller, // made available for inspection by other applications. Annotations map[string]string `protobuf:"bytes,16,rep,name=annotations" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - // KubeVersion is a SemVer constraints on what version of Kubernetes is required. + // KubeVersion is a SemVer constraint specifying the version of Kubernetes required. KubeVersion string `protobuf:"bytes,17,opt,name=kubeVersion" json:"kubeVersion,omitempty"` } @@ -244,32 +244,33 @@ func init() { func init() { proto.RegisterFile("hapi/chart/metadata.proto", fileDescriptor2) } var fileDescriptor2 = []byte{ - // 427 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0x5d, 0x6b, 0xdb, 0x30, - 0x14, 0x9d, 0x9b, 0x38, 0x89, 0xaf, 0xd7, 0xcd, 0xbb, 0x8c, 0xa2, 0x95, 0x31, 0x4c, 0xd8, 0x20, - 0x4f, 0x29, 0x6c, 0x30, 0xca, 0x1e, 0x06, 0x1b, 0x94, 0x3e, 0x6c, 0x4d, 0x87, 0xd9, 0x07, 0xec, - 0x4d, 0xb5, 0x2f, 0x8d, 0x48, 0x2c, 0x19, 0x49, 0xe9, 0xc8, 0xaf, 0xd8, 0x5f, 0x1e, 0x92, 0xad, - 0xda, 0x19, 0x7d, 0xbb, 0xe7, 0x1c, 0xdd, 0x23, 0x1d, 0xdd, 0x0b, 0x2f, 0xd6, 0xbc, 0x11, 0x67, - 0xe5, 0x9a, 0x6b, 0x7b, 0x56, 0x93, 0xe5, 0x15, 0xb7, 0x7c, 0xd9, 0x68, 0x65, 0x15, 0x82, 0x93, - 0x96, 0x5e, 0x9a, 0xbf, 0x07, 0xb8, 0xe2, 0x42, 0x5a, 0x2e, 0x24, 0x69, 0x44, 0x18, 0x4b, 0x5e, - 0x13, 0x8b, 0xf2, 0x68, 0x91, 0x14, 0xbe, 0xc6, 0xe7, 0x10, 0x53, 0xcd, 0xc5, 0x96, 0x1d, 0x79, - 0xb2, 0x05, 0xf3, 0xbf, 0x31, 0xcc, 0xae, 0x3a, 0xdb, 0x07, 0xdb, 0x10, 0xc6, 0x6b, 0x55, 0x53, - 0xd7, 0xe5, 0x6b, 0x64, 0x30, 0x35, 0x6a, 0xa7, 0x4b, 0x32, 0x6c, 0x94, 0x8f, 0x16, 0x49, 0x11, - 0xa0, 0x53, 0xee, 0x48, 0x1b, 0xa1, 0x24, 0x1b, 0xfb, 0x86, 0x00, 0x31, 0x87, 0xb4, 0x22, 0x53, - 0x6a, 0xd1, 0x58, 0xa7, 0xc6, 0x5e, 0x1d, 0x52, 0x78, 0x0a, 0xb3, 0x0d, 0xed, 0xff, 0x28, 0x5d, - 0x19, 0x36, 0xf1, 0xb6, 0xf7, 0x18, 0xcf, 0x21, 0xad, 0xef, 0xe3, 0x19, 0x36, 0xcd, 0x47, 0x8b, - 0xf4, 0xed, 0xc9, 0xb2, 0xff, 0x80, 0x65, 0x9f, 0xbe, 0x18, 0x1e, 0xc5, 0x13, 0x98, 0x90, 0xbc, - 0x15, 0x92, 0xd8, 0xcc, 0x5f, 0xd9, 0x21, 0x97, 0x4b, 0x94, 0x4a, 0xb2, 0xa4, 0xcd, 0xe5, 0x6a, - 0x7c, 0x05, 0xc0, 0x1b, 0xf1, 0xb3, 0x0b, 0x00, 0x5e, 0x19, 0x30, 0xf8, 0x12, 0x92, 0x52, 0xc9, - 0x4a, 0xf8, 0x04, 0xa9, 0x97, 0x7b, 0xc2, 0x39, 0x5a, 0x7e, 0x6b, 0xd8, 0xe3, 0xd6, 0xd1, 0xd5, - 0xad, 0x63, 0x13, 0x1c, 0x8f, 0x83, 0x63, 0x60, 0x9c, 0x5e, 0x51, 0xa3, 0xa9, 0xe4, 0x96, 0x2a, - 0xf6, 0x24, 0x8f, 0x16, 0xb3, 0x62, 0xc0, 0xe0, 0x6b, 0x38, 0xb6, 0x62, 0xbb, 0x25, 0x1d, 0x2c, - 0x9e, 0x7a, 0x8b, 0x43, 0x12, 0x2f, 0x21, 0xe5, 0x52, 0x2a, 0xcb, 0xdd, 0x3b, 0x0c, 0xcb, 0xfc, - 0xef, 0xbc, 0x39, 0xf8, 0x9d, 0xb0, 0x39, 0x9f, 0xfa, 0x73, 0x17, 0xd2, 0xea, 0x7d, 0x31, 0xec, - 0x74, 0x43, 0xda, 0xec, 0x6e, 0x28, 0x5c, 0xf6, 0xac, 0x1d, 0xd2, 0x80, 0x3a, 0xfd, 0x08, 0xd9, - 0xff, 0x16, 0x98, 0xc1, 0x68, 0x43, 0xfb, 0x6e, 0x6b, 0x5c, 0xe9, 0x76, 0xed, 0x8e, 0x6f, 0x77, - 0x61, 0x6b, 0x5a, 0xf0, 0xe1, 0xe8, 0x3c, 0x9a, 0xe7, 0x30, 0xb9, 0x68, 0x07, 0x90, 0xc2, 0xf4, - 0xc7, 0xea, 0xcb, 0xea, 0xfa, 0xd7, 0x2a, 0x7b, 0x84, 0x09, 0xc4, 0x97, 0xd7, 0xdf, 0xbf, 0x7d, - 0xcd, 0xa2, 0xcf, 0xd3, 0xdf, 0xb1, 0x7f, 0xf3, 0xcd, 0xc4, 0x6f, 0xf9, 0xbb, 0x7f, 0x01, 0x00, - 0x00, 0xff, 0xff, 0x7f, 0xc1, 0xec, 0x3d, 0x02, 0x03, 0x00, 0x00, + // 435 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0x5d, 0x6b, 0xd4, 0x40, + 0x14, 0x35, 0xcd, 0x66, 0x77, 0x73, 0x63, 0x35, 0x0e, 0x52, 0xc6, 0x22, 0x12, 0x16, 0x85, 0x7d, + 0xda, 0x82, 0xbe, 0x14, 0x1f, 0x04, 0x85, 0x52, 0x41, 0xbb, 0x95, 0xe0, 0x07, 0xf8, 0x36, 0x4d, + 0x2e, 0xdd, 0x61, 0x93, 0x99, 0x30, 0x99, 0xad, 0xec, 0xaf, 0xf0, 0x2f, 0xcb, 0xdc, 0x64, 0x9a, + 0xac, 0xf4, 0xed, 0x9e, 0x73, 0x66, 0xce, 0xcc, 0xbd, 0xf7, 0xc0, 0x8b, 0x8d, 0x68, 0xe4, 0x59, + 0xb1, 0x11, 0xc6, 0x9e, 0xd5, 0x68, 0x45, 0x29, 0xac, 0x58, 0x35, 0x46, 0x5b, 0xcd, 0xc0, 0x49, + 0x2b, 0x92, 0x16, 0x9f, 0x01, 0xae, 0x84, 0x54, 0x56, 0x48, 0x85, 0x86, 0x31, 0x98, 0x28, 0x51, + 0x23, 0x0f, 0xb2, 0x60, 0x19, 0xe7, 0x54, 0xb3, 0xe7, 0x10, 0x61, 0x2d, 0x64, 0xc5, 0x8f, 0x88, + 0xec, 0x00, 0x4b, 0x21, 0xdc, 0x99, 0x8a, 0x87, 0xc4, 0xb9, 0x72, 0xf1, 0x37, 0x82, 0xf9, 0x55, + 0xff, 0xd0, 0x83, 0x46, 0x0c, 0x26, 0x1b, 0x5d, 0x63, 0xef, 0x43, 0x35, 0xe3, 0x30, 0x6b, 0xf5, + 0xce, 0x14, 0xd8, 0xf2, 0x30, 0x0b, 0x97, 0x71, 0xee, 0xa1, 0x53, 0xee, 0xd0, 0xb4, 0x52, 0x2b, + 0x3e, 0xa1, 0x0b, 0x1e, 0xb2, 0x0c, 0x92, 0x12, 0xdb, 0xc2, 0xc8, 0xc6, 0x3a, 0x35, 0x22, 0x75, + 0x4c, 0xb1, 0x53, 0x98, 0x6f, 0x71, 0xff, 0x47, 0x9b, 0xb2, 0xe5, 0x53, 0xb2, 0xbd, 0xc7, 0xec, + 0x1c, 0x92, 0xfa, 0xbe, 0xe1, 0x96, 0xcf, 0xb2, 0x70, 0x99, 0xbc, 0x3d, 0x59, 0x0d, 0x23, 0x59, + 0x0d, 0xf3, 0xc8, 0xc7, 0x47, 0xd9, 0x09, 0x4c, 0x51, 0xdd, 0x4a, 0x85, 0x7c, 0x4e, 0x4f, 0xf6, + 0xc8, 0xf5, 0x25, 0x0b, 0xad, 0x78, 0xdc, 0xf5, 0xe5, 0x6a, 0xf6, 0x0a, 0x40, 0x34, 0xf2, 0x67, + 0xdf, 0x00, 0x90, 0x32, 0x62, 0xd8, 0x4b, 0x88, 0x0b, 0xad, 0x4a, 0x49, 0x1d, 0x24, 0x24, 0x0f, + 0x84, 0x73, 0xb4, 0xe2, 0xb6, 0xe5, 0x8f, 0x3b, 0x47, 0x57, 0x77, 0x8e, 0x8d, 0x77, 0x3c, 0xf6, + 0x8e, 0x9e, 0x71, 0x7a, 0x89, 0x8d, 0xc1, 0x42, 0x58, 0x2c, 0xf9, 0x93, 0x2c, 0x58, 0xce, 0xf3, + 0x11, 0xc3, 0x5e, 0xc3, 0xb1, 0x95, 0x55, 0x85, 0xc6, 0x5b, 0x3c, 0x25, 0x8b, 0x43, 0x92, 0x5d, + 0x42, 0x22, 0x94, 0xd2, 0x56, 0xb8, 0x7f, 0xb4, 0x3c, 0xa5, 0xe9, 0xbc, 0x39, 0x98, 0x8e, 0xcf, + 0xd2, 0xc7, 0xe1, 0xdc, 0x85, 0xb2, 0x66, 0x9f, 0x8f, 0x6f, 0xba, 0x25, 0x6d, 0x77, 0x37, 0xe8, + 0x1f, 0x7b, 0xd6, 0x2d, 0x69, 0x44, 0x9d, 0x7e, 0x80, 0xf4, 0x7f, 0x0b, 0x97, 0xaa, 0x2d, 0xee, + 0xfb, 0xd4, 0xb8, 0xd2, 0xa5, 0xef, 0x4e, 0x54, 0x3b, 0x9f, 0x9a, 0x0e, 0xbc, 0x3f, 0x3a, 0x0f, + 0x16, 0x19, 0x4c, 0x2f, 0xba, 0x05, 0x24, 0x30, 0xfb, 0xb1, 0xfe, 0xb2, 0xbe, 0xfe, 0xb5, 0x4e, + 0x1f, 0xb1, 0x18, 0xa2, 0xcb, 0xeb, 0xef, 0xdf, 0xbe, 0xa6, 0xc1, 0xa7, 0xd9, 0xef, 0x88, 0xfe, + 0x7c, 0x33, 0xa5, 0xdc, 0xbf, 0xfb, 0x17, 0x00, 0x00, 0xff, 0xff, 0x36, 0xf9, 0x0d, 0xa6, 0x14, + 0x03, 0x00, 0x00, } diff --git a/pkg/proto/hapi/release/hook.pb.go b/pkg/proto/hapi/release/hook.pb.go index bd9391c50..508448280 100644 --- a/pkg/proto/hapi/release/hook.pb.go +++ b/pkg/proto/hapi/release/hook.pb.go @@ -6,9 +6,19 @@ Package release is a generated protocol buffer package. It is generated from these files: hapi/release/hook.proto + hapi/release/info.proto + hapi/release/release.proto + hapi/release/status.proto + hapi/release/test_run.proto + hapi/release/test_suite.proto It has these top-level messages: Hook + Info + Release + Status + TestRun + TestSuite */ package release diff --git a/pkg/proto/hapi/services/tiller.pb.go b/pkg/proto/hapi/services/tiller.pb.go index 2112ea67f..37535aac7 100644 --- a/pkg/proto/hapi/services/tiller.pb.go +++ b/pkg/proto/hapi/services/tiller.pb.go @@ -275,7 +275,7 @@ type GetReleaseStatusResponse struct { Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` // Info contains information about the release. Info *hapi_release4.Info `protobuf:"bytes,2,opt,name=info" json:"info,omitempty"` - // Namesapce the release was released into + // Namespace the release was released into Namespace string `protobuf:"bytes,3,opt,name=namespace" json:"namespace,omitempty"` } @@ -949,8 +949,6 @@ type ReleaseServiceClient interface { GetHistory(ctx context.Context, in *GetHistoryRequest, opts ...grpc.CallOption) (*GetHistoryResponse, error) // RunReleaseTest executes the tests defined of a named release RunReleaseTest(ctx context.Context, in *TestReleaseRequest, opts ...grpc.CallOption) (ReleaseService_RunReleaseTestClient, error) - // PingTiller sends a test/ping signal to Tiller to ensure that it's up - PingTiller(ctx context.Context) error } type releaseServiceClient struct { @@ -1080,14 +1078,6 @@ func (c *releaseServiceClient) RunReleaseTest(ctx context.Context, in *TestRelea return x, nil } -func (c *releaseServiceClient) PingTiller(ctx context.Context) error { - err := grpc.Invoke(ctx, "/hapi.services.tiller.ReleaseService/PingTiller", "Ping", nil, c.cc, grpc.FailFast(false)) - if err != nil { - return err - } - return nil -} - type ReleaseService_RunReleaseTestClient interface { Recv() (*TestReleaseResponse, error) grpc.ClientStream @@ -1310,10 +1300,6 @@ func _ReleaseService_RunReleaseTest_Handler(srv interface{}, stream grpc.ServerS return srv.(ReleaseServiceServer).RunReleaseTest(m, &releaseServiceRunReleaseTestServer{stream}) } -func _ReleaseService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - return "Pong", nil -} - type ReleaseService_RunReleaseTestServer interface { Send(*TestReleaseResponse) error grpc.ServerStream @@ -1363,10 +1349,6 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{ MethodName: "GetHistory", Handler: _ReleaseService_GetHistory_Handler, }, - { - MethodName: "PingTiller", - Handler: _ReleaseService_Ping_Handler, - }, }, Streams: []grpc.StreamDesc{ { From 13730b0dab2feb91eb9e7ca95e7a6d501e556c94 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Fri, 2 Mar 2018 12:39:33 -0800 Subject: [PATCH 077/221] replace FAILED deployments with `helm upgrade --install --force` When using `helm upgrade --install`, if the first release fails, Helm will respond with an error saying that it cannot upgrade from an unknown state. With this feature, `helm upgrade --install --force` automates the same process as `helm delete && helm install --replace`. It will mark the previous release as DELETED, delete any existing resources inside Kubernetes, then replace it as if it was a fresh install. It will then mark the FAILED release as SUPERSEDED. --- pkg/storage/storage.go | 4 ++ pkg/tiller/release_update.go | 112 ++++++++++++++++++++++++++++++ pkg/tiller/release_update_test.go | 50 ++++++++++++- 3 files changed, 163 insertions(+), 3 deletions(-) diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index f76eb09f4..4b39e0bb2 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -129,6 +129,10 @@ func (s *Storage) Deployed(name string) (*rspb.Release, error) { return nil, err } + if len(ls) == 0 { + return nil, fmt.Errorf("%q has no deployed releases", name) + } + return ls[0], err } diff --git a/pkg/tiller/release_update.go b/pkg/tiller/release_update.go index d251db753..cb8b57792 100644 --- a/pkg/tiller/release_update.go +++ b/pkg/tiller/release_update.go @@ -18,6 +18,7 @@ package tiller import ( "fmt" + "strings" ctx "golang.org/x/net/context" @@ -37,6 +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 { + if req.Force { + // Use the --force, Luke. + return s.performUpdateForce(req) + } return nil, err } @@ -137,6 +142,113 @@ func (s *ReleaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*rele return currentRelease, updatedRelease, err } +// performUpdateForce performs the same action as a `helm delete && helm install --replace`. +func (s *ReleaseServer) performUpdateForce(req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) { + // find the last release with the given name + oldRelease, err := s.env.Releases.Last(req.Name) + if err != nil { + return nil, err + } + + newRelease, err := s.prepareRelease(&services.InstallReleaseRequest{ + Chart: req.Chart, + Values: req.Values, + DryRun: req.DryRun, + Name: req.Name, + DisableHooks: req.DisableHooks, + Namespace: oldRelease.Namespace, + ReuseName: true, + Timeout: req.Timeout, + Wait: req.Wait, + }) + res := &services.UpdateReleaseResponse{Release: newRelease} + if err != nil { + s.Log("failed update prepare step: %s", err) + // On dry run, append the manifest contents to a failed release. This is + // a stop-gap until we can revisit an error backchannel post-2.0. + if req.DryRun && strings.HasPrefix(err.Error(), "YAML parse error") { + err = fmt.Errorf("%s\n%s", err, newRelease.Manifest) + } + return res, err + } + + // From here on out, the release is considered to be in Status_DELETING or Status_DELETED + // state. There is no turning back. + oldRelease.Info.Status.Code = release.Status_DELETING + oldRelease.Info.Deleted = timeconv.Now() + oldRelease.Info.Description = "Deletion in progress (or silently failed)" + s.recordRelease(oldRelease, true) + + // pre-delete hooks + if !req.DisableHooks { + if err := s.execHook(oldRelease.Hooks, oldRelease.Name, oldRelease.Namespace, hooks.PreDelete, req.Timeout); err != nil { + return res, err + } + } else { + s.Log("hooks disabled for %s", req.Name) + } + + // delete manifests from the old release + _, errs := s.ReleaseModule.Delete(oldRelease, nil, s.env) + + oldRelease.Info.Status.Code = release.Status_DELETED + oldRelease.Info.Description = "Deletion complete" + s.recordRelease(oldRelease, true) + + if len(errs) > 0 { + es := make([]string, 0, len(errs)) + for _, e := range errs { + s.Log("error: %v", e) + es = append(es, e.Error()) + } + return res, fmt.Errorf("Upgrade --force successfully deleted the previous release, but encountered %d error(s) and cannot continue: %s", len(es), strings.Join(es, "; ")) + } + + // post-delete hooks + if !req.DisableHooks { + if err := s.execHook(oldRelease.Hooks, oldRelease.Name, oldRelease.Namespace, hooks.PostDelete, req.Timeout); err != nil { + return res, err + } + } + + // pre-install hooks + if !req.DisableHooks { + if err := s.execHook(newRelease.Hooks, newRelease.Name, newRelease.Namespace, hooks.PreInstall, req.Timeout); err != nil { + return res, err + } + } + + // update new release with next revision number so as to append to the old release's history + newRelease.Version = oldRelease.Version + 1 + s.recordRelease(newRelease, false) + if err := s.ReleaseModule.Update(oldRelease, newRelease, req, s.env); err != nil { + msg := fmt.Sprintf("Upgrade %q failed: %s", newRelease.Name, err) + s.Log("warning: %s", msg) + newRelease.Info.Status.Code = release.Status_FAILED + newRelease.Info.Description = msg + s.recordRelease(newRelease, true) + return res, err + } + + // post-install hooks + if !req.DisableHooks { + if err := s.execHook(newRelease.Hooks, newRelease.Name, newRelease.Namespace, hooks.PostInstall, req.Timeout); err != nil { + msg := fmt.Sprintf("Release %q failed post-install: %s", newRelease.Name, err) + s.Log("warning: %s", msg) + newRelease.Info.Status.Code = release.Status_FAILED + newRelease.Info.Description = msg + s.recordRelease(newRelease, true) + return res, err + } + } + + newRelease.Info.Status.Code = release.Status_DEPLOYED + newRelease.Info.Description = "Upgrade complete" + s.recordRelease(newRelease, true) + + return res, nil +} + func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.Release, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) { res := &services.UpdateReleaseResponse{Release: updatedRelease} diff --git a/pkg/tiller/release_update_test.go b/pkg/tiller/release_update_test.go index 0f2bcbabd..642952f19 100644 --- a/pkg/tiller/release_update_test.go +++ b/pkg/tiller/release_update_test.go @@ -225,9 +225,9 @@ func TestUpdateReleaseFailure(t *testing.T) { compareStoredAndReturnedRelease(t, *rs, *res) - edesc := "Upgrade \"angry-panda\" failed: Failed update in kube client" - if got := res.Release.Info.Description; got != edesc { - t.Errorf("Expected description %q, got %q", edesc, got) + expectedDescription := "Upgrade \"angry-panda\" failed: Failed update in kube client" + if got := res.Release.Info.Description; got != expectedDescription { + t.Errorf("Expected description %q, got %q", expectedDescription, got) } oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version) @@ -239,6 +239,50 @@ func TestUpdateReleaseFailure(t *testing.T) { } } +func TestUpdateReleaseFailure_Force(t *testing.T) { + c := helm.NewContext() + rs := rsFixture() + rel := namedReleaseStub("forceful-luke", release.Status_FAILED) + rs.env.Releases.Create(rel) + rs.Log = t.Logf + + req := &services.UpdateReleaseRequest{ + Name: rel.Name, + DisableHooks: true, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{Name: "hello"}, + Templates: []*chart.Template{ + {Name: "templates/something", Data: []byte("text: 'Did you ever hear the tragedy of Darth Plagueis the Wise? I thought not. It’s not a story the Jedi would tell you. It’s a Sith legend. Darth Plagueis was a Dark Lord of the Sith, so powerful and so wise he could use the Force to influence the Midichlorians to create life... He had such a knowledge of the Dark Side that he could even keep the ones he cared about from dying. The Dark Side of the Force is a pathway to many abilities some consider to be unnatural. He became so powerful... The only thing he was afraid of was losing his power, which eventually, of course, he did. Unfortunately, he taught his apprentice everything he knew, then his apprentice killed him in his sleep. Ironic. He could save others from death, but not himself.'")}, + }, + }, + Force: true, + } + + res, err := rs.UpdateRelease(c, req) + if err != nil { + t.Errorf("Expected successful update, got %v", err) + } + + if updatedStatus := res.Release.Info.Status.Code; updatedStatus != release.Status_DEPLOYED { + t.Errorf("Expected DEPLOYED release. Got %d", updatedStatus) + } + + compareStoredAndReturnedRelease(t, *rs, *res) + + expectedDescription := "Upgrade complete" + if got := res.Release.Info.Description; got != expectedDescription { + t.Errorf("Expected description %q, got %q", expectedDescription, got) + } + + oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version) + if err != nil { + t.Errorf("Expected to be able to get previous release") + } + if oldStatus := oldRelease.Info.Status.Code; oldStatus != release.Status_DELETED { + t.Errorf("Expected Deleted status on previous Release version. Got %v", oldStatus) + } +} + func TestUpdateReleaseNoHooks(t *testing.T) { c := helm.NewContext() rs := rsFixture() From d01c5e0ee6171cf9207eb1acb613d2d5e55e046e Mon Sep 17 00:00:00 2001 From: Patrick Liu Date: Fri, 9 Mar 2018 10:21:13 +0800 Subject: [PATCH 078/221] Add helm-unittest in plugins --- docs/related.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/related.md b/docs/related.md index 6fbdf7df3..c14eb3880 100644 --- a/docs/related.md +++ b/docs/related.md @@ -42,6 +42,7 @@ or [pull request](https://github.com/kubernetes/helm/pulls). - [helm-monitor](https://github.com/ContainerSolutions/helm-monitor) - Plugin to monitor a release and rollback based on Prometheus/ElasticSearch query - [helm-k8comp](https://github.com/cststack/k8comp) - Plugin to create Helm Charts from hiera using k8comp - [helm-hashtag](https://github.com/balboah/helm-hashtag) - Plugin for tracking docker tag hash digests as values +- [helm-unittest](https://github.com/lrills/helm-unittest) - Plugin for unit testing chart locally with YAML We also encourage GitHub authors to use the [helm-plugin](https://github.com/search?q=topic%3Ahelm-plugin&type=Repositories) tag on their plugin repositories. From 92972b0353430344c7dc1b9f7abc152f08bdc4f2 Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Thu, 8 Mar 2018 18:22:32 -0800 Subject: [PATCH 079/221] fix typo in docs and fake --- docs/chart_tests.md | 2 +- pkg/helm/fake.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/chart_tests.md b/docs/chart_tests.md index 0d2ae3ee7..d1cfe5017 100644 --- a/docs/chart_tests.md +++ b/docs/chart_tests.md @@ -2,7 +2,7 @@ A chart contains a number of Kubernetes resources and components that work together. As a chart author, you may want to write some tests that validate that your chart works as expected when it is installed. These tests also help the chart consumer understand what your chart is supposed to do. -A **test** in a helm chart lives under the `templates/` directory and is a pod definition that specifies a container with a given command to run. The container should exit successfully (exit 0) for a test to be considered a success. The pod definition must contain one of the helm test hook annotations: `helm.sh/hooks: test-success` or `helm.sh/hooks: test-failure`. +A **test** in a helm chart lives under the `templates/` directory and is a pod definition that specifies a container with a given command to run. The container should exit successfully (exit 0) for a test to be considered a success. The pod definition must contain one of the helm test hook annotations: `helm.sh/hook: test-success` or `helm.sh/hook: test-failure`. Example tests: - Validate that your configuration from the values.yaml file was properly injected. diff --git a/pkg/helm/fake.go b/pkg/helm/fake.go index dbb488610..0a9e77c44 100644 --- a/pkg/helm/fake.go +++ b/pkg/helm/fake.go @@ -194,7 +194,7 @@ var MockHookTemplate = `apiVersion: v1 kind: Job metadata: annotations: - "helm.sh/hooks": pre-install + "helm.sh/hook": pre-install ` // MockManifest is the manifest used for all mock release objects. From 6cfaa4ebf27374789a421246bed3b85931e3055b Mon Sep 17 00:00:00 2001 From: scriptonist Date: Fri, 9 Mar 2018 18:30:01 +0530 Subject: [PATCH 080/221] Added code to recover from a tiller pod crash in an event of template render failure --- pkg/engine/engine.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 46e0a59cf..e83476eae 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -19,6 +19,7 @@ package engine import ( "bytes" "fmt" + "log" "path" "sort" "strings" @@ -204,6 +205,11 @@ func (e *Engine) render(tpls map[string]renderable) (map[string]string, error) { // The idea with this process is to make it possible for more complex templates // to share common blocks, but to make the entire thing feel like a file-based // template engine. + defer func() { + if err := recover(); err != nil { + log.Printf("rendering template failed: %v\n", err) + } + }() t := template.New("gotpl") if e.Strict { t.Option("missingkey=error") From 73017d7e88929b950bca4cc81638fa4deebcf44c Mon Sep 17 00:00:00 2001 From: Nic Doye Date: Fri, 9 Mar 2018 13:10:10 +0000 Subject: [PATCH 081/221] Accept .yml files as well as .yaml for templates. See https://github.com/helm/helm-classic/pull/306 for helm classic and https://kubernetes.slack.com/archives/C51E88VDG/p1520588964000061 --- pkg/lint/rules/template.go | 6 +++--- pkg/lint/rules/template_test.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 260259282..a8b6a6757 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -101,7 +101,7 @@ func Templates(linter *support.Linter, values []byte, namespace string, strict b linter.RunLinterRule(support.ErrorSev, path, validateAllowedExtension(fileName)) // We only apply the following lint rules to yaml files - if filepath.Ext(fileName) != ".yaml" { + if filepath.Ext(fileName) != ".yaml" || filepath.Ext(fileName) == ".yml" { continue } @@ -138,7 +138,7 @@ func validateTemplatesDir(templatesPath string) error { func validateAllowedExtension(fileName string) error { ext := filepath.Ext(fileName) - validExtensions := []string{".yaml", ".tpl", ".txt"} + validExtensions := []string{".yaml", ".yml", ".tpl", ".txt"} for _, b := range validExtensions { if b == ext { @@ -146,7 +146,7 @@ func validateAllowedExtension(fileName string) error { } } - return fmt.Errorf("file extension '%s' not valid. Valid extensions are .yaml, .tpl, or .txt", ext) + return fmt.Errorf("file extension '%s' not valid. Valid extensions are .yaml, .yml, .tpl, or .txt", ext) } func validateYamlContent(err error) error { diff --git a/pkg/lint/rules/template_test.go b/pkg/lint/rules/template_test.go index 080064698..cb1be94a2 100644 --- a/pkg/lint/rules/template_test.go +++ b/pkg/lint/rules/template_test.go @@ -28,11 +28,11 @@ import ( const templateTestBasedir = "./testdata/albatross" func TestValidateAllowedExtension(t *testing.T) { - var failTest = []string{"/foo", "/test.yml", "/test.toml", "test.yml"} + var failTest = []string{"/foo", "/test.toml"} for _, test := range failTest { err := validateAllowedExtension(test) - if err == nil || !strings.Contains(err.Error(), "Valid extensions are .yaml, .tpl, or .txt") { - t.Errorf("validateAllowedExtension('%s') to return \"Valid extensions are .yaml, .tpl, or .txt\", got no error", test) + if err == nil || !strings.Contains(err.Error(), "Valid extensions are .yaml, .yml, .tpl, or .txt") { + t.Errorf("validateAllowedExtension('%s') to return \"Valid extensions are .yaml, .yml, .tpl, or .txt\", got no error", test) } } var successTest = []string{"/foo.yaml", "foo.yaml", "foo.tpl", "/foo/bar/baz.yaml", "NOTES.txt"} From 23948f5fd084427dd5b33f1ec663a4bb0068478e Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Fri, 9 Mar 2018 12:44:06 -0800 Subject: [PATCH 082/221] bump version to v2.8.1 (cherry picked from commit a80231648a1473929271764b920a8e346f6de844) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 01927aff3..7622fafc8 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,10 @@ Think of it like apt/yum/homebrew for Kubernetes. Binary downloads of the Helm client can be found at the following links: -- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.1-darwin-amd64.tar.gz) -- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.1-linux-amd64.tar.gz) -- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.1-linux-386.tar.gz) -- [Windows](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.1-windows-amd64.tar.gz) +- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.2-darwin-amd64.tar.gz) +- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.2-linux-amd64.tar.gz) +- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.2-linux-386.tar.gz) +- [Windows](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.2-windows-amd64.tar.gz) Unpack the `helm` binary and add it to your PATH and you are good to go! macOS/[homebrew](https://brew.sh/) users can also use `brew install kubernetes-helm`. From 46ed8027508a8ff0df9604d0ca8f0449c1d973e1 Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Fri, 9 Mar 2018 16:56:45 -0800 Subject: [PATCH 083/221] add support for output format in json or yaml --- cmd/helm/history.go | 75 ++++++++++++++++++++++++++++++++------- cmd/helm/history_test.go | 20 +++++++++++ docs/helm/helm_history.md | 3 +- 3 files changed, 84 insertions(+), 14 deletions(-) diff --git a/cmd/helm/history.go b/cmd/helm/history.go index 659c39e81..944d61509 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -23,12 +23,24 @@ import ( "github.com/gosuri/uitable" "github.com/spf13/cobra" + "encoding/json" + "github.com/ghodss/yaml" "k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/timeconv" ) +type releaseInfo struct { + Revision int32 `json:"revision" yaml:"revision"` + Updated string `json:"updated" yaml:"updated"` + Status string `json:"status" yaml:"status"` + Chart string `json:"chart" yaml:"chart"` + Description string `json:"description" yaml:"description"` +} + +type releaseHistory []releaseInfo + var historyHelp = ` History prints historical revisions for a given release. @@ -46,11 +58,12 @@ The historical release set is printed as a formatted table, e.g: ` type historyCmd struct { - max int32 - rls string - out io.Writer - helmc helm.Interface - colWidth uint + max int32 + rls string + out io.Writer + helmc helm.Interface + colWidth uint + outputFormat string } func newHistoryCmd(c helm.Interface, w io.Writer) *cobra.Command { @@ -77,6 +90,7 @@ func newHistoryCmd(c helm.Interface, w io.Writer) *cobra.Command { f := cmd.Flags() f.Int32Var(&his.max, "max", 256, "maximum number of revision to include in history") f.UintVar(&his.colWidth, "col-width", 60, "specifies the max column width of output") + f.StringVarP(&his.outputFormat, "output", "o", "", "prints the output in the specified format ('json' or 'yaml' or defaults to 'table')") return cmd } @@ -90,15 +104,29 @@ func (cmd *historyCmd) run() error { return nil } - fmt.Fprintln(cmd.out, formatHistory(r.Releases, cmd.colWidth)) + releaseHistory := getReleaseHistory(r.Releases) + + var history []byte + var formattingError error + + switch cmd.outputFormat { + case "yaml": + history, formattingError = yaml.Marshal(releaseHistory) + case "json": + history, formattingError = json.Marshal(releaseHistory) + default: + history = formatAsTable(releaseHistory, cmd.colWidth) + } + + if formattingError != nil { + return prettyError(formattingError) + } + + fmt.Fprintln(cmd.out, string(history)) return nil } -func formatHistory(rls []*release.Release, colWidth uint) string { - tbl := uitable.New() - - tbl.MaxColWidth = colWidth - tbl.AddRow("REVISION", "UPDATED", "STATUS", "CHART", "DESCRIPTION") +func getReleaseHistory(rls []*release.Release) (history releaseHistory) { for i := len(rls) - 1; i >= 0; i-- { r := rls[i] c := formatChartname(r.Chart) @@ -106,9 +134,30 @@ func formatHistory(rls []*release.Release, colWidth uint) string { s := r.Info.Status.Code.String() v := r.Version d := r.Info.Description - tbl.AddRow(v, t, s, c, d) + + rInfo := releaseInfo{ + Revision: v, + Updated: t, + Status: s, + Chart: c, + Description: d, + } + history = append(history, rInfo) + } + + return history +} + +func formatAsTable(releases releaseHistory, colWidth uint) []byte { + tbl := uitable.New() + + tbl.MaxColWidth = colWidth + tbl.AddRow("REVISION", "UPDATED", "STATUS", "CHART", "DESCRIPTION") + for i := 0; i <= len(releases)-1; i++ { + r := releases[i] + tbl.AddRow(r.Revision, r.Updated, r.Status, r.Chart, r.Description) } - return tbl.String() + return tbl.Bytes() } func formatChartname(c *chart.Chart) string { diff --git a/cmd/helm/history_test.go b/cmd/helm/history_test.go index f193f6314..7594da964 100644 --- a/cmd/helm/history_test.go +++ b/cmd/helm/history_test.go @@ -63,6 +63,26 @@ func TestHistoryCmd(t *testing.T) { }, xout: "REVISION\tUPDATED \tSTATUS \tCHART \tDESCRIPTION \n3 \t(.*)\tSUPERSEDED\tfoo-0.1.0-beta.1\tRelease mock\n4 \t(.*)\tDEPLOYED \tfoo-0.1.0-beta.1\tRelease mock\n", }, + { + cmds: "helm history --max=MAX RELEASE_NAME -o yaml", + desc: "get history with yaml output format", + args: []string{"--max=2", "-o=yaml", "angry-bird"}, + resp: []*rpb.Release{ + mk("angry-bird", 4, rpb.Status_DEPLOYED), + mk("angry-bird", 3, rpb.Status_SUPERSEDED), + }, + xout: "- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 3\n status: SUPERSEDED\n updated: (.*)\n- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 4\n status: DEPLOYED\n updated: (.*)\n\n", + }, + { + cmds: "helm history --max=MAX RELEASE_NAME -o json", + desc: "get history with json output format", + args: []string{"--max=2", "-o=json", "angry-bird"}, + resp: []*rpb.Release{ + mk("angry-bird", 4, rpb.Status_DEPLOYED), + mk("angry-bird", 3, rpb.Status_SUPERSEDED), + }, + xout: `[{"revision":3,"updated":".*","status":"SUPERSEDED","chart":"foo\-0.1.0-beta.1","description":"Release mock"},{"revision":4,"updated":".*","status":"DEPLOYED","chart":"foo\-0.1.0-beta.1","description":"Release mock"}]\n`, + }, } var buf bytes.Buffer diff --git a/docs/helm/helm_history.md b/docs/helm/helm_history.md index 81c720021..422c5f4e1 100755 --- a/docs/helm/helm_history.md +++ b/docs/helm/helm_history.md @@ -30,6 +30,7 @@ helm history [flags] RELEASE_NAME ``` --col-width uint specifies the max column width of output (default 60) --max int32 maximum number of revision to include in history (default 256) + -o, --output string prints the output in the specified format ('json' or 'yaml' or defaults to 'table') --tls enable TLS for request --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") @@ -51,4 +52,4 @@ helm history [flags] RELEASE_NAME ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 9-Mar-2018 From cdd9a85676edc2f126486ff7ccb5b14093744857 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Fri, 9 Mar 2018 15:47:34 -0500 Subject: [PATCH 084/221] fix(helm): remove duplicate code from cmd/helm/history_test.go. Closes #3649 Signed-off-by: Arash Deshmeh --- cmd/helm/history_test.go | 48 +++++++++++++--------------------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/cmd/helm/history_test.go b/cmd/helm/history_test.go index f193f6314..6e46d24d4 100644 --- a/cmd/helm/history_test.go +++ b/cmd/helm/history_test.go @@ -17,10 +17,11 @@ limitations under the License. package main import ( - "bytes" - "regexp" + "io" "testing" + "github.com/spf13/cobra" + "k8s.io/helm/pkg/helm" rpb "k8s.io/helm/pkg/proto/hapi/release" ) @@ -34,50 +35,31 @@ func TestHistoryCmd(t *testing.T) { }) } - tests := []struct { - cmds string - desc string - args []string - resp []*rpb.Release - xout string - }{ + tests := []releaseCase{ { - cmds: "helm history RELEASE_NAME", - desc: "get history for release", + name: "get history for release", args: []string{"angry-bird"}, - resp: []*rpb.Release{ + rels: []*rpb.Release{ mk("angry-bird", 4, rpb.Status_DEPLOYED), mk("angry-bird", 3, rpb.Status_SUPERSEDED), mk("angry-bird", 2, rpb.Status_SUPERSEDED), mk("angry-bird", 1, rpb.Status_SUPERSEDED), }, - xout: "REVISION\tUPDATED \tSTATUS \tCHART \tDESCRIPTION \n1 \t(.*)\tSUPERSEDED\tfoo-0.1.0-beta.1\tRelease mock\n2 \t(.*)\tSUPERSEDED\tfoo-0.1.0-beta.1\tRelease mock\n3 \t(.*)\tSUPERSEDED\tfoo-0.1.0-beta.1\tRelease mock\n4 \t(.*)\tDEPLOYED \tfoo-0.1.0-beta.1\tRelease mock\n", + expected: "REVISION\tUPDATED \tSTATUS \tCHART \tDESCRIPTION \n1 \t(.*)\tSUPERSEDED\tfoo-0.1.0-beta.1\tRelease mock\n2 \t(.*)\tSUPERSEDED\tfoo-0.1.0-beta.1\tRelease mock\n3 \t(.*)\tSUPERSEDED\tfoo-0.1.0-beta.1\tRelease mock\n4 \t(.*)\tDEPLOYED \tfoo-0.1.0-beta.1\tRelease mock\n", }, { - cmds: "helm history --max=MAX RELEASE_NAME", - desc: "get history with max limit set", - args: []string{"--max=2", "angry-bird"}, - resp: []*rpb.Release{ + name: "get history with max limit set", + args: []string{"angry-bird"}, + flags: []string{"--max", "2"}, + rels: []*rpb.Release{ mk("angry-bird", 4, rpb.Status_DEPLOYED), mk("angry-bird", 3, rpb.Status_SUPERSEDED), }, - xout: "REVISION\tUPDATED \tSTATUS \tCHART \tDESCRIPTION \n3 \t(.*)\tSUPERSEDED\tfoo-0.1.0-beta.1\tRelease mock\n4 \t(.*)\tDEPLOYED \tfoo-0.1.0-beta.1\tRelease mock\n", + expected: "REVISION\tUPDATED \tSTATUS \tCHART \tDESCRIPTION \n3 \t(.*)\tSUPERSEDED\tfoo-0.1.0-beta.1\tRelease mock\n4 \t(.*)\tDEPLOYED \tfoo-0.1.0-beta.1\tRelease mock\n", }, } - var buf bytes.Buffer - for _, tt := range tests { - frc := &helm.FakeClient{Rels: tt.resp} - cmd := newHistoryCmd(frc, &buf) - cmd.ParseFlags(tt.args) - - if err := cmd.RunE(cmd, tt.args); err != nil { - t.Fatalf("%q\n\t%s: unexpected error: %v", tt.cmds, tt.desc, err) - } - re := regexp.MustCompile(tt.xout) - if !re.Match(buf.Bytes()) { - t.Fatalf("%q\n\t%s:\nexpected\n\t%q\nactual\n\t%q", tt.cmds, tt.desc, tt.xout, buf.String()) - } - buf.Reset() - } + runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { + return newHistoryCmd(c, out) + }) } From c93ff32f5203c14fb0eed3afcbf4689f8f9d9a20 Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Mon, 12 Mar 2018 11:47:18 -0700 Subject: [PATCH 085/221] make table explicitly default --- cmd/helm/history.go | 6 ++++-- docs/helm/helm_history.md | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cmd/helm/history.go b/cmd/helm/history.go index 944d61509..573459f91 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -90,7 +90,7 @@ func newHistoryCmd(c helm.Interface, w io.Writer) *cobra.Command { f := cmd.Flags() f.Int32Var(&his.max, "max", 256, "maximum number of revision to include in history") f.UintVar(&his.colWidth, "col-width", 60, "specifies the max column width of output") - f.StringVarP(&his.outputFormat, "output", "o", "", "prints the output in the specified format ('json' or 'yaml' or defaults to 'table')") + f.StringVarP(&his.outputFormat, "output", "o", "table", "prints the output in the specified format ('json' or 'yaml' or defaults to 'table')") return cmd } @@ -114,8 +114,10 @@ func (cmd *historyCmd) run() error { history, formattingError = yaml.Marshal(releaseHistory) case "json": history, formattingError = json.Marshal(releaseHistory) - default: + case "table": history = formatAsTable(releaseHistory, cmd.colWidth) + default: + return fmt.Errorf("unknown output format %q", cmd.outputFormat) } if formattingError != nil { diff --git a/docs/helm/helm_history.md b/docs/helm/helm_history.md index 422c5f4e1..a4ef50b80 100755 --- a/docs/helm/helm_history.md +++ b/docs/helm/helm_history.md @@ -30,7 +30,7 @@ helm history [flags] RELEASE_NAME ``` --col-width uint specifies the max column width of output (default 60) --max int32 maximum number of revision to include in history (default 256) - -o, --output string prints the output in the specified format ('json' or 'yaml' or defaults to 'table') + -o, --output string prints the output in the specified format ('json' or 'yaml' or defaults to 'table') (default "table") --tls enable TLS for request --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") @@ -52,4 +52,4 @@ helm history [flags] RELEASE_NAME ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 9-Mar-2018 +###### Auto generated by spf13/cobra on 12-Mar-2018 From e25df2ae76e3c772ee6ae86e2eaf5be3be72cca9 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Mon, 12 Mar 2018 15:02:53 -0400 Subject: [PATCH 086/221] fix(helm) refactor helm status command tests to use releaseCase struct and the corresponding function runReleaseCases. Fixes #3659 Signed-off-by: Arash Deshmeh --- cmd/helm/status_test.go | 135 +++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 77 deletions(-) diff --git a/cmd/helm/status_test.go b/cmd/helm/status_test.go index 9de50b217..616b027f3 100644 --- a/cmd/helm/status_test.go +++ b/cmd/helm/status_test.go @@ -17,10 +17,8 @@ limitations under the License. package main import ( - "bytes" "fmt" "io" - "strings" "testing" "github.com/golang/protobuf/ptypes/timestamp" @@ -36,120 +34,103 @@ var ( dateString = timeconv.String(&date) ) -// statusCase describes a test case dealing with the status of a release -type statusCase struct { - name string - args []string - flags []string - expected string - err bool - rel *release.Release -} - func TestStatusCmd(t *testing.T) { - tests := []statusCase{ + tests := []releaseCase{ { name: "get status of a deployed release", args: []string{"flummoxed-chickadee"}, expected: outputWithStatus("DEPLOYED\n\n"), - rel: releaseMockWithStatus(&release.Status{ - Code: release.Status_DEPLOYED, - }), + rels: []*release.Release{ + releaseMockWithStatus(&release.Status{ + Code: release.Status_DEPLOYED, + }), + }, }, { name: "get status of a deployed release with notes", args: []string{"flummoxed-chickadee"}, expected: outputWithStatus("DEPLOYED\n\nNOTES:\nrelease notes\n"), - rel: releaseMockWithStatus(&release.Status{ - Code: release.Status_DEPLOYED, - Notes: "release notes", - }), + rels: []*release.Release{ + releaseMockWithStatus(&release.Status{ + Code: release.Status_DEPLOYED, + Notes: "release notes", + }), + }, }, { name: "get status of a deployed release with notes in json", args: []string{"flummoxed-chickadee"}, flags: []string{"-o", "json"}, expected: `{"name":"flummoxed-chickadee","info":{"status":{"code":1,"notes":"release notes"},"first_deployed":{"seconds":242085845},"last_deployed":{"seconds":242085845}}}`, - rel: releaseMockWithStatus(&release.Status{ - Code: release.Status_DEPLOYED, - Notes: "release notes", - }), + rels: []*release.Release{ + releaseMockWithStatus(&release.Status{ + Code: release.Status_DEPLOYED, + Notes: "release notes", + }), + }, }, { name: "get status of a deployed release with resources", args: []string{"flummoxed-chickadee"}, expected: outputWithStatus("DEPLOYED\n\nRESOURCES:\nresource A\nresource B\n\n"), - rel: releaseMockWithStatus(&release.Status{ - Code: release.Status_DEPLOYED, - Resources: "resource A\nresource B\n", - }), + rels: []*release.Release{ + releaseMockWithStatus(&release.Status{ + Code: release.Status_DEPLOYED, + Resources: "resource A\nresource B\n", + }), + }, }, { name: "get status of a deployed release with resources in YAML", args: []string{"flummoxed-chickadee"}, flags: []string{"-o", "yaml"}, - expected: "info:\nfirst_deployed:\nseconds:242085845\nlast_deployed:\nseconds:242085845\nstatus:\ncode:1\nresources:|\nresourceA\nresourceB\nname:flummoxed-chickadee\n", - rel: releaseMockWithStatus(&release.Status{ - Code: release.Status_DEPLOYED, - Resources: "resource A\nresource B\n", - }), + expected: "info:\n (.*)first_deployed:\n (.*)seconds: 242085845\n (.*)last_deployed:\n (.*)seconds: 242085845\n (.*)status:\n code: 1\n (.*)resources: |\n (.*)resource A\n (.*)resource B\nname: flummoxed-chickadee\n", + rels: []*release.Release{ + releaseMockWithStatus(&release.Status{ + Code: release.Status_DEPLOYED, + Resources: "resource A\nresource B\n", + }), + }, }, { name: "get status of a deployed release with test suite", args: []string{"flummoxed-chickadee"}, expected: outputWithStatus( fmt.Sprintf("DEPLOYED\n\nTEST SUITE:\nLast Started: %s\nLast Completed: %s\n\n", dateString, dateString) + - "TEST \tSTATUS \tINFO \tSTARTED \tCOMPLETED \n" + - fmt.Sprintf("test run 1\tSUCCESS \textra info\t%s\t%s\n", dateString, dateString) + - fmt.Sprintf("test run 2\tFAILURE \t \t%s\t%s\n", dateString, dateString)), - rel: releaseMockWithStatus(&release.Status{ - Code: release.Status_DEPLOYED, - LastTestSuiteRun: &release.TestSuite{ - StartedAt: &date, - CompletedAt: &date, - Results: []*release.TestRun{ - { - Name: "test run 1", - Status: release.TestRun_SUCCESS, - Info: "extra info", - StartedAt: &date, - CompletedAt: &date, - }, - { - Name: "test run 2", - Status: release.TestRun_FAILURE, - StartedAt: &date, - CompletedAt: &date, + "TEST \tSTATUS (.*)\tINFO (.*)\tSTARTED (.*)\tCOMPLETED (.*)\n" + + fmt.Sprintf("test run 1\tSUCCESS (.*)\textra info\t%s\t%s\n", dateString, dateString) + + fmt.Sprintf("test run 2\tFAILURE (.*)\t (.*)\t%s\t%s\n", dateString, dateString)), + rels: []*release.Release{ + releaseMockWithStatus(&release.Status{ + Code: release.Status_DEPLOYED, + LastTestSuiteRun: &release.TestSuite{ + StartedAt: &date, + CompletedAt: &date, + Results: []*release.TestRun{ + { + Name: "test run 1", + Status: release.TestRun_SUCCESS, + Info: "extra info", + StartedAt: &date, + CompletedAt: &date, + }, + { + Name: "test run 2", + Status: release.TestRun_FAILURE, + StartedAt: &date, + CompletedAt: &date, + }, }, }, - }, - }), + }), + }, }, } - scmd := func(c *helm.FakeClient, out io.Writer) *cobra.Command { + runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { return newStatusCmd(c, out) - } - - var buf bytes.Buffer - for _, tt := range tests { - c := &helm.FakeClient{ - Rels: []*release.Release{tt.rel}, - } - cmd := scmd(c, &buf) - cmd.ParseFlags(tt.flags) - err := cmd.RunE(cmd, tt.args) - if (err != nil) != tt.err { - t.Errorf("%q. expected error, got '%v'", tt.name, err) - } + }) - expected := strings.Replace(tt.expected, " ", "", -1) - got := strings.Replace(buf.String(), " ", "", -1) - if expected != got { - t.Errorf("%q. expected\n%q\ngot\n%q", tt.name, expected, got) - } - buf.Reset() - } } func outputWithStatus(status string) string { From 3014b9277f0be853593820d7eefe0f063f6852a3 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Mon, 12 Mar 2018 12:16:31 -0700 Subject: [PATCH 087/221] add back the default 5 second connection timeout When Helm v2.8.2 was released, we made a change to the default connection timeout by supplying a value passed from pkg/helm/environment. This broke support for third party clients relying on pkg/helm because now the default connection timeout is zero. Adding a default 5 second timeout back retains old behaviour, while not breaking backwards compatibility because the connection timeout can still be configured. --- pkg/helm/client.go | 2 ++ pkg/helm/client_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 pkg/helm/client_test.go diff --git a/pkg/helm/client.go b/pkg/helm/client.go index 372613b2a..2fb1e54e4 100644 --- a/pkg/helm/client.go +++ b/pkg/helm/client.go @@ -44,6 +44,8 @@ type Client struct { // NewClient creates a new client. func NewClient(opts ...Option) *Client { var c Client + // set some sane defaults + c.Option(ConnectTimeout(5)) return c.Option(opts...) } diff --git a/pkg/helm/client_test.go b/pkg/helm/client_test.go new file mode 100644 index 000000000..95e044499 --- /dev/null +++ b/pkg/helm/client_test.go @@ -0,0 +1,34 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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. +*/ + +package helm + +import ( + "testing" + "time" +) + +func TestNewClient(t *testing.T) { + helmClient := NewClient() + if helmClient.opts.connectTimeout != 5*time.Second { + t.Errorf("expected default timeout duration to be 5 seconds, got %v", helmClient.opts.connectTimeout) + } + + helmClient = NewClient(ConnectTimeout(60)) + if helmClient.opts.connectTimeout != time.Minute { + t.Errorf("expected timeout duration to be 1 minute, got %v", helmClient.opts.connectTimeout) + } +} From 5311bf40a8bc243d29e705b46201b760b35c6e5c Mon Sep 17 00:00:00 2001 From: scriptonist Date: Tue, 13 Mar 2018 16:33:10 +0530 Subject: [PATCH 088/221] Now returning error and stopping installation --- pkg/engine/engine.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index e83476eae..7a940fc84 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -19,7 +19,6 @@ package engine import ( "bytes" "fmt" - "log" "path" "sort" "strings" @@ -197,7 +196,7 @@ func (e *Engine) alterFuncMap(t *template.Template) template.FuncMap { } // render takes a map of templates/values and renders them. -func (e *Engine) render(tpls map[string]renderable) (map[string]string, error) { +func (e *Engine) render(tpls map[string]renderable) (rendered map[string]string, err error) { // Basically, what we do here is start with an empty parent template and then // build up a list of templates -- one for each file. Once all of the templates // have been parsed, we loop through again and execute every template. @@ -206,8 +205,8 @@ func (e *Engine) render(tpls map[string]renderable) (map[string]string, error) { // to share common blocks, but to make the entire thing feel like a file-based // template engine. defer func() { - if err := recover(); err != nil { - log.Printf("rendering template failed: %v\n", err) + if r := recover(); r != nil { + err = fmt.Errorf("rendering template failed: %v", r) } }() t := template.New("gotpl") @@ -247,7 +246,7 @@ func (e *Engine) render(tpls map[string]renderable) (map[string]string, error) { } } - rendered := make(map[string]string, len(files)) + rendered = make(map[string]string, len(files)) var buf bytes.Buffer for _, file := range files { // Don't render partials. We don't care out the direct output of partials. From 0935384bd57e3b8dc2bd7383fcd56af6515a1d91 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 13 Mar 2018 09:52:49 -0700 Subject: [PATCH 089/221] remove "This Repository" link from releases page --- scripts/get | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/get b/scripts/get index 79e9f3520..1c1e617e8 100755 --- a/scripts/get +++ b/scripts/get @@ -78,7 +78,7 @@ checkDesiredVersion() { # Use the GitHub releases webpage for the project to find the desired version for this project. local release_url="https://github.com/kubernetes/helm/releases/${DESIRED_VERSION:-latest}" if type "curl" > /dev/null; then - TAG=$(curl -SsL $release_url | awk '/\/tag\//' | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}' | awk 'a !~ $0{print}; {a=$0}') + TAG=$(curl -SsL $release_url | awk '/\/tag\//' | grep -v no-underline | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}' | awk 'a !~ $0{print}; {a=$0}') elif type "wget" > /dev/null; then TAG=$(wget -q -O - $release_url | awk '/\/tag\//' | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}' | awk 'a !~ $0{print}; {a=$0}') fi From 4f3832488b86e0b1249af8a375684ebbeac93bcf Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Tue, 13 Mar 2018 11:22:45 -0700 Subject: [PATCH 090/221] docs(OWNERS): add emeritus section (#3667) Cleaned up the owners file, adding the emeritus section and removing an account that was not a core maintainer. --- OWNERS | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/OWNERS b/OWNERS index 87f2d8f3a..32b26efa2 100644 --- a/OWNERS +++ b/OWNERS @@ -4,14 +4,11 @@ maintainers: - jascott1 - mattfarina - michelleN - - migmartri - nebril - prydonius - - seh - SlickNik - technosophos - thomastaylor312 - - vaikas-google - viglesiasce reviewers: - adamreese @@ -23,10 +20,11 @@ reviewers: - migmartri - nebril - prydonius - - sebgoa - - seh - SlickNik - technosophos - thomastaylor312 - - vaikas-google - viglesiasce +emeritus: + - migmartri + - seh + - vaikas-google From 23b570fabdb2907a6cc2887a4885cc9086cc7ad3 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Tue, 13 Mar 2018 21:10:59 -0400 Subject: [PATCH 091/221] fix(helm): refactor helm version command tests to remove duplication Signed-off-by: Arash Deshmeh --- cmd/helm/version_test.go | 72 ++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/cmd/helm/version_test.go b/cmd/helm/version_test.go index dbc40f401..e25724f4c 100644 --- a/cmd/helm/version_test.go +++ b/cmd/helm/version_test.go @@ -16,50 +16,50 @@ limitations under the License. package main import ( - "bytes" - "strings" + "fmt" + "io" + "regexp" "testing" + "github.com/spf13/cobra" + "k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/version" ) func TestVersion(t *testing.T) { + lver := regexp.QuoteMeta(version.GetVersionProto().SemVer) + sver := regexp.QuoteMeta("1.2.3-fakeclient+testonly") + clientVersion := fmt.Sprintf("Client: &version\\.Version{SemVer:\"%s\", GitCommit:\"\", GitTreeState:\"\"}\n", lver) + serverVersion := fmt.Sprintf("Server: &version\\.Version{SemVer:\"%s\", GitCommit:\"\", GitTreeState:\"\"}\n", sver) - lver := version.GetVersionProto().SemVer - sver := "1.2.3-fakeclient+testonly" - - tests := []struct { - name string - client, server bool - args []string - fail bool - }{ - {"default", true, true, []string{}, false}, - {"client", true, false, []string{"-c"}, false}, - {"server", false, true, []string{"-s"}, false}, - {"template", true, true, []string{"--template='{{ .Client.SemVer }} {{ .Server.SemVer }}'"}, false}, + tests := []releaseCase{ + { + name: "default", + args: []string{}, + expected: clientVersion + serverVersion, + }, + { + name: "client", + args: []string{}, + flags: []string{"-c"}, + expected: clientVersion, + }, + { + name: "server", + args: []string{}, + flags: []string{"-s"}, + expected: serverVersion, + }, + { + name: "template", + args: []string{}, + flags: []string{"--template", "{{ .Client.SemVer }} {{ .Server.SemVer }}"}, + expected: lver + " " + sver, + }, } - settings.TillerHost = "fake-localhost" - for _, tt := range tests { - b := new(bytes.Buffer) - c := &helm.FakeClient{} - - cmd := newVersionCmd(c, b) - cmd.ParseFlags(tt.args) - if err := cmd.RunE(cmd, tt.args); err != nil { - if tt.fail { - continue - } - t.Fatal(err) - } - - if tt.client && !strings.Contains(b.String(), lver) { - t.Errorf("Expected %q to contain %q", b.String(), lver) - } - if tt.server && !strings.Contains(b.String(), sver) { - t.Errorf("Expected %q to contain %q", b.String(), sver) - } - } + runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { + return newVersionCmd(c, out) + }) } From bb932f77022b55d3090506cb0a02d4431c52eaf2 Mon Sep 17 00:00:00 2001 From: Stuart Leeks Date: Wed, 14 Mar 2018 16:37:59 +0100 Subject: [PATCH 092/221] Fix link to github issues --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6247f7b21..34b4f8b16 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,7 +30,7 @@ apply to [third_party](third_party/) and [vendor](vendor/). Whether you are a user or contributor, official support channels include: -- GitHub [issues](https://github.com/kubenetes/helm/issues/new) +- GitHub [issues](https://github.com/kubernetes/helm/issues/new) - Slack: #Helm room in the [Kubernetes Slack](http://slack.kubernetes.io/) Before opening a new issue or submitting a new pull request, it's helpful to search the project - it's likely that another user has already reported the issue you're facing, or it's a known issue that we're already aware of. From 421499708f7353c7054ccb87516ea878f7756979 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Wed, 14 Mar 2018 08:49:16 -0700 Subject: [PATCH 093/221] add newline after header Doesn't cahnge the rendered markdown, but it makes the styling consistent with the rest of the docs. --- docs/securing_installation.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/securing_installation.md b/docs/securing_installation.md index 2233620af..ffce5df75 100644 --- a/docs/securing_installation.md +++ b/docs/securing_installation.md @@ -41,6 +41,7 @@ Helm and Tiller are designed to install, remove, and modify logical applications Specific users and teams -- developers, operators, system and network administrators -- will need their own portion of the cluster in which they can use Helm and Tiller without risking other portions of the cluster. This means using a Kubernetes cluster with RBAC enabled and Tiller configured to enforce them. For more information about using RBAC in Kubernetes, see [Using RBAC Authorization](rbac.md). #### Tiller and User Permissions + Tiller in its current form does not provide a way to map user credentials to specific permissions within Kubernetes. When Tiller is running inside of the cluster, it operates with the permissions of its service account. If no service account name is supplied to Tiller, it runs with the default service account for that namespace. This means that all Tiller operations on that server are executed using the Tiller pod's credentials and permissions. To properly limit what Tiller itself can do, the standard Kubernetes RBAC mechanisms must be attached to Tiller, including Roles and RoleBindings that place explicit limits on what things a Tiller instance can install, and where. From 3625241025783f0b5c48b64e382780f74f7c4148 Mon Sep 17 00:00:00 2001 From: Florian Zysset Date: Wed, 14 Mar 2018 18:00:39 +0000 Subject: [PATCH 094/221] feat(helm): inspect readme --- cmd/helm/inspect.go | 107 +++++++++++++++++++++++-------- cmd/helm/inspect_test.go | 13 ++-- docs/helm/helm.md | 2 +- docs/helm/helm_inspect.md | 3 +- docs/helm/helm_inspect_readme.md | 43 +++++++++++++ 5 files changed, 133 insertions(+), 35 deletions(-) create mode 100644 docs/helm/helm_inspect_readme.md diff --git a/cmd/helm/inspect.go b/cmd/helm/inspect.go index 6369b5ddc..736f14fce 100644 --- a/cmd/helm/inspect.go +++ b/cmd/helm/inspect.go @@ -19,11 +19,14 @@ package main import ( "fmt" "io" + "strings" "github.com/ghodss/yaml" + "github.com/golang/protobuf/ptypes/any" "github.com/spf13/cobra" "k8s.io/helm/pkg/chartutil" + "k8s.io/kubernetes/pkg/util/slice" ) const inspectDesc = ` @@ -43,6 +46,11 @@ This command inspects a chart (directory, file, or URL) and displays the content of the Charts.yaml file ` +const readmeChartDesc = ` +This command inspects a chart (directory, file, or URL) and displays the contents +of the README file +` + type inspectCmd struct { chartpath string output string @@ -60,13 +68,16 @@ type inspectCmd struct { const ( chartOnly = "chart" valuesOnly = "values" - both = "both" + readmeOnly = "readme" + all = "all" ) +var readmeFileNames = []string{"readme.md", "readme.txt", "readme"} + func newInspectCmd(out io.Writer) *cobra.Command { insp := &inspectCmd{ out: out, - output: both, + output: all, } inspectCommand := &cobra.Command{ @@ -125,51 +136,72 @@ func newInspectCmd(out io.Writer) *cobra.Command { }, } + readmeSubCmd := &cobra.Command{ + Use: "readme [CHART]", + Short: "shows inspect readme", + Long: readmeChartDesc, + RunE: func(cmd *cobra.Command, args []string) error { + insp.output = readmeOnly + if err := checkArgsLength(len(args), "chart name"); err != nil { + return err + } + cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring, + insp.certFile, insp.keyFile, insp.caFile) + if err != nil { + return err + } + insp.chartpath = cp + return insp.run() + }, + } + + cmds := []*cobra.Command{inspectCommand, readmeSubCmd, valuesSubCmd, chartSubCmd} vflag := "verify" vdesc := "verify the provenance data for this chart" - inspectCommand.Flags().BoolVar(&insp.verify, vflag, false, vdesc) - valuesSubCmd.Flags().BoolVar(&insp.verify, vflag, false, vdesc) - chartSubCmd.Flags().BoolVar(&insp.verify, vflag, false, vdesc) + for _, subCmd := range cmds { + subCmd.Flags().BoolVar(&insp.verify, vflag, false, vdesc) + } kflag := "keyring" kdesc := "path to the keyring containing public verification keys" kdefault := defaultKeyring() - inspectCommand.Flags().StringVar(&insp.keyring, kflag, kdefault, kdesc) - valuesSubCmd.Flags().StringVar(&insp.keyring, kflag, kdefault, kdesc) - chartSubCmd.Flags().StringVar(&insp.keyring, kflag, kdefault, kdesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.keyring, kflag, kdefault, kdesc) + } verflag := "version" verdesc := "version of the chart. By default, the newest chart is shown" - inspectCommand.Flags().StringVar(&insp.version, verflag, "", verdesc) - valuesSubCmd.Flags().StringVar(&insp.version, verflag, "", verdesc) - chartSubCmd.Flags().StringVar(&insp.version, verflag, "", verdesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.version, verflag, "", verdesc) + } repoURL := "repo" repoURLdesc := "chart repository url where to locate the requested chart" - inspectCommand.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc) - valuesSubCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc) - chartSubCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc) + } certFile := "cert-file" certFiledesc := "verify certificates of HTTPS-enabled servers using this CA bundle" - inspectCommand.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc) - valuesSubCmd.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc) - chartSubCmd.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc) + } keyFile := "key-file" keyFiledesc := "identify HTTPS client using this SSL key file" - inspectCommand.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc) - valuesSubCmd.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc) - chartSubCmd.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc) + } caFile := "ca-file" caFiledesc := "chart repository url where to locate the requested chart" - inspectCommand.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc) - valuesSubCmd.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc) - chartSubCmd.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc) + for _, subCmd := range cmds { + subCmd.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc) + } - inspectCommand.AddCommand(valuesSubCmd) - inspectCommand.AddCommand(chartSubCmd) + for _, subCmd := range cmds[1:] { + inspectCommand.AddCommand(subCmd) + } return inspectCommand } @@ -184,16 +216,35 @@ func (i *inspectCmd) run() error { return err } - if i.output == chartOnly || i.output == both { + if i.output == chartOnly || i.output == all { fmt.Fprintln(i.out, string(cf)) } - if (i.output == valuesOnly || i.output == both) && chrt.Values != nil { - if i.output == both { + if (i.output == valuesOnly || i.output == all) && chrt.Values != nil { + if i.output == all { fmt.Fprintln(i.out, "---") } fmt.Fprintln(i.out, chrt.Values.Raw) } + if i.output == readmeOnly || i.output == all { + if i.output == all { + fmt.Fprintln(i.out, "---") + } + readme := findReadme(chrt.Files) + if readme == nil { + return nil + } + fmt.Fprintln(i.out, string(readme.Value)) + } + return nil +} + +func findReadme(files []*any.Any) (file *any.Any) { + for _, file := range files { + if slice.ContainsString(readmeFileNames, strings.ToLower(file.TypeUrl), nil) { + return file + } + } return nil } diff --git a/cmd/helm/inspect_test.go b/cmd/helm/inspect_test.go index b34b793f6..44d71fbbd 100644 --- a/cmd/helm/inspect_test.go +++ b/cmd/helm/inspect_test.go @@ -28,7 +28,7 @@ func TestInspect(t *testing.T) { insp := &inspectCmd{ chartpath: "testdata/testcharts/alpine", - output: "both", + output: all, out: b, } insp.run() @@ -42,15 +42,19 @@ func TestInspect(t *testing.T) { if err != nil { t.Fatal(err) } - - parts := strings.SplitN(b.String(), "---", 2) - if len(parts) != 2 { + readmeData, err := ioutil.ReadFile("testdata/testcharts/alpine/README.md") + if err != nil { + t.Fatal(err) + } + parts := strings.SplitN(b.String(), "---", 3) + if len(parts) != 3 { t.Fatalf("Expected 2 parts, got %d", len(parts)) } expect := []string{ strings.Replace(strings.TrimSpace(string(cdata)), "\r", "", -1), strings.Replace(strings.TrimSpace(string(data)), "\r", "", -1), + strings.Replace(strings.TrimSpace(string(readmeData)), "\r", "", -1), } // Problem: ghodss/yaml doesn't marshal into struct order. To solve, we @@ -73,5 +77,4 @@ func TestInspect(t *testing.T) { if b.Len() != 0 { t.Errorf("expected empty values buffer, got %q", b.String()) } - } diff --git a/docs/helm/helm.md b/docs/helm/helm.md index f470e84b2..8592cad7c 100644 --- a/docs/helm/helm.md +++ b/docs/helm/helm.md @@ -68,4 +68,4 @@ Environment: * [helm verify](helm_verify.md) - verify that a chart at the given path has been signed and is valid * [helm version](helm_version.md) - print the client/server version information -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 14-Mar-2018 diff --git a/docs/helm/helm_inspect.md b/docs/helm/helm_inspect.md index df122f763..9928ed847 100644 --- a/docs/helm/helm_inspect.md +++ b/docs/helm/helm_inspect.md @@ -42,6 +42,7 @@ helm inspect [CHART] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. * [helm inspect chart](helm_inspect_chart.md) - shows inspect chart +* [helm inspect readme](helm_inspect_readme.md) - shows inspect readme * [helm inspect values](helm_inspect_values.md) - shows inspect values -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 14-Mar-2018 diff --git a/docs/helm/helm_inspect_readme.md b/docs/helm/helm_inspect_readme.md new file mode 100644 index 000000000..9dd9ebd43 --- /dev/null +++ b/docs/helm/helm_inspect_readme.md @@ -0,0 +1,43 @@ +## helm inspect readme + +shows inspect readme + +### Synopsis + + + +This command inspects a chart (directory, file, or URL) and displays the contents +of the README file + + +``` +helm inspect readme [CHART] +``` + +### Options + +``` + --ca-file string chart repository url where to locate the requested chart + --cert-file string verify certificates of HTTPS-enabled servers using this CA bundle + --key-file string identify HTTPS client using this SSL key file + --keyring string path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg") + --repo string chart repository url where to locate the requested chart + --verify verify the provenance data for this chart + --version string version of the chart. By default, the newest chart is shown +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --host string address of Tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use + --tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) + --tiller-namespace string namespace of Tiller (default "kube-system") +``` + +### SEE ALSO +* [helm inspect](helm_inspect.md) - inspect a chart + +###### Auto generated by spf13/cobra on 14-Mar-2018 From 333341425aea49e15cc5f0afa3ef63c5a810d6e6 Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Wed, 14 Mar 2018 13:54:06 -0700 Subject: [PATCH 095/221] update documentation as per review feedback --- cmd/helm/history.go | 2 +- docs/helm/helm_history.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/helm/history.go b/cmd/helm/history.go index 573459f91..7b8979142 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -90,7 +90,7 @@ func newHistoryCmd(c helm.Interface, w io.Writer) *cobra.Command { f := cmd.Flags() f.Int32Var(&his.max, "max", 256, "maximum number of revision to include in history") f.UintVar(&his.colWidth, "col-width", 60, "specifies the max column width of output") - f.StringVarP(&his.outputFormat, "output", "o", "table", "prints the output in the specified format ('json' or 'yaml' or defaults to 'table')") + f.StringVarP(&his.outputFormat, "output", "o", "table", "prints the output in the specified format (json|table|yaml)") return cmd } diff --git a/docs/helm/helm_history.md b/docs/helm/helm_history.md index a4ef50b80..ac51a8994 100755 --- a/docs/helm/helm_history.md +++ b/docs/helm/helm_history.md @@ -30,7 +30,7 @@ helm history [flags] RELEASE_NAME ``` --col-width uint specifies the max column width of output (default 60) --max int32 maximum number of revision to include in history (default 256) - -o, --output string prints the output in the specified format ('json' or 'yaml' or defaults to 'table') (default "table") + -o, --output string prints the output in the specified format (json|table|yaml) (default "table") --tls enable TLS for request --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") @@ -52,4 +52,4 @@ helm history [flags] RELEASE_NAME ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 12-Mar-2018 +###### Auto generated by spf13/cobra on 14-Mar-2018 From a930eb7ff4dcba13831174496dda2445e81ebeaa Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Sat, 6 Jan 2018 12:19:29 -0500 Subject: [PATCH 096/221] feat: add --set and --values options to 'helm package' When 'helm package --set stringsArray' is run, this will set/override values in the packaged chart. 'helm package --values valueFiles' uses one or more value files to achieve the same. Closes #3141 Signed-off-by: Arash Deshmeh --- cmd/helm/package.go | 18 +++++ cmd/helm/package_test.go | 152 ++++++++++++++++++++++++++++++++++++++ docs/helm/helm_package.md | 4 +- 3 files changed, 173 insertions(+), 1 deletion(-) diff --git a/cmd/helm/package.go b/cmd/helm/package.go index ed44382c7..4b2e6b398 100644 --- a/cmd/helm/package.go +++ b/cmd/helm/package.go @@ -53,6 +53,8 @@ type packageCmd struct { save bool sign bool path string + valueFiles valueFiles + values []string key string keyring string version string @@ -95,6 +97,8 @@ func newPackageCmd(out io.Writer) *cobra.Command { } f := cmd.Flags() + f.VarP(&pkg.valueFiles, "values", "f", "specify values in a YAML file or a URL(can specify multiple)") + f.StringArrayVar(&pkg.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.BoolVar(&pkg.save, "save", true, "save packaged chart to local chart repository") f.BoolVar(&pkg.sign, "sign", false, "use a PGP private key to sign this package") f.StringVar(&pkg.key, "key", "", "name of the key to use when signing. Used if --sign is true") @@ -133,6 +137,20 @@ func (p *packageCmd) run() error { return err } + overrideVals, err := vals(p.valueFiles, p.values) + if err != nil { + return err + } + combinedVals, err := chartutil.CoalesceValues(ch, &chart.Config{Raw: string(overrideVals)}) + if err != nil { + return err + } + newVals, err := combinedVals.YAML() + if err != nil { + return err + } + ch.Values = &chart.Config{Raw: newVals} + // If version is set, modify the version. if len(p.version) != 0 { if err := setVersion(ch, p.version); err != nil { diff --git a/cmd/helm/package_test.go b/cmd/helm/package_test.go index 4404586e0..4a2df3f54 100644 --- a/cmd/helm/package_test.go +++ b/cmd/helm/package_test.go @@ -21,6 +21,7 @@ import ( "os" "path/filepath" "regexp" + "strings" "testing" "github.com/spf13/cobra" @@ -122,6 +123,13 @@ func TestPackage(t *testing.T) { hasfile: "chart-missing-deps-0.1.0.tgz", err: true, }, + { + name: "package --values does-not-exist", + args: []string{"testdata/testcharts/alpine"}, + flags: map[string]string{"values": "does-not-exist"}, + expect: "does-not-exist: no such file or directory", + err: true, + }, } // Because these tests are destructive, we run them in a tempdir. @@ -245,6 +253,150 @@ func TestSetAppVersion(t *testing.T) { } } +func TestPackageValues(t *testing.T) { + testCases := []struct { + desc string + args []string + valuefilesContents []string + flags map[string]string + expected []string + }{ + { + desc: "helm package, single values file", + args: []string{"testdata/testcharts/alpine"}, + valuefilesContents: []string{"Name: chart-name-foo"}, + expected: []string{"Name: chart-name-foo"}, + }, + { + desc: "helm package, multiple values files", + args: []string{"testdata/testcharts/alpine"}, + valuefilesContents: []string{"Name: chart-name-foo", "foo: bar"}, + expected: []string{"Name: chart-name-foo", "foo: bar"}, + }, + { + desc: "helm package, with set option", + args: []string{"testdata/testcharts/alpine"}, + flags: map[string]string{"set": "Name=chart-name-foo"}, + expected: []string{"Name: chart-name-foo"}, + }, + { + desc: "helm package, set takes precedence over value file", + args: []string{"testdata/testcharts/alpine"}, + valuefilesContents: []string{"Name: chart-name-foo"}, + flags: map[string]string{"set": "Name=chart-name-bar"}, + expected: []string{"Name: chart-name-bar"}, + }, + } + + thome, err := tempHelmHome(t) + if err != nil { + t.Fatal(err) + } + cleanup := resetEnv() + defer func() { + os.RemoveAll(thome.String()) + cleanup() + }() + + settings.Home = thome + + for _, tc := range testCases { + var files []string + for _, contents := range tc.valuefilesContents { + f, err := createValuesFile(contents) + if err != nil { + t.Errorf("%q unexpected error creating temporary values file: %q", tc.desc, err) + } + defer os.RemoveAll(filepath.Dir(f)) + files = append(files, f) + } + valueFiles := strings.Join(files, ",") + + expected, err := chartutil.ReadValues([]byte(strings.Join(tc.expected, "\n"))) + if err != nil { + t.Errorf("unexpected error parsing values: %q", err) + } + + runAndVerifyPackageCommandValues(t, tc.args, tc.flags, valueFiles, expected) + } +} + +func runAndVerifyPackageCommandValues(t *testing.T, args []string, flags map[string]string, valueFiles string, expected chartutil.Values) { + outputDir, err := ioutil.TempDir("", "helm-package") + if err != nil { + t.Errorf("unexpected error creating temporary output directory: %q", err) + } + defer os.RemoveAll(outputDir) + + if len(flags) == 0 { + flags = make(map[string]string) + } + flags["destination"] = outputDir + + if len(valueFiles) > 0 { + flags["values"] = valueFiles + } + + cmd := newPackageCmd(&bytes.Buffer{}) + setFlags(cmd, flags) + err = cmd.RunE(cmd, args) + if err != nil { + t.Errorf("unexpected error: %q", err) + } + + outputFile := filepath.Join(outputDir, "alpine-0.1.0.tgz") + verifyOutputChartExists(t, outputFile) + + var actual chartutil.Values + actual, err = getChartValues(outputFile) + if err != nil { + t.Errorf("unexpected error extracting chart values: %q", err) + } + + verifyValues(t, actual, expected) +} + +func createValuesFile(data string) (string, error) { + outputDir, err := ioutil.TempDir("", "values-file") + if err != nil { + return "", err + } + + outputFile := filepath.Join(outputDir, "values.yaml") + if err = ioutil.WriteFile(outputFile, []byte(data), 0755); err != nil { + os.RemoveAll(outputFile) + return "", err + } + + return outputFile, nil +} + +func getChartValues(chartPath string) (chartutil.Values, error) { + + chart, err := chartutil.Load(chartPath) + if err != nil { + return nil, err + } + + return chartutil.ReadValues([]byte(chart.Values.Raw)) +} + +func verifyValues(t *testing.T, actual, expected chartutil.Values) { + for key, value := range expected.AsMap() { + if got := actual[key]; got != value { + t.Errorf("Expected %q, got %q (%v)", value, got, actual) + } + } +} + +func verifyOutputChartExists(t *testing.T, chartPath string) { + if chartFile, err := os.Stat(chartPath); err != nil { + t.Errorf("expected file %q, got err %q", chartPath, err) + } else if chartFile.Size() == 0 { + t.Errorf("file %q has zero bytes.", chartPath) + } +} + func setFlags(cmd *cobra.Command, flags map[string]string) { dest := cmd.Flags() for f, v := range flags { diff --git a/docs/helm/helm_package.md b/docs/helm/helm_package.md index c51aa7032..daceef32c 100644 --- a/docs/helm/helm_package.md +++ b/docs/helm/helm_package.md @@ -29,7 +29,9 @@ helm package [flags] [CHART_PATH] [...] --key string name of the key to use when signing. Used if --sign is true --keyring string location of a public keyring (default "~/.gnupg/pubring.gpg") --save save packaged chart to local chart repository (default true) + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --sign use a PGP private key to sign this package + -f, --values valueFiles specify values in a YAML file or a URL(can specify multiple) (default []) --version string set the version on the chart to this semver version ``` @@ -47,4 +49,4 @@ helm package [flags] [CHART_PATH] [...] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 14-Mar-2018 From 08a92b23d1defbb03a3f6580f3ce9b3dcb935c76 Mon Sep 17 00:00:00 2001 From: Michal Zerola Date: Thu, 15 Mar 2018 09:05:13 +0100 Subject: [PATCH 097/221] Fixed referencing the wrong env variable if SHA sum doesn't match. --- scripts/get | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/get b/scripts/get index 1c1e617e8..6654fd226 100755 --- a/scripts/get +++ b/scripts/get @@ -49,11 +49,11 @@ initOS() { # runs the given command as root (detects if we are root already) runAsRoot() { local CMD="$*" - + if [ $EUID -ne 0 ]; then CMD="sudo $CMD" fi - + $CMD } @@ -134,7 +134,7 @@ installFile() { local sum=$(openssl sha1 -sha256 ${HELM_TMP_FILE} | awk '{print $2}') local expected_sum=$(cat ${HELM_SUM_FILE}) if [ "$sum" != "$expected_sum" ]; then - echo "SHA sum of $HELM_TMP does not match. Aborting." + echo "SHA sum of ${HELM_TMP_FILE} does not match. Aborting." exit 1 fi From 4b145622a268a3aca5643c149da5a3172df03dd4 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Thu, 15 Mar 2018 05:42:19 -0400 Subject: [PATCH 098/221] fix(helm): search command returns error on index search failures (specifically on regular expression errors) Signed-off-by: Arash Deshmeh --- cmd/helm/search.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/search.go b/cmd/helm/search.go index cf924dcb0..845bfd0be 100644 --- a/cmd/helm/search.go +++ b/cmd/helm/search.go @@ -83,7 +83,7 @@ func (s *searchCmd) run(args []string) error { q := strings.Join(args, " ") res, err = index.Search(q, searchMaxScore, s.regexp) if err != nil { - return nil + return err } } From 1e4770248c9f263ee2fd54516a93a28cd2fd6670 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Thu, 15 Mar 2018 05:42:54 -0400 Subject: [PATCH 099/221] fix(helm): refactor search command tests to remove duplication Signed-off-by: Arash Deshmeh --- cmd/helm/search_test.go | 110 +++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 64 deletions(-) diff --git a/cmd/helm/search_test.go b/cmd/helm/search_test.go index 0fb54b5f9..734f752f5 100644 --- a/cmd/helm/search_test.go +++ b/cmd/helm/search_test.go @@ -17,78 +17,72 @@ limitations under the License. package main import ( - "bytes" - "strings" + "io" "testing" + + "github.com/spf13/cobra" + + "k8s.io/helm/pkg/helm" ) func TestSearchCmd(t *testing.T) { - tests := []struct { - name string - args []string - flags []string - expect string - regexp bool - fail bool - }{ + tests := []releaseCase{ { - name: "search for 'maria', expect one match", - args: []string{"maria"}, - expect: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/mariadb\t0.3.0 \t \tChart for MariaDB", + name: "search for 'maria', expect one match", + args: []string{"maria"}, + expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/mariadb\t0.3.0 \t \tChart for MariaDB", }, { - name: "search for 'alpine', expect two matches", - args: []string{"alpine"}, - expect: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod", + name: "search for 'alpine', expect two matches", + args: []string{"alpine"}, + expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod", }, { - name: "search for 'alpine' with versions, expect three matches", - args: []string{"alpine"}, - flags: []string{"--versions"}, - expect: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod\ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod", + name: "search for 'alpine' with versions, expect three matches", + args: []string{"alpine"}, + flags: []string{"--versions"}, + expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod\ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod", }, { - name: "search for 'alpine' with version constraint, expect one match with version 0.1.0", - args: []string{"alpine"}, - flags: []string{"--version", ">= 0.1, < 0.2"}, - expect: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod", + name: "search for 'alpine' with version constraint, expect one match with version 0.1.0", + args: []string{"alpine"}, + flags: []string{"--version", ">= 0.1, < 0.2"}, + expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod", }, { - name: "search for 'alpine' with version constraint, expect one match with version 0.1.0", - args: []string{"alpine"}, - flags: []string{"--versions", "--version", ">= 0.1, < 0.2"}, - expect: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod", + name: "search for 'alpine' with version constraint, expect one match with version 0.1.0", + args: []string{"alpine"}, + flags: []string{"--versions", "--version", ">= 0.1, < 0.2"}, + expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod", }, { - name: "search for 'alpine' with version constraint, expect one match with version 0.2.0", - args: []string{"alpine"}, - flags: []string{"--version", ">= 0.1"}, - expect: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod", + name: "search for 'alpine' with version constraint, expect one match with version 0.2.0", + args: []string{"alpine"}, + flags: []string{"--version", ">= 0.1"}, + expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod", }, { - name: "search for 'alpine' with version constraint and --versions, expect two matches", - args: []string{"alpine"}, - flags: []string{"--versions", "--version", ">= 0.1"}, - expect: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod\ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod", + name: "search for 'alpine' with version constraint and --versions, expect two matches", + args: []string{"alpine"}, + flags: []string{"--versions", "--version", ">= 0.1"}, + expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod\ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod", }, { - name: "search for 'syzygy', expect no matches", - args: []string{"syzygy"}, - expect: "No results found", + name: "search for 'syzygy', expect no matches", + args: []string{"syzygy"}, + expected: "No results found", }, { - name: "search for 'alp[a-z]+', expect two matches", - args: []string{"alp[a-z]+"}, - flags: []string{"--regexp"}, - expect: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod", - regexp: true, + name: "search for 'alp[a-z]+', expect two matches", + args: []string{"alp[a-z]+"}, + flags: []string{"--regexp"}, + expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod", }, { - name: "search for 'alp[', expect failure to compile regexp", - args: []string{"alp["}, - flags: []string{"--regexp"}, - regexp: true, - fail: true, + name: "search for 'alp[', expect failure to compile regexp", + args: []string{"alp["}, + flags: []string{"--regexp"}, + err: true, }, } @@ -97,19 +91,7 @@ func TestSearchCmd(t *testing.T) { settings.Home = "testdata/helmhome" - for _, tt := range tests { - buf := bytes.NewBuffer(nil) - cmd := newSearchCmd(buf) - cmd.ParseFlags(tt.flags) - if err := cmd.RunE(cmd, tt.args); err != nil { - if tt.fail { - continue - } - t.Fatalf("%s: unexpected error %s", tt.name, err) - } - got := strings.TrimSpace(buf.String()) - if got != tt.expect { - t.Errorf("%s: expected %q, got %q", tt.name, tt.expect, got) - } - } + runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { + return newSearchCmd(out) + }) } From 99da9fb54817a00e0138a08ce0b0643b923e5b6e Mon Sep 17 00:00:00 2001 From: Ali Rizwan Date: Thu, 15 Mar 2018 16:07:29 +0100 Subject: [PATCH 100/221] Fixed SIGSEGV when running helm create with -p and no values.yaml file --- pkg/chartutil/create.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 319a75e2f..c6c1308ca 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -305,8 +305,9 @@ func CreateFrom(chartfile *chart.Metadata, dest string, src string) error { } schart.Templates = updatedTemplates - schart.Values = &chart.Config{Raw: string(Transform(schart.Values.Raw, "", schart.Metadata.Name))} - + if schart.Values != nil { + schart.Values = &chart.Config{Raw: string(Transform(schart.Values.Raw, "", schart.Metadata.Name))} + } return SaveDir(schart, dest) } From 6de9ebccbca7dd085f5d8857f1715c20075ed40e Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Thu, 15 Mar 2018 16:26:57 -0700 Subject: [PATCH 101/221] fix windows path issues on `helm template -x` --- cmd/helm/template.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/helm/template.go b/cmd/helm/template.go index 4bfd4f7a3..3a7285fa1 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -122,7 +122,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error { if len(t.renderFiles) > 0 { for _, f := range t.renderFiles { if !filepath.IsAbs(f) { - af, err = filepath.Abs(t.chartPath + "/" + f) + af, err = filepath.Abs(filepath.Join(t.chartPath, f)) if err != nil { return fmt.Errorf("could not resolve template path: %s", err) } @@ -232,9 +232,9 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error { } in := func(needle string, haystack []string) bool { // make needle path absolute - d := strings.Split(needle, "/") + d := strings.Split(needle, string(os.PathSeparator)) dd := d[1:] - an := t.chartPath + "/" + strings.Join(dd, "/") + an := filepath.Join(t.chartPath, strings.Join(dd, string(os.PathSeparator))) for _, h := range haystack { if h == an { From a53f93c8ee28ad6b5ac043382b63e483a1f70e55 Mon Sep 17 00:00:00 2001 From: John Rowley Date: Thu, 15 Mar 2018 21:27:15 -0700 Subject: [PATCH 102/221] fixed an issue in versioning.mk (#3653) The MUTABLE_IMAGE_RUDDER variables was using the DOCKER_VERSION instead of MUTABLE_VERSION ``` MUTABLE_IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${MUTABLE_VERSION} MUTABLE_IMAGE_RUDDER := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME_RUDDER}:${DOCKER_VERSION} ``` --- versioning.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioning.mk b/versioning.mk index 2333530d9..d1c348f9c 100644 --- a/versioning.mk +++ b/versioning.mk @@ -28,7 +28,7 @@ LDFLAGS += -X k8s.io/helm/pkg/version.GitTreeState=${GIT_DIRTY} IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${DOCKER_VERSION} IMAGE_RUDDER := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME_RUDDER}:${DOCKER_VERSION} MUTABLE_IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${MUTABLE_VERSION} -MUTABLE_IMAGE_RUDDER := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME_RUDDER}:${DOCKER_VERSION} +MUTABLE_IMAGE_RUDDER := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME_RUDDER}:${MUTABLE_VERSION} DOCKER_PUSH = docker push ifeq ($(DOCKER_REGISTRY),gcr.io) From b66c10df10a4039adc26ae21edb649b7a2a5f630 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Thu, 15 Mar 2018 21:07:15 -0400 Subject: [PATCH 103/221] fix(helm): remove duplication in tests of repo-add command Signed-off-by: Arash Deshmeh --- cmd/helm/repo_add_test.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index 1f49e45ea..79d0d3c53 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -17,10 +17,13 @@ limitations under the License. package main import ( - "bytes" + "io" "os" "testing" + "github.com/spf13/cobra" + + "k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/repo" "k8s.io/helm/pkg/repo/repotest" ) @@ -49,17 +52,13 @@ func TestRepoAddCmd(t *testing.T) { { name: "add a repository", args: []string{testName, srv.URL()}, - expected: testName + " has been added to your repositories", + expected: "\"" + testName + "\" has been added to your repositories", }, } - for _, tt := range tests { - buf := bytes.NewBuffer(nil) - c := newRepoAddCmd(buf) - if err := c.RunE(c, tt.args); err != nil { - t.Errorf("%q: expected %q, got %q", tt.name, tt.expected, err) - } - } + runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { + return newRepoAddCmd(out) + }) } func TestRepoAdd(t *testing.T) { From 74bf7584a0333e817bca52b80e56e189cb1ed98c Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Thu, 15 Mar 2018 21:46:26 -0400 Subject: [PATCH 104/221] fix(helm): refactor tests on helm dependency list command to remove duplication Signed-off-by: Arash Deshmeh --- cmd/helm/dependency_test.go | 48 +++++++++++++------------------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/cmd/helm/dependency_test.go b/cmd/helm/dependency_test.go index 887764742..cc4519147 100644 --- a/cmd/helm/dependency_test.go +++ b/cmd/helm/dependency_test.go @@ -16,59 +16,43 @@ limitations under the License. package main import ( - "bytes" - "strings" + "io" "testing" + + "github.com/spf13/cobra" + + "k8s.io/helm/pkg/helm" ) func TestDependencyListCmd(t *testing.T) { - tests := []struct { - name string - args []string - expect string - err bool - }{ + tests := []releaseCase{ { name: "No such chart", args: []string{"/no/such/chart"}, err: true, }, { - name: "No requirements.yaml", - args: []string{"testdata/testcharts/alpine"}, - expect: "WARNING: no requirements at ", + name: "No requirements.yaml", + args: []string{"testdata/testcharts/alpine"}, + expected: "WARNING: no requirements at ", }, { name: "Requirements in chart dir", args: []string{"testdata/testcharts/reqtest"}, - expect: "NAME \tVERSION\tREPOSITORY \tSTATUS \n" + + expected: "NAME \tVERSION\tREPOSITORY \tSTATUS \n" + "reqsubchart \t0.1.0 \thttps://example.com/charts\tunpacked\n" + "reqsubchart2\t0.2.0 \thttps://example.com/charts\tunpacked\n" + "reqsubchart3\t>=0.1.0\thttps://example.com/charts\tok \n\n", }, { - name: "Requirements in chart archive", - args: []string{"testdata/testcharts/reqtest-0.1.0.tgz"}, - expect: "NAME \tVERSION\tREPOSITORY \tSTATUS \nreqsubchart \t0.1.0 \thttps://example.com/charts\tmissing\nreqsubchart2\t0.2.0 \thttps://example.com/charts\tmissing\n", + name: "Requirements in chart archive", + args: []string{"testdata/testcharts/reqtest-0.1.0.tgz"}, + expected: "NAME \tVERSION\tREPOSITORY \tSTATUS \nreqsubchart \t0.1.0 \thttps://example.com/charts\tmissing\nreqsubchart2\t0.2.0 \thttps://example.com/charts\tmissing\n", }, } - for _, tt := range tests { - buf := bytes.NewBuffer(nil) - dlc := newDependencyListCmd(buf) - if err := dlc.RunE(dlc, tt.args); err != nil { - if tt.err { - continue - } - t.Errorf("Test %q: %s", tt.name, err) - continue - } - - got := buf.String() - if !strings.Contains(got, tt.expect) { - t.Errorf("Test: %q, Expected:\n%q\nGot:\n%q", tt.name, tt.expect, got) - } - } - + runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { + return newDependencyListCmd(out) + }) } From a43ddcc191f851e343075142a3b0f9a456e95be0 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Sun, 18 Mar 2018 20:42:05 -0400 Subject: [PATCH 105/221] fix output leak from tiller release install test Signed-off-by: Arash Deshmeh --- pkg/tiller/release_install_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/tiller/release_install_test.go b/pkg/tiller/release_install_test.go index 793a36e94..8e2238e74 100644 --- a/pkg/tiller/release_install_test.go +++ b/pkg/tiller/release_install_test.go @@ -468,7 +468,6 @@ func TestInstallRelease_KubeVersion(t *testing.T) { }, } _, err := rs.InstallRelease(c, req) - fmt.Println(err) if err != nil { t.Fatalf("Expected valid range. Got %q", err) } From 87c64e7987f348c0a99a4f6e12d6ec187723b7cc Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Mon, 19 Mar 2018 15:53:15 -0700 Subject: [PATCH 106/221] fix `helm get manifest` context deadline exceeded error --- cmd/helm/get_manifest.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmd/helm/get_manifest.go b/cmd/helm/get_manifest.go index 1c42830f0..c01febfb4 100644 --- a/cmd/helm/get_manifest.go +++ b/cmd/helm/get_manifest.go @@ -55,9 +55,7 @@ func newGetManifestCmd(client helm.Interface, out io.Writer) *cobra.Command { return errReleaseRequired } get.release = args[0] - if get.client == nil { - get.client = helm.NewClient(helm.Host(settings.TillerHost)) - } + get.client = ensureHelmClient(get.client) return get.run() }, } From afed555572a1476dcb7c3bebc2701268cfde1de8 Mon Sep 17 00:00:00 2001 From: Daisuke Maki Date: Tue, 20 Mar 2018 09:44:20 +0900 Subject: [PATCH 107/221] Add actionable message in the error See #3697 --- cmd/helm/install.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index da1ee52d7..6d8d68c6e 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -443,7 +443,7 @@ func locateChartPath(repoURL, name, version string, verify bool, keyring, return filename, err } - return filename, fmt.Errorf("failed to download %q", name) + return filename, fmt.Errorf("failed to download %q (hint: running `helm repo update` may help)", name) } func generateName(nameTemplate string) (string, error) { From 34b6d12ebe0824cae6fc9ebb1b14d3c8fd822a92 Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Tue, 20 Mar 2018 00:14:43 -0700 Subject: [PATCH 108/221] fix(helm): fix helm history unit tests fixes #3652 --- cmd/helm/helm_test.go | 29 ++++++++++++++--------------- cmd/helm/history.go | 14 +++++++------- cmd/helm/history_test.go | 20 ++++++++++---------- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index 7d74d66b7..c95caa75f 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -40,23 +40,22 @@ type releaseCmd func(c *helm.FakeClient, out io.Writer) *cobra.Command // runReleaseCases runs a set of release cases through the given releaseCmd. func runReleaseCases(t *testing.T, tests []releaseCase, rcmd releaseCmd) { - var buf bytes.Buffer for _, tt := range tests { - c := &helm.FakeClient{ - Rels: tt.rels, - } - cmd := rcmd(c, &buf) - cmd.ParseFlags(tt.flags) - err := cmd.RunE(cmd, tt.args) - if (err != nil) != tt.err { - t.Errorf("%q. expected error, got '%v'", tt.name, err) - } - re := regexp.MustCompile(tt.expected) - if !re.Match(buf.Bytes()) { - t.Errorf("%q. expected\n%q\ngot\n%q", tt.name, tt.expected, buf.String()) - } - buf.Reset() + t.Run(tt.name, func(t *testing.T) { + c := &helm.FakeClient{Rels: tt.rels} + cmd := rcmd(c, &buf) + cmd.ParseFlags(tt.flags) + err := cmd.RunE(cmd, tt.args) + if (err != nil) != tt.err { + t.Errorf("expected error, got '%v'", err) + } + re := regexp.MustCompile(tt.expected) + if !re.Match(buf.Bytes()) { + t.Errorf("expected\n%q\ngot\n%q", tt.expected, buf.String()) + } + buf.Reset() + }) } } diff --git a/cmd/helm/history.go b/cmd/helm/history.go index 7b8979142..e6366d31d 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -17,14 +17,14 @@ limitations under the License. package main import ( + "encoding/json" "fmt" "io" + "github.com/ghodss/yaml" "github.com/gosuri/uitable" "github.com/spf13/cobra" - "encoding/json" - "github.com/ghodss/yaml" "k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/proto/hapi/release" @@ -32,11 +32,11 @@ import ( ) type releaseInfo struct { - Revision int32 `json:"revision" yaml:"revision"` - Updated string `json:"updated" yaml:"updated"` - Status string `json:"status" yaml:"status"` - Chart string `json:"chart" yaml:"chart"` - Description string `json:"description" yaml:"description"` + Revision int32 `json:"revision"` + Updated string `json:"updated"` + Status string `json:"status"` + Chart string `json:"chart"` + Description string `json:"description"` } type releaseHistory []releaseInfo diff --git a/cmd/helm/history_test.go b/cmd/helm/history_test.go index c6a14b333..fef433742 100644 --- a/cmd/helm/history_test.go +++ b/cmd/helm/history_test.go @@ -58,24 +58,24 @@ func TestHistoryCmd(t *testing.T) { expected: "REVISION\tUPDATED \tSTATUS \tCHART \tDESCRIPTION \n3 \t(.*)\tSUPERSEDED\tfoo-0.1.0-beta.1\tRelease mock\n4 \t(.*)\tDEPLOYED \tfoo-0.1.0-beta.1\tRelease mock\n", }, { - cmds: "helm history --max=MAX RELEASE_NAME -o yaml", - desc: "get history with yaml output format", - args: []string{"--max=2", "-o=yaml", "angry-bird"}, - resp: []*rpb.Release{ + name: "get history with yaml output format", + args: []string{"angry-bird"}, + flags: []string{"--output", "yaml"}, + rels: []*rpb.Release{ mk("angry-bird", 4, rpb.Status_DEPLOYED), mk("angry-bird", 3, rpb.Status_SUPERSEDED), }, - xout: "- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 3\n status: SUPERSEDED\n updated: (.*)\n- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 4\n status: DEPLOYED\n updated: (.*)\n\n", + expected: "- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 3\n status: SUPERSEDED\n updated: (.*)\n- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 4\n status: DEPLOYED\n updated: (.*)\n\n", }, { - cmds: "helm history --max=MAX RELEASE_NAME -o json", - desc: "get history with json output format", - args: []string{"--max=2", "-o=json", "angry-bird"}, - resp: []*rpb.Release{ + name: "get history with json output format", + args: []string{"angry-bird"}, + flags: []string{"--output", "json"}, + rels: []*rpb.Release{ mk("angry-bird", 4, rpb.Status_DEPLOYED), mk("angry-bird", 3, rpb.Status_SUPERSEDED), }, - xout: `[{"revision":3,"updated":".*","status":"SUPERSEDED","chart":"foo\-0.1.0-beta.1","description":"Release mock"},{"revision":4,"updated":".*","status":"DEPLOYED","chart":"foo\-0.1.0-beta.1","description":"Release mock"}]\n`, + expected: `[{"revision":3,"updated":".*","status":"SUPERSEDED","chart":"foo\-0.1.0-beta.1","description":"Release mock"},{"revision":4,"updated":".*","status":"DEPLOYED","chart":"foo\-0.1.0-beta.1","description":"Release mock"}]\n`, }, } From 08f450404b1a7711d12efcdbfc47abafdd42bcda Mon Sep 17 00:00:00 2001 From: Andrii Soldatenko Date: Tue, 20 Mar 2018 16:35:22 +0200 Subject: [PATCH 109/221] Fixed typo --- cmd/helm/install.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index da1ee52d7..3b6d3e076 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -229,7 +229,7 @@ func (i *installCmd) run() error { } if req, err := chartutil.LoadRequirements(chartRequested); err == nil { - // If checkDependencies returns an error, we have unfullfilled dependencies. + // If checkDependencies returns an error, we have unfulfilled dependencies. // As of Helm 2.4.0, this is treated as a stopping condition: // https://github.com/kubernetes/helm/issues/2209 if err := checkDependencies(chartRequested, req); err != nil { From b6335b7dfeb0e68952ee914877fe456ecd257779 Mon Sep 17 00:00:00 2001 From: Eyal Ben Moshe Date: Tue, 20 Mar 2018 17:56:48 +0000 Subject: [PATCH 110/221] Authentication support for remote charts repositories (#3206) Authentication support for remote charts repositories. --- cmd/helm/fetch.go | 8 ++- cmd/helm/inspect.go | 22 +++++-- cmd/helm/install.go | 12 +++- cmd/helm/repo_add.go | 10 ++- cmd/helm/repo_add_test.go | 6 +- cmd/helm/repo_remove_test.go | 2 +- cmd/helm/upgrade.go | 6 +- docs/chart_repository.md | 11 +++- docs/helm/helm_fetch.md | 4 +- docs/helm/helm_inspect.md | 2 + docs/helm/helm_inspect_chart.md | 2 + docs/helm/helm_inspect_values.md | 2 + docs/helm/helm_install.md | 2 + docs/helm/helm_repo_add.md | 2 + docs/helm/helm_upgrade.md | 2 + pkg/downloader/chart_downloader.go | 84 ++++++++++++++++++------- pkg/downloader/chart_downloader_test.go | 15 +++-- pkg/downloader/manager.go | 44 ++++++++----- pkg/downloader/manager_test.go | 9 ++- pkg/getter/httpgetter.go | 32 ++++++++-- pkg/getter/httpgetter_test.go | 4 +- pkg/repo/chartrepo.go | 18 +++++- 22 files changed, 224 insertions(+), 75 deletions(-) diff --git a/cmd/helm/fetch.go b/cmd/helm/fetch.go index 9c1f25614..069f57eff 100644 --- a/cmd/helm/fetch.go +++ b/cmd/helm/fetch.go @@ -52,6 +52,8 @@ type fetchCmd struct { destdir string version string repoURL string + username string + password string verify bool verifyLater bool @@ -106,6 +108,8 @@ func newFetchCmd(out io.Writer) *cobra.Command { f.StringVar(&fch.keyFile, "key-file", "", "identify HTTPS client using this SSL key file") f.StringVar(&fch.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") f.BoolVar(&fch.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.") + f.StringVar(&fch.username, "username", "", "chart repository username") + f.StringVar(&fch.password, "password", "", "chart repository password") return cmd } @@ -117,6 +121,8 @@ func (f *fetchCmd) run() error { Keyring: f.keyring, Verify: downloader.VerifyNever, Getters: getter.All(settings), + Username: f.username, + Password: f.password, } if f.verify { @@ -138,7 +144,7 @@ func (f *fetchCmd) run() error { } if f.repoURL != "" { - chartURL, err := repo.FindChartInRepoURL(f.repoURL, f.chartRef, f.version, f.certFile, f.keyFile, f.caFile, getter.All(settings)) + chartURL, err := repo.FindChartInAuthRepoURL(f.repoURL, f.username, f.password, f.chartRef, f.version, f.certFile, f.keyFile, f.caFile, getter.All(settings)) if err != nil { return err } diff --git a/cmd/helm/inspect.go b/cmd/helm/inspect.go index 736f14fce..999856959 100644 --- a/cmd/helm/inspect.go +++ b/cmd/helm/inspect.go @@ -59,6 +59,8 @@ type inspectCmd struct { out io.Writer version string repoURL string + username string + password string certFile string keyFile string @@ -88,7 +90,7 @@ func newInspectCmd(out io.Writer) *cobra.Command { if err := checkArgsLength(len(args), "chart name"); err != nil { return err } - cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring, + cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring, insp.certFile, insp.keyFile, insp.caFile) if err != nil { return err @@ -107,7 +109,7 @@ func newInspectCmd(out io.Writer) *cobra.Command { if err := checkArgsLength(len(args), "chart name"); err != nil { return err } - cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring, + cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring, insp.certFile, insp.keyFile, insp.caFile) if err != nil { return err @@ -126,7 +128,7 @@ func newInspectCmd(out io.Writer) *cobra.Command { if err := checkArgsLength(len(args), "chart name"); err != nil { return err } - cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring, + cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring, insp.certFile, insp.keyFile, insp.caFile) if err != nil { return err @@ -145,7 +147,7 @@ func newInspectCmd(out io.Writer) *cobra.Command { if err := checkArgsLength(len(args), "chart name"); err != nil { return err } - cp, err := locateChartPath(insp.repoURL, args[0], insp.version, insp.verify, insp.keyring, + cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring, insp.certFile, insp.keyFile, insp.caFile) if err != nil { return err @@ -181,6 +183,18 @@ func newInspectCmd(out io.Writer) *cobra.Command { subCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc) } + username := "username" + usernamedesc := "chart repository username where to locate the requested chart" + inspectCommand.Flags().StringVar(&insp.username, username, "", usernamedesc) + valuesSubCmd.Flags().StringVar(&insp.username, username, "", usernamedesc) + chartSubCmd.Flags().StringVar(&insp.username, username, "", usernamedesc) + + password := "password" + passworddesc := "chart repository password where to locate the requested chart" + inspectCommand.Flags().StringVar(&insp.password, password, "", passworddesc) + valuesSubCmd.Flags().StringVar(&insp.password, password, "", passworddesc) + chartSubCmd.Flags().StringVar(&insp.password, password, "", passworddesc) + certFile := "cert-file" certFiledesc := "verify certificates of HTTPS-enabled servers using this CA bundle" for _, subCmd := range cmds { diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 3b6d3e076..a02f543db 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -118,6 +118,8 @@ type installCmd struct { timeout int64 wait bool repoURL string + username string + password string devel bool depUp bool @@ -165,7 +167,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command { inst.version = ">0.0.0-0" } - cp, err := locateChartPath(inst.repoURL, args[0], inst.version, inst.verify, inst.keyring, + cp, err := locateChartPath(inst.repoURL, inst.username, inst.password, args[0], inst.version, inst.verify, inst.keyring, inst.certFile, inst.keyFile, inst.caFile) if err != nil { return err @@ -191,6 +193,8 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command { f.Int64Var(&inst.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)") f.BoolVar(&inst.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout") f.StringVar(&inst.repoURL, "repo", "", "chart repository url where to locate the requested chart") + f.StringVar(&inst.username, "username", "", "chart repository username where to locate the requested chart") + f.StringVar(&inst.password, "password", "", "chart repository password where to locate the requested chart") f.StringVar(&inst.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file") f.StringVar(&inst.keyFile, "key-file", "", "identify HTTPS client using this SSL key file") f.StringVar(&inst.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") @@ -381,7 +385,7 @@ func (i *installCmd) printRelease(rel *release.Release) { // - URL // // If 'verify' is true, this will attempt to also verify the chart. -func locateChartPath(repoURL, name, version string, verify bool, keyring, +func locateChartPath(repoURL, username, password, name, version string, verify bool, keyring, certFile, keyFile, caFile string) (string, error) { name = strings.TrimSpace(name) version = strings.TrimSpace(version) @@ -414,12 +418,14 @@ func locateChartPath(repoURL, name, version string, verify bool, keyring, Out: os.Stdout, Keyring: keyring, Getters: getter.All(settings), + Username: username, + Password: password, } if verify { dl.Verify = downloader.VerifyAlways } if repoURL != "" { - chartURL, err := repo.FindChartInRepoURL(repoURL, name, version, + chartURL, err := repo.FindChartInAuthRepoURL(repoURL, username, password, name, version, certFile, keyFile, caFile, getter.All(settings)) if err != nil { return "", err diff --git a/cmd/helm/repo_add.go b/cmd/helm/repo_add.go index b172d016c..77a64cc89 100644 --- a/cmd/helm/repo_add.go +++ b/cmd/helm/repo_add.go @@ -30,6 +30,8 @@ import ( type repoAddCmd struct { name string url string + username string + password string home helmpath.Home noupdate bool @@ -60,6 +62,8 @@ func newRepoAddCmd(out io.Writer) *cobra.Command { } f := cmd.Flags() + f.StringVar(&add.username, "username", "", "chart repository username") + f.StringVar(&add.password, "password", "", "chart repository password") f.BoolVar(&add.noupdate, "no-update", false, "raise error if repo is already registered") f.StringVar(&add.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file") f.StringVar(&add.keyFile, "key-file", "", "identify HTTPS client using this SSL key file") @@ -69,14 +73,14 @@ func newRepoAddCmd(out io.Writer) *cobra.Command { } func (a *repoAddCmd) run() error { - if err := addRepository(a.name, a.url, a.home, a.certFile, a.keyFile, a.caFile, a.noupdate); err != nil { + if err := addRepository(a.name, a.url, a.username, a.password, a.home, a.certFile, a.keyFile, a.caFile, a.noupdate); err != nil { return err } fmt.Fprintf(a.out, "%q has been added to your repositories\n", a.name) return nil } -func addRepository(name, url string, home helmpath.Home, certFile, keyFile, caFile string, noUpdate bool) error { +func addRepository(name, url, username, password string, home helmpath.Home, certFile, keyFile, caFile string, noUpdate bool) error { f, err := repo.LoadRepositoriesFile(home.RepositoryFile()) if err != nil { return err @@ -91,6 +95,8 @@ func addRepository(name, url string, home helmpath.Home, certFile, keyFile, caFi Name: name, Cache: cif, URL: url, + Username: username, + Password: password, CertFile: certFile, KeyFile: keyFile, CAFile: caFile, diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index 79d0d3c53..157b1cc5b 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -80,7 +80,7 @@ func TestRepoAdd(t *testing.T) { settings.Home = thome - if err := addRepository(testName, ts.URL(), hh, "", "", "", true); err != nil { + if err := addRepository(testName, ts.URL(), "", "", hh, "", "", "", true); err != nil { t.Error(err) } @@ -93,11 +93,11 @@ func TestRepoAdd(t *testing.T) { t.Errorf("%s was not successfully inserted into %s", testName, hh.RepositoryFile()) } - if err := addRepository(testName, ts.URL(), hh, "", "", "", false); err != nil { + if err := addRepository(testName, ts.URL(), "", "", hh, "", "", "", false); err != nil { t.Errorf("Repository was not updated: %s", err) } - if err := addRepository(testName, ts.URL(), hh, "", "", "", false); err != nil { + if err := addRepository(testName, ts.URL(), "", "", hh, "", "", "", false); err != nil { t.Errorf("Duplicate repository name was added") } } diff --git a/cmd/helm/repo_remove_test.go b/cmd/helm/repo_remove_test.go index 63082b42e..174a44495 100644 --- a/cmd/helm/repo_remove_test.go +++ b/cmd/helm/repo_remove_test.go @@ -51,7 +51,7 @@ func TestRepoRemove(t *testing.T) { if err := removeRepoLine(b, testName, hh); err == nil { t.Errorf("Expected error removing %s, but did not get one.", testName) } - if err := addRepository(testName, ts.URL(), hh, "", "", "", true); err != nil { + if err := addRepository(testName, ts.URL(), "", "", hh, "", "", "", true); err != nil { t.Error(err) } diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index d08dd62ef..aadb59ac2 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -73,6 +73,8 @@ type upgradeCmd struct { reuseValues bool wait bool repoURL string + username string + password string devel bool certFile string @@ -128,6 +130,8 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command { f.BoolVar(&upgrade.reuseValues, "reuse-values", false, "when upgrading, reuse the last release's values, and merge in any new values. If '--reset-values' is specified, this is ignored.") f.BoolVar(&upgrade.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout") f.StringVar(&upgrade.repoURL, "repo", "", "chart repository url where to locate the requested chart") + f.StringVar(&upgrade.username, "username", "", "chart repository username where to locate the requested chart") + f.StringVar(&upgrade.password, "password", "", "chart repository password where to locate the requested chart") f.StringVar(&upgrade.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file") f.StringVar(&upgrade.keyFile, "key-file", "", "identify HTTPS client using this SSL key file") f.StringVar(&upgrade.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") @@ -139,7 +143,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command { } func (u *upgradeCmd) run() error { - chartPath, err := locateChartPath(u.repoURL, u.chart, u.version, u.verify, u.keyring, u.certFile, u.keyFile, u.caFile) + chartPath, err := locateChartPath(u.repoURL, u.username, u.password, u.chart, u.version, u.verify, u.keyring, u.certFile, u.keyFile, u.caFile) if err != nil { return err } diff --git a/docs/chart_repository.md b/docs/chart_repository.md index 1379573fc..5a24249b8 100644 --- a/docs/chart_repository.md +++ b/docs/chart_repository.md @@ -148,6 +148,11 @@ Charts repository hosts its charts, so you may want to take a **Note:** A public GCS bucket can be accessed via simple HTTPS at this address `https://bucket-name.storage.googleapis.com/`. +### JFrog Artifactory + +You can also set up chart repositories using JFrog Artifactory. +Read more about chart repositories with JFrog Artifactory [here](https://www.jfrog.com/confluence/display/RTF/Helm+Chart+Repositories) + ### Github Pages example In a similar way you can create charts repository using GitHub Pages. @@ -270,10 +275,10 @@ fantastic-charts https://fantastic-charts.storage.googleapis.com If the charts are backed by HTTP basic authentication, you can also supply the username and password here: -```console -$ helm repo add fantastic-charts https://username:password@fantastic-charts.storage.googleapis.com +``console +$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com --username my-username --password my-password $ helm repo list -fantastic-charts https://username:password@fantastic-charts.storage.googleapis.com +fantastic-charts https://fantastic-charts.storage.googleapis.com ``` **Note:** A repository will not be added if it does not contain a valid diff --git a/docs/helm/helm_fetch.md b/docs/helm/helm_fetch.md index 3bc3334a0..1ddef65fa 100644 --- a/docs/helm/helm_fetch.md +++ b/docs/helm/helm_fetch.md @@ -33,10 +33,12 @@ helm fetch [flags] [chart URL | repo/chartname] [...] --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored. --key-file string identify HTTPS client using this SSL key file --keyring string keyring containing public keys (default "~/.gnupg/pubring.gpg") + --password string chart repository password --prov fetch the provenance file, but don't perform verification --repo string chart repository url where to locate the requested chart --untar if set to true, will untar the chart after downloading it --untardir string if untar is specified, this flag specifies the name of the directory into which the chart is expanded (default ".") + --username string chart repository username --verify verify the package against its signature --version string specific version of a chart. Without this, the latest version is fetched ``` @@ -54,5 +56,3 @@ helm fetch [flags] [chart URL | repo/chartname] [...] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. - -###### Auto generated by spf13/cobra on 8-Mar-2018 diff --git a/docs/helm/helm_inspect.md b/docs/helm/helm_inspect.md index 9928ed847..e46b3dbf4 100644 --- a/docs/helm/helm_inspect.md +++ b/docs/helm/helm_inspect.md @@ -23,7 +23,9 @@ helm inspect [CHART] --cert-file string verify certificates of HTTPS-enabled servers using this CA bundle --key-file string identify HTTPS client using this SSL key file --keyring string path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg") + --password string chart repository password where to locate the requested chart --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart --verify verify the provenance data for this chart --version string version of the chart. By default, the newest chart is shown ``` diff --git a/docs/helm/helm_inspect_chart.md b/docs/helm/helm_inspect_chart.md index bfa6061c8..cd1328b59 100644 --- a/docs/helm/helm_inspect_chart.md +++ b/docs/helm/helm_inspect_chart.md @@ -21,7 +21,9 @@ helm inspect chart [CHART] --cert-file string verify certificates of HTTPS-enabled servers using this CA bundle --key-file string identify HTTPS client using this SSL key file --keyring string path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg") + --password string chart repository password where to locate the requested chart --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart --verify verify the provenance data for this chart --version string version of the chart. By default, the newest chart is shown ``` diff --git a/docs/helm/helm_inspect_values.md b/docs/helm/helm_inspect_values.md index fbf8660c2..6a907cc7d 100644 --- a/docs/helm/helm_inspect_values.md +++ b/docs/helm/helm_inspect_values.md @@ -21,7 +21,9 @@ helm inspect values [CHART] --cert-file string verify certificates of HTTPS-enabled servers using this CA bundle --key-file string identify HTTPS client using this SSL key file --keyring string path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg") + --password string chart repository password where to locate the requested chart --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart --verify verify the provenance data for this chart --version string version of the chart. By default, the newest chart is shown ``` diff --git a/docs/helm/helm_install.md b/docs/helm/helm_install.md index 406416dc8..0ae9097ba 100644 --- a/docs/helm/helm_install.md +++ b/docs/helm/helm_install.md @@ -80,6 +80,7 @@ helm install [CHART] --name-template string specify template used to name the release --namespace string namespace to install the release into. Defaults to the current kube config namespace. --no-hooks prevent hooks from running during install + --password string chart repository password where to locate the requested chart --replace re-use the given name, even if that name is already used. This is unsafe in production --repo string chart repository url where to locate the requested chart --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) @@ -89,6 +90,7 @@ helm install [CHART] --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") --tls-key string path to TLS key file (default "$HELM_HOME/key.pem") --tls-verify enable TLS for request and verify remote + --username string chart repository username where to locate the requested chart -f, --values valueFiles specify values in a YAML file or a URL(can specify multiple) (default []) --verify verify the package before installing it --version string specify the exact chart version to install. If this is not specified, the latest version is installed diff --git a/docs/helm/helm_repo_add.md b/docs/helm/helm_repo_add.md index f0dfcbd5d..456ffa27e 100644 --- a/docs/helm/helm_repo_add.md +++ b/docs/helm/helm_repo_add.md @@ -18,6 +18,8 @@ helm repo add [flags] [NAME] [URL] --cert-file string identify HTTPS client using this SSL certificate file --key-file string identify HTTPS client using this SSL key file --no-update raise error if repo is already registered + --password string chart repository password + --username string chart repository username ``` ### Options inherited from parent commands diff --git a/docs/helm/helm_upgrade.md b/docs/helm/helm_upgrade.md index 5ed128958..5cbb9a110 100644 --- a/docs/helm/helm_upgrade.md +++ b/docs/helm/helm_upgrade.md @@ -46,6 +46,7 @@ helm upgrade [RELEASE] [CHART] --keyring string path to the keyring that contains public signing keys (default "~/.gnupg/pubring.gpg") --namespace string namespace to install the release into (only used if --install is set). Defaults to the current kube config namespace --no-hooks disable pre/post upgrade hooks + --password string chart repository password where to locate the requested chart --recreate-pods performs pods restart for the resource if applicable --repo string chart repository url where to locate the requested chart --reset-values when upgrading, reset the values to the ones built into the chart @@ -57,6 +58,7 @@ helm upgrade [RELEASE] [CHART] --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") --tls-key string path to TLS key file (default "$HELM_HOME/key.pem") --tls-verify enable TLS for request and verify remote + --username string chart repository username where to locate the requested chart -f, --values valueFiles specify values in a YAML file or a URL(can specify multiple) (default []) --verify verify the provenance of the chart before upgrading --version string specify the exact chart version to use. If this is not specified, the latest version is used diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go index c7610aaf9..9fe89820e 100644 --- a/pkg/downloader/chart_downloader.go +++ b/pkg/downloader/chart_downloader.go @@ -67,6 +67,10 @@ type ChartDownloader struct { HelmHome helmpath.Home // Getter collection for the operation Getters getter.Providers + // Chart repository username + Username string + // Chart repository password + Password string } // DownloadTo retrieves a chart. Depending on the settings, it may also download a provenance file. @@ -81,7 +85,7 @@ type ChartDownloader struct { // Returns a string path to the location where the file was downloaded and a verification // (if provenance was verified), or an error if something bad happened. func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *provenance.Verification, error) { - u, g, err := c.ResolveChartVersion(ref, version) + u, r, g, err := c.ResolveChartVersionAndGetRepo(ref, version) if err != nil { return "", nil, err } @@ -100,7 +104,7 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven // If provenance is requested, verify it. ver := &provenance.Verification{} if c.Verify > VerifyNever { - body, err := g.Get(u.String() + ".prov") + body, err := r.Client.Get(u.String() + ".prov") if err != nil { if c.Verify == VerifyAlways { return destfile, ver, fmt.Errorf("Failed to fetch provenance %q", u.String()+".prov") @@ -140,96 +144,132 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven // * If version is empty, this will return the URL for the latest version // * If no version can be found, an error is returned func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, getter.Getter, error) { + u, r, _, err := c.ResolveChartVersionAndGetRepo(ref, version) + if r != nil { + return u, r.Client, err + } + return u, nil, err +} + +// Same as the ResolveChartVersion method, but returns the chart repositoryy. +func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*url.URL, *repo.ChartRepository, *getter.HttpGetter, error) { u, err := url.Parse(ref) if err != nil { - return nil, nil, fmt.Errorf("invalid chart URL format: %s", ref) + return nil, nil, nil, fmt.Errorf("invalid chart URL format: %s", ref) } rf, err := repo.LoadRepositoriesFile(c.HelmHome.RepositoryFile()) if err != nil { - return u, nil, err + return u, nil, nil, err } + g, err := getter.NewHTTPGetter(ref, "", "", "") + if err != nil { + return u, nil, nil, err + } + g.SetCredentials(c.getRepoCredentials(nil)) + if u.IsAbs() && len(u.Host) > 0 && len(u.Path) > 0 { // In this case, we have to find the parent repo that contains this chart // URL. And this is an unfortunate problem, as it requires actually going // through each repo cache file and finding a matching URL. But basically // we want to find the repo in case we have special SSL cert config // for that repo. + rc, err := c.scanReposForURL(ref, rf) if err != nil { // If there is no special config, return the default HTTP client and // swallow the error. if err == ErrNoOwnerRepo { - getterConstructor, err := c.Getters.ByScheme(u.Scheme) - if err != nil { - return u, nil, err - } - getter, err := getterConstructor(ref, "", "", "") - return u, getter, err + r := &repo.ChartRepository{} + r.Client = g + g.SetCredentials(c.getRepoCredentials(r)) + return u, r, g, err } - return u, nil, err + return u, nil, nil, err } r, err := repo.NewChartRepository(rc, c.Getters) // If we get here, we don't need to go through the next phase of looking // up the URL. We have it already. So we just return. - return u, r.Client, err + return u, r, g, err } // See if it's of the form: repo/path_to_chart p := strings.SplitN(u.Path, "/", 2) if len(p) < 2 { - return u, nil, fmt.Errorf("Non-absolute URLs should be in form of repo_name/path_to_chart, got: %s", u) + return u, nil, nil, fmt.Errorf("Non-absolute URLs should be in form of repo_name/path_to_chart, got: %s", u) } repoName := p[0] chartName := p[1] rc, err := pickChartRepositoryConfigByName(repoName, rf.Repositories) if err != nil { - return u, nil, err + return u, nil, nil, err } r, err := repo.NewChartRepository(rc, c.Getters) if err != nil { - return u, nil, err + return u, nil, nil, err } // 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 { - return u, r.Client, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err) + return u, r, g, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err) } cv, err := i.Get(chartName, version) if err != nil { - return u, r.Client, fmt.Errorf("chart %q matching %s not found in %s index. (try 'helm repo update'). %s", chartName, version, r.Config.Name, err) + return u, r, g, fmt.Errorf("chart %q matching %s not found in %s index. (try 'helm repo update'). %s", chartName, version, r.Config.Name, err) } if len(cv.URLs) == 0 { - return u, r.Client, fmt.Errorf("chart %q has no downloadable URLs", ref) + return u, r, g, fmt.Errorf("chart %q has no downloadable URLs", ref) } // TODO: Seems that picking first URL is not fully correct u, err = url.Parse(cv.URLs[0]) if err != nil { - return u, r.Client, fmt.Errorf("invalid chart URL format: %s", ref) + return u, r, g, fmt.Errorf("invalid chart URL format: %s", ref) } // If the URL is relative (no scheme), prepend the chart repo's base URL if !u.IsAbs() { repoURL, err := url.Parse(rc.URL) if err != nil { - return repoURL, r.Client, err + return repoURL, r, nil, err } q := repoURL.Query() // We need a trailing slash for ResolveReference to work, but make sure there isn't already one repoURL.Path = strings.TrimSuffix(repoURL.Path, "/") + "/" u = repoURL.ResolveReference(u) u.RawQuery = q.Encode() - return u, r.Client, err + g, err := getter.NewHTTPGetter(rc.URL, "", "", "") + if err != nil { + return repoURL, r, nil, err + } + g.SetCredentials(c.getRepoCredentials(r)) + return u, r, g, err } - return u, r.Client, nil + return u, r, g, nil +} + +// If this ChartDownloader is not configured to use credentials, and the chart repository sent as an argument is, +// then the repository's configured credentials are returned. +// Else, this ChartDownloader's credentials are returned. +func (c *ChartDownloader) getRepoCredentials(r *repo.ChartRepository) (username, password string) { + username = c.Username + password = c.Password + if r != nil && r.Config != nil { + if username == "" { + username = r.Config.Username + } + if password == "" { + password = r.Config.Password + } + } + return } // VerifyChart takes a path to a chart archive and a keyring, and verifies the chart. diff --git a/pkg/downloader/chart_downloader_test.go b/pkg/downloader/chart_downloader_test.go index 0100772e9..80efa77e8 100644 --- a/pkg/downloader/chart_downloader_test.go +++ b/pkg/downloader/chart_downloader_test.go @@ -99,11 +99,11 @@ func TestDownload(t *testing.T) { t.Fatal("No http provider found") } - getter, err := provider.New(srv.URL, "", "", "") + g, err := provider.New(srv.URL, "", "", "") if err != nil { t.Fatal(err) } - got, err := getter.Get(srv.URL) + got, err := g.Get(srv.URL) if err != nil { t.Fatal(err) } @@ -115,16 +115,21 @@ func TestDownload(t *testing.T) { // test with server backed by basic auth basicAuthSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { username, password, ok := r.BasicAuth() - if !ok || username != "username" && password != "password" { + if !ok || username != "username" || password != "password" { t.Errorf("Expected request to use basic auth and for username == 'username' and password == 'password', got '%v', '%s', '%s'", ok, username, password) } fmt.Fprint(w, expect) })) + defer basicAuthSrv.Close() u, _ := url.ParseRequestURI(basicAuthSrv.URL) - u.User = url.UserPassword("username", "password") - got, err = getter.Get(u.String()) + httpgetter, err := getter.NewHTTPGetter(u.String(), "", "", "") + if err != nil { + t.Fatal(err) + } + httpgetter.SetCredentials("username", "password") + got, err = httpgetter.Get(u.String()) if err != nil { t.Fatal(err) } diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go index 6d4103bae..89a839b54 100644 --- a/pkg/downloader/manager.go +++ b/pkg/downloader/manager.go @@ -197,14 +197,6 @@ func (m *Manager) downloadAll(deps []*chartutil.Dependency) error { return err } - dl := ChartDownloader{ - Out: m.Out, - Verify: m.Verify, - Keyring: m.Keyring, - HelmHome: m.HelmHome, - Getters: m.Getters, - } - destPath := filepath.Join(m.ChartPath, "charts") tmpPath := filepath.Join(m.ChartPath, "tmpcharts") @@ -245,12 +237,22 @@ 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, err := findChartURL(dep.Name, dep.Version, dep.Repository, repos) + churl, username, password, err := findChartURL(dep.Name, dep.Version, dep.Repository, repos) if err != nil { saveError = fmt.Errorf("could not find %s: %s", churl, err) break } + dl := ChartDownloader{ + Out: m.Out, + Verify: m.Verify, + Keyring: m.Keyring, + HelmHome: m.HelmHome, + Getters: m.Getters, + Username: username, + Password: password, + } + if _, _, err := dl.DownloadTo(churl, "", destPath); err != nil { saveError = fmt.Errorf("could not download %s: %s", churl, err) break @@ -476,22 +478,30 @@ 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) (string, error) { +func 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) { - entry, err := findEntryByName(name, cr) + var entry repo.ChartVersions + entry, err = findEntryByName(name, cr) if err != nil { - return "", err + return } - ve, err := findVersionedEntry(version, entry) + var ve *repo.ChartVersion + ve, err = findVersionedEntry(version, entry) if err != nil { - return "", err + return } - - return normalizeURL(repoURL, ve.URLs[0]) + url, err = normalizeURL(repoURL, ve.URLs[0]) + if err != nil { + return + } + username = cr.Config.Username + password = cr.Config.Password + return } } - return "", fmt.Errorf("chart %s not found in %s", name, repoURL) + err = fmt.Errorf("chart %s not found in %s", name, repoURL) + return } // findEntryByName finds an entry in the chart repository whose name matches the given name. diff --git a/pkg/downloader/manager_test.go b/pkg/downloader/manager_test.go index 091277689..1ff2a9c17 100644 --- a/pkg/downloader/manager_test.go +++ b/pkg/downloader/manager_test.go @@ -77,14 +77,19 @@ func TestFindChartURL(t *testing.T) { version := "0.1.0" repoURL := "http://example.com/charts" - churl, err := findChartURL(name, version, repoURL, repos) + churl, username, password, err := findChartURL(name, version, repoURL, repos) if err != nil { t.Fatal(err) } if churl != "https://kubernetes-charts.storage.googleapis.com/alpine-0.1.0.tgz" { t.Errorf("Unexpected URL %q", churl) } - + if username != "" { + t.Errorf("Unexpected username %q", username) + } + if password != "" { + t.Errorf("Unexpected password %q", password) + } } func TestGetRepoNames(t *testing.T) { diff --git a/pkg/getter/httpgetter.go b/pkg/getter/httpgetter.go index c86b96458..dd462ce5f 100644 --- a/pkg/getter/httpgetter.go +++ b/pkg/getter/httpgetter.go @@ -28,12 +28,23 @@ import ( ) //httpGetter is the efault HTTP(/S) backend handler -type httpGetter struct { - client *http.Client +type HttpGetter struct { + client *http.Client + username string + password string +} + +func (g *HttpGetter) SetCredentials(username, password string) { + g.username = username + g.password = password } //Get performs a Get from repo.Getter and returns the body. -func (g *httpGetter) Get(href string) (*bytes.Buffer, error) { +func (g *HttpGetter) Get(href string) (*bytes.Buffer, error) { + return g.get(href) +} + +func (g *HttpGetter) get(href string) (*bytes.Buffer, error) { buf := bytes.NewBuffer(nil) // Set a helm specific user agent so that a repo server and metrics can @@ -44,6 +55,10 @@ func (g *httpGetter) Get(href string) (*bytes.Buffer, error) { } req.Header.Set("User-Agent", "Helm/"+strings.TrimPrefix(version.GetVersion(), "v")) + if g.username != "" && g.password != "" { + req.SetBasicAuth(g.username, g.password) + } + resp, err := g.client.Do(req) if err != nil { return buf, err @@ -59,17 +74,22 @@ func (g *httpGetter) Get(href string) (*bytes.Buffer, error) { // newHTTPGetter constructs a valid http/https client as Getter func newHTTPGetter(URL, CertFile, KeyFile, CAFile string) (Getter, error) { - var client httpGetter + return NewHTTPGetter(URL, CertFile, KeyFile, CAFile) +} + +// NewHTTPGetter constructs a valid http/https client as HttpGetter +func NewHTTPGetter(URL, CertFile, KeyFile, CAFile string) (*HttpGetter, error) { + var client HttpGetter if CertFile != "" && KeyFile != "" { tlsConf, err := tlsutil.NewClientTLS(CertFile, KeyFile, CAFile) if err != nil { - return nil, fmt.Errorf("can't create TLS config for client: %s", err.Error()) + return &client, fmt.Errorf("can't create TLS config for client: %s", err.Error()) } tlsConf.BuildNameToCertificate() sni, err := urlutil.ExtractHostname(URL) if err != nil { - return nil, err + return &client, err } tlsConf.ServerName = sni diff --git a/pkg/getter/httpgetter_test.go b/pkg/getter/httpgetter_test.go index 477e0bc4f..fe3fde22a 100644 --- a/pkg/getter/httpgetter_test.go +++ b/pkg/getter/httpgetter_test.go @@ -27,7 +27,7 @@ func TestHTTPGetter(t *testing.T) { t.Fatal(err) } - if hg, ok := g.(*httpGetter); !ok { + if hg, ok := g.(*HttpGetter); !ok { t.Fatal("Expected newHTTPGetter to produce an httpGetter") } else if hg.client != http.DefaultClient { t.Fatal("Expected newHTTPGetter to return a default HTTP client.") @@ -42,7 +42,7 @@ func TestHTTPGetter(t *testing.T) { t.Fatal(err) } - if _, ok := g.(*httpGetter); !ok { + if _, ok := g.(*HttpGetter); !ok { t.Fatal("Expected newHTTPGetter to produce an httpGetter") } } diff --git a/pkg/repo/chartrepo.go b/pkg/repo/chartrepo.go index b95a7ae07..c76cc7913 100644 --- a/pkg/repo/chartrepo.go +++ b/pkg/repo/chartrepo.go @@ -36,6 +36,8 @@ type Entry struct { Name string `json:"name"` Cache string `json:"cache"` URL string `json:"url"` + Username string `json:"username"` + Password string `json:"password"` CertFile string `json:"certFile"` KeyFile string `json:"keyFile"` CAFile string `json:"caFile"` @@ -117,7 +119,12 @@ func (r *ChartRepository) DownloadIndexFile(cachePath string) error { parsedURL.Path = strings.TrimSuffix(parsedURL.Path, "/") + "/index.yaml" indexURL = parsedURL.String() - resp, err := r.Client.Get(indexURL) + g, err := getter.NewHTTPGetter(indexURL, r.Config.CertFile, r.Config.KeyFile, r.Config.CAFile) + if err != nil { + return err + } + g.SetCredentials(r.Config.Username, r.Config.Password) + resp, err := g.Get(indexURL) if err != nil { return err } @@ -186,6 +193,13 @@ func (r *ChartRepository) generateIndex() error { // FindChartInRepoURL finds chart in chart repository pointed by repoURL // without adding repo to repositories func FindChartInRepoURL(repoURL, chartName, chartVersion, certFile, keyFile, caFile string, getters getter.Providers) (string, error) { + return FindChartInAuthRepoURL(repoURL, "", "", chartName, chartVersion, certFile, keyFile, caFile, getters) +} + +// FindChartInRepoURL finds chart in chart repository pointed by repoURL +// without adding repo to repositories. +// Unlike the FindChartInRepoURL function, this function also receives credentials for the chart repository. +func FindChartInAuthRepoURL(repoURL, username, password, chartName, chartVersion, certFile, keyFile, caFile string, getters getter.Providers) (string, error) { // Download and write the index file to a temporary location tempIndexFile, err := ioutil.TempFile("", "tmp-repo-file") @@ -196,6 +210,8 @@ func FindChartInRepoURL(repoURL, chartName, chartVersion, certFile, keyFile, caF c := Entry{ URL: repoURL, + Username: username, + Password: password, CertFile: certFile, KeyFile: keyFile, CAFile: caFile, From a615f80c9266c49110773662d7d7c3b6700971c6 Mon Sep 17 00:00:00 2001 From: Arturo Contreras Date: Wed, 14 Mar 2018 16:33:02 -0600 Subject: [PATCH 111/221] Adding --set-string flag to force string values. --- cmd/helm/install.go | 22 ++++++++-- cmd/helm/lint.go | 9 +++++ cmd/helm/template.go | 4 +- cmd/helm/upgrade.go | 8 +++- docs/chart_best_practices/values.md | 2 +- docs/helm/helm_install.md | 62 ++++++++++++++++------------- docs/helm/helm_lint.md | 11 ++--- docs/helm/helm_template.md | 21 +++++----- docs/helm/helm_upgrade.md | 60 ++++++++++++++-------------- pkg/strvals/parser.go | 45 +++++++++++++++------ pkg/strvals/parser_test.go | 40 +++++++++++++++++++ scripts/completions.bash | 2 + 12 files changed, 194 insertions(+), 92 deletions(-) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index a02f543db..1d8ec85f1 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -50,7 +50,8 @@ The install argument must be a chart reference, a path to a packaged chart, a path to an unpacked chart directory or a URL. To override values in a chart, use either the '--values' flag and pass in a file -or use the '--set' flag and pass configuration from the command line. +or use the '--set' flag and pass configuration from the command line, to force +a string value use '--set-string'. $ helm install -f myvalues.yaml ./redis @@ -58,6 +59,10 @@ or $ helm install --set name=prod ./redis +or + + $ helm install --set-string long_int=1234567890 ./redis + You can specify the '--values'/'-f' flag multiple times. The priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called 'Test', the value set in override.yaml would take precedence: @@ -113,6 +118,7 @@ type installCmd struct { out io.Writer client helm.Interface values []string + stringValues []string nameTemplate string version string timeout int64 @@ -186,6 +192,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command { f.BoolVar(&inst.disableHooks, "no-hooks", false, "prevent hooks from running during install") f.BoolVar(&inst.replace, "replace", false, "re-use the given name, even if that name is already used. This is unsafe in production") f.StringArrayVar(&inst.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") + f.StringArrayVar(&inst.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringVar(&inst.nameTemplate, "name-template", "", "specify template used to name the release") f.BoolVar(&inst.verify, "verify", false, "verify the package before installing it") f.StringVar(&inst.keyring, "keyring", defaultKeyring(), "location of public keys used for verification") @@ -211,7 +218,7 @@ func (i *installCmd) run() error { i.namespace = defaultNamespace() } - rawVals, err := vals(i.valueFiles, i.values) + rawVals, err := vals(i.valueFiles, i.values, i.stringValues) if err != nil { return err } @@ -325,8 +332,8 @@ func mergeValues(dest map[string]interface{}, src map[string]interface{}) map[st } // vals merges values from files specified via -f/--values and -// directly via --set, marshaling them to YAML -func vals(valueFiles valueFiles, values []string) ([]byte, error) { +// directly via --set or --set-string, marshaling them to YAML +func vals(valueFiles valueFiles, values []string, stringValues []string) ([]byte, error) { base := map[string]interface{}{} // User specified a values files via -f/--values @@ -359,6 +366,13 @@ func vals(valueFiles valueFiles, values []string) ([]byte, error) { } } + // User specified a value via --set-string + for _, value := range stringValues { + if err := strvals.ParseIntoString(value, base); err != nil { + return []byte{}, fmt.Errorf("failed parsing --set-string data: %s", err) + } + } + return yaml.Marshal(base) } diff --git a/cmd/helm/lint.go b/cmd/helm/lint.go index 29eea1a88..6e08f2747 100644 --- a/cmd/helm/lint.go +++ b/cmd/helm/lint.go @@ -46,6 +46,7 @@ or recommendation, it will emit [WARNING] messages. type lintCmd struct { valueFiles valueFiles values []string + sValues []string namespace string strict bool paths []string @@ -71,6 +72,7 @@ func newLintCmd(out io.Writer) *cobra.Command { cmd.Flags().VarP(&l.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)") cmd.Flags().StringArrayVar(&l.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") + cmd.Flags().StringArrayVar(&l.sValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") cmd.Flags().StringVar(&l.namespace, "namespace", "default", "namespace to install the release into (only used if --install is set)") cmd.Flags().BoolVar(&l.strict, "strict", false, "fail on lint warnings") @@ -192,5 +194,12 @@ func (l *lintCmd) vals() ([]byte, error) { } } + // User specified a value via --set-string + for _, value := range l.sValues { + if err := strvals.ParseIntoString(value, base); err != nil { + return []byte{}, fmt.Errorf("failed parsing --set-string data: %s", err) + } + } + return yaml.Marshal(base) } diff --git a/cmd/helm/template.go b/cmd/helm/template.go index 3a7285fa1..c04bc2dc8 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -68,6 +68,7 @@ type templateCmd struct { chartPath string out io.Writer values []string + stringValues []string nameTemplate string showNotes bool releaseName string @@ -96,6 +97,7 @@ func newTemplateCmd(out io.Writer) *cobra.Command { f.VarP(&t.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)") f.StringVar(&t.namespace, "namespace", "", "namespace to install the release into") f.StringArrayVar(&t.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") + f.StringArrayVar(&t.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringVar(&t.nameTemplate, "name-template", "", "specify template used to name the release") f.StringVar(&t.kubeVersion, "kube-version", defaultKubeVersion, "kubernetes version used as Capabilities.KubeVersion.Major/Minor") f.StringVar(&t.outputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout") @@ -149,7 +151,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error { t.namespace = defaultNamespace() } // get combined values and create config - rawVals, err := vals(t.valueFiles, t.values) + rawVals, err := vals(t.valueFiles, t.values, t.stringValues) if err != nil { return err } diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index aadb59ac2..125796762 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -37,7 +37,8 @@ a packaged chart, or a fully qualified URL. For chart references, the latest version will be specified unless the '--version' flag is set. To override values in a chart, use either the '--values' flag and pass in a file -or use the '--set' flag and pass configuration from the command line. +or use the '--set' flag and pass configuration from the command line, to force string +values, use '--set-string'. You can specify the '--values'/'-f' flag multiple times. The priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml @@ -63,6 +64,7 @@ type upgradeCmd struct { disableHooks bool valueFiles valueFiles values []string + stringValues []string verify bool keyring string install bool @@ -118,6 +120,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command { f.BoolVar(&upgrade.recreate, "recreate-pods", false, "performs pods restart for the resource if applicable") f.BoolVar(&upgrade.force, "force", false, "force resource update through delete/recreate if needed") f.StringArrayVar(&upgrade.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") + f.StringArrayVar(&upgrade.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks. DEPRECATED. Use no-hooks") f.BoolVar(&upgrade.disableHooks, "no-hooks", false, "disable pre/post upgrade hooks") f.BoolVar(&upgrade.verify, "verify", false, "verify the provenance of the chart before upgrading") @@ -183,6 +186,7 @@ func (u *upgradeCmd) run() error { disableHooks: u.disableHooks, keyring: u.keyring, values: u.values, + stringValues: u.stringValues, namespace: u.namespace, timeout: u.timeout, wait: u.wait, @@ -191,7 +195,7 @@ func (u *upgradeCmd) run() error { } } - rawVals, err := vals(u.valueFiles, u.values) + rawVals, err := vals(u.valueFiles, u.values, u.stringValues) if err != nil { return err } diff --git a/docs/chart_best_practices/values.md b/docs/chart_best_practices/values.md index c338f7f4c..2962e7d45 100644 --- a/docs/chart_best_practices/values.md +++ b/docs/chart_best_practices/values.md @@ -92,7 +92,7 @@ There are three potential sources of values: - A chart's `values.yaml` file - A values file supplied by `helm install -f` or `helm upgrade -f` -- The values passed to a `--set` flag on `helm install` or `helm upgrade` +- The values passed to a `--set` or `--set-string` flag on `helm install` or `helm upgrade` When designing the structure of your values, keep in mind that users of your chart may want to override them via either the `-f` flag or with the `--set` diff --git a/docs/helm/helm_install.md b/docs/helm/helm_install.md index 0ae9097ba..25ccea1bd 100644 --- a/docs/helm/helm_install.md +++ b/docs/helm/helm_install.md @@ -12,7 +12,8 @@ The install argument must be a chart reference, a path to a packaged chart, a path to an unpacked chart directory or a URL. To override values in a chart, use either the '--values' flag and pass in a file -or use the '--set' flag and pass configuration from the command line. +or use the '--set' flag and pass configuration from the command line, to force +a string value use '--set-string'. $ helm install -f myvalues.yaml ./redis @@ -20,6 +21,10 @@ or $ helm install --set name=prod ./redis +or + + $ helm install --set-string long_int=1234567890 ./redis + You can specify the '--values'/'-f' flag multiple times. The priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml contained a key called 'Test', the value set in override.yaml would take precedence: @@ -69,32 +74,33 @@ helm install [CHART] ### Options ``` - --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle - --cert-file string identify HTTPS client using this SSL certificate file - --dep-up run helm dependency update before installing the chart - --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored. - --dry-run simulate an install - --key-file string identify HTTPS client using this SSL key file - --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") - -n, --name string release name. If unspecified, it will autogenerate one for you - --name-template string specify template used to name the release - --namespace string namespace to install the release into. Defaults to the current kube config namespace. - --no-hooks prevent hooks from running during install - --password string chart repository password where to locate the requested chart - --replace re-use the given name, even if that name is already used. This is unsafe in production - --repo string chart repository url where to locate the requested chart - --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) - --timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300) - --tls enable TLS for request - --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") - --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") - --tls-key string path to TLS key file (default "$HELM_HOME/key.pem") - --tls-verify enable TLS for request and verify remote - --username string chart repository username where to locate the requested chart - -f, --values valueFiles specify values in a YAML file or a URL(can specify multiple) (default []) - --verify verify the package before installing it - --version string specify the exact chart version to install. If this is not specified, the latest version is installed - --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --dep-up run helm dependency update before installing the chart + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored. + --dry-run simulate an install + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + -n, --name string release name. If unspecified, it will autogenerate one for you + --name-template string specify template used to name the release + --namespace string namespace to install the release into. Defaults to the current kube config namespace. + --no-hooks prevent hooks from running during install + --password string chart repository password where to locate the requested chart + --replace re-use the given name, even if that name is already used. This is unsafe in production + --repo string chart repository url where to locate the requested chart + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300) + --tls enable TLS for request + --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") + --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") + --tls-key string path to TLS key file (default "$HELM_HOME/key.pem") + --tls-verify enable TLS for request and verify remote + --username string chart repository username where to locate the requested chart + -f, --values valueFiles specify values in a YAML file or a URL(can specify multiple) (default []) + --verify verify the package before installing it + --version string specify the exact chart version to install. If this is not specified, the latest version is installed + --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout ``` ### Options inherited from parent commands @@ -111,4 +117,4 @@ helm install [CHART] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 20-Mar-2018 diff --git a/docs/helm/helm_lint.md b/docs/helm/helm_lint.md index da3cdf945..596edf2bb 100644 --- a/docs/helm/helm_lint.md +++ b/docs/helm/helm_lint.md @@ -21,10 +21,11 @@ helm lint [flags] PATH ### Options ``` - --namespace string namespace to install the release into (only used if --install is set) (default "default") - --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) - --strict fail on lint warnings - -f, --values valueFiles specify values in a YAML file (can specify multiple) (default []) + --namespace string namespace to install the release into (only used if --install is set) (default "default") + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --strict fail on lint warnings + -f, --values valueFiles specify values in a YAML file (can specify multiple) (default []) ``` ### Options inherited from parent commands @@ -41,4 +42,4 @@ helm lint [flags] PATH ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 9-Mar-2018 diff --git a/docs/helm/helm_template.md b/docs/helm/helm_template.md index 126adb02f..3a4e9ce4a 100644 --- a/docs/helm/helm_template.md +++ b/docs/helm/helm_template.md @@ -25,15 +25,16 @@ helm template [flags] CHART ### Options ``` - -x, --execute stringArray only execute the given templates - --kube-version string kubernetes version used as Capabilities.KubeVersion.Major/Minor (default "1.9") - -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 - --notes show the computed NOTES.txt file as well - --output-dir string writes the executed templates to files in output-dir instead of stdout - --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) - -f, --values valueFiles specify values in a YAML file (can specify multiple) (default []) + -x, --execute stringArray only execute the given templates + --kube-version string kubernetes version used as Capabilities.KubeVersion.Major/Minor (default "1.9") + -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 + --notes show the computed NOTES.txt file as well + --output-dir string writes the executed templates to files in output-dir instead of stdout + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + -f, --values valueFiles specify values in a YAML file (can specify multiple) (default []) ``` ### Options inherited from parent commands @@ -50,4 +51,4 @@ helm template [flags] CHART ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 9-Mar-2018 diff --git a/docs/helm/helm_upgrade.md b/docs/helm/helm_upgrade.md index 5cbb9a110..7ada6025f 100644 --- a/docs/helm/helm_upgrade.md +++ b/docs/helm/helm_upgrade.md @@ -14,7 +14,8 @@ a packaged chart, or a fully qualified URL. For chart references, the latest version will be specified unless the '--version' flag is set. To override values in a chart, use either the '--values' flag and pass in a file -or use the '--set' flag and pass configuration from the command line. +or use the '--set' flag and pass configuration from the command line, to force string +values, use '--set-string'. You can specify the '--values'/'-f' flag multiple times. The priority will be given to the last (right-most) file specified. For example, if both myvalues.yaml and override.yaml @@ -36,33 +37,34 @@ helm upgrade [RELEASE] [CHART] ### Options ``` - --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle - --cert-file string identify HTTPS client using this SSL certificate file - --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored. - --dry-run simulate an upgrade - --force force resource update through delete/recreate if needed - -i, --install if a release by this name doesn't already exist, run an install - --key-file string identify HTTPS client using this SSL key file - --keyring string path to the keyring that contains public signing keys (default "~/.gnupg/pubring.gpg") - --namespace string namespace to install the release into (only used if --install is set). Defaults to the current kube config namespace - --no-hooks disable pre/post upgrade hooks - --password string chart repository password where to locate the requested chart - --recreate-pods performs pods restart for the resource if applicable - --repo string chart repository url where to locate the requested chart - --reset-values when upgrading, reset the values to the ones built into the chart - --reuse-values when upgrading, reuse the last release's values, and merge in any new values. If '--reset-values' is specified, this is ignored. - --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) - --timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300) - --tls enable TLS for request - --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") - --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") - --tls-key string path to TLS key file (default "$HELM_HOME/key.pem") - --tls-verify enable TLS for request and verify remote - --username string chart repository username where to locate the requested chart - -f, --values valueFiles specify values in a YAML file or a URL(can specify multiple) (default []) - --verify verify the provenance of the chart before upgrading - --version string specify the exact chart version to use. If this is not specified, the latest version is used - --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored. + --dry-run simulate an upgrade + --force force resource update through delete/recreate if needed + -i, --install if a release by this name doesn't already exist, run an install + --key-file string identify HTTPS client using this SSL key file + --keyring string path to the keyring that contains public signing keys (default "~/.gnupg/pubring.gpg") + --namespace string namespace to install the release into (only used if --install is set). Defaults to the current kube config namespace + --no-hooks disable pre/post upgrade hooks + --password string chart repository password where to locate the requested chart + --recreate-pods performs pods restart for the resource if applicable + --repo string chart repository url where to locate the requested chart + --reset-values when upgrading, reset the values to the ones built into the chart + --reuse-values when upgrading, reuse the last release's values, and merge in any new values. If '--reset-values' is specified, this is ignored. + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300) + --tls enable TLS for request + --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") + --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") + --tls-key string path to TLS key file (default "$HELM_HOME/key.pem") + --tls-verify enable TLS for request and verify remote + --username string chart repository username where to locate the requested chart + -f, --values valueFiles specify values in a YAML file or a URL(can specify multiple) (default []) + --verify verify the provenance of the chart before upgrading + --version string specify the exact chart version to use. If this is not specified, the latest version is used + --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout ``` ### Options inherited from parent commands @@ -79,4 +81,4 @@ helm upgrade [RELEASE] [CHART] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 20-Mar-2018 diff --git a/pkg/strvals/parser.go b/pkg/strvals/parser.go index 8e97b4d44..8a999feb7 100644 --- a/pkg/strvals/parser.go +++ b/pkg/strvals/parser.go @@ -45,18 +45,38 @@ func ToYAML(s string) (string, error) { func Parse(s string) (map[string]interface{}, error) { vals := map[string]interface{}{} scanner := bytes.NewBufferString(s) - t := newParser(scanner, vals) + t := newParser(scanner, vals, false) err := t.parse() return vals, err } -//ParseInto parses a strvals line and merges the result into dest. +// Parse parses a set line and forces a string value. +// +// A set line is of the form name1=value1,name2=value2 +func ParseString(s string) (map[string]interface{}, error) { + vals := map[string]interface{}{} + scanner := bytes.NewBufferString(s) + t := newParser(scanner, vals, true) + err := t.parse() + return vals, err +} + +// ParseInto parses a strvals line and merges the result into dest. // // If the strval string has a key that exists in dest, it overwrites the // dest version. func ParseInto(s string, dest map[string]interface{}) error { scanner := bytes.NewBufferString(s) - t := newParser(scanner, dest) + t := newParser(scanner, dest, false) + return t.parse() +} + +// ParseIntoString parses a strvals line nad merges the result into dest. +// +// This method always returns a string as the value. +func ParseIntoString(s string, dest map[string]interface{}) error { + scanner := bytes.NewBufferString(s) + t := newParser(scanner, dest, true) return t.parse() } @@ -65,10 +85,11 @@ func ParseInto(s string, dest map[string]interface{}) error { type parser struct { sc *bytes.Buffer data map[string]interface{} + st bool } -func newParser(sc *bytes.Buffer, data map[string]interface{}) *parser { - return &parser{sc: sc, data: data} +func newParser(sc *bytes.Buffer, data map[string]interface{}, stringBool bool) *parser { + return &parser{sc: sc, data: data, st: stringBool} } func (t *parser) parse() error { @@ -133,7 +154,7 @@ func (t *parser) key(data map[string]interface{}) error { return e case ErrNotList: v, e := t.val() - set(data, string(k), typedVal(v)) + set(data, string(k), typedVal(v, t.st)) return e default: return e @@ -206,7 +227,7 @@ func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) { return setIndex(list, i, ""), err case ErrNotList: v, e := t.val() - return setIndex(list, i, typedVal(v)), e + return setIndex(list, i, typedVal(v, t.st)), e default: return list, e } @@ -265,10 +286,10 @@ func (t *parser) valList() ([]interface{}, error) { if r, _, e := t.sc.ReadRune(); e == nil && r != ',' { t.sc.UnreadRune() } - list = append(list, typedVal(v)) + list = append(list, typedVal(v, t.st)) return list, nil case last == ',': - list = append(list, typedVal(v)) + list = append(list, typedVal(v, t.st)) } } } @@ -298,7 +319,7 @@ func inMap(k rune, m map[rune]bool) bool { return ok } -func typedVal(v []rune) interface{} { +func typedVal(v []rune, st bool) interface{} { val := string(v) if strings.EqualFold(val, "true") { return true @@ -308,8 +329,8 @@ func typedVal(v []rune) interface{} { return false } - // If this value does not start with zero, try parsing it to an int - if len(val) != 0 && val[0] != '0' { + // If this value does not start with zero, and not returnString, try parsing it to an int + if !st && len(val) != 0 && val[0] != '0' { if iv, err := strconv.ParseInt(val, 10, 64); err == nil { return iv } diff --git a/pkg/strvals/parser_test.go b/pkg/strvals/parser_test.go index a3f6e4207..3f9828498 100644 --- a/pkg/strvals/parser_test.go +++ b/pkg/strvals/parser_test.go @@ -65,6 +65,17 @@ func TestSetIndex(t *testing.T) { } func TestParseSet(t *testing.T) { + testsString := []struct { + str string + expect map[string]interface{} + err bool + }{ + { + str: "long_int_string=1234567890", + expect: map[string]interface{}{"long_int_string": "1234567890"}, + err: false, + }, + } tests := []struct { str string expect map[string]interface{} @@ -97,6 +108,10 @@ func TestParseSet(t *testing.T) { str: "leading_zeros=00009", expect: map[string]interface{}{"leading_zeros": "00009"}, }, + { + str: "long_int=1234567890", + expect: map[string]interface{}{"long_int": 1234567890}, + }, { str: "name1,name2=", err: true, @@ -278,6 +293,31 @@ func TestParseSet(t *testing.T) { t.Fatalf("Error serializing parsed value: %s", err) } + if string(y1) != string(y2) { + t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.str, y1, y2) + } + } + for _, tt := range testsString { + got, err := ParseString(tt.str) + if err != nil { + if tt.err { + continue + } + t.Fatalf("%s: %s", tt.str, err) + } + if tt.err { + t.Errorf("%s: Expected error. Got nil", tt.str) + } + + y1, err := yaml.Marshal(tt.expect) + if err != nil { + t.Fatal(err) + } + y2, err := yaml.Marshal(got) + if err != nil { + t.Fatalf("Error serializing parsed value: %s", err) + } + if string(y1) != string(y2) { t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.str, y1, y2) } diff --git a/scripts/completions.bash b/scripts/completions.bash index b2524ea38..c24f3d257 100644 --- a/scripts/completions.bash +++ b/scripts/completions.bash @@ -830,6 +830,8 @@ _helm_install() local_nonpersistent_flags+=("--repo=") flags+=("--set=") local_nonpersistent_flags+=("--set=") + flags+=("--set-string=") + local_nonpersistent_flags+=("--set-string=") flags+=("--timeout=") local_nonpersistent_flags+=("--timeout=") flags+=("--tls") From 1d4883bf3c85ea43ed071dff4e02cc47bb66f44f Mon Sep 17 00:00:00 2001 From: Alexey igrychev Date: Wed, 21 Mar 2018 17:19:53 +0300 Subject: [PATCH 112/221] Implement before-hook-creation delete policy Existing helm.sh/hook-delete-policy annotation variables (hook-failed, hook-succeeded) do not allow to leave failed jobs for debugging without blocking the next job launching: every failed job must be deleted manually before the next related release is launching (installing, updating or rolling back). New policy, before-hook-creation, removes the hook from previous release if there is one before the new hook is launched and can be used with another variable. --- _proto/hapi/release/hook.proto | 1 + docs/charts_hooks.md | 17 +++++++- pkg/hooks/hooks.go | 5 ++- pkg/proto/hapi/release/hook.pb.go | 68 ++++++++++++++++--------------- pkg/tiller/hooks.go | 35 ++++++++-------- pkg/tiller/release_server.go | 39 ++++++++++-------- 6 files changed, 97 insertions(+), 68 deletions(-) diff --git a/_proto/hapi/release/hook.proto b/_proto/hapi/release/hook.proto index 22c1fedef..f0332ecb8 100644 --- a/_proto/hapi/release/hook.proto +++ b/_proto/hapi/release/hook.proto @@ -38,6 +38,7 @@ message Hook { enum DeletePolicy { SUCCEEDED = 0; FAILED = 1; + BEFORE_HOOK_CREATION = 2; } string name = 1; // Kind is the Kubernetes kind. diff --git a/docs/charts_hooks.md b/docs/charts_hooks.md index 5fc9462e4..af6d0f4f9 100644 --- a/docs/charts_hooks.md +++ b/docs/charts_hooks.md @@ -180,4 +180,19 @@ It is also possible to define policies that determine when to delete correspondi "helm.sh/hook-delete-policy": hook-succeeded ``` -When using `"helm.sh/hook-delete-policy"` annotation, you can choose its value from `"hook-succeeded"` and `"hook-failed"`. The value `"hook-succeeded"` specifies Tiller should delete the hook after the hook is successfully executed, while the value `"hook-failed"`specifies Tiller should delete the hook if the hook failed during execution. +You can choose one or more defined annotation values: +* `"hook-succeeded"` specifies Tiller should delete the hook after the hook is successfully executed. +* `"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. + +### Automatically delete hook from previous release + +When helm release being updated it is possible, that hook resource already exists in cluster. By default helm will try to create resource and fail with `"... already exists"` error. + +One might choose `"helm.sh/hook-delete-policy": "before-hook-creation"` over `"helm.sh/hook-delete-policy": "hook-succeeded,hook-failed"` because: + +* It is convinient to keep failed hook job resource in kubernetes for example for manual debug. +* It may be necessary to keep succeeded hook resource in kubernetes for some reason. +* At the same time it is not desireable to do manual resource deletion before helm release upgrade. + +`"helm.sh/hook-delete-policy": "before-hook-creation"` annotation on hook causes tiller to remove the hook from previous release if there is one before the new hook is launched and can be used with another policies. diff --git a/pkg/hooks/hooks.go b/pkg/hooks/hooks.go index ed2d946a4..80f838368 100644 --- a/pkg/hooks/hooks.go +++ b/pkg/hooks/hooks.go @@ -45,8 +45,9 @@ const ( // Type of policy for deleting the hook const ( - HookSucceeded = "hook-succeeded" - HookFailed = "hook-failed" + HookSucceeded = "hook-succeeded" + HookFailed = "hook-failed" + BeforeHookCreation = "before-hook-creation" ) // FilterTestHooks filters the list of hooks are returns only testing hooks. diff --git a/pkg/proto/hapi/release/hook.pb.go b/pkg/proto/hapi/release/hook.pb.go index 508448280..00fa5c188 100644 --- a/pkg/proto/hapi/release/hook.pb.go +++ b/pkg/proto/hapi/release/hook.pb.go @@ -89,17 +89,20 @@ func (Hook_Event) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []i type Hook_DeletePolicy int32 const ( - Hook_SUCCEEDED Hook_DeletePolicy = 0 - Hook_FAILED Hook_DeletePolicy = 1 + Hook_SUCCEEDED Hook_DeletePolicy = 0 + Hook_FAILED Hook_DeletePolicy = 1 + Hook_BEFORE_HOOK_CREATION Hook_DeletePolicy = 2 ) var Hook_DeletePolicy_name = map[int32]string{ 0: "SUCCEEDED", 1: "FAILED", + 2: "BEFORE_HOOK_CREATION", } var Hook_DeletePolicy_value = map[string]int32{ - "SUCCEEDED": 0, - "FAILED": 1, + "SUCCEEDED": 0, + "FAILED": 1, + "BEFORE_HOOK_CREATION": 2, } func (x Hook_DeletePolicy) String() string { @@ -196,32 +199,33 @@ func init() { func init() { proto.RegisterFile("hapi/release/hook.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 428 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0xd1, 0x6e, 0xda, 0x30, - 0x14, 0x86, 0x9b, 0x12, 0x12, 0x38, 0x50, 0xea, 0x59, 0xd3, 0x66, 0x71, 0x53, 0xc4, 0x15, 0xbb, - 0x09, 0x53, 0xa7, 0x3d, 0x40, 0x4a, 0xce, 0xd6, 0xaa, 0x11, 0x20, 0x27, 0x68, 0xd2, 0x6e, 0xa2, - 0x74, 0xb8, 0x10, 0x11, 0xe2, 0x88, 0x98, 0x4d, 0x7b, 0xa6, 0xbd, 0xce, 0x1e, 0x68, 0xb2, 0x09, - 0x59, 0xa5, 0xed, 0xee, 0x9c, 0xef, 0x7c, 0x76, 0xce, 0x1f, 0xc3, 0xdb, 0x6d, 0x5a, 0x66, 0xd3, - 0x83, 0xc8, 0x45, 0x5a, 0x89, 0xe9, 0x56, 0xca, 0x9d, 0x57, 0x1e, 0xa4, 0x92, 0xb4, 0xaf, 0x07, - 0x5e, 0x3d, 0x18, 0xde, 0x6c, 0xa4, 0xdc, 0xe4, 0x62, 0x6a, 0x66, 0x4f, 0xc7, 0xe7, 0xa9, 0xca, - 0xf6, 0xa2, 0x52, 0xe9, 0xbe, 0x3c, 0xe9, 0xe3, 0x5f, 0x36, 0xd8, 0xf7, 0x52, 0xee, 0x28, 0x05, - 0xbb, 0x48, 0xf7, 0x82, 0x59, 0x23, 0x6b, 0xd2, 0xe5, 0xa6, 0xd6, 0x6c, 0x97, 0x15, 0x6b, 0x76, - 0x79, 0x62, 0xba, 0xd6, 0xac, 0x4c, 0xd5, 0x96, 0xb5, 0x4e, 0x4c, 0xd7, 0x74, 0x08, 0x9d, 0x7d, - 0x5a, 0x64, 0xcf, 0xa2, 0x52, 0xcc, 0x36, 0xbc, 0xe9, 0xe9, 0x7b, 0x70, 0xc4, 0x77, 0x51, 0xa8, - 0x8a, 0xb5, 0x47, 0xad, 0xc9, 0xe0, 0x96, 0x79, 0x2f, 0x17, 0xf4, 0xf4, 0xb7, 0x3d, 0xd4, 0x02, - 0xaf, 0x3d, 0xfa, 0x11, 0x3a, 0x79, 0x5a, 0xa9, 0xe4, 0x70, 0x2c, 0x98, 0x33, 0xb2, 0x26, 0xbd, - 0xdb, 0xa1, 0x77, 0x8a, 0xe1, 0x9d, 0x63, 0x78, 0xf1, 0x39, 0x06, 0x77, 0xb5, 0xcb, 0x8f, 0x05, - 0x7d, 0x03, 0xce, 0x0f, 0x91, 0x6d, 0xb6, 0x8a, 0xb9, 0x23, 0x6b, 0xd2, 0xe6, 0x75, 0x47, 0xef, - 0xe1, 0x7a, 0x2d, 0x72, 0xa1, 0x44, 0x52, 0xca, 0x3c, 0xfb, 0x96, 0x89, 0x8a, 0x75, 0xcc, 0x26, - 0x37, 0xff, 0xd9, 0x24, 0x30, 0xe6, 0x52, 0x8b, 0x3f, 0xf9, 0x60, 0xfd, 0xb7, 0xcb, 0x44, 0x35, - 0xfe, 0x6d, 0x41, 0xdb, 0xac, 0x4a, 0x7b, 0xe0, 0xae, 0xe6, 0x8f, 0xf3, 0xc5, 0x97, 0x39, 0xb9, - 0xa0, 0xd7, 0xd0, 0x5b, 0x72, 0x4c, 0x1e, 0xe6, 0x51, 0xec, 0x87, 0x21, 0xb1, 0x28, 0x81, 0xfe, - 0x72, 0x11, 0xc5, 0x0d, 0xb9, 0xa4, 0x03, 0x00, 0xad, 0x04, 0x18, 0x62, 0x8c, 0xa4, 0x65, 0x8e, - 0x68, 0xa3, 0x06, 0xf6, 0xf9, 0x8e, 0xd5, 0xf2, 0x33, 0xf7, 0x03, 0x24, 0xed, 0xe6, 0x8e, 0x33, - 0x71, 0x0c, 0xe1, 0x98, 0xf0, 0x45, 0x18, 0xde, 0xf9, 0xb3, 0x47, 0xe2, 0xd2, 0x57, 0x70, 0x65, - 0x9c, 0x06, 0x75, 0x28, 0x83, 0xd7, 0x1c, 0x43, 0xf4, 0x23, 0x4c, 0x62, 0x8c, 0xe2, 0x24, 0x5a, - 0xcd, 0x66, 0x18, 0x45, 0xa4, 0xfb, 0xcf, 0xe4, 0x93, 0xff, 0x10, 0xae, 0x38, 0x12, 0x18, 0xbf, - 0x83, 0xfe, 0xcb, 0xd8, 0xf4, 0x0a, 0xba, 0xe6, 0x18, 0x06, 0x18, 0x90, 0x0b, 0x0a, 0xe0, 0x68, - 0x17, 0x03, 0x62, 0xdd, 0x75, 0xbf, 0xba, 0xf5, 0xef, 0x7a, 0x72, 0xcc, 0x5b, 0x7c, 0xf8, 0x13, - 0x00, 0x00, 0xff, 0xff, 0xb9, 0x8a, 0xe1, 0xaf, 0x89, 0x02, 0x00, 0x00, + // 445 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x51, 0x8f, 0x9a, 0x40, + 0x10, 0x80, 0x8f, 0x13, 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, 0x0f, 0xec, 0x3f, 0xe8, 0x0f, 0x6a, 0x76, 0x45, 0x7b, + 0x49, 0xfb, 0x36, 0xf3, 0xcd, 0x37, 0xc3, 0x0c, 0x0b, 0xef, 0x77, 0x49, 0x99, 0x4e, 0x8f, 0x22, + 0x13, 0x49, 0x25, 0xa6, 0xbb, 0xa2, 0xd8, 0x5b, 0xe5, 0xb1, 0xa8, 0x0b, 0xda, 0x97, 0x05, 0xab, + 0x29, 0x0c, 0x1f, 0xb6, 0x45, 0xb1, 0xcd, 0xc4, 0x54, 0xd5, 0x9e, 0x4f, 0x2f, 0xd3, 0x3a, 0x3d, + 0x88, 0xaa, 0x4e, 0x0e, 0xe5, 0x59, 0x1f, 0xff, 0xd2, 0x41, 0x9f, 0x17, 0xc5, 0x9e, 0x52, 0xd0, + 0xf3, 0xe4, 0x20, 0x98, 0x36, 0xd2, 0x26, 0x5d, 0xae, 0x62, 0xc9, 0xf6, 0x69, 0xbe, 0x61, 0xb7, + 0x67, 0x26, 0x63, 0xc9, 0xca, 0xa4, 0xde, 0xb1, 0xd6, 0x99, 0xc9, 0x98, 0x0e, 0xa1, 0x73, 0x48, + 0xf2, 0xf4, 0x45, 0x54, 0x35, 0xd3, 0x15, 0xbf, 0xe6, 0xf4, 0x03, 0x18, 0xe2, 0xbb, 0xc8, 0xeb, + 0x8a, 0xb5, 0x47, 0xad, 0xc9, 0xe0, 0x91, 0x59, 0xaf, 0x17, 0xb4, 0xe4, 0xb7, 0x2d, 0x94, 0x02, + 0x6f, 0x3c, 0xfa, 0x09, 0x3a, 0x59, 0x52, 0xd5, 0xf1, 0xf1, 0x94, 0x33, 0x63, 0xa4, 0x4d, 0x7a, + 0x8f, 0x43, 0xeb, 0x7c, 0x86, 0x75, 0x39, 0xc3, 0x8a, 0x2e, 0x67, 0x70, 0x53, 0xba, 0xfc, 0x94, + 0xd3, 0x77, 0x60, 0xfc, 0x10, 0xe9, 0x76, 0x57, 0x33, 0x73, 0xa4, 0x4d, 0xda, 0xbc, 0xc9, 0xe8, + 0x1c, 0xee, 0x37, 0x22, 0x13, 0xb5, 0x88, 0xcb, 0x22, 0x4b, 0xbf, 0xa5, 0xa2, 0x62, 0x1d, 0xb5, + 0xc9, 0xc3, 0x7f, 0x36, 0x71, 0x95, 0xb9, 0x92, 0xe2, 0x4f, 0x3e, 0xd8, 0xfc, 0xcd, 0x52, 0x51, + 0x8d, 0x7f, 0x6b, 0xd0, 0x56, 0xab, 0xd2, 0x1e, 0x98, 0x6b, 0x7f, 0xe9, 0x07, 0x5f, 0x7c, 0x72, + 0x43, 0xef, 0xa1, 0xb7, 0xe2, 0x18, 0x2f, 0xfc, 0x30, 0xb2, 0x3d, 0x8f, 0x68, 0x94, 0x40, 0x7f, + 0x15, 0x84, 0xd1, 0x95, 0xdc, 0xd2, 0x01, 0x80, 0x54, 0x5c, 0xf4, 0x30, 0x42, 0xd2, 0x52, 0x2d, + 0xd2, 0x68, 0x80, 0x7e, 0x99, 0xb1, 0x5e, 0x7d, 0xe6, 0xb6, 0x8b, 0xa4, 0x7d, 0x9d, 0x71, 0x21, + 0x86, 0x22, 0x1c, 0x63, 0x1e, 0x78, 0xde, 0xcc, 0x76, 0x96, 0xc4, 0xa4, 0x6f, 0xe0, 0x4e, 0x39, + 0x57, 0xd4, 0xa1, 0x0c, 0xde, 0x72, 0xf4, 0xd0, 0x0e, 0x31, 0x8e, 0x30, 0x8c, 0xe2, 0x70, 0xed, + 0x38, 0x18, 0x86, 0xa4, 0xfb, 0x4f, 0xe5, 0xc9, 0x5e, 0x78, 0x6b, 0x8e, 0x04, 0xc6, 0x0e, 0xf4, + 0x5f, 0x9f, 0x4d, 0xef, 0xa0, 0xab, 0xda, 0xd0, 0x45, 0x97, 0xdc, 0x50, 0x00, 0x43, 0xba, 0xe8, + 0x12, 0x4d, 0x0e, 0x99, 0xe1, 0x53, 0xc0, 0x31, 0x9e, 0x07, 0xc1, 0x32, 0x76, 0x38, 0xda, 0xd1, + 0x22, 0xf0, 0xc9, 0xed, 0xac, 0xfb, 0xd5, 0x6c, 0x7e, 0xe4, 0xb3, 0xa1, 0x5e, 0xe9, 0xe3, 0x9f, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x13, 0x64, 0x75, 0x6c, 0xa3, 0x02, 0x00, 0x00, } diff --git a/pkg/tiller/hooks.go b/pkg/tiller/hooks.go index 6ac2cc636..e1e965d08 100644 --- a/pkg/tiller/hooks.go +++ b/pkg/tiller/hooks.go @@ -46,8 +46,9 @@ var events = map[string]release.Hook_Event{ // deletePolices represents a mapping between the key in the annotation for label deleting policy and its real meaning var deletePolices = map[string]release.Hook_DeletePolicy{ - hooks.HookSucceeded: release.Hook_SUCCEEDED, - hooks.HookFailed: release.Hook_FAILED, + hooks.HookSucceeded: release.Hook_SUCCEEDED, + hooks.HookFailed: release.Hook_FAILED, + hooks.BeforeHookCreation: release.Hook_BEFORE_HOOK_CREATION, } // Manifest represents a manifest file, which has a name and some content. @@ -189,21 +190,14 @@ func (file *manifestFile) sort(result *result) error { result.hooks = append(result.hooks, h) - isKnownDeletePolices := false - dps, ok := entry.Metadata.Annotations[hooks.HookDeleteAnno] - if ok { - for _, dp := range strings.Split(dps, ",") { - dp = strings.ToLower(strings.TrimSpace(dp)) - p, exist := deletePolices[dp] - if exist { - isKnownDeletePolices = true - h.DeletePolicies = append(h.DeletePolicies, p) - } + operateAnnotationValues(entry, hooks.HookDeleteAnno, func(value string) { + policy, exist := deletePolices[value] + if exist { + h.DeletePolicies = append(h.DeletePolicies, policy) + } else { + log.Printf("info: skipping unknown hook delete policy: %q", value) } - if !isKnownDeletePolices { - log.Printf("info: skipping unknown hook delete policy: %q", dps) - } - } + }) } return nil @@ -228,3 +222,12 @@ func calculateHookWeight(entry util.SimpleHead) int32 { return int32(hw) } + +func operateAnnotationValues(entry util.SimpleHead, annotation string, operate func(p string)) { + if dps, ok := entry.Metadata.Annotations[annotation]; ok { + for _, dp := range strings.Split(dps, ",") { + dp = strings.ToLower(strings.TrimSpace(dp)) + operate(dp) + } + } +} diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index a96c64938..eaa6515bb 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -347,6 +347,9 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin executingHooks = sortByHookWeight(executingHooks) for _, h := range executingHooks { + if err := s.deleteHookIfShouldBeDeletedByDeletePolicy(h, hooks.BeforeHookCreation, name, namespace, hook, kubeCli); err != nil { + return err + } b := bytes.NewBufferString(h.Manifest) if err := kubeCli.Create(namespace, b, timeout, false); err != nil { @@ -356,18 +359,13 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin // No way to rewind a bytes.Buffer()? b.Reset() b.WriteString(h.Manifest) + if err := kubeCli.WatchUntilReady(namespace, b, timeout, false); err != nil { s.Log("warning: Release %s %s %s could not complete: %s", name, hook, h.Path, err) // If a hook is failed, checkout the annotation of the hook to determine whether the hook should be deleted // under failed condition. If so, then clear the corresponding resource object in the hook - if hookShouldBeDeleted(h, hooks.HookFailed) { - b.Reset() - b.WriteString(h.Manifest) - s.Log("deleting %s hook %s for release %s due to %q policy", hook, h.Name, name, hooks.HookFailed) - if errHookDelete := kubeCli.Delete(namespace, b); errHookDelete != nil { - s.Log("warning: Release %s %s %S could not be deleted: %s", name, hook, h.Path, errHookDelete) - return errHookDelete - } + if err := s.deleteHookIfShouldBeDeletedByDeletePolicy(h, hooks.HookFailed, name, namespace, hook, kubeCli); err != nil { + return err } return err } @@ -377,13 +375,8 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin // If all hooks are succeeded, checkout the annotation of each hook to determine whether the hook should be deleted // under succeeded condition. If so, then clear the corresponding resource object in each hook for _, h := range executingHooks { - b := bytes.NewBufferString(h.Manifest) - if hookShouldBeDeleted(h, hooks.HookSucceeded) { - s.Log("deleting %s hook %s for release %s due to %q policy", hook, h.Name, name, hooks.HookSucceeded) - if errHookDelete := kubeCli.Delete(namespace, b); errHookDelete != nil { - s.Log("warning: Release %s %s %S could not be deleted: %s", name, hook, h.Path, errHookDelete) - return errHookDelete - } + if err := s.deleteHookIfShouldBeDeletedByDeletePolicy(h, hooks.HookSucceeded, name, namespace, hook, kubeCli); err != nil { + return err } h.LastRun = timeconv.Now() } @@ -409,11 +402,23 @@ func validateReleaseName(releaseName string) error { return nil } +func (s *ReleaseServer) deleteHookIfShouldBeDeletedByDeletePolicy(h *release.Hook, policy string, name, namespace, hook string, kubeCli environment.KubeClient) error { + 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 { + s.Log("warning: Release %s %s %S could not be deleted: %s", name, hook, h.Path, errHookDelete) + return errHookDelete + } + } + return nil +} + // hookShouldBeDeleted determines whether the defined hook deletion policy matches the hook deletion polices // supported by helm. If so, mark the hook as one should be deleted. -func hookShouldBeDeleted(hook *release.Hook, policy string) bool { +func hookHasDeletePolicy(h *release.Hook, policy string) bool { if dp, ok := deletePolices[policy]; ok { - for _, v := range hook.DeletePolicies { + for _, v := range h.DeletePolicies { if dp == v { return true } From 332dc83c46b1cb135bc42b7afa1c9b50629e0e15 Mon Sep 17 00:00:00 2001 From: Morgan Parry Date: Wed, 13 Dec 2017 15:50:25 +0000 Subject: [PATCH 113/221] (fix) Handle caFile alone being set for repos Previously it was only respected if certFile and keyFile were also specified. However, these are independent features. --- pkg/getter/httpgetter.go | 15 +++---------- pkg/getter/httpgetter_test.go | 20 +++++++++++++---- pkg/tlsutil/tls.go | 42 ++++++++++++++++++++++++++++------- 3 files changed, 53 insertions(+), 24 deletions(-) diff --git a/pkg/getter/httpgetter.go b/pkg/getter/httpgetter.go index dd462ce5f..d04b1076c 100644 --- a/pkg/getter/httpgetter.go +++ b/pkg/getter/httpgetter.go @@ -23,7 +23,6 @@ import ( "strings" "k8s.io/helm/pkg/tlsutil" - "k8s.io/helm/pkg/urlutil" "k8s.io/helm/pkg/version" ) @@ -80,19 +79,11 @@ func newHTTPGetter(URL, CertFile, KeyFile, CAFile string) (Getter, error) { // NewHTTPGetter constructs a valid http/https client as HttpGetter func NewHTTPGetter(URL, CertFile, KeyFile, CAFile string) (*HttpGetter, error) { var client HttpGetter - if CertFile != "" && KeyFile != "" { - tlsConf, err := tlsutil.NewClientTLS(CertFile, KeyFile, CAFile) + if (CertFile != "" && KeyFile != "") || CAFile != "" { + tlsConf, err := tlsutil.NewTLSConfig(URL, CertFile, KeyFile, CAFile) if err != nil { - return &client, fmt.Errorf("can't create TLS config for client: %s", err.Error()) + return &client, fmt.Errorf("can't create TLS config: %s", err.Error()) } - tlsConf.BuildNameToCertificate() - - sni, err := urlutil.ExtractHostname(URL) - if err != nil { - return &client, err - } - tlsConf.ServerName = sni - client.client = &http.Client{ Transport: &http.Transport{ TLSClientConfig: tlsConf, diff --git a/pkg/getter/httpgetter_test.go b/pkg/getter/httpgetter_test.go index fe3fde22a..ec730f401 100644 --- a/pkg/getter/httpgetter_test.go +++ b/pkg/getter/httpgetter_test.go @@ -28,7 +28,7 @@ func TestHTTPGetter(t *testing.T) { } if hg, ok := g.(*HttpGetter); !ok { - t.Fatal("Expected newHTTPGetter to produce an httpGetter") + t.Fatal("Expected newHTTPGetter to produce an HttpGetter") } else if hg.client != http.DefaultClient { t.Fatal("Expected newHTTPGetter to return a default HTTP client.") } @@ -37,12 +37,24 @@ func TestHTTPGetter(t *testing.T) { cd := "../../testdata" join := filepath.Join ca, pub, priv := join(cd, "ca.pem"), join(cd, "crt.pem"), join(cd, "key.pem") - g, err = newHTTPGetter("http://example.com/", pub, priv, ca) + g, err = newHTTPGetter("https://example.com/", pub, priv, ca) if err != nil { t.Fatal(err) } + if hg, ok := g.(*HttpGetter); !ok { + t.Fatal("Expected newHTTPGetter to produce an HttpGetter") + } else if hg.client == http.DefaultClient { + t.Fatal("Expected newHTTPGetter to return a non-default HTTP client") + } - if _, ok := g.(*HttpGetter); !ok { - t.Fatal("Expected newHTTPGetter to produce an httpGetter") + // Test with SSL, caFile only + g, err = newHTTPGetter("https://example.com/", "", "", ca) + if err != nil { + t.Fatal(err) + } + if hg, ok := g.(*HttpGetter); !ok { + t.Fatal("Expected newHTTPGetter to produce an HttpGetter") + } else if hg.client == http.DefaultClient { + t.Fatal("Expected newHTTPGetter to return a non-default HTTP client") } } diff --git a/pkg/tlsutil/tls.go b/pkg/tlsutil/tls.go index df698fd4e..c166a1662 100644 --- a/pkg/tlsutil/tls.go +++ b/pkg/tlsutil/tls.go @@ -21,17 +21,20 @@ import ( "crypto/x509" "fmt" "io/ioutil" + "k8s.io/helm/pkg/urlutil" ) -// NewClientTLS returns tls.Config appropriate for client auth. -func NewClientTLS(certFile, keyFile, caFile string) (*tls.Config, error) { - cert, err := CertFromFilePair(certFile, keyFile) - if err != nil { - return nil, err - } - config := tls.Config{ - Certificates: []tls.Certificate{*cert}, +func newTLSConfigCommon(certFile, keyFile, caFile string) (*tls.Config, error) { + config := tls.Config{} + + if certFile != "" && keyFile != "" { + cert, err := CertFromFilePair(certFile, keyFile) + if err != nil { + return nil, err + } + config.Certificates = []tls.Certificate{*cert} } + if caFile != "" { cp, err := CertPoolFromFile(caFile) if err != nil { @@ -39,9 +42,32 @@ func NewClientTLS(certFile, keyFile, caFile string) (*tls.Config, error) { } config.RootCAs = cp } + return &config, nil } +// NewClientTLS returns tls.Config appropriate for client auth. +func NewClientTLS(certFile, keyFile, caFile string) (*tls.Config, error) { + return newTLSConfigCommon(certFile, keyFile, caFile) +} + +// NewTLSConfig returns tls.Config appropriate for client and/or server auth. +func NewTLSConfig(url, certFile, keyFile, caFile string) (*tls.Config, error) { + config, err := newTLSConfigCommon(certFile, keyFile, caFile) + if err != nil { + return nil, err + } + config.BuildNameToCertificate() + + serverName, err := urlutil.ExtractHostname(url) + if err != nil { + return nil, err + } + config.ServerName = serverName + + return config, nil +} + // CertPoolFromFile returns an x509.CertPool containing the certificates // in the given PEM-encoded file. // Returns an error if the file could not be read, a certificate could not From 141e0155903f85d245e156746fadfca4bf6734fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Helgi=20=C3=9Eorbj=C3=B6rnsson?= Date: Wed, 21 Mar 2018 17:28:27 -0700 Subject: [PATCH 114/221] Create index.yaml if missing when running repo index --merge Fixes #3682 --- cmd/helm/repo_index.go | 14 +++++++++++--- cmd/helm/repo_index_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/cmd/helm/repo_index.go b/cmd/helm/repo_index.go index 95e4b8aac..540057eb8 100644 --- a/cmd/helm/repo_index.go +++ b/cmd/helm/repo_index.go @@ -19,6 +19,7 @@ package main import ( "fmt" "io" + "os" "path/filepath" "github.com/spf13/cobra" @@ -86,9 +87,16 @@ func index(dir, url, mergeTo string) error { return err } if mergeTo != "" { - i2, err := repo.LoadIndexFile(mergeTo) - if err != nil { - return fmt.Errorf("Merge failed: %s", err) + // if index.yaml is missing then create an empty one to merge into + var i2 *repo.IndexFile + if _, err := os.Stat(mergeTo); os.IsNotExist(err) { + i2 = repo.NewIndexFile() + i2.WriteFile(mergeTo, 0755) + } else { + i2, err = repo.LoadIndexFile(mergeTo) + if err != nil { + return fmt.Errorf("Merge failed: %s", err) + } } i.Merge(i2) } diff --git a/cmd/helm/repo_index_test.go b/cmd/helm/repo_index_test.go index bd1010dd7..4d6313f6c 100644 --- a/cmd/helm/repo_index_test.go +++ b/cmd/helm/repo_index_test.go @@ -112,6 +112,36 @@ func TestRepoIndexCmd(t *testing.T) { if vs[0].Version != expectedVersion { t.Errorf("expected %q, got %q", expectedVersion, vs[0].Version) } + + // test that index.yaml gets generated on merge even when it doesn't exist + if err := os.Remove(destIndex); err != nil { + t.Fatal(err) + } + + c.ParseFlags([]string{"--merge", destIndex}) + if err := c.RunE(c, []string{dir}); err != nil { + t.Error(err) + } + + _, err = repo.LoadIndexFile(destIndex) + if err != nil { + t.Fatal(err) + } + + // verify it didn't create an empty index.yaml and the merged happened + if len(index.Entries) != 2 { + t.Errorf("expected 2 entries, got %d: %#v", len(index.Entries), index.Entries) + } + + vs = index.Entries["compressedchart"] + if len(vs) != 3 { + t.Errorf("expected 3 versions, got %d: %#v", len(vs), vs) + } + + expectedVersion = "0.3.0" + if vs[0].Version != expectedVersion { + t.Errorf("expected %q, got %q", expectedVersion, vs[0].Version) + } } func linkOrCopy(old, new string) error { From 502db80b263a9498535f42c71e36adcdbacad4fa Mon Sep 17 00:00:00 2001 From: James Strachan Date: Thu, 22 Mar 2018 08:22:09 +0000 Subject: [PATCH 115/221] add a link to Jenkins X and how it uses helm for promoting applications through environments via GitOps --- docs/related.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/related.md b/docs/related.md index c14eb3880..dfe0b1c1f 100644 --- a/docs/related.md +++ b/docs/related.md @@ -69,6 +69,7 @@ Tools layered on top of Helm or Tiller. - [ChartMuseum](https://github.com/chartmuseum/chartmuseum) - Helm Chart Repository with support for Amazon S3 and Google Cloud Storage - [Helm.NET](https://github.com/qmfrederik/helm) - A .NET client for Tiller's API - [Codefresh](https://codefresh.io) - Kubernetes native CI/CD and management platform with UI dashboards for managing Helm charts and releases +- [Jenkins X](http://jenkins-x.io/) - open source automated C/CD for Kubernetes which uses Helm for [promoting](http://jenkins-x.io/about/features/#promotion) applications through [environments via GitOps](http://jenkins-x.io/about/features/#environments) ## Helm Included From 908addd6fc778515fc0b2ed54a5050149554b961 Mon Sep 17 00:00:00 2001 From: Ferenc- Date: Thu, 22 Mar 2018 14:51:45 +0100 Subject: [PATCH 116/221] Fix HTML parsing when setting TAG with wget Now the parsing part is the same as in the curl scenario --- scripts/get | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/get b/scripts/get index 6654fd226..3c4fb9f7d 100755 --- a/scripts/get +++ b/scripts/get @@ -80,7 +80,7 @@ checkDesiredVersion() { if type "curl" > /dev/null; then TAG=$(curl -SsL $release_url | awk '/\/tag\//' | grep -v no-underline | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}' | awk 'a !~ $0{print}; {a=$0}') elif type "wget" > /dev/null; then - TAG=$(wget -q -O - $release_url | awk '/\/tag\//' | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}' | awk 'a !~ $0{print}; {a=$0}') + TAG=$(wget -q -O - $release_url | awk '/\/tag\//' | grep -v no-underline | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}' | awk 'a !~ $0{print}; {a=$0}') fi if [ "x$TAG" == "x" ]; then echo "Cannot determine ${DESIRED_VERSION} tag." From bddb6591d46ce176e87668ed458da54fa0da5eaf Mon Sep 17 00:00:00 2001 From: fqsghostcloud Date: Thu, 22 Mar 2018 23:21:32 +0800 Subject: [PATCH 117/221] fix Syntax error fix Syntax error --- docs/chart_repository.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chart_repository.md b/docs/chart_repository.md index 5a24249b8..01d457e63 100644 --- a/docs/chart_repository.md +++ b/docs/chart_repository.md @@ -275,7 +275,7 @@ fantastic-charts https://fantastic-charts.storage.googleapis.com If the charts are backed by HTTP basic authentication, you can also supply the username and password here: -``console +```console $ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com --username my-username --password my-password $ helm repo list fantastic-charts https://fantastic-charts.storage.googleapis.com From 49cda9a81d4453f2e9b67f701dd1db9a48561bb4 Mon Sep 17 00:00:00 2001 From: Justin Scott Date: Thu, 22 Mar 2018 12:23:11 -0700 Subject: [PATCH 118/221] Add issue_template.md which asks for version info. --- .github/issue_template.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/issue_template.md diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 000000000..f4a3a8219 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,9 @@ + + +Helm version: + +Kubernetes version: + +Cloud Provider/Platform (AKS, GKE, Minikube etc.): + + From 537bfbb75ef25cc3f3e18607d98a7c2633aab9f0 Mon Sep 17 00:00:00 2001 From: Justin Scott Date: Thu, 22 Mar 2018 13:21:03 -0700 Subject: [PATCH 119/221] Update to specify version command output. --- .github/issue_template.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/issue_template.md b/.github/issue_template.md index f4a3a8219..48f48e5b6 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -1,8 +1,8 @@ -Helm version: +Output of `helm version`: -Kubernetes version: +Output of `kubectl version`: Cloud Provider/Platform (AKS, GKE, Minikube etc.): From 6abbee0d44f2890ad76cb5f2bd09a79a540a63d9 Mon Sep 17 00:00:00 2001 From: James Strachan Date: Fri, 23 Mar 2018 06:33:25 +0000 Subject: [PATCH 120/221] fixed typo + moved into Helm Included section --- docs/related.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/related.md b/docs/related.md index dfe0b1c1f..997e3f01d 100644 --- a/docs/related.md +++ b/docs/related.md @@ -69,7 +69,6 @@ Tools layered on top of Helm or Tiller. - [ChartMuseum](https://github.com/chartmuseum/chartmuseum) - Helm Chart Repository with support for Amazon S3 and Google Cloud Storage - [Helm.NET](https://github.com/qmfrederik/helm) - A .NET client for Tiller's API - [Codefresh](https://codefresh.io) - Kubernetes native CI/CD and management platform with UI dashboards for managing Helm charts and releases -- [Jenkins X](http://jenkins-x.io/) - open source automated C/CD for Kubernetes which uses Helm for [promoting](http://jenkins-x.io/about/features/#promotion) applications through [environments via GitOps](http://jenkins-x.io/about/features/#environments) ## Helm Included @@ -79,6 +78,7 @@ Platforms, distributions, and services that include Helm support. - [Cabin](http://www.skippbox.com/cabin/) - Mobile App for Managing Kubernetes - [Qstack](https://qstack.com) - [Fabric8](https://fabric8.io) - Integrated development platform for Kubernetes +- [Jenkins X](http://jenkins-x.io/) - open source automated CI/CD for Kubernetes which uses Helm for [promoting](http://jenkins-x.io/about/features/#promotion) applications through [environments via GitOps](http://jenkins-x.io/about/features/#environments) ## Misc From 9d0dc294d76d1401809b586a75e7bec000f4aa22 Mon Sep 17 00:00:00 2001 From: Russell Morrisey Date: Fri, 23 Mar 2018 15:43:54 -0400 Subject: [PATCH 121/221] Updated to mention the --purge flag on delete See: https://github.com/kubernetes/helm/issues/2332 --- docs/install_faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/install_faq.md b/docs/install_faq.md index ff9ee89e6..f2eae5b48 100644 --- a/docs/install_faq.md +++ b/docs/install_faq.md @@ -224,7 +224,7 @@ I am trying to remove stuff. **Q: When I delete the Tiller deployment, how come all the releases are still there?** Releases are stored in ConfigMaps inside of the `kube-system` namespace. You will -have to manually delete them to get rid of the record. +have to manually delete them to get rid of the record, or use ```helm delete --purge```. **Q: I want to delete my local Helm. Where are all its files?** From 6a59683c01f053ab6490a82f64985aeea9894358 Mon Sep 17 00:00:00 2001 From: cameronconradt <16780811+cameronconradt@users.noreply.github.com> Date: Fri, 23 Mar 2018 23:57:35 -0600 Subject: [PATCH 122/221] Update files.go Should suppress the warnings about the naming of these two functions. Added TODO --- pkg/chartutil/files.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go index a711a3366..f9fc0a26d 100644 --- a/pkg/chartutil/files.go +++ b/pkg/chartutil/files.go @@ -211,7 +211,8 @@ func ToToml(v interface{}) string { // always return a string, even on marshal error (empty string). // // This is designed to be called from a template. -func ToJson(v interface{}) string { +//TODO:change the function signature in Helm 3 +func ToJson(v interface{}) string { //nolint data, err := json.Marshal(v) if err != nil { // Swallow errors inside of a template. @@ -226,7 +227,8 @@ func ToJson(v interface{}) string { // JSON documents. Additionally, because its intended use is within templates // it tolerates errors. It will insert the returned error message string into // m["Error"] in the returned map. -func FromJson(str string) map[string]interface{} { +//TODO:change the function signature in Helm 3 +func FromJson(str string) map[string]interface{} { //nolint m := map[string]interface{}{} if err := json.Unmarshal([]byte(str), &m); err != nil { From 31c03a24845a29fd4bf32c5ad934424acc9bf18e Mon Sep 17 00:00:00 2001 From: AdamDang Date: Sun, 25 Mar 2018 15:51:57 +0800 Subject: [PATCH 123/221] Update tiller_ssl.md "that" is duplicated. --- docs/tiller_ssl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tiller_ssl.md b/docs/tiller_ssl.md index db1603068..d7f0166c4 100644 --- a/docs/tiller_ssl.md +++ b/docs/tiller_ssl.md @@ -251,7 +251,7 @@ This configuration sends our client-side certificate to establish identity, uses the client key for encryption, and uses the CA certificate to validate the remote Tiller's identity. -Typing a line that that is cumbersome, though. The shortcut is to move the key, +Typing a line that is cumbersome, though. The shortcut is to move the key, cert, and CA into `$HELM_HOME`: ```console From 7c19cb7040810f0eaedb50ca29eafb108bd9611e Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Mon, 26 Mar 2018 22:15:36 -0700 Subject: [PATCH 124/221] ref(*): kubernetes v1.10 support --- glide.lock | 184 +++++++++----------------------- glide.yaml | 20 ++-- pkg/kube/client.go | 14 ++- pkg/kube/client_test.go | 226 ++++++++++++---------------------------- 4 files changed, 133 insertions(+), 311 deletions(-) diff --git a/glide.lock b/glide.lock index 1ccdae61c..068f86372 100644 --- a/glide.lock +++ b/glide.lock @@ -1,71 +1,20 @@ -hash: d93f565214b112cf8560e9cd2da2f3ab7852a1f19544569fc112bd4fb2d1d506 -updated: 2018-03-08T14:06:06.497394911-08:00 +hash: 6837936360d447b64aa7a09d3c89c18ac5540b009a57fc4d3227af299bf40268 +updated: 2018-03-27T05:13:24.967040785Z imports: -- name: cloud.google.com/go - version: 3b1ae45394a234c385be014e9a488f2bb6eef821 - repo: https://github.com/GoogleCloudPlatform/google-cloud-go.git - subpackages: - - compute - - compute/metadata - - internal - name: github.com/aokoli/goutils version: 9c37978a95bd5c709a15883b6242714ea6709e64 - name: github.com/asaskevich/govalidator version: 7664702784775e51966f0885f5cd27435916517b -- name: github.com/aws/aws-sdk-go - version: 760741802ad40f49ae9fc4a69ef6706d2527d62e - subpackages: - - aws - - aws/awserr - - aws/awsutil - - aws/client - - aws/client/metadata - - aws/corehandlers - - aws/credentials - - aws/credentials/ec2rolecreds - - aws/credentials/endpointcreds - - aws/credentials/stscreds - - aws/defaults - - aws/ec2metadata - - aws/endpoints - - aws/request - - aws/session - - aws/signer/v4 - - internal/shareddefaults - - private/protocol - - private/protocol/ec2query - - private/protocol/json/jsonutil - - private/protocol/jsonrpc - - private/protocol/query - - private/protocol/query/queryutil - - private/protocol/rest - - private/protocol/xml/xmlutil - - service/autoscaling - - service/ec2 - - service/ecr - - service/elb - - service/elbv2 - - service/kms - - service/sts - name: github.com/Azure/go-ansiterm version: 19f72df4d05d31cbe1c56bfc8045c96babff6c7e subpackages: - winterm -- name: github.com/Azure/go-autorest - version: e14a70c556c8e0db173358d1a903dca345a8e75e - subpackages: - - autorest - - autorest/adal - - autorest/azure - - autorest/date - name: github.com/beorn7/perks version: 3ac7bf7a47d159a033b107610db8a1b6575507a4 subpackages: - quantile - name: github.com/BurntSushi/toml version: b26d9c308763d68093482582cea63d69be07a0f0 -- name: github.com/chai2010/gettext-go - version: bf70f2a70fb1b1f36d90d671a72795984eab0fcb - name: github.com/cpuguy83/go-md2man version: 71acacd42f85e5e82f70a55327789582a5200a90 subpackages: @@ -74,8 +23,6 @@ imports: version: 782f4967f2dc4564575ca782fe2d04090b5faca8 subpackages: - spew -- name: github.com/dgrijalva/jwt-go - version: 01aeca54ebda6e0fbfafd0a524d234159c05ec20 - name: github.com/docker/distribution version: edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c subpackages: @@ -106,8 +53,9 @@ imports: - pkg/jsonmessage - pkg/longpath - pkg/mount + - pkg/parsers - pkg/stdcopy - - pkg/symlink + - pkg/sysinfo - pkg/system - pkg/term - pkg/term/windows @@ -124,10 +72,6 @@ imports: version: 449fdfce4d962303d702fec724ef0ad181c92528 subpackages: - spdy -- name: github.com/emicklei/go-restful - version: ff4f55a206334ef123e4f79bbf348980da81ca46 - subpackages: - - log - name: github.com/evanphx/json-patch version: 944e07253867aacae43c04b2e6a239005443f33a - name: github.com/exponent-io/jsonpath @@ -136,14 +80,12 @@ imports: version: f6a740d52f961c60348ebb109adde9f4635d7540 - name: github.com/ghodss/yaml version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee -- name: github.com/go-ini/ini - version: 300e940a926eb277d3901b20bdfcc54928ad3642 - name: github.com/go-openapi/jsonpointer version: 46af16f9f7b149af66e5d1bd010e3574dc06de98 - name: github.com/go-openapi/jsonreference version: 13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272 - name: github.com/go-openapi/spec - version: 7abd5745472fff5eb3685386d5fb8bf38683154d + version: 1de3e0542de65ad8d75452a595886fdd0befb363 - name: github.com/go-openapi/swag version: f3f9494671f93fcff853e3c6e9e948b3eb71e590 - name: github.com/gobwas/glob @@ -185,15 +127,6 @@ imports: - OpenAPIv2 - compiler - extensions -- name: github.com/gophercloud/gophercloud - version: 8183543f90d1aef267a5ecc209f2e0715b355acb - subpackages: - - openstack - - openstack/identity/v2/tenants - - openstack/identity/v2/tokens - - openstack/identity/v3/tokens - - openstack/utils - - pagination - name: github.com/gosuri/uitable version: 36ee7e946282a3fb1cfecd476ddc9b35d8847e42 subpackages: @@ -217,12 +150,8 @@ imports: version: 6633656539c1639d9d78127b7d47c622b5d7b6dc - name: github.com/inconshreveable/mousetrap version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 -- name: github.com/jmespath/go-jmespath - version: 0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74 - name: github.com/json-iterator/go - version: 36b14963da70d11297d313183d7e6388c8510e1e -- name: github.com/juju/ratelimit - version: 5b9ff866471762aa2ab2dced63c9fb6f53921342 + version: 13f86432b882000a51c6e610c620974462691a97 - name: github.com/mailru/easyjson version: 2f5df55504ebc322e4d52d34df6a1f5b503bf26d subpackages: @@ -245,8 +174,6 @@ imports: - pbutil - name: github.com/mitchellh/go-wordwrap version: ad45545899c7b13c020ea92b2072220eefad42b8 -- name: github.com/naoina/go-stringutil - version: 6b638e95a32d0c1131db0e7fe83775cbea4a0d0b - name: github.com/opencontainers/go-digest version: a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb - name: github.com/opencontainers/image-spec @@ -301,6 +228,8 @@ imports: version: 81e90905daefcd6fd217b62423c0908922eadb30 subpackages: - cast5 + - ed25519 + - ed25519/internal/edwards25519 - openpgp - openpgp/armor - openpgp/clearsign @@ -315,20 +244,12 @@ imports: version: 1c05540f6879653db88113bc4a2b70aec4bd491f subpackages: - context - - context/ctxhttp - http2 - http2/hpack - idna - internal/timeseries - lex/httplex - trace -- name: golang.org/x/oauth2 - version: a6bd8cefa1811bd24b86f8902872e4e8225f74c4 - subpackages: - - google - - internal - - jws - - jwt - name: golang.org/x/sys version: 43eea11bc92608addb41b8a406b0407495c106f6 subpackages: @@ -353,18 +274,10 @@ imports: - unicode/bidi - unicode/norm - width -- name: google.golang.org/appengine - version: 12d5545dc1cfa6047a286d5e853841b6471f4c19 +- name: golang.org/x/time + version: f51c12702a4d776e4c1fa9b0fabab841babae631 subpackages: - - internal - - internal/app_identity - - internal/base - - internal/datastore - - internal/log - - internal/modules - - internal/remote_api - - internal/urlfetch - - urlfetch + - rate - name: google.golang.org/genproto version: 09f6ed296fc66555a25fe4ce95173148778dfa85 subpackages: @@ -390,20 +303,18 @@ imports: - status - tap - transport -- name: gopkg.in/gcfg.v1 - version: 27e4946190b4a327b539185f2b5b1f7c84730728 - subpackages: - - scanner - - token - - types - name: gopkg.in/inf.v0 version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 -- name: gopkg.in/warnings.v0 - version: 8a331561fe74dadba6edfc59f3be66c22c3b065d +- name: gopkg.in/square/go-jose.v2 + version: f8f38de21b4dcd69d0413faf231983f5fd6634b1 + subpackages: + - cipher + - json + - jwt - name: gopkg.in/yaml.v2 version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 - name: k8s.io/api - version: 006a217681ae70cbacdd66a5e2fca1a61a8ff28e + version: c699ec51538f0cfd4afa8bfcfe1e0779cafbe666 subpackages: - admission/v1beta1 - admissionregistration/v1alpha1 @@ -436,11 +347,11 @@ imports: - storage/v1alpha1 - storage/v1beta1 - name: k8s.io/apiextensions-apiserver - version: a5bbfd114a9b122acd741c61d88c84812375d9e1 + version: 898b0eda132e1aeac43a459785144ee4bf9b0a2e subpackages: - pkg/features - name: k8s.io/apimachinery - version: 68f9c3a1feb3140df59c67ced62d3a5df8e6c9c2 + version: 54101a56dda9a0962bc48751c058eb4c546dcbb9 subpackages: - pkg/api/equality - pkg/api/errors @@ -454,7 +365,7 @@ imports: - pkg/apis/meta/v1 - pkg/apis/meta/v1/unstructured - pkg/apis/meta/v1/validation - - pkg/apis/meta/v1alpha1 + - pkg/apis/meta/v1beta1 - pkg/conversion - pkg/conversion/queryparams - pkg/fields @@ -472,6 +383,7 @@ imports: - pkg/util/cache - pkg/util/clock - pkg/util/diff + - pkg/util/duration - pkg/util/errors - pkg/util/framer - pkg/util/httpstream @@ -496,7 +408,7 @@ imports: - third_party/forked/golang/netutil - third_party/forked/golang/reflect - name: k8s.io/apiserver - version: 2a1092aaa7202e8f9b188281ff9424a014ce61c2 + version: ea53f8588c655568158b4ff53f5ec6fa4ebfc332 subpackages: - pkg/apis/audit - pkg/authentication/authenticator @@ -507,7 +419,7 @@ imports: - pkg/util/feature - pkg/util/flag - name: k8s.io/client-go - version: 78700dec6369ba22221b72770783300f143df150 + version: 23781f4d6632d88e869066eaebb743857aa1ef9b subpackages: - discovery - discovery/fake @@ -635,15 +547,21 @@ imports: - listers/storage/v1 - listers/storage/v1alpha1 - listers/storage/v1beta1 + - pkg/apis/clientauthentication + - pkg/apis/clientauthentication/v1alpha1 - pkg/version - - plugin/pkg/client/auth - - plugin/pkg/client/auth/azure - - plugin/pkg/client/auth/gcp - - plugin/pkg/client/auth/oidc - - plugin/pkg/client/auth/openstack + - plugin/pkg/client/auth/exec - rest - rest/fake - rest/watch + - scale + - scale/scheme + - scale/scheme/appsint + - scale/scheme/appsv1beta1 + - scale/scheme/appsv1beta2 + - scale/scheme/autoscalingv1 + - scale/scheme/extensionsint + - scale/scheme/extensionsv1beta1 - testing - third_party/forked/golang/template - tools/auth @@ -670,13 +588,12 @@ imports: - util/retry - util/workqueue - name: k8s.io/kube-openapi - version: 39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1 + version: 50ae88d24ede7b8bad68e23c805b5d3da5c8abaf subpackages: - - pkg/common - pkg/util/proto - pkg/util/proto/validation - name: k8s.io/kubernetes - version: 5fa2db2bd46ac79e5e00a4e6ed24191080aa463b + version: 923d8441db527e908cd7d266c4a9d18daa596d4c subpackages: - pkg/api/events - pkg/api/legacyscheme @@ -686,7 +603,6 @@ imports: - pkg/api/service - pkg/api/testapi - pkg/api/v1/pod - - pkg/api/v1/service - pkg/apis/admission - pkg/apis/admission/install - pkg/apis/admission/v1beta1 @@ -799,9 +715,8 @@ imports: - pkg/client/clientset_generated/internalclientset/typed/settings/internalversion/fake - pkg/client/clientset_generated/internalclientset/typed/storage/internalversion - pkg/client/clientset_generated/internalclientset/typed/storage/internalversion/fake - - pkg/client/unversioned + - pkg/client/conditions - pkg/cloudprovider - - pkg/cloudprovider/providers/aws - pkg/controller - pkg/controller/daemon - pkg/controller/daemon/util @@ -810,8 +725,8 @@ imports: - pkg/controller/statefulset - pkg/controller/volume/events - pkg/controller/volume/persistentvolume + - pkg/controller/volume/persistentvolume/metrics - pkg/credentialprovider - - pkg/credentialprovider/aws - pkg/features - pkg/fieldpath - pkg/kubectl @@ -830,6 +745,7 @@ imports: - pkg/kubectl/util/hash - pkg/kubectl/util/slice - pkg/kubectl/util/term + - pkg/kubectl/util/transport - pkg/kubectl/validation - pkg/kubelet/apis - pkg/kubelet/types @@ -837,6 +753,13 @@ imports: - pkg/printers - pkg/printers/internalversion - pkg/registry/rbac/validation + - pkg/scheduler/algorithm + - pkg/scheduler/algorithm/predicates + - pkg/scheduler/algorithm/priorities/util + - pkg/scheduler/api + - pkg/scheduler/schedulercache + - pkg/scheduler/util + - pkg/scheduler/volumebinder - pkg/security/apparmor - pkg/serviceaccount - pkg/util/file @@ -858,14 +781,9 @@ imports: - pkg/version - pkg/volume - pkg/volume/util - - pkg/watch/json - - plugin/pkg/scheduler/algorithm - - plugin/pkg/scheduler/algorithm/predicates - - plugin/pkg/scheduler/algorithm/priorities/util - - plugin/pkg/scheduler/api - - plugin/pkg/scheduler/schedulercache - - plugin/pkg/scheduler/util - - plugin/pkg/scheduler/volumebinder + - pkg/volume/util/fs + - pkg/volume/util/recyclerclient + - pkg/volume/util/types - name: k8s.io/utils version: aedf551cdb8b0119df3a19c65fde413a13b34997 subpackages: @@ -874,8 +792,6 @@ imports: - exec/testing - name: vbom.ml/util version: db5cfe13f5cc80a4990d98e2e1b0707a4d1a5394 - repo: https://github.com/fvbommel/util.git - vcs: git subpackages: - sortorder testImports: diff --git a/glide.yaml b/glide.yaml index 7d0fce978..7fcb16d0b 100644 --- a/glide.yaml +++ b/glide.yaml @@ -43,28 +43,20 @@ import: - package: github.com/evanphx/json-patch - package: github.com/BurntSushi/toml version: ~0.3.0 -- package: github.com/naoina/go-stringutil - version: ~0.1.0 -- package: github.com/chai2010/gettext-go - package: github.com/prometheus/client_golang version: 0.8.0 -- package: vbom.ml/util - repo: https://github.com/fvbommel/util.git - vcs: git +- package: github.com/grpc-ecosystem/go-grpc-prometheus - package: k8s.io/kubernetes - version: 1.9.2 + version: release-1.10 - package: k8s.io/client-go - version: ~6.0.0 + version: kubernetes-1.10.0 - package: k8s.io/api - version: kubernetes-1.9.2 + version: release-1.10 - package: k8s.io/apimachinery - version: kubernetes-1.9.2 + version: release-1.10 - package: k8s.io/apiserver - version: kubernetes-1.9.2 - -- package: cloud.google.com/go/compute - repo: https://github.com/GoogleCloudPlatform/google-cloud-go.git + version: release-1.10 testImports: - package: github.com/stretchr/testify diff --git a/pkg/kube/client.go b/pkg/kube/client.go index cd5227dd7..e4e2dc1bb 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -47,7 +47,7 @@ import ( "k8s.io/client-go/tools/clientcmd" batchinternal "k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/core" - conditions "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/conditions" "k8s.io/kubernetes/pkg/kubectl" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" @@ -77,10 +77,12 @@ func New(config clientcmd.ClientConfig) *Client { return &Client{ Factory: cmdutil.NewFactory(config), SchemaCacheDir: clientcmd.RecommendedSchemaFile, - Log: func(_ string, _ ...interface{}) {}, + Log: nopLogger, } } +var nopLogger = func(_ string, _ ...interface{}) {} + // ResourceActorFunc performs an action on a single resource. type ResourceActorFunc func(*resource.Info) error @@ -205,7 +207,10 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) { // an object type changes, so we can just rely on that. Problem is it doesn't seem to keep // track of tab widths. buf := new(bytes.Buffer) - p, _ := c.Printer(nil, printers.PrintOptions{}) + p, err := cmdutil.PrinterForOptions(&printers.PrintOptions{}) + if err != nil { + return "", err + } for t, ot := range objs { if _, err = buf.WriteString("==> " + t + "\n"); err != nil { return "", err @@ -608,7 +613,8 @@ func (c *Client) AsVersionedObject(obj runtime.Object) (runtime.Object, error) { return nil, err } versions := &runtime.VersionedObjects{} - err = runtime.DecodeInto(c.Decoder(true), json, versions) + decoder := unstructured.UnstructuredJSONScheme + err = runtime.DecodeInto(decoder, json, versions) return versions.First(), err } diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go index a81b2c949..47049810a 100644 --- a/pkg/kube/client_test.go +++ b/pkg/kube/client_test.go @@ -18,8 +18,6 @@ package kube import ( "bytes" - "encoding/json" - "fmt" "io" "io/ioutil" "net/http" @@ -31,19 +29,20 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/dynamic" "k8s.io/client-go/rest/fake" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/kubectl" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" - "k8s.io/kubernetes/pkg/printers" - watchjson "k8s.io/kubernetes/pkg/watch/json" + "k8s.io/kubernetes/pkg/kubectl/scheme" ) +var unstructuredSerializer = dynamic.ContentConfig().NegotiatedSerializer + func objBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser { return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj)))) } @@ -117,31 +116,21 @@ func (f *fakeReaperFactory) Reaper(mapping *meta.RESTMapping) (kubectl.Reaper, e return f.reaper, nil } -func newEventResponse(code int, e *watch.Event) (*http.Response, error) { - dispatchedEvent, err := encodeAndMarshalEvent(e) - if err != nil { - return nil, err - } - - header := http.Header{} - header.Set("Content-Type", runtime.ContentTypeJSON) - body := ioutil.NopCloser(bytes.NewReader(dispatchedEvent)) - return &http.Response{StatusCode: code, Header: header, Body: body}, nil +type testClient struct { + *Client + *cmdtesting.TestFactory } -func encodeAndMarshalEvent(e *watch.Event) ([]byte, error) { - encodedEvent, err := watchjson.Object(testapi.Default.Codec(), e) - if err != nil { - return nil, err +func newTestClient() *testClient { + tf := cmdtesting.NewTestFactory() + c := &Client{ + Factory: tf, + Log: nopLogger, + } + return &testClient{ + Client: c, + TestFactory: tf, } - - return json.Marshal(encodedEvent) -} - -func newTestClient(f cmdutil.Factory) *Client { - c := New(nil) - c.Factory = f - return c } func TestUpdate(t *testing.T) { @@ -153,10 +142,11 @@ func TestUpdate(t *testing.T) { var actions []string - f, tf, codec, _ := cmdtesting.NewAPIFactory() + tf := cmdtesting.NewTestFactory() + defer tf.Cleanup() tf.UnstructuredClient = &fake.RESTClient{ GroupVersion: schema.GroupVersion{Version: "v1"}, - NegotiatedSerializer: dynamic.ContentConfig().NegotiatedSerializer, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { p, m := req.URL.Path, req.Method actions = append(actions, p+":"+m) @@ -190,9 +180,11 @@ func TestUpdate(t *testing.T) { }), } + c := newTestClient() reaper := &fakeReaper{} - rf := &fakeReaperFactory{Factory: f, reaper: reaper} - c := newTestClient(rf) + rf := &fakeReaperFactory{Factory: tf, reaper: reaper} + c.Client.Factory = rf + codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...) if err := c.Update(core.NamespaceDefault, objBody(codec, &listA), objBody(codec, &listB), false, false, 0, false); err != nil { t.Fatal(err) } @@ -251,54 +243,35 @@ func TestBuild(t *testing.T) { }, } + c := newTestClient() for _, tt := range tests { - f, _, _, _ := cmdtesting.NewAPIFactory() - c := newTestClient(f) - - // Test for an invalid manifest - infos, err := c.Build(tt.namespace, tt.reader) - if err != nil && !tt.err { - t.Errorf("%q. Got error message when no error should have occurred: %v", tt.name, err) - } else if err != nil && strings.Contains(err.Error(), "--validate=false") { - t.Errorf("%q. error message was not scrubbed", tt.name) - } + t.Run(tt.name, func(t *testing.T) { + c.Cleanup() + + // Test for an invalid manifest + infos, err := c.Build(tt.namespace, tt.reader) + if err != nil && !tt.err { + t.Errorf("Got error message when no error should have occurred: %v", err) + } else if err != nil && strings.Contains(err.Error(), "--validate=false") { + t.Error("error message was not scrubbed") + } - if len(infos) != tt.count { - t.Errorf("%q. expected %d result objects, got %d", tt.name, tt.count, len(infos)) - } + if len(infos) != tt.count { + t.Errorf("expected %d result objects, got %d", tt.count, len(infos)) + } + }) } } -type testPrinter struct { - Objects []runtime.Object - Err error - printers.ResourcePrinter -} - -func (t *testPrinter) PrintObj(obj runtime.Object, out io.Writer) error { - t.Objects = append(t.Objects, obj) - fmt.Fprintf(out, "%#v", obj) - return t.Err -} - -func (t *testPrinter) HandledResources() []string { - return []string{} -} - -func (t *testPrinter) AfterPrint(io.Writer, string) error { - return t.Err -} - func TestGet(t *testing.T) { list := newPodList("starfish", "otter") - f, tf, _, _ := cmdtesting.NewAPIFactory() - tf.Printer = &testPrinter{} - tf.UnstructuredClient = &fake.RESTClient{ + c := newTestClient() + defer c.Cleanup() + c.TestFactory.UnstructuredClient = &fake.RESTClient{ GroupVersion: schema.GroupVersion{Version: "v1"}, - NegotiatedSerializer: dynamic.ContentConfig().NegotiatedSerializer, + NegotiatedSerializer: unstructuredSerializer, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { p, m := req.URL.Path, req.Method - //actions = append(actions, p+":"+m) t.Logf("got request %s %s", p, m) switch { case p == "/namespaces/default/pods/starfish" && m == "GET": @@ -311,7 +284,6 @@ func TestGet(t *testing.T) { } }), } - c := newTestClient(f) // Test Success data := strings.NewReader("kind: Pod\napiVersion: v1\nmetadata:\n name: otter") @@ -358,101 +330,37 @@ func TestPerform(t *testing.T) { } for _, tt := range tests { - results := []*resource.Info{} + t.Run(tt.name, func(t *testing.T) { + results := []*resource.Info{} - fn := func(info *resource.Info) error { - results = append(results, info) + fn := func(info *resource.Info) error { + results = append(results, info) - if info.Namespace != tt.namespace { - t.Errorf("%q. expected namespace to be '%s', got %s", tt.name, tt.namespace, info.Namespace) + if info.Namespace != tt.namespace { + t.Errorf("expected namespace to be '%s', got %s", tt.namespace, info.Namespace) + } + return nil } - return nil - } - f, _, _, _ := cmdtesting.NewAPIFactory() - c := newTestClient(f) - infos, err := c.Build(tt.namespace, tt.reader) - if err != nil && err.Error() != tt.errMessage { - t.Errorf("%q. Error while building manifests: %v", tt.name, err) - } - - err = perform(infos, fn) - if (err != nil) != tt.err { - t.Errorf("%q. expected error: %v, got %v", tt.name, tt.err, err) - } - if err != nil && err.Error() != tt.errMessage { - t.Errorf("%q. expected error message: %v, got %v", tt.name, tt.errMessage, err) - } - - if len(results) != tt.count { - t.Errorf("%q. expected %d result objects, got %d", tt.name, tt.count, len(results)) - } - } -} - -func TestWaitAndGetCompletedPodPhase(t *testing.T) { - tests := []struct { - podPhase core.PodPhase - expectedPhase core.PodPhase - err bool - errMessage string - }{ - { - podPhase: core.PodPending, - expectedPhase: core.PodUnknown, - err: true, - errMessage: "watch closed before Until timeout", - }, { - podPhase: core.PodRunning, - expectedPhase: core.PodUnknown, - err: true, - errMessage: "watch closed before Until timeout", - }, { - podPhase: core.PodSucceeded, - expectedPhase: core.PodSucceeded, - }, { - podPhase: core.PodFailed, - expectedPhase: core.PodFailed, - }, - } - - for _, tt := range tests { - f, tf, codec, ns := cmdtesting.NewAPIFactory() - actions := make(map[string]string) - - var testPodList core.PodList - testPodList.Items = append(testPodList.Items, newPodWithStatus("bestpod", core.PodStatus{Phase: tt.podPhase}, "test")) - - tf.Client = &fake.RESTClient{ - NegotiatedSerializer: ns, - Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { - p, m := req.URL.Path, req.Method - actions[p] = m - switch { - case p == "/namespaces/test/pods/bestpod" && m == "GET": - return newResponse(200, &testPodList.Items[0]) - case p == "/namespaces/test/pods" && m == "GET": - event := watch.Event{Type: watch.Added, Object: &testPodList.Items[0]} - return newEventResponse(200, &event) - default: - t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) - return nil, nil - } - }), - } + c := newTestClient() + defer c.Cleanup() + infos, err := c.Build(tt.namespace, tt.reader) + if err != nil && err.Error() != tt.errMessage { + t.Errorf("Error while building manifests: %v", err) + } - c := newTestClient(f) + err = perform(infos, fn) + if (err != nil) != tt.err { + t.Errorf("expected error: %v, got %v", tt.err, err) + } + if err != nil && err.Error() != tt.errMessage { + t.Errorf("expected error message: %v, got %v", tt.errMessage, err) + } - phase, err := c.WaitAndGetCompletedPodPhase("test", objBody(codec, &testPodList), 1*time.Second) - if (err != nil) != tt.err { - t.Fatalf("Expected error but there was none.") - } - if err != nil && err.Error() != tt.errMessage { - t.Fatalf("Expected error %s, got %s", tt.errMessage, err.Error()) - } - if phase != tt.expectedPhase { - t.Fatalf("Expected pod phase %s, got %s", tt.expectedPhase, phase) - } + if len(results) != tt.count { + t.Errorf("expected %d result objects, got %d", tt.count, len(results)) + } + }) } } From 52b7abac26ca0088082121aa26215bf411ad928b Mon Sep 17 00:00:00 2001 From: Shredgar Date: Tue, 27 Mar 2018 14:52:32 +0200 Subject: [PATCH 125/221] Updated kubernetes_distros.md with DC/OS note. Updated kubernetes_distros.md with a note that Helm is running fine on Kubernetes on DC/OS --- docs/kubernetes_distros.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/kubernetes_distros.md b/docs/kubernetes_distros.md index 04a86d0b4..c30bc87f3 100644 --- a/docs/kubernetes_distros.md +++ b/docs/kubernetes_distros.md @@ -43,3 +43,9 @@ Helm works straightforward on OpenShift Online, OpenShift Dedicated, OpenShift C ## Platform9 Helm Client and Helm Server (Tiller) are pre-installed with [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/?utm_source=helm_distro_notes). Platform9 provides access to all official Helm charts through the App Catalog UI and native Kubernetes CLI. Additional repositories can be manually added. Further details are available in this [Platform9 App Catalog article](https://platform9.com/support/deploying-kubernetes-apps-platform9-managed-kubernetes/?utm_source=helm_distro_notes). + +## DC/OS ++ ++Helm (both client and server) has been tested and is working on Mesospheres DC/OS Kubernetes platform, and requires ++no additional configuration. + From 6e3a0a129172db913491a83443813ea0ae3861c5 Mon Sep 17 00:00:00 2001 From: Jonathan Hall Date: Tue, 27 Mar 2018 19:56:46 +0200 Subject: [PATCH 126/221] Remove outdated note. --- docs/provenance.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/provenance.md b/docs/provenance.md index 1eb69f8f3..331074e8c 100644 --- a/docs/provenance.md +++ b/docs/provenance.md @@ -4,13 +4,6 @@ Helm has provenance tools which help chart users verify the integrity and origin of a package. Using industry-standard tools based on PKI, GnuPG, and well-respected package managers, Helm can generate and verify signature files. -**Note:** -Version 2.0.0-alpha.4 introduced a system for verifying the authenticity of charts. -While we do not anticipate that any major changes will be made to the file formats -or provenancing algorithms, this portion of Helm is not considered _frozen_ until -2.0.0-RC1 is released. The original plan for this feature can be found -[at issue 983](https://github.com/kubernetes/helm/issues/983). - ## Overview Integrity is established by comparing a chart to a provenance record. Provenance From 1a55161a53345816d724e1df9664f789113e1328 Mon Sep 17 00:00:00 2001 From: adshmh Date: Tue, 27 Mar 2018 16:06:04 -0400 Subject: [PATCH 127/221] Fix several golint warnings (#3756) * fix(helm): fix golint warning due to ApiVersionV1 constant name Signed-off-by: Arash Deshmeh * fix(helm): fix golint warning due to ResolveChartVersionAndGetRepo comment Signed-off-by: Arash Deshmeh * fix(helm): fix golint warnings on HttpGetter type and SetCredentials method missing a comment Signed-off-by: Arash Deshmeh * fix(helm):fix golint warning due to comment on FindChartInAuthRepoURL function Signed-off-by: Arash Deshmeh * fix(helm): fix golint warning due to RepoFile type name Signed-off-by: Arash Deshmeh * fix(helm): fix golint warning due to ParseString comment Signed-off-by: Arash Deshmeh --- pkg/chartutil/chartfile.go | 2 +- pkg/downloader/chart_downloader.go | 2 +- pkg/getter/httpgetter.go | 6 ++++-- pkg/repo/chartrepo.go | 6 +++--- pkg/repo/repo.go | 3 ++- pkg/strvals/parser.go | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/pkg/chartutil/chartfile.go b/pkg/chartutil/chartfile.go index 9897d66ff..c2879cdae 100644 --- a/pkg/chartutil/chartfile.go +++ b/pkg/chartutil/chartfile.go @@ -31,7 +31,7 @@ import ( // ApiVersionV1 is the API version number for version 1. // // This is ApiVersionV1 instead of APIVersionV1 to match the protobuf-generated name. -const ApiVersionV1 = "v1" +const ApiVersionV1 = "v1" // nolint // UnmarshalChartfile takes raw Chart.yaml data and unmarshals it. func UnmarshalChartfile(data []byte) (*chart.Metadata, error) { diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go index 9fe89820e..9262ea547 100644 --- a/pkg/downloader/chart_downloader.go +++ b/pkg/downloader/chart_downloader.go @@ -151,7 +151,7 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, ge return u, nil, err } -// Same as the ResolveChartVersion method, but returns the chart repositoryy. +// ResolveChartVersionAndGetRepo is the same as the ResolveChartVersion method, but returns the chart repositoryy. func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*url.URL, *repo.ChartRepository, *getter.HttpGetter, error) { u, err := url.Parse(ref) if err != nil { diff --git a/pkg/getter/httpgetter.go b/pkg/getter/httpgetter.go index dd462ce5f..3c20e35e1 100644 --- a/pkg/getter/httpgetter.go +++ b/pkg/getter/httpgetter.go @@ -27,13 +27,15 @@ import ( "k8s.io/helm/pkg/version" ) -//httpGetter is the efault HTTP(/S) backend handler -type HttpGetter struct { +//HttpGetter is the efault HTTP(/S) backend handler +// TODO: change the name to HTTPGetter in Helm 3 +type HttpGetter struct { //nolint client *http.Client username string password string } +//SetCredentials sets the credentials for the getter func (g *HttpGetter) SetCredentials(username, password string) { g.username = username g.password = password diff --git a/pkg/repo/chartrepo.go b/pkg/repo/chartrepo.go index c76cc7913..bf03a68bb 100644 --- a/pkg/repo/chartrepo.go +++ b/pkg/repo/chartrepo.go @@ -196,9 +196,9 @@ func FindChartInRepoURL(repoURL, chartName, chartVersion, certFile, keyFile, caF return FindChartInAuthRepoURL(repoURL, "", "", chartName, chartVersion, certFile, keyFile, caFile, getters) } -// FindChartInRepoURL finds chart in chart repository pointed by repoURL -// without adding repo to repositories. -// Unlike the FindChartInRepoURL function, this function also receives credentials for the chart repository. +// FindChartInAuthRepoURL finds chart in chart repository pointed by repoURL +// without adding repo to repositories, like FindChartInRepoURL, +// but it also receives credentials for the chart repository. func FindChartInAuthRepoURL(repoURL, username, password, chartName, chartVersion, certFile, keyFile, caFile string, getters getter.Providers) (string, error) { // Download and write the index file to a temporary location diff --git a/pkg/repo/repo.go b/pkg/repo/repo.go index 194eace79..b5bba164e 100644 --- a/pkg/repo/repo.go +++ b/pkg/repo/repo.go @@ -31,7 +31,8 @@ import ( var ErrRepoOutOfDate = errors.New("repository file is out of date") // RepoFile represents the repositories.yaml file in $HELM_HOME -type RepoFile struct { +// TODO: change type name to File in Helm 3 to resolve linter warning +type RepoFile struct { // nolint APIVersion string `json:"apiVersion"` Generated time.Time `json:"generated"` Repositories []*Entry `json:"repositories"` diff --git a/pkg/strvals/parser.go b/pkg/strvals/parser.go index 8a999feb7..8a16adf7e 100644 --- a/pkg/strvals/parser.go +++ b/pkg/strvals/parser.go @@ -50,7 +50,7 @@ func Parse(s string) (map[string]interface{}, error) { return vals, err } -// Parse parses a set line and forces a string value. +// ParseString parses a set line and forces a string value. // // A set line is of the form name1=value1,name2=value2 func ParseString(s string) (map[string]interface{}, error) { From 75387fe3183a724684b2bea29c2a0023e7a9a354 Mon Sep 17 00:00:00 2001 From: muhongwei <32874157+muhongwei@users.noreply.github.com> Date: Wed, 28 Mar 2018 04:06:48 +0800 Subject: [PATCH 128/221] fix 'mulitenant'->'multitenant' (#3755) --- docs/securing_installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/securing_installation.md b/docs/securing_installation.md index ffce5df75..5c420242e 100644 --- a/docs/securing_installation.md +++ b/docs/securing_installation.md @@ -71,7 +71,7 @@ Enabling this feature currently requires setting the `--storage=secret` flag in Because of the relative longevity of Helm, the Helm chart ecosystem evolved without the immediate concern for cluster-wide control, and especially in the developer space this makes complete sense. However, charts are a kind of package that not only installs containers you may or may not have validated yourself, but it may also install into more than one namespace. -As with all shared software, in a controlled or shared environment you must validate all software you install yourself _before_ you install it. If you have secured Tiller with TLS and have installed it with permissions to only one or a subset of namespaces, some charts may fail to install -- but in these environments, that is exactly what you want. If you need to use the chart, you may have to work with the creator or modify it yourself in order to use it securely in a mulitenant cluster with proper RBAC rules applied. The `helm template` command renders the chart locally and displays the output. +As with all shared software, in a controlled or shared environment you must validate all software you install yourself _before_ you install it. If you have secured Tiller with TLS and have installed it with permissions to only one or a subset of namespaces, some charts may fail to install -- but in these environments, that is exactly what you want. If you need to use the chart, you may have to work with the creator or modify it yourself in order to use it securely in a multitenant cluster with proper RBAC rules applied. The `helm template` command renders the chart locally and displays the output. Once vetted, you can use Helm's provenance tools to [ensure the provenance and integrity of charts](provenance.md) that you use. From 0ba75b6652aec058c51fc1152988e01403496318 Mon Sep 17 00:00:00 2001 From: muhongwei <32874157+muhongwei@users.noreply.github.com> Date: Wed, 28 Mar 2018 04:07:13 +0800 Subject: [PATCH 129/221] fix 'eveything' -> 'everything' (#3754) --- docs/release_checklist.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release_checklist.md b/docs/release_checklist.md index 9bb3ae00c..26506985c 100644 --- a/docs/release_checklist.md +++ b/docs/release_checklist.md @@ -197,7 +197,7 @@ From here on just repeat this process, continuously testing until you're happy w ## 6. Finalize the Release -When you're finally happy with the quality of a release candidate, you can move on and create the real thing. Double-check one last time to make sure eveything is in order, then finally push the release tag. +When you're finally happy with the quality of a release candidate, you can move on and create the real thing. Double-check one last time to make sure everything is in order, then finally push the release tag. ```shell git checkout $RELEASE_BRANCH_NAME From 3334309a9193b61da6b24ceceb5435ef4d2f71ed Mon Sep 17 00:00:00 2001 From: Shredgar Date: Wed, 28 Mar 2018 10:12:56 +0200 Subject: [PATCH 130/221] Removed typos (additional plus signs) Removed typos (additional plus signs) --- docs/kubernetes_distros.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/kubernetes_distros.md b/docs/kubernetes_distros.md index c30bc87f3..8b80519ec 100644 --- a/docs/kubernetes_distros.md +++ b/docs/kubernetes_distros.md @@ -45,7 +45,7 @@ Helm works straightforward on OpenShift Online, OpenShift Dedicated, OpenShift C Helm Client and Helm Server (Tiller) are pre-installed with [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/?utm_source=helm_distro_notes). Platform9 provides access to all official Helm charts through the App Catalog UI and native Kubernetes CLI. Additional repositories can be manually added. Further details are available in this [Platform9 App Catalog article](https://platform9.com/support/deploying-kubernetes-apps-platform9-managed-kubernetes/?utm_source=helm_distro_notes). ## DC/OS -+ -+Helm (both client and server) has been tested and is working on Mesospheres DC/OS Kubernetes platform, and requires -+no additional configuration. + +Helm (both client and server) has been tested and is working on Mesospheres DC/OS 1.11 Kubernetes platform, and requires +no additional configuration. From 2dd9b34d28338e24a646d393ed4e522be55b7851 Mon Sep 17 00:00:00 2001 From: fibonacci1729 Date: Wed, 28 Mar 2018 15:43:23 -0600 Subject: [PATCH 131/221] stream releases when listing --- cmd/helm/list.go | 18 +++++++++++------- pkg/helm/client.go | 18 ++++++++++++++++-- pkg/tiller/release_list.go | 17 +++++++++++------ 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/cmd/helm/list.go b/cmd/helm/list.go index 0219d60f2..4332ceb21 100644 --- a/cmd/helm/list.go +++ b/cmd/helm/list.go @@ -148,7 +148,7 @@ func (l *listCmd) run() error { return prettyError(err) } - if len(res.Releases) == 0 { + if len(res.GetReleases()) == 0 { return nil } @@ -239,12 +239,16 @@ func formatList(rels []*release.Release, colWidth uint) string { table.MaxColWidth = colWidth table.AddRow("NAME", "REVISION", "UPDATED", "STATUS", "CHART", "NAMESPACE") for _, r := range rels { - c := fmt.Sprintf("%s-%s", r.Chart.Metadata.Name, r.Chart.Metadata.Version) - t := timeconv.String(r.Info.LastDeployed) - s := r.Info.Status.Code.String() - v := r.Version - n := r.Namespace - table.AddRow(r.Name, v, t, s, c, n) + md := r.GetChart().GetMetadata() + c := fmt.Sprintf("%s-%s", md.GetName(), md.GetVersion()) + t := "-" + if tspb := r.GetInfo().GetLastDeployed(); tspb != nil { + t = timeconv.String(tspb) + } + s := r.GetInfo().GetStatus().GetCode().String() + v := r.GetVersion() + n := r.GetNamespace() + table.AddRow(r.GetName(), v, t, s, c, n) } return table.String() } diff --git a/pkg/helm/client.go b/pkg/helm/client.go index 2fb1e54e4..43e9f4daf 100644 --- a/pkg/helm/client.go +++ b/pkg/helm/client.go @@ -346,8 +346,22 @@ func (h *Client) list(ctx context.Context, req *rls.ListReleasesRequest) (*rls.L if err != nil { return nil, err } - - return s.Recv() + var resp *rls.ListReleasesResponse + for { + r, err := s.Recv() + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + if resp == nil { + resp = r + continue + } + resp.Releases = append(resp.Releases, r.GetReleases()[0]) + } + return resp, nil } // Executes tiller.InstallRelease RPC. diff --git a/pkg/tiller/release_list.go b/pkg/tiller/release_list.go index 9ccc8a686..ec4dbfb39 100644 --- a/pkg/tiller/release_list.go +++ b/pkg/tiller/release_list.go @@ -108,13 +108,18 @@ func (s *ReleaseServer) ListReleases(req *services.ListReleasesRequest, stream s l = int64(len(rels)) } - res := &services.ListReleasesResponse{ - Next: next, - Count: l, - Total: total, - Releases: rels, + for i := 0; i < min(len(rels), int(req.Limit)); i++ { + res := &services.ListReleasesResponse{ + Next: next, + Count: l, + Total: total, + Releases: []*release.Release{rels[i]}, + } + if err := stream.Send(res); err != nil { + return err + } } - return stream.Send(res) + return nil } func filterByNamespace(namespace string, rels []*release.Release) ([]*release.Release, error) { From 343acc5a60c8d63272f6ad9511473218e6b7a6ea Mon Sep 17 00:00:00 2001 From: Ryan Hartje Date: Wed, 28 Mar 2018 18:51:26 -0400 Subject: [PATCH 132/221] return a non 0 exit code when lint fails due to missing Chart.yaml --- cmd/helm/lint.go | 8 ++++++++ cmd/helm/lint_test.go | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/cmd/helm/lint.go b/cmd/helm/lint.go index 6e08f2747..e83026117 100644 --- a/cmd/helm/lint.go +++ b/cmd/helm/lint.go @@ -97,10 +97,14 @@ func (l *lintCmd) run() error { var total int var failures int + rc := 0 for _, path := range l.paths { if linter, err := lintChart(path, rvals, l.namespace, l.strict); err != nil { fmt.Println("==> Skipping", path) fmt.Println(err) + if err == errLintNoChart { + rc = 1 + } } else { fmt.Println("==> Linting", path) @@ -127,6 +131,10 @@ func (l *lintCmd) run() error { fmt.Fprintf(l.out, "%s, no failures\n", msg) + if rc != 0 { + os.Exit(rc) + } + return nil } diff --git a/cmd/helm/lint_test.go b/cmd/helm/lint_test.go index 7f045153c..973af9b63 100644 --- a/cmd/helm/lint_test.go +++ b/cmd/helm/lint_test.go @@ -28,6 +28,7 @@ var ( archivedChartPathWithHyphens = "testdata/testcharts/compressedchart-with-hyphens-0.1.0.tgz" invalidArchivedChartPath = "testdata/testcharts/invalidcompressedchart0.1.0.tgz" chartDirPath = "testdata/testcharts/decompressedchart/" + chartMissingManifest = "testdata/testcharts/chart-missing-manifest" ) func TestLintChart(t *testing.T) { @@ -46,4 +47,8 @@ func TestLintChart(t *testing.T) { if _, err := lintChart(invalidArchivedChartPath, values, namespace, strict); err == nil { t.Errorf("Expected a chart parsing error") } + + if _, err := lintChart(chartMissingManifest, values, namespace, strict); err == nil { + t.Errorf("Expected a chart parsing error") + } } From 1e03f1bce5eaab384c8ddabbf38b8f566d1c1d14 Mon Sep 17 00:00:00 2001 From: John Koleszar Date: Wed, 28 Mar 2018 18:05:54 -0700 Subject: [PATCH 133/221] Fix tiller deployment on RBAC clusters Adds automountServiceAccountToken when a serviceAccount is specified. Prior to this, tiller falls back to contacting the KUBERNETES_SERVICE on localhost:8080 rather than respecting the cluster IP in the KUBERNETES_SERVICE_{HOST,PORT} environment variables. Fixes #3460, fixes #3467. --- cmd/helm/installer/install.go | 4 +++- cmd/helm/installer/install_test.go | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cmd/helm/installer/install.go b/cmd/helm/installer/install.go index fc81fa26b..a45179a48 100644 --- a/cmd/helm/installer/install.go +++ b/cmd/helm/installer/install.go @@ -176,6 +176,7 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) { return nil, err } } + automountServiceAccountToken := opts.ServiceAccount != "" d := &v1beta1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Namespace: opts.Namespace, @@ -189,7 +190,8 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) { Labels: labels, }, Spec: v1.PodSpec{ - ServiceAccountName: opts.ServiceAccount, + ServiceAccountName: opts.ServiceAccount, + AutomountServiceAccountToken: &automountServiceAccountToken, Containers: []v1.Container{ { Name: "tiller", diff --git a/cmd/helm/installer/install_test.go b/cmd/helm/installer/install_test.go index dbb7143e3..80219505a 100644 --- a/cmd/helm/installer/install_test.go +++ b/cmd/helm/installer/install_test.go @@ -96,6 +96,9 @@ func TestDeploymentManifestForServiceAccount(t *testing.T) { if got := d.Spec.Template.Spec.ServiceAccountName; got != tt.serviceAccount { t.Errorf("%s: expected service account value %q, got %q", tt.name, tt.serviceAccount, got) } + if got := *d.Spec.Template.Spec.AutomountServiceAccountToken; got != (tt.serviceAccount != "") { + t.Errorf("%s: unexpected automountServiceAccountToken = %t for serviceAccount %q", tt.name, got, tt.serviceAccount) + } } } From e0056a9e41d5432192ee4d103a72e36ba9aeec36 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Thu, 29 Mar 2018 05:08:56 -0400 Subject: [PATCH 134/221] fix(helm): fix output leak from unit tests of helm create command Signed-off-by: Arash Deshmeh --- cmd/helm/create_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/helm/create_test.go b/cmd/helm/create_test.go index cb7b1d387..84ccebece 100644 --- a/cmd/helm/create_test.go +++ b/cmd/helm/create_test.go @@ -46,7 +46,7 @@ func TestCreateCmd(t *testing.T) { defer os.Chdir(pwd) // Run a create - cmd := newCreateCmd(os.Stdout) + cmd := newCreateCmd(ioutil.Discard) if err := cmd.RunE(cmd, []string{cname}); err != nil { t.Errorf("Failed to run create: %s", err) return @@ -117,7 +117,7 @@ func TestCreateStarterCmd(t *testing.T) { defer os.Chdir(pwd) // Run a create - cmd := newCreateCmd(os.Stdout) + cmd := newCreateCmd(ioutil.Discard) cmd.ParseFlags([]string{"--starter", "starterchart"}) if err := cmd.RunE(cmd, []string{cname}); err != nil { t.Errorf("Failed to run create: %s", err) From 026e6b55e5510e0e521760829e041aeac26b22be Mon Sep 17 00:00:00 2001 From: AdamDang Date: Thu, 29 Mar 2018 23:43:04 +0800 Subject: [PATCH 135/221] Update rbac.md In the main text and paragraph title, "Tiller" and "tiller" are both used, It's better use same format. --- docs/rbac.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/rbac.md b/docs/rbac.md index bc138ceee..b48a85ad2 100644 --- a/docs/rbac.md +++ b/docs/rbac.md @@ -4,7 +4,7 @@ In Kubernetes, granting a role to an application-specific service account is a b Bitnami also has a fantastic guide for [configuring RBAC in your cluster](https://docs.bitnami.com/kubernetes/how-to/configure-rbac-in-your-kubernetes-cluster/) that takes you through RBAC basics. -This guide is for users who want to restrict tiller's capabilities to install resources to certain namespaces, or to grant a helm client running access to a tiller instance. +This guide is for users who want to restrict Tiller's capabilities to install resources to certain namespaces, or to grant a helm client running access to a Tiller instance. ## Tiller and Role-based Access Control @@ -51,7 +51,7 @@ clusterrolebinding "tiller" created $ helm init --service-account tiller ``` -### Example: Deploy tiller in a namespace, restricted to deploying resources only in that namespace +### Example: Deploy Tiller in a namespace, restricted to deploying resources only in that namespace In the example above, we gave Tiller admin access to the entire cluster. You are not at all required to give Tiller cluster-admin access for it to work. Instead of specifying a ClusterRole or a ClusterRoleBinding, you can specify a Role and RoleBinding to limit Tiller's scope to a particular namespace. @@ -62,7 +62,7 @@ $ kubectl create serviceaccount tiller --namespace tiller-world serviceaccount "tiller" created ``` -Define a Role that allows tiller to manage all resources in `tiller-world` like in `role-tiller.yaml`: +Define a Role that allows Tiller to manage all resources in `tiller-world` like in `role-tiller.yaml`: ```yaml kind: Role @@ -104,7 +104,7 @@ $ kubectl create -f rolebinding-tiller.yaml rolebinding "tiller-binding" created ``` -Afterwards you can run `helm init` to install tiller in the `tiller-world` namespace. +Afterwards you can run `helm init` to install Tiller in the `tiller-world` namespace. ```console $ helm init --service-account tiller --tiller-namespace tiller-world @@ -125,11 +125,11 @@ NAME READY STATUS RESTARTS AGE wayfaring-yak-alpine 0/1 ContainerCreating 0 0s ``` -### Example: Deploy tiller in a namespace, restricted to deploying resources in another namespace +### Example: Deploy Tiller in a namespace, restricted to deploying resources in another namespace In the example above, we gave Tiller admin access to the namespace it was deployed inside. Now, let's limit Tiller's scope to deploy resources in a different namespace! -For example, let's install tiller in the namespace `myorg-system` and allow tiller to deploy resources in the namespace `myorg-users`. +For example, let's install Tiller in the namespace `myorg-system` and allow Tiller to deploy resources in the namespace `myorg-users`. ```console $ kubectl create namespace myorg-system @@ -138,7 +138,7 @@ $ kubectl create serviceaccount tiller --namespace myorg-system serviceaccount "tiller" created ``` -Define a Role that allows tiller to manage all resources in `myorg-users` like in `role-tiller.yaml`: +Define a Role that allows Tiller to manage all resources in `myorg-users` like in `role-tiller.yaml`: ```yaml kind: Role @@ -180,7 +180,7 @@ $ kubectl create -f rolebinding-tiller.yaml rolebinding "tiller-binding" created ``` -We'll also need to grant tiller access to read configmaps in myorg-system so it can store release information. In `role-tiller-myorg-system.yaml`: +We'll also need to grant Tiller access to read configmaps in myorg-system so it can store release information. In `role-tiller-myorg-system.yaml`: ```yaml kind: Role @@ -224,11 +224,11 @@ rolebinding "tiller-binding" created ## Helm and Role-based Access Control -When running a helm client in a pod, in order for the helm client to talk to a tiller instance, it will need certain privileges to be granted. Specifically, the helm client will need to be able to create pods, forward ports and be able to list pods in the namespace where tiller is running (so it can find tiller). +When running a helm client in a pod, in order for the helm client to talk to a Tiller instance, it will need certain privileges to be granted. Specifically, the helm client will need to be able to create pods, forward ports and be able to list pods in the namespace where Tiller is running (so it can find Tiller). ### Example: Deploy Helm in a namespace, talking to Tiller in another namespace -In this example, we will assume tiller is running in a namespace called `tiller-world` and that the helm client is running in a namespace called `helm-world`. By default, tiller is running in the `kube-system` namespace. +In this example, we will assume Tiller is running in a namespace called `tiller-world` and that the helm client is running in a namespace called `helm-world`. By default, Tiller is running in the `kube-system` namespace. In `helm-user.yaml`: From 09e0ab18090fed1c0b2c91fa401154fcd8e93a0f Mon Sep 17 00:00:00 2001 From: ReSearchITEng Date: Fri, 30 Mar 2018 09:59:06 +0300 Subject: [PATCH 136/221] closes #3795 closes #3795 --- scripts/get | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/get b/scripts/get index 3c4fb9f7d..943ca4158 100755 --- a/scripts/get +++ b/scripts/get @@ -184,7 +184,9 @@ help () { # cleanup temporary files to avoid https://github.com/kubernetes/helm/issues/2977 cleanup() { - rm -rf "$HELM_TMP_ROOT" + if [[ -d "${HELM_TMP_ROOT:-}" ]]; then + rm -rf "$HELM_TMP_ROOT" + fi } # Execution From ea7c3fefc8cd79ac497965a7fca2aef390f82287 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Sun, 1 Apr 2018 12:39:43 -0400 Subject: [PATCH 137/221] fix(helm) refactor release_testing unit tests to utilize runReleaseCases Signed-off-by: Arash Deshmeh --- cmd/helm/helm_test.go | 8 ++++-- cmd/helm/release_testing_test.go | 47 ++++++++------------------------ 2 files changed, 18 insertions(+), 37 deletions(-) diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index c95caa75f..79b8c16f2 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -43,7 +43,10 @@ func runReleaseCases(t *testing.T, tests []releaseCase, rcmd releaseCmd) { var buf bytes.Buffer for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - c := &helm.FakeClient{Rels: tt.rels} + c := &helm.FakeClient{ + Rels: tt.rels, + Responses: tt.responses, + } cmd := rcmd(c, &buf) cmd.ParseFlags(tt.flags) err := cmd.RunE(cmd, tt.args) @@ -69,7 +72,8 @@ type releaseCase struct { err bool resp *release.Release // Rels are the available releases at the start of the test. - rels []*release.Release + rels []*release.Release + responses map[string]release.TestRun_Status } // tempHelmHome sets up a Helm Home in a temp dir. diff --git a/cmd/helm/release_testing_test.go b/cmd/helm/release_testing_test.go index 02ab1883c..b946746d0 100644 --- a/cmd/helm/release_testing_test.go +++ b/cmd/helm/release_testing_test.go @@ -17,55 +17,50 @@ limitations under the License. package main import ( - "bytes" + "io" "testing" + "github.com/spf13/cobra" "k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/proto/hapi/release" ) func TestReleaseTesting(t *testing.T) { - tests := []struct { - name string - args []string - flags []string - responses map[string]release.TestRun_Status - fail bool - }{ + tests := []releaseCase{ { name: "basic test", args: []string{"example-release"}, flags: []string{}, responses: map[string]release.TestRun_Status{"PASSED: green lights everywhere": release.TestRun_SUCCESS}, - fail: false, + err: false, }, { name: "test failure", args: []string{"example-fail"}, flags: []string{}, responses: map[string]release.TestRun_Status{"FAILURE: red lights everywhere": release.TestRun_FAILURE}, - fail: true, + err: true, }, { name: "test unknown", args: []string{"example-unknown"}, flags: []string{}, responses: map[string]release.TestRun_Status{"UNKNOWN: yellow lights everywhere": release.TestRun_UNKNOWN}, - fail: false, + err: false, }, { name: "test error", args: []string{"example-error"}, flags: []string{}, responses: map[string]release.TestRun_Status{"ERROR: yellow lights everywhere": release.TestRun_FAILURE}, - fail: true, + err: true, }, { name: "test running", args: []string{"example-running"}, flags: []string{}, responses: map[string]release.TestRun_Status{"RUNNING: things are happpeningggg": release.TestRun_RUNNING}, - fail: false, + err: false, }, { name: "multiple tests example", @@ -78,29 +73,11 @@ func TestReleaseTesting(t *testing.T) { "FAILURE: good thing u checked :)": release.TestRun_FAILURE, "RUNNING: things are happpeningggg yet again": release.TestRun_RUNNING, "PASSED: feel free to party again": release.TestRun_SUCCESS}, - fail: true, + err: true, }, } - for _, tt := range tests { - c := &helm.FakeClient{Responses: tt.responses} - - buf := bytes.NewBuffer(nil) - cmd := newReleaseTestCmd(c, buf) - cmd.ParseFlags(tt.flags) - - err := cmd.RunE(cmd, tt.args) - if err == nil && tt.fail { - t.Errorf("%q did not fail but should have failed", tt.name) - } - - if err != nil { - if tt.fail { - continue - } else { - t.Errorf("%q reported error: %s", tt.name, err) - } - } - - } + runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { + return newReleaseTestCmd(c, out) + }) } From ad99c1b749df43c6dcdbc1df278a88e8093290fb Mon Sep 17 00:00:00 2001 From: fibonacci1729 Date: Fri, 30 Mar 2018 09:28:42 -0600 Subject: [PATCH 138/221] release list paritioning --- pkg/tiller/release_list.go | 51 ++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/pkg/tiller/release_list.go b/pkg/tiller/release_list.go index ec4dbfb39..72c21d97c 100644 --- a/pkg/tiller/release_list.go +++ b/pkg/tiller/release_list.go @@ -18,11 +18,11 @@ package tiller import ( "fmt" - "regexp" - + "github.com/golang/protobuf/proto" "k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/services" relutil "k8s.io/helm/pkg/releaseutil" + "regexp" ) // ListReleases lists the releases found by the server. @@ -107,21 +107,52 @@ func (s *ReleaseServer) ListReleases(req *services.ListReleasesRequest, stream s rels = rels[0:req.Limit] l = int64(len(rels)) } - - for i := 0; i < min(len(rels), int(req.Limit)); i++ { - res := &services.ListReleasesResponse{ - Next: next, - Count: l, - Total: total, - Releases: []*release.Release{rels[i]}, - } + res := &services.ListReleasesResponse{ + Next: next, + Count: l, + Total: total, + } + chunks := s.partition(rels[:min(len(rels), int(req.Limit))], maxMsgSize-proto.Size(res)) + for res.Releases = range chunks { if err := stream.Send(res); err != nil { + for range chunks { // drain + } return err } } return nil } +// partition packs releases into slices upto the capacity cap in bytes. +func (s *ReleaseServer) partition(rels []*release.Release, cap int) <-chan []*release.Release { + chunks := make(chan []*release.Release, 1) + go func() { + var ( + fill = 0 // fill is space available to fill + size int // size is size of a release + ) + var chunk []*release.Release + for _, rls := range rels { + if size = proto.Size(rls); size+fill > cap { + // Over-cap, push chunk onto channel to send over gRPC stream + s.Log("partitioned at %d with %d releases (cap=%d)", fill, len(chunk), cap) + chunks <- chunk + // reset paritioning state + chunk = chunk[:0] + fill = 0 + } + chunk = append(chunk, rls) + fill += size + } + if len(chunk) > 0 { + // send remaining if any + chunks <- chunk + } + close(chunks) + }() + return chunks +} + func filterByNamespace(namespace string, rels []*release.Release) ([]*release.Release, error) { matches := []*release.Release{} for _, r := range rels { From 458ba8ce37d5068ec03384257d4cbeed79e4906d Mon Sep 17 00:00:00 2001 From: Gijs Kunze Date: Tue, 3 Apr 2018 11:12:12 +0200 Subject: [PATCH 139/221] Removes unnecessary if block --- cmd/helm/install.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 55e34f405..d52dbc667 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -313,11 +313,6 @@ func mergeValues(dest map[string]interface{}, src map[string]interface{}) map[st dest[k] = v continue } - // If the key doesn't exist already, then just set the key to that value - if _, exists := dest[k]; !exists { - dest[k] = nextMap - continue - } // Edge case: If the key exists in the destination, but isn't a map destMap, isMap := dest[k].(map[string]interface{}) // If the source map has a map for this key, prefer it From b7fe0d0bd7d059ad45b71fe84be5275f66e1bf4a Mon Sep 17 00:00:00 2001 From: Timofey Kirillov Date: Wed, 21 Mar 2018 23:13:29 +0300 Subject: [PATCH 140/221] Add hook-delete-policy ReleaseServer unit tests Cover hook-succeeded, hook-failed and before-hook-creation hook delete policies. --- pkg/tiller/release_server_test.go | 464 ++++++++++++++++++++++++++++++ 1 file changed, 464 insertions(+) diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index d71e34bee..6c4d42e04 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -18,18 +18,25 @@ package tiller import ( "errors" + "fmt" "io" "io/ioutil" "os" "regexp" "testing" + "time" + "github.com/ghodss/yaml" "github.com/golang/protobuf/ptypes/timestamp" "golang.org/x/net/context" "google.golang.org/grpc/metadata" + "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" + "k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/helm/pkg/helm" + "k8s.io/helm/pkg/hooks" + "k8s.io/helm/pkg/kube" "k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/services" @@ -345,3 +352,460 @@ func (rs mockRunReleaseTestServer) SetTrailer(m metadata.MD) {} func (rs mockRunReleaseTestServer) SendMsg(v interface{}) error { return nil } func (rs mockRunReleaseTestServer) RecvMsg(v interface{}) error { return nil } func (rs mockRunReleaseTestServer) Context() context.Context { return helm.NewContext() } + +type mockHooksManifest struct { + Metadata struct { + Name string + Annotations map[string]string + } +} +type mockHooksKubeClient struct { + Resources map[string]*mockHooksManifest +} + +var errResourceExists = errors.New("resource already exists") + +func (kc *mockHooksKubeClient) makeManifest(r io.Reader) (*mockHooksManifest, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + manifest := &mockHooksManifest{} + err = yaml.Unmarshal(b, manifest) + if err != nil { + return nil, err + } + + return manifest, nil +} +func (kc *mockHooksKubeClient) Create(ns string, r io.Reader, timeout int64, shouldWait bool) error { + manifest, err := kc.makeManifest(r) + if err != nil { + return err + } + + if _, hasKey := kc.Resources[manifest.Metadata.Name]; hasKey { + return errResourceExists + } + + kc.Resources[manifest.Metadata.Name] = manifest + + return nil +} +func (kc *mockHooksKubeClient) Get(ns string, r io.Reader) (string, error) { + return "", nil +} +func (kc *mockHooksKubeClient) Delete(ns string, r io.Reader) error { + manifest, err := kc.makeManifest(r) + if err != nil { + return err + } + + delete(kc.Resources, manifest.Metadata.Name) + + return nil +} +func (kc *mockHooksKubeClient) WatchUntilReady(ns string, r io.Reader, timeout int64, shouldWait bool) error { + paramManifest, err := kc.makeManifest(r) + if err != nil { + return err + } + + manifest, hasManifest := kc.Resources[paramManifest.Metadata.Name] + if !hasManifest { + return fmt.Errorf("mockHooksKubeClient.WatchUntilReady: no such resource %s found", paramManifest.Metadata.Name) + } + + if manifest.Metadata.Annotations["mockHooksKubeClient/Emulate"] == "hook-failed" { + return fmt.Errorf("mockHooksKubeClient.WatchUntilReady: hook-failed") + } + + return nil +} +func (kc *mockHooksKubeClient) Update(ns string, currentReader, modifiedReader io.Reader, force bool, recreate bool, timeout int64, shouldWait bool) error { + return nil +} +func (kc *mockHooksKubeClient) Build(ns string, reader io.Reader) (kube.Result, error) { + return []*resource.Info{}, nil +} +func (kc *mockHooksKubeClient) BuildUnstructured(ns string, reader io.Reader) (kube.Result, error) { + return []*resource.Info{}, nil +} +func (kc *mockHooksKubeClient) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (core.PodPhase, error) { + return core.PodUnknown, nil +} + +func deletePolicyStub(kubeClient *mockHooksKubeClient) *ReleaseServer { + e := environment.New() + e.Releases = storage.Init(driver.NewMemory()) + e.KubeClient = kubeClient + + clientset := fake.NewSimpleClientset() + return &ReleaseServer{ + ReleaseModule: &LocalReleaseModule{ + clientset: clientset, + }, + env: e, + clientset: clientset, + Log: func(_ string, _ ...interface{}) {}, + } +} + +func deletePolicyHookStub(hookName string, extraAnnotations map[string]string, DeletePolicies []release.Hook_DeletePolicy) *release.Hook { + extraAnnotationsStr := "" + for k, v := range extraAnnotations { + extraAnnotationsStr += fmt.Sprintf(" \"%s\": \"%s\"\n", k, v) + } + + return &release.Hook{ + Name: hookName, + Kind: "Job", + Path: hookName, + Manifest: fmt.Sprintf(`kind: Job +metadata: + name: %s + annotations: + "helm.sh/hook": pre-install,pre-upgrade +%sdata: +name: value`, hookName, extraAnnotationsStr), + Events: []release.Hook_Event{ + release.Hook_PRE_INSTALL, + release.Hook_PRE_UPGRADE, + }, + DeletePolicies: DeletePolicies, + } +} + +func execHookShouldSucceed(rs *ReleaseServer, hook *release.Hook, releaseName string, namespace string, hookType string) error { + err := rs.execHook([]*release.Hook{hook}, releaseName, namespace, hookType, 600) + if err != nil { + return fmt.Errorf("expected hook %s to be successful: %s", hook.Name, err) + } + return nil +} + +func execHookShouldFail(rs *ReleaseServer, hook *release.Hook, releaseName string, namespace string, hookType string) error { + err := rs.execHook([]*release.Hook{hook}, releaseName, namespace, hookType, 600) + if err == nil { + return fmt.Errorf("expected hook %s to be failed", hook.Name) + } + return nil +} + +func execHookShouldFailWithError(rs *ReleaseServer, hook *release.Hook, releaseName string, namespace string, hookType string, expectedError error) error { + err := rs.execHook([]*release.Hook{hook}, releaseName, namespace, hookType, 600) + if err != expectedError { + return fmt.Errorf("expected hook %s to fail with error %v, got %v", hook.Name, expectedError, err) + } + return nil +} + +type deletePolicyContext struct { + ReleaseServer *ReleaseServer + ReleaseName string + Namespace string + HookName string + KubeClient *mockHooksKubeClient +} + +func newDeletePolicyContext() *deletePolicyContext { + kubeClient := &mockHooksKubeClient{ + Resources: make(map[string]*mockHooksManifest), + } + + return &deletePolicyContext{ + KubeClient: kubeClient, + ReleaseServer: deletePolicyStub(kubeClient), + ReleaseName: "flying-carp", + Namespace: "river", + HookName: "migration-job", + } +} + +func TestSuccessfulHookWithoutDeletePolicy(t *testing.T) { + ctx := newDeletePolicyContext() + hook := deletePolicyHookStub(ctx.HookName, nil, nil) + + err := execHookShouldSucceed(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; !hasResource { + t.Errorf("expected resource %s to be created by kube client", hook.Name) + } +} + +func TestFailedHookWithoutDeletePolicy(t *testing.T) { + ctx := newDeletePolicyContext() + hook := deletePolicyHookStub(ctx.HookName, + map[string]string{"mockHooksKubeClient/Emulate": "hook-failed"}, + nil, + ) + + err := execHookShouldFail(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; !hasResource { + t.Errorf("expected resource %s to be created by kube client", hook.Name) + } +} + +func TestSuccessfulHookWithSucceededDeletePolicy(t *testing.T) { + ctx := newDeletePolicyContext() + hook := deletePolicyHookStub(ctx.HookName, + map[string]string{"helm.sh/hook-delete-policy": "hook-succeeded"}, + []release.Hook_DeletePolicy{release.Hook_SUCCEEDED}, + ) + + err := execHookShouldSucceed(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; hasResource { + t.Errorf("expected resource %s to be unexisting after hook succeeded", hook.Name) + } +} + +func TestSuccessfulHookWithFailedDeletePolicy(t *testing.T) { + ctx := newDeletePolicyContext() + hook := deletePolicyHookStub(ctx.HookName, + map[string]string{"helm.sh/hook-delete-policy": "hook-failed"}, + []release.Hook_DeletePolicy{release.Hook_FAILED}, + ) + + err := execHookShouldSucceed(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; !hasResource { + t.Errorf("expected resource %s to be existing after hook succeeded", hook.Name) + } +} + +func TestFailedHookWithSucceededDeletePolicy(t *testing.T) { + ctx := newDeletePolicyContext() + + hook := deletePolicyHookStub(ctx.HookName, + map[string]string{ + "mockHooksKubeClient/Emulate": "hook-failed", + "helm.sh/hook-delete-policy": "hook-succeeded", + }, + []release.Hook_DeletePolicy{release.Hook_SUCCEEDED}, + ) + + err := execHookShouldFail(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; !hasResource { + t.Errorf("expected resource %s to be existing after hook failed", hook.Name) + } +} + +func TestFailedHookWithFailedDeletePolicy(t *testing.T) { + ctx := newDeletePolicyContext() + + hook := deletePolicyHookStub(ctx.HookName, + map[string]string{ + "mockHooksKubeClient/Emulate": "hook-failed", + "helm.sh/hook-delete-policy": "hook-failed", + }, + []release.Hook_DeletePolicy{release.Hook_FAILED}, + ) + + err := execHookShouldFail(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; hasResource { + t.Errorf("expected resource %s to be unexisting after hook failed", hook.Name) + } +} + +func TestSuccessfulHookWithSuccededOrFailedDeletePolicy(t *testing.T) { + ctx := newDeletePolicyContext() + + hook := deletePolicyHookStub(ctx.HookName, + map[string]string{ + "helm.sh/hook-delete-policy": "hook-succeeded,hook-failed", + }, + []release.Hook_DeletePolicy{release.Hook_SUCCEEDED, release.Hook_FAILED}, + ) + + err := execHookShouldSucceed(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; hasResource { + t.Errorf("expected resource %s to be unexisting after hook succeeded", hook.Name) + } +} + +func TestFailedHookWithSuccededOrFailedDeletePolicy(t *testing.T) { + ctx := newDeletePolicyContext() + + hook := deletePolicyHookStub(ctx.HookName, + map[string]string{ + "mockHooksKubeClient/Emulate": "hook-failed", + "helm.sh/hook-delete-policy": "hook-succeeded,hook-failed", + }, + []release.Hook_DeletePolicy{release.Hook_SUCCEEDED, release.Hook_FAILED}, + ) + + err := execHookShouldFail(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; hasResource { + t.Errorf("expected resource %s to be unexisting after hook failed", hook.Name) + } +} + +func TestHookAlreadyExists(t *testing.T) { + ctx := newDeletePolicyContext() + + hook := deletePolicyHookStub(ctx.HookName, nil, nil) + + err := execHookShouldSucceed(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; !hasResource { + t.Errorf("expected resource %s to be existing after hook succeeded", hook.Name) + } + + err = execHookShouldFailWithError(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreUpgrade, errResourceExists) + if err != nil { + t.Error(err) + } + + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; !hasResource { + t.Errorf("expected resource %s to be existing after already exists error", hook.Name) + } +} + +func TestHookDeletingWithBeforeHookCreationDeletePolicy(t *testing.T) { + ctx := newDeletePolicyContext() + + hook := deletePolicyHookStub(ctx.HookName, + map[string]string{"helm.sh/hook-delete-policy": "before-hook-creation"}, + []release.Hook_DeletePolicy{release.Hook_BEFORE_HOOK_CREATION}, + ) + + err := execHookShouldSucceed(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; !hasResource { + t.Errorf("expected resource %s to be existing after hook succeeded", hook.Name) + } + + err = execHookShouldSucceed(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreUpgrade) + if err != nil { + t.Error(err) + } + + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; !hasResource { + t.Errorf("expected resource %s to be existing after hook succeeded", hook.Name) + } +} + +func TestSuccessfulHookWithMixedDeletePolicies(t *testing.T) { + ctx := newDeletePolicyContext() + + hook := deletePolicyHookStub(ctx.HookName, + map[string]string{ + "helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation", + }, + []release.Hook_DeletePolicy{release.Hook_SUCCEEDED, release.Hook_BEFORE_HOOK_CREATION}, + ) + + err := execHookShouldSucceed(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; hasResource { + t.Errorf("expected resource %s to be unexisting after hook succeeded", hook.Name) + } + + err = execHookShouldSucceed(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreUpgrade) + if err != nil { + t.Error(err) + } + + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; hasResource { + t.Errorf("expected resource %s to be unexisting after hook succeeded", hook.Name) + } +} + +func TestFailedHookWithMixedDeletePolicies(t *testing.T) { + ctx := newDeletePolicyContext() + + hook := deletePolicyHookStub(ctx.HookName, + map[string]string{ + "mockHooksKubeClient/Emulate": "hook-failed", + "helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation", + }, + []release.Hook_DeletePolicy{release.Hook_SUCCEEDED, release.Hook_BEFORE_HOOK_CREATION}, + ) + + err := execHookShouldFail(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; !hasResource { + t.Errorf("expected resource %s to be existing after hook failed", hook.Name) + } + + err = execHookShouldFail(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreUpgrade) + if err != nil { + t.Error(err) + } + + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; !hasResource { + t.Errorf("expected resource %s to be existing after hook failed", hook.Name) + } +} + +func TestFailedThenSuccessfulHookWithMixedDeletePolicies(t *testing.T) { + ctx := newDeletePolicyContext() + + hook := deletePolicyHookStub(ctx.HookName, + map[string]string{ + "mockHooksKubeClient/Emulate": "hook-failed", + "helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation", + }, + []release.Hook_DeletePolicy{release.Hook_SUCCEEDED, release.Hook_BEFORE_HOOK_CREATION}, + ) + + err := execHookShouldFail(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreInstall) + if err != nil { + t.Error(err) + } + + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; !hasResource { + t.Errorf("expected resource %s to be existing after hook failed", hook.Name) + } + + hook = deletePolicyHookStub(ctx.HookName, + map[string]string{ + "helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation", + }, + []release.Hook_DeletePolicy{release.Hook_SUCCEEDED, release.Hook_BEFORE_HOOK_CREATION}, + ) + + err = execHookShouldSucceed(ctx.ReleaseServer, hook, ctx.ReleaseName, ctx.Namespace, hooks.PreUpgrade) + if err != nil { + t.Error(err) + } + + if _, hasResource := ctx.KubeClient.Resources[hook.Name]; hasResource { + t.Errorf("expected resource %s to be unexisting after hook succeeded", hook.Name) + } +} From c52707fb26e67609606f6ec35971068e79e32641 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 3 Apr 2018 08:13:18 -0700 Subject: [PATCH 141/221] import client auth plugins --- cmd/helm/helm.go | 2 ++ glide.lock | 58 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 497565209..f19cb3c50 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -30,6 +30,8 @@ import ( "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + // Import to initialize client auth plugins. + _ "k8s.io/client-go/plugin/pkg/client/auth" "k8s.io/helm/pkg/helm" helm_env "k8s.io/helm/pkg/helm/environment" "k8s.io/helm/pkg/helm/portforwarder" diff --git a/glide.lock b/glide.lock index 068f86372..6c54c927c 100644 --- a/glide.lock +++ b/glide.lock @@ -1,6 +1,11 @@ hash: 6837936360d447b64aa7a09d3c89c18ac5540b009a57fc4d3227af299bf40268 -updated: 2018-03-27T05:13:24.967040785Z +updated: 2018-04-03T08:17:14.801847688-07:00 imports: +- name: cloud.google.com/go + version: 3b1ae45394a234c385be014e9a488f2bb6eef821 + subpackages: + - compute/metadata + - internal - name: github.com/aokoli/goutils version: 9c37978a95bd5c709a15883b6242714ea6709e64 - name: github.com/asaskevich/govalidator @@ -9,6 +14,13 @@ imports: version: 19f72df4d05d31cbe1c56bfc8045c96babff6c7e subpackages: - winterm +- name: github.com/Azure/go-autorest + version: d4e6b95c12a08b4de2d48b45d5b4d594e5d32fab + subpackages: + - autorest + - autorest/adal + - autorest/azure + - autorest/date - name: github.com/beorn7/perks version: 3ac7bf7a47d159a033b107610db8a1b6575507a4 subpackages: @@ -23,6 +35,8 @@ imports: version: 782f4967f2dc4564575ca782fe2d04090b5faca8 subpackages: - spew +- name: github.com/dgrijalva/jwt-go + version: 01aeca54ebda6e0fbfafd0a524d234159c05ec20 - name: github.com/docker/distribution version: edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c subpackages: @@ -121,12 +135,23 @@ imports: version: 7d79101e329e5a3adf994758c578dab82b90c017 - name: github.com/google/gofuzz version: 44d81051d367757e1c7c6a5a86423ece9afcf63c +- name: github.com/google/uuid + version: 064e2069ce9c359c118179501254f67d7d37ba24 - name: github.com/googleapis/gnostic version: 0c5108395e2debce0d731cf0287ddf7242066aba subpackages: - OpenAPIv2 - compiler - extensions +- name: github.com/gophercloud/gophercloud + version: 6da026c32e2d622cc242d32984259c77237aefe1 + subpackages: + - openstack + - openstack/identity/v2/tenants + - openstack/identity/v2/tokens + - openstack/identity/v3/tokens + - openstack/utils + - pagination - name: github.com/gosuri/uitable version: 36ee7e946282a3fb1cfecd476ddc9b35d8847e42 subpackages: @@ -163,7 +188,7 @@ imports: - name: github.com/Masterminds/semver version: 517734cc7d6470c0d07130e40fd40bdeb9bcd3fd - name: github.com/Masterminds/sprig - version: b217b9c388de2cacde4354c536e520c52c055563 + version: 6b2a58267f6a8b1dc8e2eb5519b984008fa85e8c - name: github.com/Masterminds/vcs version: 3084677c2c188840777bff30054f2b553729d329 - name: github.com/mattn/go-runewidth @@ -210,8 +235,6 @@ imports: version: 5bd2802263f21d8788851d5305584c82a5c75d7e - name: github.com/russross/blackfriday version: 300106c228d52c8941d4b3de6054a6062a86dda3 -- name: github.com/satori/go.uuid - version: f58768cc1a7a7e77a3bd49e98cdd21419399b6a3 - name: github.com/shurcooL/sanitized_anchor_name version: 10ef21a441db47d8b13ebcc5fd2310f636973c77 - name: github.com/sirupsen/logrus @@ -244,12 +267,20 @@ imports: version: 1c05540f6879653db88113bc4a2b70aec4bd491f subpackages: - context + - context/ctxhttp - http2 - http2/hpack - idna - internal/timeseries - lex/httplex - trace +- name: golang.org/x/oauth2 + version: a6bd8cefa1811bd24b86f8902872e4e8225f74c4 + subpackages: + - google + - internal + - jws + - jwt - name: golang.org/x/sys version: 43eea11bc92608addb41b8a406b0407495c106f6 subpackages: @@ -278,6 +309,18 @@ imports: version: f51c12702a4d776e4c1fa9b0fabab841babae631 subpackages: - rate +- name: google.golang.org/appengine + version: 12d5545dc1cfa6047a286d5e853841b6471f4c19 + subpackages: + - internal + - internal/app_identity + - internal/base + - internal/datastore + - internal/log + - internal/modules + - internal/remote_api + - internal/urlfetch + - urlfetch - name: google.golang.org/genproto version: 09f6ed296fc66555a25fe4ce95173148778dfa85 subpackages: @@ -550,7 +593,12 @@ imports: - pkg/apis/clientauthentication - pkg/apis/clientauthentication/v1alpha1 - pkg/version + - plugin/pkg/client/auth + - plugin/pkg/client/auth/azure - plugin/pkg/client/auth/exec + - plugin/pkg/client/auth/gcp + - plugin/pkg/client/auth/oidc + - plugin/pkg/client/auth/openstack - rest - rest/fake - rest/watch @@ -593,7 +641,7 @@ imports: - pkg/util/proto - pkg/util/proto/validation - name: k8s.io/kubernetes - version: 923d8441db527e908cd7d266c4a9d18daa596d4c + version: a22f9fd34871d9dc9e5db2c02c713821d18ab2cd subpackages: - pkg/api/events - pkg/api/legacyscheme From 1d3ae54185e369477f42fb15d3a97f80c014c09c Mon Sep 17 00:00:00 2001 From: Zack Williams Date: Tue, 3 Apr 2018 13:10:56 -0700 Subject: [PATCH 142/221] Fix #3822 --- pkg/chartutil/create.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 319a75e2f..07bd11449 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -59,6 +59,9 @@ image: tag: stable pullPolicy: IfNotPresent +nameOverride: "" +fullnameOverride: "" + service: type: ClusterIP port: 80 From 58ac6023653632afe1bb13d01ed5516fff3737f5 Mon Sep 17 00:00:00 2001 From: AdamDang Date: Wed, 4 Apr 2018 07:07:55 +0800 Subject: [PATCH 143/221] Typo fix helm->Helm --- docs/rbac.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/rbac.md b/docs/rbac.md index b48a85ad2..2a3dfe7a0 100644 --- a/docs/rbac.md +++ b/docs/rbac.md @@ -4,11 +4,11 @@ In Kubernetes, granting a role to an application-specific service account is a b Bitnami also has a fantastic guide for [configuring RBAC in your cluster](https://docs.bitnami.com/kubernetes/how-to/configure-rbac-in-your-kubernetes-cluster/) that takes you through RBAC basics. -This guide is for users who want to restrict Tiller's capabilities to install resources to certain namespaces, or to grant a helm client running access to a Tiller instance. +This guide is for users who want to restrict Tiller's capabilities to install resources to certain namespaces, or to grant a Helm client running access to a Tiller instance. ## Tiller and Role-based Access Control -You can add a service account to Tiller using the `--service-account ` flag while you're configuring helm. As a prerequisite, you'll have to create a role binding which specifies a [role](https://kubernetes.io/docs/admin/authorization/rbac/#role-and-clusterrole) and a [service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) name that have been set up in advance. +You can add a service account to Tiller using the `--service-account ` flag while you're configuring Helm. As a prerequisite, you'll have to create a role binding which specifies a [role](https://kubernetes.io/docs/admin/authorization/rbac/#role-and-clusterrole) and a [service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) name that have been set up in advance. Once you have satisfied the pre-requisite and have a service account with the correct permissions, you'll run a command like this: `helm init --service-account ` @@ -110,7 +110,7 @@ Afterwards you can run `helm init` to install Tiller in the `tiller-world` names $ helm init --service-account tiller --tiller-namespace tiller-world $HELM_HOME has been configured at /Users/awesome-user/.helm. -Tiller (the helm server side component) has been installed into your Kubernetes Cluster. +Tiller (the Helm server side component) has been installed into your Kubernetes Cluster. Happy Helming! $ helm install nginx --tiller-namespace tiller-world --namespace tiller-world @@ -224,11 +224,11 @@ rolebinding "tiller-binding" created ## Helm and Role-based Access Control -When running a helm client in a pod, in order for the helm client to talk to a Tiller instance, it will need certain privileges to be granted. Specifically, the helm client will need to be able to create pods, forward ports and be able to list pods in the namespace where Tiller is running (so it can find Tiller). +When running a Helm client in a pod, in order for the Helm client to talk to a Tiller instance, it will need certain privileges to be granted. Specifically, the Helm client will need to be able to create pods, forward ports and be able to list pods in the namespace where Tiller is running (so it can find Tiller). ### Example: Deploy Helm in a namespace, talking to Tiller in another namespace -In this example, we will assume Tiller is running in a namespace called `tiller-world` and that the helm client is running in a namespace called `helm-world`. By default, Tiller is running in the `kube-system` namespace. +In this example, we will assume Tiller is running in a namespace called `tiller-world` and that the Helm client is running in a namespace called `helm-world`. By default, Tiller is running in the `kube-system` namespace. In `helm-user.yaml`: From 9b20d91e427da1d8bc5c961a25174ccee2f4ff6c Mon Sep 17 00:00:00 2001 From: Ryan Hartje Date: Tue, 3 Apr 2018 20:17:54 -0400 Subject: [PATCH 144/221] using existing mechanism to flag for failures --- cmd/helm/lint.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/cmd/helm/lint.go b/cmd/helm/lint.go index e83026117..63f11c062 100644 --- a/cmd/helm/lint.go +++ b/cmd/helm/lint.go @@ -97,13 +97,12 @@ func (l *lintCmd) run() error { var total int var failures int - rc := 0 for _, path := range l.paths { if linter, err := lintChart(path, rvals, l.namespace, l.strict); err != nil { fmt.Println("==> Skipping", path) fmt.Println(err) if err == errLintNoChart { - rc = 1 + failures = failures + 1 } } else { fmt.Println("==> Linting", path) @@ -131,10 +130,6 @@ func (l *lintCmd) run() error { fmt.Fprintf(l.out, "%s, no failures\n", msg) - if rc != 0 { - os.Exit(rc) - } - return nil } From bac4f45f94bf2856215f9e5657ee6a67d16d71fd Mon Sep 17 00:00:00 2001 From: Stuart Leeks Date: Wed, 4 Apr 2018 09:17:57 +0100 Subject: [PATCH 145/221] Switch flag to update existing record --- pkg/tiller/release_rollback.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/tiller/release_rollback.go b/pkg/tiller/release_rollback.go index fe9a6a032..fa3d943f4 100644 --- a/pkg/tiller/release_rollback.go +++ b/pkg/tiller/release_rollback.go @@ -135,7 +135,7 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R targetRelease.Info.Status.Code = release.Status_FAILED targetRelease.Info.Description = msg s.recordRelease(currentRelease, true) - s.recordRelease(targetRelease, false) + s.recordRelease(targetRelease, true) return res, err } From 499636d70c85d7615eb27d9c58d69ef55f26fc4a Mon Sep 17 00:00:00 2001 From: Michelle Noorali Date: Wed, 4 Apr 2018 12:04:27 -0400 Subject: [PATCH 146/221] ref(cmd/helm): show grpc error msg from prettyError --- cmd/helm/helm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 497565209..86d7696fb 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -214,7 +214,7 @@ func prettyError(err error) error { } // If it's grpc's error, make it more user-friendly. if s, ok := status.FromError(err); ok { - return s.Err() + return fmt.Errorf(s.Message()) } // Else return the original error. return err From 9266731dc45aac2aa6a726e5a887ee1078aaf35f Mon Sep 17 00:00:00 2001 From: Michelle Noorali Date: Wed, 4 Apr 2018 15:44:28 -0400 Subject: [PATCH 147/221] fix(pkg/tiller): reuseValues combines all prev val Resolves #3655 We were seeing that when running helm upgrade with the reuse-values flag enabled that you could end up in the position where overrides a.k.a computed values from previous revisions were not being saved on the updated revision. This left us in a weird position where some computed values would disappear mysteriously in the abyss. That happened because computed values from previous revisions weren't merged with the new computed values every time the reuse-values flag was used. This PR merges computed values from the previous revisions so you don't end up in that kind of conundrum. --- pkg/tiller/release_server.go | 16 +++++ pkg/tiller/release_update_test.go | 106 +++++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 2 deletions(-) diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index a96c64938..c72107026 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -25,6 +25,7 @@ import ( "strings" "github.com/technosophos/moniker" + "gopkg.in/yaml.v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/discovery" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" @@ -135,7 +136,22 @@ func (s *ReleaseServer) reuseValues(req *services.UpdateReleaseRequest, current if err != nil { return err } + + // merge new values with current + req.Values.Raw = current.Config.Raw + "\n" + req.Values.Raw req.Chart.Values = &chart.Config{Raw: nv} + + // yaml unmarshal and marshal to remove duplicate keys + y := map[string]interface{}{} + if err := yaml.Unmarshal([]byte(req.Values.Raw), &y); err != nil { + return err + } + data, err := yaml.Marshal(y) + if err != nil { + return err + } + + req.Values.Raw = string(data) return nil } diff --git a/pkg/tiller/release_update_test.go b/pkg/tiller/release_update_test.go index 642952f19..0189201d1 100644 --- a/pkg/tiller/release_update_test.go +++ b/pkg/tiller/release_update_test.go @@ -17,6 +17,7 @@ limitations under the License. package tiller import ( + "fmt" "strings" "testing" @@ -128,6 +129,107 @@ func TestUpdateRelease_ResetValues(t *testing.T) { } } +// This is a regression test for bug found in issue #3655 +func TestUpdateRelease_ComplexReuseValues(t *testing.T) { + c := helm.NewContext() + rs := rsFixture() + + installReq := &services.InstallReleaseRequest{ + Namespace: "spaced", + Chart: &chart.Chart{ + Metadata: &chart.Metadata{Name: "hello"}, + Templates: []*chart.Template{ + {Name: "templates/hello", Data: []byte("hello: world")}, + {Name: "templates/hooks", Data: []byte(manifestWithHook)}, + }, + Values: &chart.Config{Raw: "defaultFoo: defaultBar"}, + }, + Values: &chart.Config{Raw: "foo: bar"}, + } + + fmt.Println("Running Install release with foo: bar override") + installResp, err := rs.InstallRelease(c, installReq) + if err != nil { + t.Fatal(err) + } + + rel := installResp.Release + req := &services.UpdateReleaseRequest{ + Name: rel.Name, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{Name: "hello"}, + Templates: []*chart.Template{ + {Name: "templates/hello", Data: []byte("hello: world")}, + {Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)}, + }, + Values: &chart.Config{Raw: "defaultFoo: defaultBar"}, + }, + } + + fmt.Println("Running Update release with no overrides and no reuse-values flag") + res, err := rs.UpdateRelease(c, req) + if err != nil { + t.Fatalf("Failed updated: %s", err) + } + + expect := "foo: bar" + if res.Release.Config != nil && res.Release.Config.Raw != expect { + t.Errorf("Expected chart values to be %q, got %q", expect, res.Release.Config.Raw) + } + + rel = res.Release + req = &services.UpdateReleaseRequest{ + Name: rel.Name, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{Name: "hello"}, + Templates: []*chart.Template{ + {Name: "templates/hello", Data: []byte("hello: world")}, + {Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)}, + }, + Values: &chart.Config{Raw: "defaultFoo: defaultBar"}, + }, + Values: &chart.Config{Raw: "foo2: bar2"}, + ReuseValues: true, + } + + fmt.Println("Running Update release with foo2: bar2 override and reuse-values") + res, err = rs.UpdateRelease(c, req) + if err != nil { + t.Fatalf("Failed updated: %s", err) + } + + // This should have the newly-passed overrides. + expect = "foo: bar\nfoo2: bar2\n" + if res.Release.Config != nil && res.Release.Config.Raw != expect { + t.Errorf("Expected request config to be %q, got %q", expect, res.Release.Config.Raw) + } + + rel = res.Release + req = &services.UpdateReleaseRequest{ + Name: rel.Name, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{Name: "hello"}, + Templates: []*chart.Template{ + {Name: "templates/hello", Data: []byte("hello: world")}, + {Name: "templates/hooks", Data: []byte(manifestWithUpgradeHooks)}, + }, + Values: &chart.Config{Raw: "defaultFoo: defaultBar"}, + }, + Values: &chart.Config{Raw: "foo: baz"}, + ReuseValues: true, + } + + fmt.Println("Running Update release with foo=baz override with reuse-values flag") + res, err = rs.UpdateRelease(c, req) + if err != nil { + t.Fatalf("Failed updated: %s", err) + } + expect = "foo: baz\nfoo2: bar2\n" + if res.Release.Config != nil && res.Release.Config.Raw != expect { + t.Errorf("Expected chart values to be %q, got %q", expect, res.Release.Config.Raw) + } +} + func TestUpdateRelease_ReuseValues(t *testing.T) { c := helm.NewContext() rs := rsFixture() @@ -157,8 +259,8 @@ func TestUpdateRelease_ReuseValues(t *testing.T) { if res.Release.Chart.Values != nil && res.Release.Chart.Values.Raw != expect { t.Errorf("Expected chart values to be %q, got %q", expect, res.Release.Chart.Values.Raw) } - // This should have the newly-passed overrides. - expect = "name2: val2" + // This should have the newly-passed overrides and any other computed values. `name: value` comes from release Config via releaseStub() + expect = "name: value\nname2: val2" if res.Release.Config != nil && res.Release.Config.Raw != expect { t.Errorf("Expected request config to be %q, got %q", expect, res.Release.Config.Raw) } From e02802ba95e17c2a21dceeb56df893c01001e5d8 Mon Sep 17 00:00:00 2001 From: Michelle Noorali Date: Wed, 4 Apr 2018 15:54:12 -0400 Subject: [PATCH 148/221] ref(pkg/tiller): clarify reuseValues comment --- pkg/tiller/release_update.go | 2 +- pkg/tiller/release_update_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/tiller/release_update.go b/pkg/tiller/release_update.go index cb8b57792..6f5d37331 100644 --- a/pkg/tiller/release_update.go +++ b/pkg/tiller/release_update.go @@ -80,7 +80,7 @@ func (s *ReleaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*rele return nil, nil, err } - // If new values were not supplied in the upgrade, re-use the existing values. + // determine if values will be reused if err := s.reuseValues(req, currentRelease); err != nil { return nil, nil, err } diff --git a/pkg/tiller/release_update_test.go b/pkg/tiller/release_update_test.go index 0189201d1..a1b9a4bff 100644 --- a/pkg/tiller/release_update_test.go +++ b/pkg/tiller/release_update_test.go @@ -260,7 +260,7 @@ func TestUpdateRelease_ReuseValues(t *testing.T) { t.Errorf("Expected chart values to be %q, got %q", expect, res.Release.Chart.Values.Raw) } // This should have the newly-passed overrides and any other computed values. `name: value` comes from release Config via releaseStub() - expect = "name: value\nname2: val2" + expect = "name: value\nname2: val2\n" if res.Release.Config != nil && res.Release.Config.Raw != expect { t.Errorf("Expected request config to be %q, got %q", expect, res.Release.Config.Raw) } From e922a873bc30acfb1ed65031014eea6e25f604c1 Mon Sep 17 00:00:00 2001 From: Michelle Noorali Date: Mon, 19 Mar 2018 12:35:42 -0400 Subject: [PATCH 149/221] ref(cmd/upgrade): update reuse-values flag descrip helps clarify behavior. See #3655 --- cmd/helm/upgrade.go | 2 +- docs/helm/helm_upgrade.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 125796762..66c4a3657 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -130,7 +130,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command { f.StringVar(&upgrade.version, "version", "", "specify the exact chart version to use. If this is not specified, the latest version is used") f.Int64Var(&upgrade.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)") f.BoolVar(&upgrade.resetValues, "reset-values", false, "when upgrading, reset the values to the ones built into the chart") - f.BoolVar(&upgrade.reuseValues, "reuse-values", false, "when upgrading, reuse the last release's values, and merge in any new values. If '--reset-values' is specified, this is ignored.") + f.BoolVar(&upgrade.reuseValues, "reuse-values", false, "when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored.") f.BoolVar(&upgrade.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout") f.StringVar(&upgrade.repoURL, "repo", "", "chart repository url where to locate the requested chart") f.StringVar(&upgrade.username, "username", "", "chart repository username where to locate the requested chart") diff --git a/docs/helm/helm_upgrade.md b/docs/helm/helm_upgrade.md index 7ada6025f..c2882265e 100644 --- a/docs/helm/helm_upgrade.md +++ b/docs/helm/helm_upgrade.md @@ -51,7 +51,7 @@ helm upgrade [RELEASE] [CHART] --recreate-pods performs pods restart for the resource if applicable --repo string chart repository url where to locate the requested chart --reset-values when upgrading, reset the values to the ones built into the chart - --reuse-values when upgrading, reuse the last release's values, and merge in any new values. If '--reset-values' is specified, this is ignored. + --reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored. --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300) @@ -81,4 +81,4 @@ helm upgrade [RELEASE] [CHART] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 20-Mar-2018 +###### Auto generated by spf13/cobra on 4-Apr-2018 From 1e7915587f383a5e37f8506c9c1784bd37f43753 Mon Sep 17 00:00:00 2001 From: Daryl Walleck Date: Wed, 4 Apr 2018 18:43:03 -0500 Subject: [PATCH 150/221] Fixes typos introduced in #3540. Closes #3823 --- docs/charts_hooks.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/charts_hooks.md b/docs/charts_hooks.md index af6d0f4f9..4142f2ce0 100644 --- a/docs/charts_hooks.md +++ b/docs/charts_hooks.md @@ -191,8 +191,8 @@ When helm release being updated it is possible, that hook resource already exist One might choose `"helm.sh/hook-delete-policy": "before-hook-creation"` over `"helm.sh/hook-delete-policy": "hook-succeeded,hook-failed"` because: -* It is convinient to keep failed hook job resource in kubernetes for example for manual debug. +* It is convenient to keep failed hook job resource in kubernetes for example for manual debug. * It may be necessary to keep succeeded hook resource in kubernetes for some reason. -* At the same time it is not desireable to do manual resource deletion before helm release upgrade. +* At the same time it is not desirable to do manual resource deletion before helm release upgrade. -`"helm.sh/hook-delete-policy": "before-hook-creation"` annotation on hook causes tiller to remove the hook from previous release if there is one before the new hook is launched and can be used with another policies. +`"helm.sh/hook-delete-policy": "before-hook-creation"` annotation on hook causes tiller to remove the hook from previous release if there is one before the new hook is launched and can be used with another policy. From f52d0f4f18003ab6392a1b768abc2bd68cf82649 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Thu, 5 Apr 2018 08:06:47 -0700 Subject: [PATCH 151/221] rename TPR to CRD --- .../custom_resource_definitions.md | 37 ++++++++++++++++++ .../third_party_resources.md | 38 ------------------- 2 files changed, 37 insertions(+), 38 deletions(-) create mode 100644 docs/chart_best_practices/custom_resource_definitions.md delete mode 100644 docs/chart_best_practices/third_party_resources.md diff --git a/docs/chart_best_practices/custom_resource_definitions.md b/docs/chart_best_practices/custom_resource_definitions.md new file mode 100644 index 000000000..96690dc9b --- /dev/null +++ b/docs/chart_best_practices/custom_resource_definitions.md @@ -0,0 +1,37 @@ +# Custom Resource Definitions + +This section of the Best Practices Guide deals with creating and using Custom Resource Definition +objects. + +When working with Custom Resource Definitions (CRDs), it is important to distinguish +two different pieces: + +- There is a declaration of a CRD. This is the YAML file that has the kind `CustomResourceDefinition` +- Then there are resources that _use_ the CRD. Say a CRD defines `foo.example.com/v1`. Any resource + that has `apiVersion: example.com/v1` and kind `Foo` is a resource that uses the CRD. + +## Install a CRD Declaration Before Using the Resource + +Helm is optimized to load as many resources into Kubernetes as fast as possible. +By design, Kubernetes can take an entire set of manifests and bring them all +online (this is called the reconciliation loop). + +But there's a difference with CRDs. + +For a CRD, the declaration must be registered before any resources of that CRDs +kind(s) can be used. And the registration process sometimes takes a few seconds. + +### Method 1: Separate Charts + +One way to do this is to put the CRD definition in one chart, and then put any +resources that use that CRD in _another_ chart. + +In this method, each chart must be installed separately. + +### Method 2: Pre-install Hooks + +To package the two together, add a `pre-install` hook to the CRD definition so +that it is fully installed before the rest of the chart is executed. + +Note that if you create the CRD with a `pre-install` hook, that CRD definition +will not be deleted when `helm delete` is run. diff --git a/docs/chart_best_practices/third_party_resources.md b/docs/chart_best_practices/third_party_resources.md deleted file mode 100644 index cb0fcc754..000000000 --- a/docs/chart_best_practices/third_party_resources.md +++ /dev/null @@ -1,38 +0,0 @@ -# Third Party Resources - -This section of the Best Practices Guide deals with creating and using Third Party Resource -objects. - -When working with Third Party Resources (TPRs), it is important to distinguish -two different pieces: - -- There is a declaration of a TPR. This is the YAML file that has the kind `ThirdPartyResource` -- Then there are resources that _use_ the TPR. Say a TPR defines `foo.example.com/v1`. Any resource - that has `apiVersion: example.com/v1` and kind `Foo` is a resource that uses the - TPR. - -## Install a TPR Declaration Before Using the Resource - -Helm is optimized to load as many resources into Kubernetes as fast as possible. -By design, Kubernetes can take an entire set of manifests and bring them all -online (this is called the reconciliation loop). - -But there's a difference with TPRs. - -For a TPR, the declaration must be registered before any resources of that TPRs -kind(s) can be used. And the registration process sometimes takes a few seconds. - -### Method 1: Separate Charts - -One way to do this is to put the TPR definition in one chart, and then put any -resources that use that TPR in _another_ chart. - -In this method, each chart must be installed separately. - -### Method 2: Pre-install Hooks - -To package the two together, add a `pre-install` hook to the TPR definition so -that it is fully installed before the rest of the chart is executed. - -Note that if you create the TPR with a `pre-install` hook, that TPR definition -will not be deleted when `helm delete` is run. From c6faed101b4ad9c60c99f7f0fdb8edf093b73490 Mon Sep 17 00:00:00 2001 From: Stefan Henseler Date: Thu, 5 Apr 2018 23:51:21 +0200 Subject: [PATCH 152/221] Updates readme with choco install command --- README.md | 6 +++++- docs/install.md | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7622fafc8..fb2e16bce 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,11 @@ Binary downloads of the Helm client can be found at the following links: - [Windows](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.2-windows-amd64.tar.gz) Unpack the `helm` binary and add it to your PATH and you are good to go! -macOS/[homebrew](https://brew.sh/) users can also use `brew install kubernetes-helm`. + +If you want to use a package manager: + +- macOS/[homebrew](https://brew.sh/) users can use `brew install kubernetes-helm`. +- Windows/[chocolatey](https://chocolatey.org/) users can use `choco install kubernetes-helm`. 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 78b1a53b6..6ca13c90a 100755 --- a/docs/install.md +++ b/docs/install.md @@ -36,6 +36,15 @@ brew install kubernetes-helm (Note: There is also a formula for emacs-helm, which is a different project.) +### From Chocolatey (Windows) + +Members of the Kubernetes community have contributed a [Helm package](https://chocolatey.org/packages/kubernetes-helm) build to +[Chocolatey](https://chocolatey.org/). This package is generally up to date. + +``` +choco install kubernetes-helm +``` + ## From Script Helm now has an installer script that will automatically grab the latest version From 35132d141c54598e7dab23207acce7e6fb1dfa4a Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Fri, 6 Apr 2018 00:40:43 +0200 Subject: [PATCH 153/221] toYaml - Fixes #3410 - trailing \n issue `toYaml` utilized by `.Files` was introducing a new line. It is an issue since the new line is part of a functions output, it can't be whitespace chomped away so it would require a `trimSuffix "\n"` pipe. This commit trims one trailing `\n` from the toYaml output. --- pkg/chartutil/files.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go index a711a3366..ced8ce15a 100644 --- a/pkg/chartutil/files.go +++ b/pkg/chartutil/files.go @@ -175,7 +175,7 @@ func ToYaml(v interface{}) string { // Swallow errors inside of a template. return "" } - return string(data) + return strings.TrimSuffix(string(data), "\n") } // FromYaml converts a YAML document into a map[string]interface{}. From 6cdf6cee56dcd90e3dca82950b15d46e6bb4587b Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Fri, 6 Apr 2018 00:41:14 +0200 Subject: [PATCH 154/221] toYaml - Fixes #3470 - trailing \n issue `toYaml` was introducing a new line. It is an issue since the new line is part of a functions output, it can't be whitespace chomped away so it would require a `trimSuffix "\n"` pipe. This commit trims one trailing `\n` from the toYaml output. --- pkg/strvals/parser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/strvals/parser.go b/pkg/strvals/parser.go index 8a16adf7e..aa3d15904 100644 --- a/pkg/strvals/parser.go +++ b/pkg/strvals/parser.go @@ -36,7 +36,7 @@ func ToYAML(s string) (string, error) { return "", err } d, err := yaml.Marshal(m) - return string(d), err + return strings.TrimSuffix(string(d), "\n"), err } // Parse parses a set line. From 05a1f7f46c2ce2beacbb099d06a99422376f848d Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Fri, 6 Apr 2018 00:59:22 +0200 Subject: [PATCH 155/221] Updated tests for PR #3837 --- pkg/chartutil/files_test.go | 8 ++++---- pkg/strvals/parser_test.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/chartutil/files_test.go b/pkg/chartutil/files_test.go index 731c82e6f..5cec35883 100644 --- a/pkg/chartutil/files_test.go +++ b/pkg/chartutil/files_test.go @@ -72,10 +72,10 @@ func TestToConfig(t *testing.T) { f := NewFiles(getTestFiles()) out := f.Glob("**/captain.txt").AsConfig() - as.Equal("captain.txt: The Captain\n", out) + as.Equal("captain.txt: The Captain", out) out = f.Glob("ship/**").AsConfig() - as.Equal("captain.txt: The Captain\nstowaway.txt: Legatt\n", out) + as.Equal("captain.txt: The Captain\nstowaway.txt: Legatt", out) } func TestToSecret(t *testing.T) { @@ -84,7 +84,7 @@ func TestToSecret(t *testing.T) { f := NewFiles(getTestFiles()) out := f.Glob("ship/**").AsSecrets() - as.Equal("captain.txt: VGhlIENhcHRhaW4=\nstowaway.txt: TGVnYXR0\n", out) + as.Equal("captain.txt: VGhlIENhcHRhaW4=\nstowaway.txt: TGVnYXR0", out) } func TestLines(t *testing.T) { @@ -99,7 +99,7 @@ func TestLines(t *testing.T) { } func TestToYaml(t *testing.T) { - expect := "foo: bar\n" + expect := "foo: bar" v := struct { Foo string `json:"foo"` }{ diff --git a/pkg/strvals/parser_test.go b/pkg/strvals/parser_test.go index 3f9828498..fd287bf8a 100644 --- a/pkg/strvals/parser_test.go +++ b/pkg/strvals/parser_test.go @@ -365,7 +365,7 @@ func TestToYAML(t *testing.T) { if err != nil { t.Fatal(err) } - expect := "name: value\n" + expect := "name: value" if o != expect { t.Errorf("Expected %q, got %q", expect, o) } From 138de17c64e6c01468f4e17ddff0231b34d3f683 Mon Sep 17 00:00:00 2001 From: AdamDang Date: Fri, 6 Apr 2018 16:58:40 +0800 Subject: [PATCH 156/221] Fix some typos outout->output Get's->get the the->the --- pkg/kube/client.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index e4e2dc1bb..89e919e3d 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -56,7 +56,7 @@ import ( ) const ( - // MissingGetHeader is added to Get's outout when a resource is not found. + // MissingGetHeader is added to get output when a resource is not found. MissingGetHeader = "==> MISSING\nKIND\t\tNAME\n" ) @@ -406,7 +406,7 @@ func createPatch(mapping *meta.RESTMapping, target, current runtime.Object) ([]b // While different objects need different merge types, the parent function // that calls this does not try to create a patch when the data (first - // returned object) is nil. We can skip calculating the the merge type as + // returned object) is nil. We can skip calculating the merge type as // the returned merge type is ignored. if apiequality.Semantic.DeepEqual(oldData, newData) { return nil, types.StrategicMergePatchType, nil @@ -692,7 +692,7 @@ func (c *Client) watchPodUntilComplete(timeout time.Duration, info *resource.Inf return err } -//get an kubernetes resources's relation pods +//get a kubernetes resources' relation pods // kubernetes resource used select labels to relate pods func (c *Client) getSelectRelationPod(info *resource.Info, objPods map[string][]core.Pod) (map[string][]core.Pod, error) { if info == nil { From 8bd42d264515d65372c6728c2762df1b6e9da7ce Mon Sep 17 00:00:00 2001 From: Steffen Windoffer Date: Fri, 6 Apr 2018 11:21:54 +0200 Subject: [PATCH 157/221] remove unused servicePort from default ingress template --- pkg/chartutil/create.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 07bd11449..9f2a8cc1f 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -123,7 +123,6 @@ const defaultIgnore = `# Patterns to ignore when building packages. const defaultIngress = `{{- if .Values.ingress.enabled -}} {{- $fullName := include ".fullname" . -}} -{{- $servicePort := .Values.service.port -}} {{- $ingressPath := .Values.ingress.path -}} apiVersion: extensions/v1beta1 kind: Ingress From b718b1c87038d44f2519f50d2df25454aad5f926 Mon Sep 17 00:00:00 2001 From: Taylor Thomas Date: Fri, 6 Apr 2018 15:43:37 -0700 Subject: [PATCH 158/221] fix(package): Adds missing `set-string` flag and parameter A recent PR (#3471) wasn't up to date with the latest master changes. This fixes the issue and adds the right number of parameters to the `vals` function call. --- cmd/helm/package.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/helm/package.go b/cmd/helm/package.go index 4b2e6b398..bf171e534 100644 --- a/cmd/helm/package.go +++ b/cmd/helm/package.go @@ -55,6 +55,7 @@ type packageCmd struct { path string valueFiles valueFiles values []string + stringValues []string key string keyring string version string @@ -99,6 +100,7 @@ func newPackageCmd(out io.Writer) *cobra.Command { f := cmd.Flags() f.VarP(&pkg.valueFiles, "values", "f", "specify values in a YAML file or a URL(can specify multiple)") f.StringArrayVar(&pkg.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") + f.StringArrayVar(&pkg.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.BoolVar(&pkg.save, "save", true, "save packaged chart to local chart repository") f.BoolVar(&pkg.sign, "sign", false, "use a PGP private key to sign this package") f.StringVar(&pkg.key, "key", "", "name of the key to use when signing. Used if --sign is true") @@ -137,7 +139,7 @@ func (p *packageCmd) run() error { return err } - overrideVals, err := vals(p.valueFiles, p.values) + overrideVals, err := vals(p.valueFiles, p.values, p.stringValues) if err != nil { return err } From 85282ab864973cbbb85d97849c37be0432df7149 Mon Sep 17 00:00:00 2001 From: Taylor Thomas Date: Fri, 6 Apr 2018 16:33:38 -0700 Subject: [PATCH 159/221] fix(docs): Add the missing docs Because I was too stupid to regen the docs and flake made it so we didn't get a reminder --- docs/helm/helm_package.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/helm/helm_package.md b/docs/helm/helm_package.md index daceef32c..957f9c3b2 100644 --- a/docs/helm/helm_package.md +++ b/docs/helm/helm_package.md @@ -23,16 +23,17 @@ helm package [flags] [CHART_PATH] [...] ### Options ``` - --app-version string set the appVersion on the chart to this version - -u, --dependency-update update dependencies from "requirements.yaml" to dir "charts/" before packaging - -d, --destination string location to write the chart. (default ".") - --key string name of the key to use when signing. Used if --sign is true - --keyring string location of a public keyring (default "~/.gnupg/pubring.gpg") - --save save packaged chart to local chart repository (default true) - --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) - --sign use a PGP private key to sign this package - -f, --values valueFiles specify values in a YAML file or a URL(can specify multiple) (default []) - --version string set the version on the chart to this semver version + --app-version string set the appVersion on the chart to this version + -u, --dependency-update update dependencies from "requirements.yaml" to dir "charts/" before packaging + -d, --destination string location to write the chart. (default ".") + --key string name of the key to use when signing. Used if --sign is true + --keyring string location of a public keyring (default "~/.gnupg/pubring.gpg") + --save save packaged chart to local chart repository (default true) + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --sign use a PGP private key to sign this package + -f, --values valueFiles specify values in a YAML file or a URL(can specify multiple) (default []) + --version string set the version on the chart to this semver version ``` ### Options inherited from parent commands @@ -49,4 +50,4 @@ helm package [flags] [CHART_PATH] [...] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 14-Mar-2018 +###### Auto generated by spf13/cobra on 6-Apr-2018 From ee9ef91df0ea72646ae0ea23497622bfd019a944 Mon Sep 17 00:00:00 2001 From: AdamDang Date: Sat, 7 Apr 2018 08:56:44 +0800 Subject: [PATCH 160/221] typo fix get->Get's typo fix get->Get's --- pkg/kube/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 89e919e3d..8a7402938 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -56,7 +56,7 @@ import ( ) const ( - // MissingGetHeader is added to get output when a resource is not found. + // MissingGetHeader is added to Get's output when a resource is not found. MissingGetHeader = "==> MISSING\nKIND\t\tNAME\n" ) From 826781a1a3ceddaf0abeced14bee867d86c96b4e Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Sat, 7 Apr 2018 12:04:29 -0400 Subject: [PATCH 161/221] fix(helm) refactor reset command unit tests to remove duplication in test code Signed-off-by: Arash Deshmeh --- cmd/helm/reset_test.go | 169 ++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 104 deletions(-) diff --git a/cmd/helm/reset_test.go b/cmd/helm/reset_test.go index 458736a63..ae6a00036 100644 --- a/cmd/helm/reset_test.go +++ b/cmd/helm/reset_test.go @@ -31,40 +31,58 @@ import ( "k8s.io/helm/pkg/proto/hapi/release" ) +type resetCase struct { + name string + err bool + resp []*release.Release + removeHelmHome bool + force bool + expectedActions int + expectedOutput string +} + func TestResetCmd(t *testing.T) { - home, err := ioutil.TempDir("", "helm_home") - if err != nil { - t.Fatal(err) - } - defer os.Remove(home) - var buf bytes.Buffer - c := &helm.FakeClient{} - fc := fake.NewSimpleClientset() - cmd := &resetCmd{ - out: &buf, - home: helmpath.Home(home), - client: c, - kubeClient: fc, - namespace: core.NamespaceDefault, - } - if err := cmd.run(); err != nil { - t.Errorf("unexpected error: %v", err) - } - actions := fc.Actions() - if len(actions) != 3 { - t.Errorf("Expected 3 actions, got %d", len(actions)) - } - expected := "Tiller (the Helm server-side component) has been uninstalled from your Kubernetes Cluster." - if !strings.Contains(buf.String(), expected) { - t.Errorf("expected %q, got %q", expected, buf.String()) - } - if _, err := os.Stat(home); err != nil { - t.Errorf("Helm home directory %s does not exists", home) - } + verifyResetCmd(t, resetCase{ + name: "test reset command", + expectedActions: 3, + expectedOutput: "Tiller (the Helm server-side component) has been uninstalled from your Kubernetes Cluster.", + }) } func TestResetCmd_removeHelmHome(t *testing.T) { + verifyResetCmd(t, resetCase{ + name: "test reset command - remove helm home", + removeHelmHome: true, + expectedActions: 3, + expectedOutput: "Tiller (the Helm server-side component) has been uninstalled from your Kubernetes Cluster.", + }) +} + +func TestReset_deployedReleases(t *testing.T) { + verifyResetCmd(t, resetCase{ + name: "test reset command - deployed releases", + resp: []*release.Release{ + helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), + }, + err: true, + expectedOutput: "there are still 1 deployed releases (Tip: use --force to remove Tiller. Releases will not be deleted.)", + }) +} + +func TestReset_forceFlag(t *testing.T) { + verifyResetCmd(t, resetCase{ + name: "test reset command - force flag", + force: true, + resp: []*release.Release{ + helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), + }, + expectedActions: 3, + expectedOutput: "Tiller (the Helm server-side component) has been uninstalled from your Kubernetes Cluster.", + }) +} + +func verifyResetCmd(t *testing.T, tc resetCase) { home, err := ioutil.TempDir("", "helm_home") if err != nil { t.Fatal(err) @@ -72,99 +90,42 @@ func TestResetCmd_removeHelmHome(t *testing.T) { defer os.Remove(home) var buf bytes.Buffer - c := &helm.FakeClient{} + c := &helm.FakeClient{ + Rels: tc.resp, + } fc := fake.NewSimpleClientset() cmd := &resetCmd{ - removeHelmHome: true, + removeHelmHome: tc.removeHelmHome, + force: tc.force, out: &buf, home: helmpath.Home(home), client: c, kubeClient: fc, namespace: core.NamespaceDefault, } - if err := cmd.run(); err != nil { - t.Errorf("unexpected error: %v", err) - } - actions := fc.Actions() - if len(actions) != 3 { - t.Errorf("Expected 3 actions, got %d", len(actions)) - } - expected := "Tiller (the Helm server-side component) has been uninstalled from your Kubernetes Cluster." - if !strings.Contains(buf.String(), expected) { - t.Errorf("expected %q, got %q", expected, buf.String()) - } - if _, err := os.Stat(home); err == nil { - t.Errorf("Helm home directory %s already exists", home) - } -} -func TestReset_deployedReleases(t *testing.T) { - home, err := ioutil.TempDir("", "helm_home") - if err != nil { - t.Fatal(err) - } - defer os.Remove(home) - - var buf bytes.Buffer - resp := []*release.Release{ - helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), - } - c := &helm.FakeClient{ - Rels: resp, - } - fc := fake.NewSimpleClientset() - cmd := &resetCmd{ - out: &buf, - home: helmpath.Home(home), - client: c, - kubeClient: fc, - namespace: core.NamespaceDefault, - } err = cmd.run() - expected := "there are still 1 deployed releases (Tip: use --force to remove Tiller. Releases will not be deleted.)" - if !strings.Contains(err.Error(), expected) { + if !tc.err && err != nil { t.Errorf("unexpected error: %v", err) } - if _, err := os.Stat(home); err != nil { - t.Errorf("Helm home directory %s does not exists", home) - } -} -func TestReset_forceFlag(t *testing.T) { - home, err := ioutil.TempDir("", "helm_home") - if err != nil { - t.Fatal(err) + got := buf.String() + if tc.err { + got = err.Error() } - defer os.Remove(home) - var buf bytes.Buffer - resp := []*release.Release{ - helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), - } - c := &helm.FakeClient{ - Rels: resp, - } - fc := fake.NewSimpleClientset() - cmd := &resetCmd{ - force: true, - out: &buf, - home: helmpath.Home(home), - client: c, - kubeClient: fc, - namespace: core.NamespaceDefault, - } - if err := cmd.run(); err != nil { - t.Errorf("unexpected error: %v", err) - } actions := fc.Actions() - if len(actions) != 3 { - t.Errorf("Expected 3 actions, got %d", len(actions)) + if tc.expectedActions > 0 && len(actions) != tc.expectedActions { + t.Errorf("Expected %d actions, got %d", tc.expectedActions, len(actions)) } - expected := "Tiller (the Helm server-side component) has been uninstalled from your Kubernetes Cluster." - if !strings.Contains(buf.String(), expected) { - t.Errorf("expected %q, got %q", expected, buf.String()) + if !strings.Contains(got, tc.expectedOutput) { + t.Errorf("expected %q, got %q", tc.expectedOutput, got) } - if _, err := os.Stat(home); err != nil { + _, err = os.Stat(home) + if !tc.removeHelmHome && err != nil { t.Errorf("Helm home directory %s does not exists", home) } + if tc.removeHelmHome && err == nil { + t.Errorf("Helm home directory %s exists", home) + } } From 3f5e82c83207c7444f98cc65a73bf71a0babeb1d Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 8 Apr 2018 23:18:47 +0200 Subject: [PATCH 162/221] Typo fix `*/ }}` would cause an error actually, one must use `*/}}` or `*/ -}}`. Not obvious at all. --- docs/chart_best_practices/templates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chart_best_practices/templates.md b/docs/chart_best_practices/templates.md index c9995ea0a..7b21c5fea 100644 --- a/docs/chart_best_practices/templates.md +++ b/docs/chart_best_practices/templates.md @@ -155,7 +155,7 @@ Template comments should be used when documenting features of a template, such a ```yaml {{- /* mychart.shortname provides a 6 char truncated version of the release name. -*/ }} +*/ -}} {{ define "mychart.shortname" -}} {{ .Release.Name | trunc 6 }} {{- end -}} From c22492ff016ea85d7b05be013ecd4458b00b02ae Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Mon, 9 Apr 2018 12:18:23 -0400 Subject: [PATCH 163/221] fix(helm): refactor tiller release install unit tests using chart and install request stubs Signed-off-by: Arash Deshmeh --- pkg/tiller/release_install_test.go | 150 +++++++---------------------- pkg/tiller/release_server_test.go | 125 ++++++++++++++++++++++-- 2 files changed, 148 insertions(+), 127 deletions(-) diff --git a/pkg/tiller/release_install_test.go b/pkg/tiller/release_install_test.go index 8e2238e74..2f21dc46b 100644 --- a/pkg/tiller/release_install_test.go +++ b/pkg/tiller/release_install_test.go @@ -22,7 +22,6 @@ import ( "testing" "k8s.io/helm/pkg/helm" - "k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/services" "k8s.io/helm/pkg/version" @@ -32,17 +31,7 @@ func TestInstallRelease(t *testing.T) { c := helm.NewContext() rs := rsFixture() - // TODO: Refactor this into a mock. - req := &services.InstallReleaseRequest{ - Namespace: "spaced", - Chart: &chart.Chart{ - Metadata: &chart.Metadata{Name: "hello"}, - Templates: []*chart.Template{ - {Name: "templates/hello", Data: []byte("hello: world")}, - {Name: "templates/hooks", Data: []byte(manifestWithHook)}, - }, - }, - } + req := installRequest() res, err := rs.InstallRelease(c, req) if err != nil { t.Fatalf("Failed install: %s", err) @@ -96,18 +85,9 @@ func TestInstallRelease_WithNotes(t *testing.T) { c := helm.NewContext() rs := rsFixture() - // TODO: Refactor this into a mock. - req := &services.InstallReleaseRequest{ - Namespace: "spaced", - Chart: &chart.Chart{ - Metadata: &chart.Metadata{Name: "hello"}, - Templates: []*chart.Template{ - {Name: "templates/hello", Data: []byte("hello: world")}, - {Name: "templates/hooks", Data: []byte(manifestWithHook)}, - {Name: "templates/NOTES.txt", Data: []byte(notesText)}, - }, - }, - } + req := installRequest( + withChart(withNotes(notesText)), + ) res, err := rs.InstallRelease(c, req) if err != nil { t.Fatalf("Failed install: %s", err) @@ -165,18 +145,9 @@ func TestInstallRelease_WithNotesRendered(t *testing.T) { c := helm.NewContext() rs := rsFixture() - // TODO: Refactor this into a mock. - req := &services.InstallReleaseRequest{ - Namespace: "spaced", - Chart: &chart.Chart{ - Metadata: &chart.Metadata{Name: "hello"}, - Templates: []*chart.Template{ - {Name: "templates/hello", Data: []byte("hello: world")}, - {Name: "templates/hooks", Data: []byte(manifestWithHook)}, - {Name: "templates/NOTES.txt", Data: []byte(notesText + " {{.Release.Name}}")}, - }, - }, - } + req := installRequest( + withChart(withNotes(notesText + " {{.Release.Name}}")), + ) res, err := rs.InstallRelease(c, req) if err != nil { t.Fatalf("Failed install: %s", err) @@ -236,17 +207,9 @@ func TestInstallRelease_TillerVersion(t *testing.T) { c := helm.NewContext() rs := rsFixture() - // TODO: Refactor this into a mock. - req := &services.InstallReleaseRequest{ - Namespace: "spaced", - Chart: &chart.Chart{ - Metadata: &chart.Metadata{Name: "hello", TillerVersion: ">=2.2.0"}, - Templates: []*chart.Template{ - {Name: "templates/hello", Data: []byte("hello: world")}, - {Name: "templates/hooks", Data: []byte(manifestWithHook)}, - }, - }, - } + req := installRequest( + withChart(withTiller(">=2.2.0")), + ) _, err := rs.InstallRelease(c, req) if err != nil { t.Fatalf("Expected valid range. Got %q", err) @@ -258,17 +221,9 @@ func TestInstallRelease_WrongTillerVersion(t *testing.T) { c := helm.NewContext() rs := rsFixture() - // TODO: Refactor this into a mock. - req := &services.InstallReleaseRequest{ - Namespace: "spaced", - Chart: &chart.Chart{ - Metadata: &chart.Metadata{Name: "hello", TillerVersion: "<2.0.0"}, - Templates: []*chart.Template{ - {Name: "templates/hello", Data: []byte("hello: world")}, - {Name: "templates/hooks", Data: []byte(manifestWithHook)}, - }, - }, - } + req := installRequest( + withChart(withTiller("<2.0.0")), + ) _, err := rs.InstallRelease(c, req) if err == nil { t.Fatalf("Expected to fail because of wrong version") @@ -284,29 +239,10 @@ func TestInstallRelease_WithChartAndDependencyNotes(t *testing.T) { c := helm.NewContext() rs := rsFixture() - // TODO: Refactor this into a mock. - req := &services.InstallReleaseRequest{ - Namespace: "spaced", - Chart: &chart.Chart{ - Metadata: &chart.Metadata{Name: "hello"}, - Templates: []*chart.Template{ - {Name: "templates/hello", Data: []byte("hello: world")}, - {Name: "templates/hooks", Data: []byte(manifestWithHook)}, - {Name: "templates/NOTES.txt", Data: []byte(notesText)}, - }, - Dependencies: []*chart.Chart{ - { - Metadata: &chart.Metadata{Name: "hello"}, - Templates: []*chart.Template{ - {Name: "templates/hello", Data: []byte("hello: world")}, - {Name: "templates/hooks", Data: []byte(manifestWithHook)}, - {Name: "templates/NOTES.txt", Data: []byte(notesText + " child")}, - }, - }, - }, - }, - } - + req := installRequest(withChart( + withNotes(notesText), + withDependency(withNotes(notesText+" child")), + )) res, err := rs.InstallRelease(c, req) if err != nil { t.Fatalf("Failed install: %s", err) @@ -335,10 +271,9 @@ func TestInstallRelease_DryRun(t *testing.T) { c := helm.NewContext() rs := rsFixture() - req := &services.InstallReleaseRequest{ - Chart: chartStub(), - DryRun: true, - } + req := installRequest(withDryRun(), + withChart(withSampleTemplates()), + ) res, err := rs.InstallRelease(c, req) if err != nil { t.Errorf("Failed install: %s", err) @@ -389,10 +324,7 @@ func TestInstallRelease_NoHooks(t *testing.T) { rs := rsFixture() rs.env.Releases.Create(releaseStub()) - req := &services.InstallReleaseRequest{ - Chart: chartStub(), - DisableHooks: true, - } + req := installRequest(withDisabledHooks()) res, err := rs.InstallRelease(c, req) if err != nil { t.Errorf("Failed install: %s", err) @@ -409,9 +341,7 @@ func TestInstallRelease_FailedHooks(t *testing.T) { rs.env.Releases.Create(releaseStub()) rs.env.KubeClient = newHookFailingKubeClient() - req := &services.InstallReleaseRequest{ - Chart: chartStub(), - } + req := installRequest() res, err := rs.InstallRelease(c, req) if err == nil { t.Error("Expected failed install") @@ -429,11 +359,10 @@ func TestInstallRelease_ReuseName(t *testing.T) { rel.Info.Status.Code = release.Status_DELETED rs.env.Releases.Create(rel) - req := &services.InstallReleaseRequest{ - Chart: chartStub(), - ReuseName: true, - Name: rel.Name, - } + req := installRequest( + withReuseName(), + withName(rel.Name), + ) res, err := rs.InstallRelease(c, req) if err != nil { t.Fatalf("Failed install: %s", err) @@ -457,16 +386,9 @@ func TestInstallRelease_KubeVersion(t *testing.T) { c := helm.NewContext() rs := rsFixture() - // TODO: Refactor this into a mock. - req := &services.InstallReleaseRequest{ - Chart: &chart.Chart{ - Metadata: &chart.Metadata{Name: "hello", KubeVersion: ">=0.0.0"}, - Templates: []*chart.Template{ - {Name: "templates/hello", Data: []byte("hello: world")}, - {Name: "templates/hooks", Data: []byte(manifestWithHook)}, - }, - }, - } + req := installRequest( + withChart(withKube(">=0.0.0")), + ) _, err := rs.InstallRelease(c, req) if err != nil { t.Fatalf("Expected valid range. Got %q", err) @@ -477,16 +399,10 @@ func TestInstallRelease_WrongKubeVersion(t *testing.T) { c := helm.NewContext() rs := rsFixture() - // TODO: Refactor this into a mock. - req := &services.InstallReleaseRequest{ - Chart: &chart.Chart{ - Metadata: &chart.Metadata{Name: "hello", KubeVersion: ">=5.0.0"}, - Templates: []*chart.Template{ - {Name: "templates/hello", Data: []byte("hello: world")}, - {Name: "templates/hooks", Data: []byte(manifestWithHook)}, - }, - }, - } + req := installRequest( + withChart(withKube(">=5.0.0")), + ) + _, err := rs.InstallRelease(c, req) if err == nil { t.Fatalf("Expected to fail because of wrong version") diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index 6c4d42e04..73ba08f67 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -105,23 +105,128 @@ func rsFixture() *ReleaseServer { } } -// chartStub creates a fully stubbed out chart. -func chartStub() *chart.Chart { - return &chart.Chart{ - // TODO: This should be more complete. - Metadata: &chart.Metadata{ - Name: "hello", +type chartOptions struct { + *chart.Chart +} + +type chartOption func(*chartOptions) + +func buildChart(opts ...chartOption) *chart.Chart { + c := &chartOptions{ + Chart: &chart.Chart{ + // TODO: This should be more complete. + Metadata: &chart.Metadata{ + Name: "hello", + }, + // This adds a basic template and hooks. + Templates: []*chart.Template{ + {Name: "templates/hello", Data: []byte("hello: world")}, + {Name: "templates/hooks", Data: []byte(manifestWithHook)}, + }, }, - // This adds basic templates, partials, and hooks. - Templates: []*chart.Template{ - {Name: "templates/hello", Data: []byte("hello: world")}, + } + + for _, opt := range opts { + opt(c) + } + + return c.Chart +} + +func withKube(version string) chartOption { + return func(opts *chartOptions) { + opts.Metadata.KubeVersion = version + } +} + +func withTiller(version string) chartOption { + return func(opts *chartOptions) { + opts.Metadata.TillerVersion = version + } +} + +func withDependency(dependencyOpts ...chartOption) chartOption { + return func(opts *chartOptions) { + opts.Dependencies = append(opts.Dependencies, buildChart(dependencyOpts...)) + } +} + +func withNotes(notes string) chartOption { + return func(opts *chartOptions) { + opts.Templates = append(opts.Templates, &chart.Template{ + Name: "templates/NOTES.txt", + Data: []byte(notes), + }) + } +} + +func withSampleTemplates() chartOption { + return func(opts *chartOptions) { + sampleTemplates := []*chart.Template{ + // This adds basic templates and partials. {Name: "templates/goodbye", Data: []byte("goodbye: world")}, {Name: "templates/empty", Data: []byte("")}, {Name: "templates/with-partials", Data: []byte(`hello: {{ template "_planet" . }}`)}, {Name: "templates/partials/_planet", Data: []byte(`{{define "_planet"}}Earth{{end}}`)}, - {Name: "templates/hooks", Data: []byte(manifestWithHook)}, + } + opts.Templates = append(opts.Templates, sampleTemplates...) + } +} + +type installOptions struct { + *services.InstallReleaseRequest +} + +type installOption func(*installOptions) + +func withName(name string) installOption { + return func(opts *installOptions) { + opts.Name = name + } +} + +func withDryRun() installOption { + return func(opts *installOptions) { + opts.DryRun = true + } +} + +func withDisabledHooks() installOption { + return func(opts *installOptions) { + opts.DisableHooks = true + } +} + +func withReuseName() installOption { + return func(opts *installOptions) { + opts.ReuseName = true + } +} + +func withChart(chartOpts ...chartOption) installOption { + return func(opts *installOptions) { + opts.Chart = buildChart(chartOpts...) + } +} + +func installRequest(opts ...installOption) *services.InstallReleaseRequest { + reqOpts := &installOptions{ + &services.InstallReleaseRequest{ + Namespace: "spaced", + Chart: buildChart(), }, } + + for _, opt := range opts { + opt(reqOpts) + } + + return reqOpts.InstallReleaseRequest +} + +// chartStub creates a fully stubbed out chart. +func chartStub() *chart.Chart { + return buildChart(withSampleTemplates()) } // releaseStub creates a release stub, complete with the chartStub as its chart. From 79ffa98ec0c05415961e1e87f1415fd47136d277 Mon Sep 17 00:00:00 2001 From: AdamDang Date: Tue, 10 Apr 2018 23:54:19 +0800 Subject: [PATCH 164/221] Proper none not in capitals Helm is a proper none, should be written in capitals. --- docs/chart_repository_sync_example.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/chart_repository_sync_example.md b/docs/chart_repository_sync_example.md index 2fff70de9..de140c636 100644 --- a/docs/chart_repository_sync_example.md +++ b/docs/chart_repository_sync_example.md @@ -3,7 +3,7 @@ ## Prerequisites * Install the [gsutil](https://cloud.google.com/storage/docs/gsutil) tool. *We rely heavily on the gsutil rsync functionality* -* Be sure to have access to the helm binary +* Be sure to have access to the Helm binary * _Optional: We recommend you set [object versioning](https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#top_of_page) on your GCS bucket in case you accidentally delete something._ ## Set up a local chart repository directory @@ -16,7 +16,7 @@ $ mv alpine-0.1.0.tgz fantastic-charts/ ``` ## Generate an updated index.yaml -Use helm to generate an updated index.yaml file by passing in the directory path and the url of the remote repository to the `helm repo index` command like this: +Use Helm to generate an updated index.yaml file by passing in the directory path and the url of the remote repository to the `helm repo index` command like this: ```console $ helm repo index fantastic-charts/ --url https://fantastic-charts.storage.googleapis.com From 4b09b0489b6ba1fbd413aaf599fe44e6697a1b1c Mon Sep 17 00:00:00 2001 From: xianlubird Date: Wed, 11 Apr 2018 20:51:58 +0800 Subject: [PATCH 165/221] Fix some typo Signed-off-by: xianlubird --- docs/chart_template_guide/named_templates.md | 2 +- docs/charts.md | 2 +- docs/plugins.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/chart_template_guide/named_templates.md b/docs/chart_template_guide/named_templates.md index 042842427..33425d102 100644 --- a/docs/chart_template_guide/named_templates.md +++ b/docs/chart_template_guide/named_templates.md @@ -105,7 +105,7 @@ data: {{- end }} ``` -As mentioned above, **template names are global**. As a result of this, if two templates are declared with the same name the last occurance will be the one that is used. Since templates in subcharts are compiled together with top-level templates, it is best to name your templates with _chart specific names_. A popular naming convention is to prefix each defined template with the name of the chart: `{{ define "mychart.labels" }}`. +As mentioned above, **template names are global**. As a result of this, if two templates are declared with the same name the last occurrence will be the one that is used. Since templates in subcharts are compiled together with top-level templates, it is best to name your templates with _chart specific names_. A popular naming convention is to prefix each defined template with the name of the chart: `{{ define "mychart.labels" }}`. ## Setting the scope of a template diff --git a/docs/charts.md b/docs/charts.md index 8722e6862..1bbab5f19 100644 --- a/docs/charts.md +++ b/docs/charts.md @@ -850,7 +850,7 @@ considerations in mind: - The `Chart.yaml` will be overwritten by the generator. - Users will expect to modify such a chart's contents, so documentation should indicate how users can do so. -- All occurences of `` will be replaced with the specified chart +- All occurrences of `` will be replaced with the specified chart name so that starter charts can be used as templates. Currently the only way to add a chart to `$HELM_HOME/starters` is to manually diff --git a/docs/plugins.md b/docs/plugins.md index b2cc3c812..82bcfe33b 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -134,7 +134,7 @@ downloaders: If such plugin is installed, Helm can interact with the repository using the specified protocol scheme by invoking the `command`. The special repository shall be added -similarily to the regular ones: `helm repo add favorite myprotocol://example.com/` +similarly to the regular ones: `helm repo add favorite myprotocol://example.com/` The rules for the special repos are the same to the regular ones: Helm must be able to download the `index.yaml` file in order to discover and cache the list of available Charts. From fa62c476fc2156495dce4cce76780d7c166f3011 Mon Sep 17 00:00:00 2001 From: eyalbe4 Date: Wed, 11 Apr 2018 19:07:15 +0300 Subject: [PATCH 166/221] Basic auth credentials from repo not used in install/upgrade/fetch commands #3858 --- pkg/downloader/chart_downloader.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go index 9262ea547..fe2f3ce92 100644 --- a/pkg/downloader/chart_downloader.go +++ b/pkg/downloader/chart_downloader.go @@ -167,7 +167,6 @@ func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*u if err != nil { return u, nil, nil, err } - g.SetCredentials(c.getRepoCredentials(nil)) if u.IsAbs() && len(u.Host) > 0 && len(u.Path) > 0 { // In this case, we have to find the parent repo that contains this chart @@ -203,6 +202,7 @@ func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*u repoName := p[0] chartName := p[1] rc, err := pickChartRepositoryConfigByName(repoName, rf.Repositories) + if err != nil { return u, nil, nil, err } @@ -211,6 +211,7 @@ func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*u if err != nil { return u, nil, nil, err } + g.SetCredentials(c.getRepoCredentials(r)) // Next, we need to load the index, and actually look up the chart. i, err := repo.LoadIndexFile(c.HelmHome.CacheIndex(r.Config.Name)) From 87cd8ce79a16e3a17d97c7668b8d021a42932006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20R=C3=BCger?= Date: Wed, 11 Apr 2018 18:33:50 +0200 Subject: [PATCH 167/221] Remove Mercurial build-time dependency Since the only dep (bitbucket.org/ww/goautoneg) that required it is gone in https://github.com/kubernetes/helm/commit/845e99014362983d01179a411ae664b104e6c1f7#diff-f16a80eae23d5b298c2652448ec420cfL4 --- Makefile | 4 ---- docs/developers.md | 1 - docs/install.md | 2 +- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 709cc301a..2dfbd2c3c 100644 --- a/Makefile +++ b/Makefile @@ -120,7 +120,6 @@ coverage: HAS_GLIDE := $(shell command -v glide;) HAS_GOX := $(shell command -v gox;) HAS_GIT := $(shell command -v git;) -HAS_HG := $(shell command -v hg;) .PHONY: bootstrap bootstrap: @@ -133,9 +132,6 @@ endif ifndef HAS_GIT $(error You must install Git) -endif -ifndef HAS_HG - $(error You must install Mercurial) endif glide install --strip-vendor go build -o bin/protoc-gen-go ./vendor/github.com/golang/protobuf/protoc-gen-go diff --git a/docs/developers.md b/docs/developers.md index 5095bf1a0..e18c28d5d 100644 --- a/docs/developers.md +++ b/docs/developers.md @@ -10,7 +10,6 @@ Helm and Tiller. - A Kubernetes cluster w/ kubectl (optional) - The gRPC toolchain - Git -- Mercurial ## Building Helm/Tiller diff --git a/docs/install.md b/docs/install.md index 6ca13c90a..17905a805 100755 --- a/docs/install.md +++ b/docs/install.md @@ -81,7 +81,7 @@ Building Helm from source is slightly more work, but is the best way to go if you want to test the latest (pre-release) Helm version. You must have a working Go environment with -[glide](https://github.com/Masterminds/glide) and Mercurial installed. +[glide](https://github.com/Masterminds/glide) installed. ```console $ cd $GOPATH From 00afbd7e74bf8d5ef7f7f30fc5e914b4a50ac7ef Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Wed, 11 Apr 2018 14:43:44 -0700 Subject: [PATCH 168/221] remove optional field from charts and templates --- docs/charts.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/charts.md b/docs/charts.md index 1bbab5f19..a19c1a477 100644 --- a/docs/charts.md +++ b/docs/charts.md @@ -27,8 +27,8 @@ wordpress/ README.md # OPTIONAL: A human-readable README file requirements.yaml # OPTIONAL: A YAML file listing dependencies for the chart values.yaml # The default configuration values for this chart - charts/ # OPTIONAL: A directory containing any charts upon which this chart depends. - templates/ # OPTIONAL: A directory of templates that, when combined with values, + charts/ # A directory containing any charts upon which this chart depends. + templates/ # A directory of templates that, when combined with values, # will generate valid Kubernetes manifest files. templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes ``` @@ -36,8 +36,6 @@ wordpress/ Helm reserves use of the `charts/` and `templates/` directories, and of the listed file names. Other files will be left as they are. -While the `charts` and `templates` directories are optional there must be at least one chart dependency or template file for the chart to be valid. - ## The Chart.yaml File The `Chart.yaml` file is required for a chart. It contains the following fields: From 62f85322ef114089724835e545d8d32d9bc30e12 Mon Sep 17 00:00:00 2001 From: Chance Zibolski Date: Wed, 11 Apr 2018 14:46:18 -0700 Subject: [PATCH 169/221] Update helm template -x to support children chart manifests in more cases The previous code validated the manifests exist within the file system, which only works when a chart is unpacked, meaning children charts stored as tgz's in the parent chart's `charts/` directory don't exist as individual files in the filesystem, causing validation to file. Instead, we validate against the paths within the chart itself rather than the filesystem, handling both chart.tgz's and charts that are unpacked as directories in the chart/ directory. --- cmd/helm/template.go | 78 ++++++++++++++++++++------------------- cmd/helm/template_test.go | 7 ++++ 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/cmd/helm/template.go b/cmd/helm/template.go index c04bc2dc8..fc1f44392 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -117,31 +117,10 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error { } else { return err } - // verify specified templates exist relative to chart - rf := []string{} - var af string - var err error - if len(t.renderFiles) > 0 { - for _, f := range t.renderFiles { - if !filepath.IsAbs(f) { - af, err = filepath.Abs(filepath.Join(t.chartPath, f)) - if err != nil { - return fmt.Errorf("could not resolve template path: %s", err) - } - } else { - af = f - } - rf = append(rf, af) - - if _, err := os.Stat(af); err != nil { - return fmt.Errorf("could not resolve template path: %s", err) - } - } - } // verify that output-dir exists if provided if t.outputDir != "" { - _, err = os.Stat(t.outputDir) + _, err := os.Stat(t.outputDir) if os.IsNotExist(err) { return fmt.Errorf("output-dir '%s' does not exist", t.outputDir) } @@ -232,19 +211,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error { m := tiller.Manifest{Name: k, Content: v, Head: &util.SimpleHead{Kind: h}} listManifests = append(listManifests, m) } - in := func(needle string, haystack []string) bool { - // make needle path absolute - d := strings.Split(needle, string(os.PathSeparator)) - dd := d[1:] - an := filepath.Join(t.chartPath, strings.Join(dd, string(os.PathSeparator))) - - for _, h := range haystack { - if h == an { - return true - } - } - return false - } + if settings.Debug { rel := &release.Release{ Name: t.releaseName, @@ -257,10 +224,45 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error { printRelease(os.Stdout, rel) } - for _, m := range tiller.SortByKind(listManifests) { - if len(t.renderFiles) > 0 && !in(m.Name, rf) { - continue + var manifestsToRender []tiller.Manifest + + // if we have a list of files to render, then check that each of the + // provided files exists in the chart. + if len(t.renderFiles) > 0 { + for _, f := range t.renderFiles { + missing := true + if !filepath.IsAbs(f) { + newF, err := filepath.Abs(filepath.Join(t.chartPath, f)) + if err != nil { + return fmt.Errorf("could not turn template path %s into absolute path: %s", f, err) + } + f = newF + } + + for _, manifest := range listManifests { + manifestPathSplit := strings.Split(manifest.Name, string(filepath.Separator)) + // remove the chart name from the path + manifestPathSplit = manifestPathSplit[1:] + toJoin := append([]string{t.chartPath}, manifestPathSplit...) + manifestPath := filepath.Join(toJoin...) + + // if the filepath provided matches a manifest path in the + // chart, render that manifest + if f == manifestPath { + manifestsToRender = append(manifestsToRender, manifest) + missing = false + } + } + if missing { + return fmt.Errorf("could not find template %s in chart", f) + } } + } else { + // no renderFiles provided, render all manifests in the chart + manifestsToRender = listManifests + } + + for _, m := range tiller.SortByKind(manifestsToRender) { data := m.Content b := filepath.Base(m.Name) if !t.showNotes && b == "NOTES.txt" { diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index eefa46774..bbcc9f3af 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -69,6 +69,13 @@ func TestTemplateCmd(t *testing.T) { expectKey: "subchart1/templates/service.yaml", expectValue: "protocol: TCP\n name: apache", }, + { + name: "check_execute_subchart_template", + desc: "verify --execute single template on a subchart template", + args: []string{chartPath, "-x", "charts/subcharta/templates/service.yaml", "--set", "subcharta.service.name=foobar"}, + expectKey: "subchart1/charts/subcharta/templates/service.yaml", + expectValue: "protocol: TCP\n name: foobar", + }, { name: "check_namespace", desc: "verify --namespace", From d7e71709935b2f3b93c90c85ecdbf3d247cc7ebf Mon Sep 17 00:00:00 2001 From: Chance Zibolski Date: Wed, 11 Apr 2018 16:26:15 -0700 Subject: [PATCH 170/221] Add working template to mariner chart for use in testing subcharts --- pkg/chartutil/testdata/frobnitz-1.2.3.tgz | Bin 2070 -> 3654 bytes .../frobnitz/charts/mariner-4.3.2.tgz | Bin 1034 -> 1012 bytes .../mariner/charts/albatross-0.1.0.tgz | Bin 347 -> 292 bytes .../mariner/templates/placeholder.tpl | 2 ++ 4 files changed, 2 insertions(+) diff --git a/pkg/chartutil/testdata/frobnitz-1.2.3.tgz b/pkg/chartutil/testdata/frobnitz-1.2.3.tgz index fb21cd08fb08fd2f4e45e940634ce1cdb0421457..cd12d2c1ef7d96805820389c38a21d03add7f06d 100644 GIT binary patch literal 3654 zcmV-M4!Q9kiwFR5n9f=N1MOT3eA84H-+ti4f}qF;D$HFn{Rzs_cgxCnOg4}=Y`kAv z+T5*SX;YGPUBNK~kqPn;KINs;!KWZ^##B&n2r4=RR1i@ZQxPVQjhD(mpx;f>m90D~ z&=t`9e~hHL=RT5?bMCq4oSQV3G21DAj54hDpi-%fdOZ-22I;8M=%k|;K&{mnv^t$Z ztP;|UfG#bPDw7IQsL^W?|MfbpDh#NCJ&>#6U(SDt<4VQt9*2zE1E2hN zwh}Cly9pZ|^gaT~zd@_^)Bk#nRx8VYC_p%+6a zDt5-qknS3lIL66ZptnaW&pSAiQdx~anZ__mGr=mXjL@<`QIkMHS%iDOT2+HC%b>#@ z_H+edw=+B;JUX!_n8mXMdO9ZQER&#}!Z-;;WQD9);60a$Ld1Wc{96S1=W4|a{CoCa z_4!|?H)>`3FBI_cpJXhx!~L7$zea16`5y}S_%En5oXbqFg+2n!|9XSLpZ`XKQJ()p zfw+!YHX3-R@%CsIS79AHDB{qI08jy%y3kpB%sU0TTrS+D#ThnTsX;fXL}i#nc3l#2 zI+j|?qA7dE)ri%xv9U_AR3fi2BH*G(-r641=nWXM0jP8<@BKlM?J*v5Jk|l#iWAJ0 z4vEri41^atPAOgz%2;UOMe;O?Mf4yGwSWP)_`kP#o$7My26UcA(R6#vPGq_g|BCqkE)jWSU!?HfZN@(GIuJ6gmes!VO4@bI|C>qdNE<^bX6odHCeNXSdFY zy^|AbqmO{{uhIL@|5~+Lmj6(|%XWYS+XAf&O+r={?SBz`@}HC#pU^82w~@i`Bar-S zME_sS^}j(Q%YP^k4Z2kM=oHm#0k2C7h+ZLFp@@zK12`fbUX2I`-FRRnIACXhQy`M) z6JRE!8HZp=C=^{77Ld{f$RbN4jcEfo2$3m){uoCLEtCNkIv9@P8P+Z9pb)_)|12Es zq*y4hi^FNgk`cT<0?EHt6!7t1j5-Hf^GgV% z|J6Ew{jb*S<0|^U>I~-{!BGVP{l7Z@_>a+`mF>Tf;8{r13>Z5W z7e)6uK*BV_N%H`6F)U4D+1auH|D#be|EG4Gzyal7f5rT-SIhq2kl=DsXSE0rNE6(( z-Y~G&0Jz-)l~F73&;Lx3HUy;Dg18GLp#87%&;K$Q)Uy2_5{UB8Ss5oy0yDDRMed_h zw-}nC83L(;Ho)wZGC%|hyM=a=h(t8=z44*jeHSur7XI=t`Tc_H1G;hlk3prA^S?s^ zfBt*jv@xP%7U$E)1fh=r`X8sD<^PP9xiYAwksCdSRpI?idpxvzb@bTC!-=}&k67%|MeIzPU1CyE+6WpJyQ_7B<0{v7#i(x{;u zhR5ufF>&5U3*MMllAh=B45@G4(q$c9m|Jhc0|S~oP&jJke=v6C_Bsiz7j`dLKBb^R z-F}Vl(bxU&XZ!nymqtIZYlXG7HRHEE2Y*{lo{l>FWog$n8@sMPeJW-4gt;dv>%6y9 zCU$5v;58;Pr{BxpR@R^LRF7|Rv2QA$p78jj@qN#)*#DI$?vkOfZ-Za^gfEWnv*pDe z4Yp2yKH}@#p7pIi%nqN`Fk*Da=T}dwcY0k+y|JHwd2=f3&0!1HzOZF~$;XkOM<#vY z0mTP?*}JLyi0Al)#gQ)^$%$?CY1E>IrJKHZ#&D{;txo-;MUCe*%Ng(>e8+RBQ&+se zNoGWxHn#|S50usWx@V^ekvkU^g^z#bSXRVnhbbcIg>@sBuWV?W_*w=wl3V`a`llKX zPvUb|Z<@Mc)AFB-y0v8Mev|slsPd_);UA3f>{{L|F?NY(p<TGBA;nIvt4+6zUTP-&tE*;Yo}4SV#Idt)zswTlVKM- zo$TIu*XKh`ncnZob2ocT#pupAp}0dcm=>7Oh(hZ+dv$kdL;Rnnos=$EQZAr>^JhdvboX zwmLM|v^j2ckNk-GdvYdd26>`+u*_4u`S|g?NcZ$%C)$p|rgchxvUHYqGX2$Rdl!sZw`}U6l8xIoob{N0NNL``JdVmaQ@UzR-%Hzm-)X+I4Ew{g1e@B%v+a|m zy81 zuD^6}&C~PBx39{h+pTHo-aW5H#f5g-wHJ0L>|8(RV_Uy_f8t9!xsG1g(Wuez{l?hJ z)MNa`8R_GWJ~C$EFJ-Uf*_2V)KP8^!53l;}$SV~ck0}TA*?wWoqRrckY|3Tdi8rc7@_4of7W&eL@P$Sw~ zW4mVpbkK|&+4yFHqbwj^Bmq4syE6+o81nMgPcbT7ZLg#dxXozG;S{43_G`+EgF6}5 zkpH0W2EB3n->B8d`~O0MYw$m)j^IH0Uw=jZpHVCOe?kM%|5KIi>moRi4$<BuEAeQ4scPJtoWL_SI@K>uEsU=!XjK)+W?12} zB2^k<4C+lZWm17Jw5d=GVVuBHZPycD{Xs~#F5PamZBblRLQ<8Sq~7(euWQJEP_uz< zSpREODxF%^|DnJ&_#f14pg{Ux<)8nfQE4>t{;!ZATHNF*=wo3eP?hClbH_+8f}Fqe z4@W@#?>C3uOdo;d-=Ou||EbX!4YK@)1b*Lt%Ao9|3G_wFdt`tSB*7Dxv-`%5#giZn z2@Z!;7 zaMF?<-P#n-cPDDf-(UEp8-y*AIDc@!qf2=j3_bdig-#B@>Ph`Djl?qj4P@ zHve!@*OKO=<`lnWFZ^9+doQx^d%WGKW1An}k+|ar`|v%3SFJ4?_ekZMtV^AX@d3>% zD=tRu%vtk#&dSFtJUw#HjkPu0IDbawtj3jzmy!%$cp958b^Wf-k8ht3uUzWkhP-jn z^W{5fzk7PD%fGke-FMG6$pD4t`!J;{1_hFT zwfYMCPb2UD4GpR`=OI4V4FAMSU*Hs91kt0`!)b=B9ilbC)k8m+yjHvm@pt6^R-HkC zDc zVQyr3R8em|NM&qo0PLOLZ`(K$$NQ|mVxYXPWl8>ZHInWHO%_{RHdt(P2P_VU3oVT; zB9y2lX*<4b{`UhZS$33ol{Svjr2IZKvPhA##1Cgk4&ABXlZ>kWbw4IVC~rkl_HN(u zecvAq2IjBt`}M#6&>vOD=6n#2g26l3`;9!Lxl}~F^ZlomQ~z?WL?p|&B8u`%jvWA! zah0IB!qs?vydZ3j4gg*&K}>=VGe5Bfok|6b7V zTmIY70USf|>S0P5Lc|R^QXfp|Y%WaS;5lV8cXiW;bCRO#I1(d6dc}pS6M$wwpiFaL zu4P+2Miu`G)0`27vO4lqzMrn3iGRNz*7zUvf}Z8S4gHLaak#nh47z_pj8iga3fv_Z zEOu{iEx>PD75|?0kLWDp0{2}D`@ZGB4IRKw>zQk3%NHo8tRXV1LXLBA0RNO^h7V=(;FE%cNXR(Mb*3W! z2`-TFTze9Z^Ai^k7bj2v&8GYZkcglX1jX|X(`g_u=aMQeR<;jnNfrMwkK{9T0*&^6 zaDV=PWchDJn?<@U4*;eb*K!z8E&#mrjaog6D*kE2GfysN&rnAb|AXPMZvXpzyZ+yb z4u8B(8I-HhM{eNx?vEdwL%Ep2b;>e1mW$buTQ1lymrHNi^SGFGL*Mtiaxrs@Y=4=> z0f4f!YeuuHhcXB6-@osg)FS(xJAx&RRdVEpgP{uv(pjR)4>Ue<6-woPZ~zWtl+lON z(sj`d`mk$G=`?|nGTEn8Nae!yksG?OGXIvv_x(-jL*IodW$eh!$YSMo@0KAk;#q78 z2?nN=enTk&V_nFhejp#dq0Y48U*I2eDp2?M(qlZj+Fu<_{P+C2{qOe%cKyE<#h7Cj zV-`^~0YIH{DW9;MX1I;w7+l}eG@6qeSN-9r9W!u{TLq>>&X+ z3rp;`tR4LCH5#~yfB#wm52z%26TJT_)}9p#&@Iz>aU@w;zaJNVy30~aSc zIgh`(H)!I2*sHDohkn0j`ENzF4Lnygi^uRQkDU}1iHRbc=>D4A&fB${C1+uP2~ zjaN8|#b*bAkqI(0kN`+fP(@~Uul$T+L8Brw6w8a}>(XmwmC4oZRXNHt@F)B+=c>qD z+s6dpYQMyjNjDNm6vplt+^ze#psBu@h-b09y>%U#W27$>sM~}3l`|Txbe&Z|^f@k2 zxZssJ{+pXDrt)&rgxPPj8SyL$Rpo$(rsg@g1x(|f*DJ<65l>U1pZLGs?u2Gt$q;k* z2lu`2`|f|*=zDkYzt@GpCjJNa=l@0{>;JbRv;MbU?OzfJGt5wEU|=q3HZv>qWiy3K z%@hh_<30)%JrZzIyR> zx56UjdO~8&$>pnG7u~^s`6(q*1y7y~XdM6h{TlzH(IB+^x1l@Z|KnmGta|EEp{H1Qt>y}JJ&27%?j4IRMAedB3fyXPEiZQ=j@_?NTJ zl#7%o?HgzttTUWo#E3xS@fPg_azcd!#bKh4rNkI$rZ}wlTvP^F>WlS7a0ITo&dxNv zh?@BiU&j91^}km174|>0_W$kZG5kNb{r7wQ`}W`R-->qH|M1lhZLJ=mI{#&u#$E#e zn(co*{&z6!+4%of^u_kSh~lX{029Dtdx}@9UHtDe0HAUFKdAFR^zHnAJKACYO(STY z0jOeuW>h8fiHXxwJY^k5vY9#B#~i`fP7yqtcJaSi&e`4>{&l|y*6jZWb^m|l+xfp% zv`x7E4S?@YyZGPdc7R6ze^CGZpOO9jzm~K+{(nN0;8H#+HhXdFct$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){L36ZtiaDKCZKKh4VpUVhPw(Vq+5%p#1{`AAuCqVmyct4N85WAVyGp#n=>Wj1n4S z;p*((BjusRcz0-+&)sGA_I7u6_dCDuclIoZ4IANLpo|EDpsOnITP@cLl9Frl08!F) zQI-`+mw+HDk|+d#TF#Ryka7vc^i(WJNH|3z353tP9o;Mz`UG2>HDDfLsOK$)?XBLPk%{~bzM;vs=p>GasUXWKb3R2#PzqKg+d@d3b-h8BiKk1 z!?8nP9+;0z3q-t;0b&jY&8aZLHX_L7+7WjBjTBzyB`)E3N2#gdF81Xx{vn0>_f>Yw z69X6O|EeIVvL?{_R~21m{$B|S`eW3VGBC1`P25t)z?A;4N@wN2u8Au1|4I-=Nn}Tn z9Wjs_;sB@zxkP|w7!vHbE?oxzMoGsth=bE1kRT-KhJrz~0$NEE@e#)gp6Md~F2#hX z5qOaoSTy`MDJVw}6%*2EFGB=ep#M*v|4Cl`Gyg9?1^wHhnL;IZ{v1>Jzocru{;DFY zvZ8zXD}u!QzY@#>_o5g~nFQoUfIrdC4+@@}1r{d^7tl8ZOXofKKt27{yHO|#Vg~j8 zVi?2?l1PR9EFg|$)|=3d`%9eHLBxa@`N5JKXCMg;>;mF|u(#~G^mv9%zowlO21P6K z`p>0NjlUbqkkWIm|I;Rd5{?vdH?_;X^S7q6M{?qA4k~LcYf~K+m|0+Ut*A;=jm8X{kE*t&)SnE4r zM%A}7hwC=o@X3?4*}Ff!Z$VXtJ9Kn&ORKnfAk%L&Pun>D;)phO*KK{PKizeFOIz=n zy*o!wAB(P@-@O0Xt)Vxb?^^Wuz7^Z9s$0DG<(79l=RDI;yJg+Mmmb}CrBT z-!}KT=4?9KaOjJkYcgQjk@g!0$KO1e>6trl|4%m!{=B?u+4!Emw}w`2=pOv&TJ81s z9#V$gq1JEK%Ii?$Zt#20ucxXP^=-QPiQlpZ?i{{l`pMzO-oRHAJB1&st=E><&K!N! zdCK`A=yslR;D-|}568cpeRH7ta7WJ{hsPI;tY0|c!1o)c|1u-g@WGDm6TNL{-wPw* z(Wd>^e|==&5o^vX4U=!@9%pP?@baZ~f!i;ZpbQ3s!C){L3#Uqb*v{OB-fRab*UwBA(c`Y z>HD>GHpXPa)Jof#p|#i7P0QBn5B52oW3GRMndiUgOi0D6>D{frG2KU{)b;s`Qe4bm z%SvX%Z{5gy{`vd|)7ysTSHM;_wqg5{wti^nk)EvUsolQ}TKhoH^`Tah5&VKqp@FnN`?~EI5yvGmVv;1>iU*^A(0{Q~{uR`@o*M z%7&edw#^PUw8u^~=X1(x-;Xn!Wk0%GbA5)&B41Dtb&pGEL74_#ol>prTw=m`( zZL@bK9qp@cfp6q5bA|kGVa)$vTxZ)U9snQJf0Fvu`%medQ2%dX$UhbD7&<%4vW@eV tab?Ds>0<3e$rj$(uw88|syhGx0000000000006*m_5v>lSt Date: Wed, 11 Apr 2018 16:28:14 -0700 Subject: [PATCH 171/221] test helm template -x against subcharts stored as tgz's --- cmd/helm/template_test.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index bbcc9f3af..46adecca7 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -27,7 +27,10 @@ import ( "testing" ) -var chartPath = "./../../pkg/chartutil/testdata/subpop/charts/subchart1" +var ( + chartPath = "./../../pkg/chartutil/testdata/subpop/charts/subchart1" + frobnitzChartPath = "./../../pkg/chartutil/testdata/frobnitz" +) func TestTemplateCmd(t *testing.T) { absChartPath, err := filepath.Abs(chartPath) @@ -76,6 +79,13 @@ func TestTemplateCmd(t *testing.T) { expectKey: "subchart1/charts/subcharta/templates/service.yaml", expectValue: "protocol: TCP\n name: foobar", }, + { + name: "check_execute_subchart_template_for_tgz_subchart", + desc: "verify --execute single template on a subchart template where the subchart is a .tgz in the chart directory", + args: []string{frobnitzChartPath, "-x", "charts/mariner/templates/placeholder.tpl", "--set", "mariner.name=moon"}, + expectKey: "frobnitz/charts/mariner/templates/placeholder.tpl", + expectValue: "Goodbye moon", + }, { name: "check_namespace", desc: "verify --namespace", From ced20f6f4ebacbc120cd7e580668e3797aa7f2a9 Mon Sep 17 00:00:00 2001 From: Chance Zibolski Date: Wed, 11 Apr 2018 16:28:56 -0700 Subject: [PATCH 172/221] Disambigutate chartPaths variables in helm template tests --- cmd/helm/template_test.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index 46adecca7..d2469525e 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -28,12 +28,12 @@ import ( ) var ( - chartPath = "./../../pkg/chartutil/testdata/subpop/charts/subchart1" - frobnitzChartPath = "./../../pkg/chartutil/testdata/frobnitz" + subchart1ChartPath = "./../../pkg/chartutil/testdata/subpop/charts/subchart1" + frobnitzChartPath = "./../../pkg/chartutil/testdata/frobnitz" ) func TestTemplateCmd(t *testing.T) { - absChartPath, err := filepath.Abs(chartPath) + subchart1AbsChartPath, err := filepath.Abs(subchart1ChartPath) if err != nil { t.Fatal(err) } @@ -47,35 +47,35 @@ func TestTemplateCmd(t *testing.T) { { name: "check_name", desc: "check for a known name in chart", - args: []string{chartPath}, + args: []string{subchart1ChartPath}, expectKey: "subchart1/templates/service.yaml", expectValue: "protocol: TCP\n name: nginx", }, { name: "check_set_name", desc: "verify --set values exist", - args: []string{chartPath, "-x", "templates/service.yaml", "--set", "service.name=apache"}, + args: []string{subchart1ChartPath, "-x", "templates/service.yaml", "--set", "service.name=apache"}, expectKey: "subchart1/templates/service.yaml", expectValue: "protocol: TCP\n name: apache", }, { name: "check_execute", desc: "verify --execute single template", - args: []string{chartPath, "-x", "templates/service.yaml", "--set", "service.name=apache"}, + args: []string{subchart1ChartPath, "-x", "templates/service.yaml", "--set", "service.name=apache"}, expectKey: "subchart1/templates/service.yaml", expectValue: "protocol: TCP\n name: apache", }, { name: "check_execute_absolute", desc: "verify --execute single template", - args: []string{chartPath, "-x", absChartPath + "/" + "templates/service.yaml", "--set", "service.name=apache"}, + args: []string{subchart1ChartPath, "-x", subchart1AbsChartPath + "/" + "templates/service.yaml", "--set", "service.name=apache"}, expectKey: "subchart1/templates/service.yaml", expectValue: "protocol: TCP\n name: apache", }, { name: "check_execute_subchart_template", desc: "verify --execute single template on a subchart template", - args: []string{chartPath, "-x", "charts/subcharta/templates/service.yaml", "--set", "subcharta.service.name=foobar"}, + args: []string{subchart1ChartPath, "-x", "charts/subcharta/templates/service.yaml", "--set", "subcharta.service.name=foobar"}, expectKey: "subchart1/charts/subcharta/templates/service.yaml", expectValue: "protocol: TCP\n name: foobar", }, @@ -89,42 +89,42 @@ func TestTemplateCmd(t *testing.T) { { name: "check_namespace", desc: "verify --namespace", - args: []string{chartPath, "--namespace", "test"}, + args: []string{subchart1ChartPath, "--namespace", "test"}, expectKey: "subchart1/templates/service.yaml", expectValue: "namespace: \"test\"", }, { name: "check_release_name", desc: "verify --release exists", - args: []string{chartPath, "--name", "test"}, + args: []string{subchart1ChartPath, "--name", "test"}, expectKey: "subchart1/templates/service.yaml", expectValue: "release-name: \"test\"", }, { name: "check_notes", desc: "verify --notes shows notes", - args: []string{chartPath, "--notes", "true"}, + args: []string{subchart1ChartPath, "--notes", "true"}, expectKey: "subchart1/templates/NOTES.txt", expectValue: "Sample notes for subchart1", }, { name: "check_values_files", desc: "verify --values files values exist", - args: []string{chartPath, "--values", chartPath + "/charts/subchartA/values.yaml"}, + args: []string{subchart1ChartPath, "--values", subchart1ChartPath + "/charts/subchartA/values.yaml"}, expectKey: "subchart1/templates/service.yaml", expectValue: "name: apache", }, { name: "check_name_template", desc: "verify --name-template result exists", - args: []string{chartPath, "--name-template", "foobar-{{ b64enc \"abc\" }}-baz"}, + args: []string{subchart1ChartPath, "--name-template", "foobar-{{ b64enc \"abc\" }}-baz"}, expectKey: "subchart1/templates/service.yaml", expectValue: "release-name: \"foobar-YWJj-baz\"", }, { name: "check_kube_version", desc: "verify --kube-version overrides the kubernetes version", - args: []string{chartPath, "--kube-version", "1.6"}, + args: []string{subchart1ChartPath, "--kube-version", "1.6"}, expectKey: "subchart1/templates/service.yaml", expectValue: "kube-version/major: \"1\"\n kube-version/minor: \"6\"\n kube-version/gitversion: \"v1.6.0\"", }, From b9adc356e8d1fe68b139a0b4c2495aa1e5fdebf8 Mon Sep 17 00:00:00 2001 From: Chance Zibolski Date: Wed, 11 Apr 2018 16:46:24 -0700 Subject: [PATCH 173/221] Correctly use subtests in helm template tests The testing.T in the subtest wasn't being used, so subtests were effectively not being used. Additionally, in case subtests run in parallel, we assign tt := tt to fix closure captures on range variables, since the variables produced by a range are re-used between iterations. --- cmd/helm/template_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index d2469525e..7505b0474 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -132,7 +132,8 @@ func TestTemplateCmd(t *testing.T) { var buf bytes.Buffer for _, tt := range tests { - t.Run(tt.name, func(T *testing.T) { + tt := tt + t.Run(tt.name, func(t *testing.T) { // capture stdout old := os.Stdout r, w, _ := os.Pipe() From fb1dd48b5a1994e8a81a9b734cb6503d024799cd Mon Sep 17 00:00:00 2001 From: Chance Zibolski Date: Wed, 11 Apr 2018 16:48:53 -0700 Subject: [PATCH 174/221] test helm template -x with non-existent manifest --- cmd/helm/template_test.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index 7505b0474..68ed87cd2 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -43,6 +43,7 @@ func TestTemplateCmd(t *testing.T) { args []string expectKey string expectValue string + expectError string }{ { name: "check_name", @@ -65,6 +66,12 @@ func TestTemplateCmd(t *testing.T) { expectKey: "subchart1/templates/service.yaml", expectValue: "protocol: TCP\n name: apache", }, + { + name: "check_execute_non_existent", + desc: "verify --execute fails on a template that doesnt exist", + args: []string{subchart1ChartPath, "-x", "templates/thisdoesntexist.yaml"}, + expectError: "could not find template", + }, { name: "check_execute_absolute", desc: "verify --execute single template", @@ -143,8 +150,21 @@ func TestTemplateCmd(t *testing.T) { cmd := newTemplateCmd(out) cmd.SetArgs(tt.args) err := cmd.Execute() - if err != nil { - t.Errorf("expected: %v, got %v", tt.expectValue, err) + + if tt.expectError != "" { + if err == nil { + t.Errorf("expected err: %s, but no error occurred", tt.expectError) + } + // non nil error, check if it contains the expected error + if strings.Contains(err.Error(), tt.expectError) { + // had the error we were looking for, this test case is + // done + return + } else { + t.Fatalf("expected err: %q, got: %q", tt.expectError, err) + } + } else if err != nil { + t.Errorf("expected no error, got %v", err) } // restore stdout w.Close() From 4ce35363d40fa6e8d8789121384d397748571e57 Mon Sep 17 00:00:00 2001 From: Jesse Weinstein Date: Fri, 13 Apr 2018 09:57:35 -0700 Subject: [PATCH 175/221] Document apiVersion field Added in https://github.com/kubernetes/helm/issues/1264 --- docs/charts.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/charts.md b/docs/charts.md index a19c1a477..a55038e3e 100644 --- a/docs/charts.md +++ b/docs/charts.md @@ -41,6 +41,7 @@ the listed file names. Other files will be left as they are. The `Chart.yaml` file is required for a chart. It contains the following fields: ```yaml +apiVersion: The chart API version, always "v1" (required) name: The name of the chart (required) version: A SemVer 2 version (required) kubeVersion: A SemVer range of compatible Kubernetes versions (optional) From 75682ed5844400e5dcd24ec7532c0fa454defd4d Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Sat, 14 Apr 2018 05:52:34 -0400 Subject: [PATCH 176/221] fix(helm): resolve linter's warning on template command unit tests Signed-off-by: Arash Deshmeh --- cmd/helm/template_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index 68ed87cd2..cad42db16 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -160,9 +160,8 @@ func TestTemplateCmd(t *testing.T) { // had the error we were looking for, this test case is // done return - } else { - t.Fatalf("expected err: %q, got: %q", tt.expectError, err) } + t.Fatalf("expected err: %q, got: %q", tt.expectError, err) } else if err != nil { t.Errorf("expected no error, got %v", err) } From 7631b8a926d1cc533a94951b6a96c948081e78e7 Mon Sep 17 00:00:00 2001 From: Sergii Manannikov Date: Sat, 14 Apr 2018 15:51:01 +0200 Subject: [PATCH 177/221] Create PodSecurityPolicy before Pods and ServiceAccounts --- 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 f367e65c8..43726d53e 100644 --- a/pkg/tiller/kind_sorter.go +++ b/pkg/tiller/kind_sorter.go @@ -30,6 +30,7 @@ var InstallOrder SortOrder = []string{ "Namespace", "ResourceQuota", "LimitRange", + "PodSecurityPolicy", "Secret", "ConfigMap", "StorageClass", @@ -80,6 +81,7 @@ var UninstallOrder SortOrder = []string{ "StorageClass", "ConfigMap", "Secret", + "PodSecurityPolicy", "LimitRange", "ResourceQuota", "Namespace", diff --git a/pkg/tiller/kind_sorter_test.go b/pkg/tiller/kind_sorter_test.go index ef7296e89..8d01fac17 100644 --- a/pkg/tiller/kind_sorter_test.go +++ b/pkg/tiller/kind_sorter_test.go @@ -85,6 +85,10 @@ func TestKindSorter(t *testing.T) { Name: "o", Head: &util.SimpleHead{Kind: "Pod"}, }, + { + Name: "3", + Head: &util.SimpleHead{Kind: "PodSecurityPolicy"}, + }, { Name: "q", Head: &util.SimpleHead{Kind: "ReplicaSet"}, @@ -136,8 +140,8 @@ func TestKindSorter(t *testing.T) { order SortOrder expected string }{ - {"install", InstallOrder, "abcde1fgh2ijklmnopqrstuvw!"}, - {"uninstall", UninstallOrder, "wvmutsrqponlkji2hgf1edcba!"}, + {"install", InstallOrder, "abc3de1fgh2ijklmnopqrstuvw!"}, + {"uninstall", UninstallOrder, "wvmutsrqponlkji2hgf1ed3cba!"}, } { var buf bytes.Buffer t.Run(test.description, func(t *testing.T) { From 223c89e6aac873a8fe9b0228d39364f566881831 Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Sat, 14 Apr 2018 15:37:42 -0400 Subject: [PATCH 178/221] feat(helm): support removing multiple repositories with repo remove command Signed-off-by: Arash Deshmeh --- cmd/helm/repo_remove.go | 15 ++++++--- cmd/helm/repo_remove_test.go | 64 ++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/cmd/helm/repo_remove.go b/cmd/helm/repo_remove.go index 201ee9ca8..728852fa1 100644 --- a/cmd/helm/repo_remove.go +++ b/cmd/helm/repo_remove.go @@ -41,13 +41,18 @@ func newRepoRemoveCmd(out io.Writer) *cobra.Command { Aliases: []string{"rm"}, Short: "remove a chart repository", RunE: func(cmd *cobra.Command, args []string) error { - if err := checkArgsLength(len(args), "name of chart repository"); err != nil { - return err + if len(args) == 0 { + return fmt.Errorf("need at least one argument, name of chart repository") } - remove.name = args[0] - remove.home = settings.Home - return remove.run() + remove.home = settings.Home + for i := 0; i < len(args); i++ { + remove.name = args[i] + if err := remove.run(); err != nil { + return err + } + } + return nil }, } diff --git a/cmd/helm/repo_remove_test.go b/cmd/helm/repo_remove_test.go index 174a44495..bc071b989 100644 --- a/cmd/helm/repo_remove_test.go +++ b/cmd/helm/repo_remove_test.go @@ -18,6 +18,7 @@ package main import ( "bytes" + "io/ioutil" "os" "strings" "testing" @@ -79,3 +80,66 @@ func TestRepoRemove(t *testing.T) { t.Errorf("%s was not successfully removed from repositories list", testName) } } + +func TestRepoRemove_NoArguments(t *testing.T) { + cmd := newRepoRemoveCmd(ioutil.Discard) + if err := cmd.RunE(cmd, []string{}); err == nil { + t.Errorf("Expected an error since no repo names were provided") + } +} + +func TestRepoRemove_MultipleRepos(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 + + repoFoo := testName + "foo" + repoBar := testName + "bar" + + if err := addRepository(repoFoo, ts.URL(), "", "", hh, "", "", "", true); err != nil { + t.Error(err) + } + if err := addRepository(repoBar, ts.URL(), "", "", hh, "", "", "", true); err != nil { + t.Error(err) + } + + b := bytes.NewBuffer(nil) + + cmd := newRepoRemoveCmd(b) + if err := cmd.RunE(cmd, []string{repoFoo, repoBar}); err != nil { + t.Error(err) + } + + if !strings.Contains(b.String(), repoFoo) { + t.Errorf("Expected %q in output, found: %q", repoFoo, b.String()) + } + if !strings.Contains(b.String(), repoBar) { + t.Errorf("Expected %q in output, found: %q", repoBar, b.String()) + } + + f, err := repo.LoadRepositoriesFile(hh.RepositoryFile()) + if err != nil { + t.Error(err) + } + + if f.Has(repoFoo) { + t.Errorf("%s was not successfully removed from repositories list", repoFoo) + } + if f.Has(repoBar) { + t.Errorf("%s was not successfully removed from repositories list", repoBar) + } +} From f291fdbb43730dbb266d7aeb146c40aa978a0c66 Mon Sep 17 00:00:00 2001 From: AdamDang Date: Sun, 15 Apr 2018 23:37:13 +0800 Subject: [PATCH 179/221] Typo fix in functions_and_pipelines.md useable->usable --- 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 54eb8e24f..66176fc59 100644 --- a/docs/chart_template_guide/functions_and_pipelines.md +++ b/docs/chart_template_guide/functions_and_pipelines.md @@ -1,6 +1,6 @@ # Template Functions and Pipelines -So far, we've seen how to place information into a template. But that information is placed into the template unmodified. Sometimes we want to transform the supplied data in a way that makes it more useable to us. +So far, we've seen how to place information into a template. But that information is placed into the template unmodified. Sometimes we want to transform the supplied data in a way that makes it more usable to us. Let's start with a best practice: When injecting strings from the `.Values` object into the template, we ought to quote these strings. We can do that by calling the `quote` function in the template directive: From 0209ac32ddb8da3fb70e82855970146eec4031f9 Mon Sep 17 00:00:00 2001 From: Derek Bassett Date: Thu, 22 Mar 2018 23:21:45 -0600 Subject: [PATCH 180/221] Add App Version to the helm ls command. --- cmd/helm/list.go | 5 +++-- cmd/helm/list_test.go | 27 ++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/cmd/helm/list.go b/cmd/helm/list.go index 4332ceb21..c2633d21c 100644 --- a/cmd/helm/list.go +++ b/cmd/helm/list.go @@ -237,7 +237,7 @@ func formatList(rels []*release.Release, colWidth uint) string { table := uitable.New() table.MaxColWidth = colWidth - table.AddRow("NAME", "REVISION", "UPDATED", "STATUS", "CHART", "NAMESPACE") + table.AddRow("NAME", "REVISION", "UPDATED", "STATUS", "CHART", "APP VERSION", "NAMESPACE") for _, r := range rels { md := r.GetChart().GetMetadata() c := fmt.Sprintf("%s-%s", md.GetName(), md.GetVersion()) @@ -247,8 +247,9 @@ func formatList(rels []*release.Release, colWidth uint) string { } s := r.GetInfo().GetStatus().GetCode().String() v := r.GetVersion() + a := md.GetAppVersion() n := r.GetNamespace() - table.AddRow(r.GetName(), v, t, s, c, n) + table.AddRow(r.GetName(), v, t, s, c, a, n) } return table.String() } diff --git a/cmd/helm/list_test.go b/cmd/helm/list_test.go index d853fa6b1..e292b4b5a 100644 --- a/cmd/helm/list_test.go +++ b/cmd/helm/list_test.go @@ -22,11 +22,29 @@ import ( "github.com/spf13/cobra" + "io/ioutil" + "k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/helm" + "k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/proto/hapi/release" + "os" ) func TestListCmd(t *testing.T) { + tmpChart, _ := ioutil.TempDir("testdata", "tmp") + defer os.RemoveAll(tmpChart) + cfile := &chart.Metadata{ + Name: "foo", + Description: "A Helm chart for Kubernetes", + Version: "0.1.0-beta.1", + AppVersion: "2.X.A", + } + chartPath, err := chartutil.Create(cfile, tmpChart) + if err != nil { + t.Errorf("Error creating chart for list: %v", err) + } + ch, _ := chartutil.Load(chartPath) + tests := []releaseCase{ { name: "with a release", @@ -40,7 +58,14 @@ func TestListCmd(t *testing.T) { rels: []*release.Release{ helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas"}), }, - expected: "NAME \tREVISION\tUPDATED \tSTATUS \tCHART \tNAMESPACE\natlas\t1 \t(.*)\tDEPLOYED\tfoo-0.1.0-beta.1\tdefault \n", + expected: "NAME \tREVISION\tUPDATED \tSTATUS \tCHART \tAPP VERSION\tNAMESPACE\natlas\t1 \t(.*)\tDEPLOYED\tfoo-0.1.0-beta.1\t \tdefault \n", + }, + { + name: "list with appVersion", + rels: []*release.Release{ + helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas", Chart: ch}), + }, + expected: "NAME \tREVISION\tUPDATED \tSTATUS \tCHART \tAPP VERSION\tNAMESPACE\natlas\t1 \t(.*)\tDEPLOYED\tfoo-0.1.0-beta.1\t2.X.A \tdefault \n", }, { name: "list, one deployed, one failed", From 7b8aae466761448522acbd3beb2a16ad2283013a Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Mon, 16 Apr 2018 16:46:47 -0700 Subject: [PATCH 181/221] Revert "feat: add --set and --values options to 'helm package'" This reverts commit a930eb7ff4dcba13831174496dda2445e81ebeaa. --- cmd/helm/package.go | 20 ----- cmd/helm/package_test.go | 152 -------------------------------------- docs/helm/helm_package.md | 21 +++--- 3 files changed, 9 insertions(+), 184 deletions(-) diff --git a/cmd/helm/package.go b/cmd/helm/package.go index bf171e534..ed44382c7 100644 --- a/cmd/helm/package.go +++ b/cmd/helm/package.go @@ -53,9 +53,6 @@ type packageCmd struct { save bool sign bool path string - valueFiles valueFiles - values []string - stringValues []string key string keyring string version string @@ -98,9 +95,6 @@ func newPackageCmd(out io.Writer) *cobra.Command { } f := cmd.Flags() - f.VarP(&pkg.valueFiles, "values", "f", "specify values in a YAML file or a URL(can specify multiple)") - f.StringArrayVar(&pkg.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") - f.StringArrayVar(&pkg.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.BoolVar(&pkg.save, "save", true, "save packaged chart to local chart repository") f.BoolVar(&pkg.sign, "sign", false, "use a PGP private key to sign this package") f.StringVar(&pkg.key, "key", "", "name of the key to use when signing. Used if --sign is true") @@ -139,20 +133,6 @@ func (p *packageCmd) run() error { return err } - overrideVals, err := vals(p.valueFiles, p.values, p.stringValues) - if err != nil { - return err - } - combinedVals, err := chartutil.CoalesceValues(ch, &chart.Config{Raw: string(overrideVals)}) - if err != nil { - return err - } - newVals, err := combinedVals.YAML() - if err != nil { - return err - } - ch.Values = &chart.Config{Raw: newVals} - // If version is set, modify the version. if len(p.version) != 0 { if err := setVersion(ch, p.version); err != nil { diff --git a/cmd/helm/package_test.go b/cmd/helm/package_test.go index 4a2df3f54..4404586e0 100644 --- a/cmd/helm/package_test.go +++ b/cmd/helm/package_test.go @@ -21,7 +21,6 @@ import ( "os" "path/filepath" "regexp" - "strings" "testing" "github.com/spf13/cobra" @@ -123,13 +122,6 @@ func TestPackage(t *testing.T) { hasfile: "chart-missing-deps-0.1.0.tgz", err: true, }, - { - name: "package --values does-not-exist", - args: []string{"testdata/testcharts/alpine"}, - flags: map[string]string{"values": "does-not-exist"}, - expect: "does-not-exist: no such file or directory", - err: true, - }, } // Because these tests are destructive, we run them in a tempdir. @@ -253,150 +245,6 @@ func TestSetAppVersion(t *testing.T) { } } -func TestPackageValues(t *testing.T) { - testCases := []struct { - desc string - args []string - valuefilesContents []string - flags map[string]string - expected []string - }{ - { - desc: "helm package, single values file", - args: []string{"testdata/testcharts/alpine"}, - valuefilesContents: []string{"Name: chart-name-foo"}, - expected: []string{"Name: chart-name-foo"}, - }, - { - desc: "helm package, multiple values files", - args: []string{"testdata/testcharts/alpine"}, - valuefilesContents: []string{"Name: chart-name-foo", "foo: bar"}, - expected: []string{"Name: chart-name-foo", "foo: bar"}, - }, - { - desc: "helm package, with set option", - args: []string{"testdata/testcharts/alpine"}, - flags: map[string]string{"set": "Name=chart-name-foo"}, - expected: []string{"Name: chart-name-foo"}, - }, - { - desc: "helm package, set takes precedence over value file", - args: []string{"testdata/testcharts/alpine"}, - valuefilesContents: []string{"Name: chart-name-foo"}, - flags: map[string]string{"set": "Name=chart-name-bar"}, - expected: []string{"Name: chart-name-bar"}, - }, - } - - thome, err := tempHelmHome(t) - if err != nil { - t.Fatal(err) - } - cleanup := resetEnv() - defer func() { - os.RemoveAll(thome.String()) - cleanup() - }() - - settings.Home = thome - - for _, tc := range testCases { - var files []string - for _, contents := range tc.valuefilesContents { - f, err := createValuesFile(contents) - if err != nil { - t.Errorf("%q unexpected error creating temporary values file: %q", tc.desc, err) - } - defer os.RemoveAll(filepath.Dir(f)) - files = append(files, f) - } - valueFiles := strings.Join(files, ",") - - expected, err := chartutil.ReadValues([]byte(strings.Join(tc.expected, "\n"))) - if err != nil { - t.Errorf("unexpected error parsing values: %q", err) - } - - runAndVerifyPackageCommandValues(t, tc.args, tc.flags, valueFiles, expected) - } -} - -func runAndVerifyPackageCommandValues(t *testing.T, args []string, flags map[string]string, valueFiles string, expected chartutil.Values) { - outputDir, err := ioutil.TempDir("", "helm-package") - if err != nil { - t.Errorf("unexpected error creating temporary output directory: %q", err) - } - defer os.RemoveAll(outputDir) - - if len(flags) == 0 { - flags = make(map[string]string) - } - flags["destination"] = outputDir - - if len(valueFiles) > 0 { - flags["values"] = valueFiles - } - - cmd := newPackageCmd(&bytes.Buffer{}) - setFlags(cmd, flags) - err = cmd.RunE(cmd, args) - if err != nil { - t.Errorf("unexpected error: %q", err) - } - - outputFile := filepath.Join(outputDir, "alpine-0.1.0.tgz") - verifyOutputChartExists(t, outputFile) - - var actual chartutil.Values - actual, err = getChartValues(outputFile) - if err != nil { - t.Errorf("unexpected error extracting chart values: %q", err) - } - - verifyValues(t, actual, expected) -} - -func createValuesFile(data string) (string, error) { - outputDir, err := ioutil.TempDir("", "values-file") - if err != nil { - return "", err - } - - outputFile := filepath.Join(outputDir, "values.yaml") - if err = ioutil.WriteFile(outputFile, []byte(data), 0755); err != nil { - os.RemoveAll(outputFile) - return "", err - } - - return outputFile, nil -} - -func getChartValues(chartPath string) (chartutil.Values, error) { - - chart, err := chartutil.Load(chartPath) - if err != nil { - return nil, err - } - - return chartutil.ReadValues([]byte(chart.Values.Raw)) -} - -func verifyValues(t *testing.T, actual, expected chartutil.Values) { - for key, value := range expected.AsMap() { - if got := actual[key]; got != value { - t.Errorf("Expected %q, got %q (%v)", value, got, actual) - } - } -} - -func verifyOutputChartExists(t *testing.T, chartPath string) { - if chartFile, err := os.Stat(chartPath); err != nil { - t.Errorf("expected file %q, got err %q", chartPath, err) - } else if chartFile.Size() == 0 { - t.Errorf("file %q has zero bytes.", chartPath) - } -} - func setFlags(cmd *cobra.Command, flags map[string]string) { dest := cmd.Flags() for f, v := range flags { diff --git a/docs/helm/helm_package.md b/docs/helm/helm_package.md index 957f9c3b2..21090fa45 100644 --- a/docs/helm/helm_package.md +++ b/docs/helm/helm_package.md @@ -23,17 +23,14 @@ helm package [flags] [CHART_PATH] [...] ### Options ``` - --app-version string set the appVersion on the chart to this version - -u, --dependency-update update dependencies from "requirements.yaml" to dir "charts/" before packaging - -d, --destination string location to write the chart. (default ".") - --key string name of the key to use when signing. Used if --sign is true - --keyring string location of a public keyring (default "~/.gnupg/pubring.gpg") - --save save packaged chart to local chart repository (default true) - --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) - --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) - --sign use a PGP private key to sign this package - -f, --values valueFiles specify values in a YAML file or a URL(can specify multiple) (default []) - --version string set the version on the chart to this semver version + --app-version string set the appVersion on the chart to this version + -u, --dependency-update update dependencies from "requirements.yaml" to dir "charts/" before packaging + -d, --destination string location to write the chart. (default ".") + --key string name of the key to use when signing. Used if --sign is true + --keyring string location of a public keyring (default "~/.gnupg/pubring.gpg") + --save save packaged chart to local chart repository (default true) + --sign use a PGP private key to sign this package + --version string set the version on the chart to this semver version ``` ### Options inherited from parent commands @@ -50,4 +47,4 @@ helm package [flags] [CHART_PATH] [...] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 6-Apr-2018 +###### Auto generated by spf13/cobra on 16-Apr-2018 From 9f78c33c644cbf4599c30605470b752126573471 Mon Sep 17 00:00:00 2001 From: AdamDang Date: Tue, 17 Apr 2018 13:55:29 +0800 Subject: [PATCH 182/221] Correct the returned message Correct the returned message --- pkg/plugin/installer/vcs_installer_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/plugin/installer/vcs_installer_test.go b/pkg/plugin/installer/vcs_installer_test.go index 453899543..d6eb32c1b 100644 --- a/pkg/plugin/installer/vcs_installer_test.go +++ b/pkg/plugin/installer/vcs_installer_test.go @@ -133,9 +133,9 @@ func TestVCSInstallerNonExistentVersion(t *testing.T) { } if err := Install(i); err == nil { - t.Error("expected error for version does not exists, got none") + t.Error("expected error for version does not exist, got none") } else if err.Error() != fmt.Sprintf("requested version %q does not exist for plugin %q", version, source) { - t.Errorf("expected error for version does not exists, got (%v)", err) + t.Errorf("expected error for version does not exist, got (%v)", err) } } func TestVCSInstallerUpdate(t *testing.T) { From fac7caf5d266c33cc95d0413e73a9a4636e48317 Mon Sep 17 00:00:00 2001 From: AdamDang Date: Tue, 17 Apr 2018 14:42:09 +0800 Subject: [PATCH 183/221] Correct the returned message in reset_test.go Correct the returned message --- cmd/helm/reset_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/reset_test.go b/cmd/helm/reset_test.go index ae6a00036..189b69273 100644 --- a/cmd/helm/reset_test.go +++ b/cmd/helm/reset_test.go @@ -123,7 +123,7 @@ func verifyResetCmd(t *testing.T, tc resetCase) { } _, err = os.Stat(home) if !tc.removeHelmHome && err != nil { - t.Errorf("Helm home directory %s does not exists", home) + t.Errorf("Helm home directory %s does not exist", home) } if tc.removeHelmHome && err == nil { t.Errorf("Helm home directory %s exists", home) From fed7e69c81eef1cf0686a5a73d01901c1584e169 Mon Sep 17 00:00:00 2001 From: Michelle Noorali Date: Sat, 14 Apr 2018 11:29:27 -0400 Subject: [PATCH 184/221] ref(pkg/plugin): create clean path for extracting plugins --- glide.lock | 10 ++- glide.yaml | 2 + pkg/plugin/installer/http_installer.go | 16 ++-- pkg/plugin/installer/http_installer_test.go | 88 +++++++++++++++++++++ 4 files changed, 108 insertions(+), 8 deletions(-) diff --git a/glide.lock b/glide.lock index 6c54c927c..a91c31b7b 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 6837936360d447b64aa7a09d3c89c18ac5540b009a57fc4d3227af299bf40268 -updated: 2018-04-03T08:17:14.801847688-07:00 +hash: 4023a1644d60060fbf2fdbbe5b73cbb4b957eb686ce925640d102db2d1858676 +updated: 2018-04-14T11:27:34.604716498-04:00 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -31,6 +31,8 @@ imports: version: 71acacd42f85e5e82f70a55327789582a5200a90 subpackages: - md2man +- name: github.com/cyphar/filepath-securejoin + version: 06bda8370f45268db985f7af15732444d94ed51c - name: github.com/davecgh/go-spew version: 782f4967f2dc4564575ca782fe2d04090b5faca8 subpackages: @@ -210,6 +212,8 @@ imports: version: ca53cad383cad2479bbba7f7a1a05797ec1386e4 - name: github.com/peterbourgon/diskv version: 5f041e8faa004a95c88a202771f4cc3e991971e6 +- name: github.com/pkg/errors + version: 645ef00459ed84a119197bfb8d8205042c6df63d - name: github.com/prometheus/client_golang version: c5b7fccd204277076155f10851dad72b76a49317 subpackages: @@ -641,7 +645,7 @@ imports: - pkg/util/proto - pkg/util/proto/validation - name: k8s.io/kubernetes - version: a22f9fd34871d9dc9e5db2c02c713821d18ab2cd + version: baab3992147260d47cb59b9c485a24fdeff2e457 subpackages: - pkg/api/events - pkg/api/legacyscheme diff --git a/glide.yaml b/glide.yaml index 7fcb16d0b..ce5d0e8c2 100644 --- a/glide.yaml +++ b/glide.yaml @@ -57,6 +57,8 @@ import: version: release-1.10 - package: k8s.io/apiserver version: release-1.10 +- package: github.com/cyphar/filepath-securejoin + version: ^0.2.1 testImports: - package: github.com/stretchr/testify diff --git a/pkg/plugin/installer/http_installer.go b/pkg/plugin/installer/http_installer.go index 91d497651..b5c205de6 100644 --- a/pkg/plugin/installer/http_installer.go +++ b/pkg/plugin/installer/http_installer.go @@ -21,14 +21,17 @@ import ( "compress/gzip" "fmt" "io" - "k8s.io/helm/pkg/getter" - "k8s.io/helm/pkg/helm/environment" - "k8s.io/helm/pkg/helm/helmpath" - "k8s.io/helm/pkg/plugin/cache" "os" "path/filepath" "regexp" "strings" + + fp "github.com/cyphar/filepath-securejoin" + + "k8s.io/helm/pkg/getter" + "k8s.io/helm/pkg/helm/environment" + "k8s.io/helm/pkg/helm/helmpath" + "k8s.io/helm/pkg/plugin/cache" ) // HTTPInstaller installs plugins from an archive served by a web server. @@ -181,7 +184,10 @@ func (g *TarGzExtractor) Extract(buffer *bytes.Buffer, targetDir string) error { return err } - path := filepath.Join(targetDir, header.Name) + path, err := fp.SecureJoin(targetDir, header.Name) + if err != nil { + return err + } switch header.Typeflag { case tar.TypeDir: diff --git a/pkg/plugin/installer/http_installer_test.go b/pkg/plugin/installer/http_installer_test.go index ca1a71e3e..bab5f7a92 100644 --- a/pkg/plugin/installer/http_installer_test.go +++ b/pkg/plugin/installer/http_installer_test.go @@ -16,12 +16,15 @@ limitations under the License. package installer // import "k8s.io/helm/pkg/plugin/installer" import ( + "archive/tar" "bytes" + "compress/gzip" "encoding/base64" "fmt" "io/ioutil" "k8s.io/helm/pkg/helm/helmpath" "os" + "path/filepath" "testing" ) @@ -187,3 +190,88 @@ func TestHTTPInstallerUpdate(t *testing.T) { t.Error("update method not implemented for http installer") } } + +func TestExtract(t *testing.T) { + //create a temp home + hh, err := ioutil.TempDir("", "helm-home-") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(hh) + + home := helmpath.Home(hh) + if err := os.MkdirAll(home.Plugins(), 0755); err != nil { + t.Fatalf("Could not create %s: %s", home.Plugins(), err) + } + + cacheDir := filepath.Join(home.Cache(), "plugins", "plugin-key") + if err := os.MkdirAll(cacheDir, 0755); err != nil { + t.Fatalf("Could not create %s: %s", cacheDir, err) + } + + //{"plugin.yaml", "plugin metadata up in here"}, + //{"README.md", "so you know what's upp"}, + //{"script.sh", "echo script"}, + + var tarbuf bytes.Buffer + tw := tar.NewWriter(&tarbuf) + var files = []struct { + Name, Body string + }{ + {"../../plugin.yaml", "sneaky plugin metadata"}, + {"README.md", "some text"}, + } + for _, file := range files { + hdr := &tar.Header{ + Name: file.Name, + Typeflag: tar.TypeReg, + Mode: 0600, + Size: int64(len(file.Body)), + } + if err := tw.WriteHeader(hdr); err != nil { + t.Fatal(err) + } + if _, err := tw.Write([]byte(file.Body)); err != nil { + t.Fatal(err) + } + } + if err := tw.Close(); err != nil { + t.Fatal(err) + } + + var buf bytes.Buffer + gz := gzip.NewWriter(&buf) + if _, err := gz.Write(tarbuf.Bytes()); err != nil { + t.Fatal(err) + } + gz.Close() + + source := "https://repo.localdomain/plugins/fake-plugin-0.0.1.tgz" + extr, err := NewExtractor(source) + if err != nil { + t.Fatal(err) + } + + if err = extr.Extract(&buf, cacheDir); err != nil { + t.Errorf("Did not expect error but got error: %v", err) + } + + pluginYAMLFullPath := filepath.Join(cacheDir, "plugin.yaml") + if _, err := os.Stat(pluginYAMLFullPath); err != nil { + if os.IsNotExist(err) { + t.Errorf("Expected %s to exist but doesn't", pluginYAMLFullPath) + } else { + t.Error(err) + } + } + + readmeFullPath := filepath.Join(cacheDir, "README.md") + if _, err := os.Stat(readmeFullPath); err != nil { + if os.IsNotExist(err) { + t.Errorf("Expected %s to exist but doesn't", readmeFullPath) + } else { + t.Error(err) + } + } + +} From 1850aeade9efe7edb960b130daa46c727ad98bab Mon Sep 17 00:00:00 2001 From: Michelle Noorali Date: Tue, 17 Apr 2018 15:04:53 -0400 Subject: [PATCH 185/221] fix(pkg/strvals): evaluate "null" values resolves #3891 Co-authored-by: Matthew Fisher --- pkg/strvals/parser.go | 8 ++++++++ pkg/strvals/parser_test.go | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/pkg/strvals/parser.go b/pkg/strvals/parser.go index aa3d15904..8d20c3bc3 100644 --- a/pkg/strvals/parser.go +++ b/pkg/strvals/parser.go @@ -82,6 +82,10 @@ func ParseIntoString(s string, dest map[string]interface{}) error { // parser is a simple parser that takes a strvals line and parses it into a // map representation. +// +// where sc is the source of the original data being parsed +// where data is the final parsed data from the parses with correct types +// where st is a boolean to figure out if we're forcing it to parse values as string type parser struct { sc *bytes.Buffer data map[string]interface{} @@ -329,6 +333,10 @@ func typedVal(v []rune, st bool) interface{} { return false } + if strings.EqualFold(val, "null") { + return nil + } + // If this value does not start with zero, and not returnString, try parsing it to an int if !st && len(val) != 0 && val[0] != '0' { if iv, err := strconv.ParseInt(val, 10, 64); err == nil { diff --git a/pkg/strvals/parser_test.go b/pkg/strvals/parser_test.go index fd287bf8a..482377c32 100644 --- a/pkg/strvals/parser_test.go +++ b/pkg/strvals/parser_test.go @@ -81,6 +81,11 @@ func TestParseSet(t *testing.T) { expect map[string]interface{} err bool }{ + { + "name1=null,f=false,t=true", + map[string]interface{}{"name1": nil, "f": false, "t": true}, + false, + }, { "name1=value1", map[string]interface{}{"name1": "value1"}, From 31ddd707e8f832c2ac429aa09284e196f1664ec6 Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Tue, 17 Apr 2018 15:14:09 -0700 Subject: [PATCH 186/221] fix(kube): use correct object type in watch fixes #3902 --- pkg/kube/client.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 8a7402938..08707fa76 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -47,7 +47,6 @@ import ( "k8s.io/client-go/tools/clientcmd" batchinternal "k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/client/conditions" "k8s.io/kubernetes/pkg/kubectl" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" @@ -686,12 +685,27 @@ func (c *Client) watchPodUntilComplete(timeout time.Duration, info *resource.Inf c.Log("Watching pod %s for completion with timeout of %v", info.Name, timeout) _, err = watch.Until(timeout, w, func(e watch.Event) (bool, error) { - return conditions.PodCompleted(e) + return isPodComplete(e) }) return err } +func isPodComplete(event watch.Event) (bool, error) { + o, ok := event.Object.(*core.Pod) + if !ok { + return true, fmt.Errorf("expected a *core.Pod, got %T", event.Object) + } + if event.Type == watch.Deleted { + return false, fmt.Errorf("pod not found") + } + switch o.Status.Phase { + case core.PodFailed, core.PodSucceeded: + return true, nil + } + return false, nil +} + //get a kubernetes resources' relation pods // kubernetes resource used select labels to relate pods func (c *Client) getSelectRelationPod(info *resource.Info, objPods map[string][]core.Pod) (map[string][]core.Pod, error) { From aa2976f0cea3b80278c07c31ffc40072ff81b289 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Tue, 17 Apr 2018 16:36:50 -0700 Subject: [PATCH 187/221] swallow the error when returning the default HTTP client --- pkg/downloader/chart_downloader.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go index fe2f3ce92..8b386fc09 100644 --- a/pkg/downloader/chart_downloader.go +++ b/pkg/downloader/chart_downloader.go @@ -183,7 +183,7 @@ func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*u r := &repo.ChartRepository{} r.Client = g g.SetCredentials(c.getRepoCredentials(r)) - return u, r, g, err + return u, r, g, nil } return u, nil, nil, err } From 6ffff5fea9febb3c2522a391a80cb09b838288a7 Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Wed, 18 Apr 2018 11:42:56 -0700 Subject: [PATCH 188/221] fix(kube): get correct versioned object from info helper fixes: #3826 --- pkg/kube/client.go | 85 ++++++++++++++++------------------------------ pkg/kube/wait.go | 2 +- 2 files changed, 30 insertions(+), 57 deletions(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 08707fa76..34d979d47 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -35,9 +35,7 @@ import ( extv1beta1 "k8s.io/api/extensions/v1beta1" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" @@ -393,12 +391,12 @@ func deleteResource(c *Client, info *resource.Info) error { return reaper.Stop(info.Namespace, info.Name, 0, nil) } -func createPatch(mapping *meta.RESTMapping, target, current runtime.Object) ([]byte, types.PatchType, error) { +func createPatch(target *resource.Info, current runtime.Object) ([]byte, types.PatchType, error) { oldData, err := json.Marshal(current) if err != nil { return nil, types.StrategicMergePatchType, fmt.Errorf("serializing current configuration: %s", err) } - newData, err := json.Marshal(target) + newData, err := json.Marshal(target.Object) if err != nil { return nil, types.StrategicMergePatchType, fmt.Errorf("serializing target configuration: %s", err) } @@ -412,7 +410,7 @@ func createPatch(mapping *meta.RESTMapping, target, current runtime.Object) ([]b } // Get a versioned object - versionedObject, err := mapping.ConvertToVersion(target, mapping.GroupVersionKind.GroupVersion()) + versionedObject, err := target.Versioned() // Unstructured objects, such as CRDs, may not have an not registered error // returned from ConvertToVersion. Anything that's unstructured should @@ -434,7 +432,7 @@ func createPatch(mapping *meta.RESTMapping, target, current runtime.Object) ([]b } func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, force bool, recreate bool) error { - patch, patchType, err := createPatch(target.Mapping, target.Object, currentObj) + patch, patchType, err := createPatch(target, currentObj) if err != nil { return fmt.Errorf("failed to create patch: %s", err) } @@ -484,16 +482,9 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, return nil } - versioned, err := c.AsVersionedObject(target.Object) - if runtime.IsNotRegisteredError(err) { - return nil - } - if err != nil { - return err - } - - selector, err := getSelectorFromObject(versioned) - if err != nil { + versioned := target.AsVersioned() + selector, ok := getSelectorFromObject(versioned) + if !ok { return nil } @@ -522,45 +513,45 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, return nil } -func getSelectorFromObject(obj runtime.Object) (map[string]string, error) { +func getSelectorFromObject(obj runtime.Object) (map[string]string, bool) { switch typed := obj.(type) { case *v1.ReplicationController: - return typed.Spec.Selector, nil + return typed.Spec.Selector, true case *extv1beta1.ReplicaSet: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *appsv1.ReplicaSet: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *extv1beta1.Deployment: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *appsv1beta1.Deployment: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *appsv1beta2.Deployment: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *appsv1.Deployment: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *extv1beta1.DaemonSet: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *appsv1beta2.DaemonSet: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *appsv1.DaemonSet: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *batch.Job: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *appsv1beta1.StatefulSet: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *appsv1beta2.StatefulSet: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true case *appsv1.StatefulSet: - return typed.Spec.Selector.MatchLabels, nil + return typed.Spec.Selector.MatchLabels, true default: - return nil, fmt.Errorf("Unsupported kind when getting selector: %v", obj) + return nil, false } } @@ -605,18 +596,6 @@ func (c *Client) watchUntilReady(timeout time.Duration, info *resource.Info) err return err } -// AsVersionedObject converts a runtime.object to a versioned object. -func (c *Client) AsVersionedObject(obj runtime.Object) (runtime.Object, error) { - json, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj) - if err != nil { - return nil, err - } - versions := &runtime.VersionedObjects{} - decoder := unstructured.UnstructuredJSONScheme - err = runtime.DecodeInto(decoder, json, versions) - return versions.First(), err -} - // waitForJob is a helper that waits for a job to complete. // // This operates on an event returned from a watcher. @@ -715,22 +694,16 @@ 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, err := c.AsVersionedObject(info.Object) - if runtime.IsNotRegisteredError(err) { + versioned, err := info.Versioned() + switch { + case runtime.IsNotRegisteredError(err): return objPods, nil - } - if err != nil { + case err != nil: return objPods, err } - // We can ignore this error because it will only error if it isn't a type that doesn't - // have pods. In that case, we don't care - selector, _ := getSelectorFromObject(versioned) - - selectorString := labels.Set(selector).AsSelector().String() - - // If we have an empty selector, this likely is a service or config map, so bail out now - if selectorString == "" { + selector, ok := getSelectorFromObject(versioned) + if !ok { return objPods, nil } diff --git a/pkg/kube/wait.go b/pkg/kube/wait.go index 27ede15db..88f3c7d34 100644 --- a/pkg/kube/wait.go +++ b/pkg/kube/wait.go @@ -56,7 +56,7 @@ func (c *Client) waitForResources(timeout time.Duration, created Result) error { pvc := []v1.PersistentVolumeClaim{} deployments := []deployment{} for _, v := range created { - obj, err := c.AsVersionedObject(v.Object) + obj, err := v.Versioned() if err != nil && !runtime.IsNotRegisteredError(err) { return false, err } From b0eb40b2ca67146b7bb76e0197bfba0c83c5dd60 Mon Sep 17 00:00:00 2001 From: Colin Dickson Date: Thu, 19 Apr 2018 19:20:42 -0400 Subject: [PATCH 189/221] fixed flag for tls ca cert option in the documentation --- docs/securing_installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/securing_installation.md b/docs/securing_installation.md index 5c420242e..9f74f6049 100644 --- a/docs/securing_installation.md +++ b/docs/securing_installation.md @@ -95,10 +95,10 @@ If these steps are followed, an example `helm init` command might look something $ helm init \ --tiller-tls \ --tiller-tls-verify \ ---tiller-tls-ca-cert=ca.pem \ --tiller-tls-cert=cert.pem \ --tiller-tls-key=key.pem \ ---service-account=accountname +--tls-ca-cert=ca.pem \ +--service-account=accountname ``` This command will start Tiller with both strong authentication over gRPC, and a service account to which RBAC policies have been applied. From 28fb950588f64c4341886509a62d3b7670578e7a Mon Sep 17 00:00:00 2001 From: AdamDang Date: Mon, 23 Apr 2018 13:05:12 +0800 Subject: [PATCH 190/221] Typo fix in plugins.md "that that"->"that" "that that"->"that" --- docs/plugins.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins.md b/docs/plugins.md index 82bcfe33b..3087d1b39 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -183,7 +183,7 @@ If a plugin specifies `useTunnel: true`, Helm will do the following (in order): 5. Close the tunnel The tunnel is removed as soon as the `command` returns. So, for example, a -command cannot background a process and assume that that process will be able +command cannot background a process and assume that process will be able to use the tunnel. ## A Note on Flag Parsing From bcf5688e9a9da64fe5c8580c435bd248ec499e99 Mon Sep 17 00:00:00 2001 From: AdamDang Date: Mon, 23 Apr 2018 13:06:24 +0800 Subject: [PATCH 191/221] Update install.go --- cmd/helm/installer/install.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/installer/install.go b/cmd/helm/installer/install.go index a45179a48..0abd6774b 100644 --- a/cmd/helm/installer/install.go +++ b/cmd/helm/installer/install.go @@ -73,7 +73,7 @@ func Upgrade(client kubernetes.Interface, opts *Options) error { if _, err := client.ExtensionsV1beta1().Deployments(opts.Namespace).Update(obj); err != nil { return err } - // If the service does not exists that would mean we are upgrading from a Tiller version + // If the service does not exist that would mean we are upgrading from a Tiller version // that didn't deploy the service, so install it. _, err = client.CoreV1().Services(opts.Namespace).Get(serviceName, metav1.GetOptions{}) if apierrors.IsNotFound(err) { From 6b2384f8b4dbc64e0452dfb60b987e94e8c21f00 Mon Sep 17 00:00:00 2001 From: Julius Kammerl Date: Mon, 23 Apr 2018 15:42:07 +0200 Subject: [PATCH 192/221] Avoid to call 'go' with empty -tags argument go1.10.1 linux/amd64 complains: flag provided but not defined: -tags when compiling with: "make build-cross dist". This seems to fix it. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2dfbd2c3c..a8f778377 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ build: .PHONY: build-cross build-cross: LDFLAGS += -extldflags "-static" build-cross: - CGO_ENABLED=0 gox -parallel=3 -output="_dist/{{.OS}}-{{.Arch}}/{{.Dir}}" -osarch='$(TARGETS)' $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' k8s.io/helm/cmd/$(APP) + CGO_ENABLED=0 gox -parallel=3 -output="_dist/{{.OS}}-{{.Arch}}/{{.Dir}}" -osarch='$(TARGETS)' $(GOFLAGS) $(if $(TAGS),-tags '$(TAGS)',) -ldflags '$(LDFLAGS)' k8s.io/helm/cmd/$(APP) .PHONY: dist dist: From ed39f16ee57c094476ea61ef4983efcb501e7643 Mon Sep 17 00:00:00 2001 From: Fabian Ruff Date: Mon, 23 Apr 2018 20:12:40 +0200 Subject: [PATCH 193/221] Fix --tiller-namespace flag for plugins This fixes using `--tiller-namespace $namespace` flag (without the equal sign) for helm plugins. --- cmd/helm/load_plugins.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/load_plugins.go b/cmd/helm/load_plugins.go index ef24e7883..f4c97bde7 100644 --- a/cmd/helm/load_plugins.go +++ b/cmd/helm/load_plugins.go @@ -131,7 +131,7 @@ func manuallyProcessArgs(args []string) ([]string, []string) { switch a := args[i]; a { case "--debug": known = append(known, a) - case "--host", "--kube-context", "--home": + case "--host", "--kube-context", "--home", "--tiller-namespace": known = append(known, a, args[i+1]) i++ default: From cefee4b749122bc38d019c2791faf79a4ab1376f Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Mon, 23 Apr 2018 14:30:34 -0700 Subject: [PATCH 194/221] fix(kube): output internal object table fixes #3937 --- pkg/kube/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 34d979d47..e4c6b6a9f 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -178,7 +178,7 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) { // versions per cluster, but this certainly won't hurt anything, so let's be safe. gvk := info.ResourceMapping().GroupVersionKind vk := gvk.Version + "/" + gvk.Kind - objs[vk] = append(objs[vk], info.Object) + objs[vk] = append(objs[vk], info.AsInternal()) //Get the relation pods objPods, err = c.getSelectRelationPod(info, objPods) From 7a65f7479acd2ae76289b0742d5e2349c22fec18 Mon Sep 17 00:00:00 2001 From: Marat Garafutdinov Date: Mon, 23 Apr 2018 16:35:29 -0700 Subject: [PATCH 195/221] add --col-width to `helm search` (#3949) * add customizeable --col-width * make docs. whitespacing --- cmd/helm/search.go | 8 +++++--- docs/helm/helm_search.md | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cmd/helm/search.go b/cmd/helm/search.go index 845bfd0be..ab284a898 100644 --- a/cmd/helm/search.go +++ b/cmd/helm/search.go @@ -47,6 +47,7 @@ type searchCmd struct { versions bool regexp bool version string + colWidth uint } func newSearchCmd(out io.Writer) *cobra.Command { @@ -66,6 +67,7 @@ func newSearchCmd(out io.Writer) *cobra.Command { f.BoolVarP(&sc.regexp, "regexp", "r", false, "use regular expressions for searching") f.BoolVarP(&sc.versions, "versions", "l", false, "show the long listing, with each version of each chart on its own line") f.StringVarP(&sc.version, "version", "v", "", "search using semantic versioning constraints") + f.UintVar(&sc.colWidth, "col-width", 60, "specifies the max column width of output") return cmd } @@ -93,7 +95,7 @@ func (s *searchCmd) run(args []string) error { return err } - fmt.Fprintln(s.out, s.formatSearchResults(data)) + fmt.Fprintln(s.out, s.formatSearchResults(data, s.colWidth)) return nil } @@ -126,12 +128,12 @@ func (s *searchCmd) applyConstraint(res []*search.Result) ([]*search.Result, err return data, nil } -func (s *searchCmd) formatSearchResults(res []*search.Result) string { +func (s *searchCmd) formatSearchResults(res []*search.Result, colWidth uint) string { if len(res) == 0 { return "No results found" } table := uitable.New() - table.MaxColWidth = 50 + table.MaxColWidth = colWidth table.AddRow("NAME", "CHART VERSION", "APP VERSION", "DESCRIPTION") for _, r := range res { table.AddRow(r.Name, r.Chart.Version, r.Chart.AppVersion, r.Chart.Description) diff --git a/docs/helm/helm_search.md b/docs/helm/helm_search.md index f59814b9a..1ed04e880 100644 --- a/docs/helm/helm_search.md +++ b/docs/helm/helm_search.md @@ -19,6 +19,7 @@ helm search [keyword] ### Options ``` + --col-width uint specifies the max column width of output (default 60) -r, --regexp use regular expressions for searching -v, --version string search using semantic versioning constraints -l, --versions show the long listing, with each version of each chart on its own line @@ -38,4 +39,4 @@ helm search [keyword] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 8-Mar-2018 +###### Auto generated by spf13/cobra on 23-Apr-2018 From 718578036d4c13604ec557a32dfd31b5403aac31 Mon Sep 17 00:00:00 2001 From: BarryWilliams Date: Mon, 23 Apr 2018 22:25:11 -0400 Subject: [PATCH 196/221] Changed whitespacing in comments --- pkg/chartutil/files.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go index f9fc0a26d..a09bb8f43 100644 --- a/pkg/chartutil/files.go +++ b/pkg/chartutil/files.go @@ -211,8 +211,8 @@ func ToToml(v interface{}) string { // always return a string, even on marshal error (empty string). // // This is designed to be called from a template. -//TODO:change the function signature in Helm 3 -func ToJson(v interface{}) string { //nolint +// TODO: change the function signature in Helm 3 +func ToJson(v interface{}) string { // nolint data, err := json.Marshal(v) if err != nil { // Swallow errors inside of a template. @@ -227,8 +227,8 @@ func ToJson(v interface{}) string { //nolint // JSON documents. Additionally, because its intended use is within templates // it tolerates errors. It will insert the returned error message string into // m["Error"] in the returned map. -//TODO:change the function signature in Helm 3 -func FromJson(str string) map[string]interface{} { //nolint +// TODO: change the function signature in Helm 3 +func FromJson(str string) map[string]interface{} { // nolint m := map[string]interface{}{} if err := json.Unmarshal([]byte(str), &m); err != nil { From cf3ded91f2143fed6850dee70630c1049bf937ec Mon Sep 17 00:00:00 2001 From: Julien Bordellier Date: Tue, 24 Apr 2018 15:26:57 +0200 Subject: [PATCH 197/221] Add quoting support in ingress to allow wildcard domain --- pkg/chartutil/create.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 4c6b484a9..30c6310b2 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -143,14 +143,14 @@ spec: {{- range .Values.ingress.tls }} - hosts: {{- range .hosts }} - - {{ . }} + - {{ . | quote }} {{- end }} secretName: {{ .secretName }} {{- end }} {{- end }} rules: {{- range .Values.ingress.hosts }} - - host: {{ . }} + - host: {{ . | quote }} http: paths: - path: {{ $ingressPath }} From c2fa72ebcdc9a12381eec29b642374af75f5b45c Mon Sep 17 00:00:00 2001 From: eyalbe4 Date: Wed, 25 Apr 2018 03:44:47 +0300 Subject: [PATCH 198/221] Fix for - Downloader plugins not used when downloading new repo's index.yaml #3938 --- pkg/downloader/chart_downloader.go | 73 ++++++++++++++---------------- pkg/repo/chartrepo.go | 18 +++++--- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go index 8b386fc09..6861a8270 100644 --- a/pkg/downloader/chart_downloader.go +++ b/pkg/downloader/chart_downloader.go @@ -23,6 +23,7 @@ import ( "net/url" "os" "path/filepath" + "reflect" "strings" "k8s.io/helm/pkg/getter" @@ -85,7 +86,7 @@ type ChartDownloader struct { // Returns a string path to the location where the file was downloaded and a verification // (if provenance was verified), or an error if something bad happened. func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *provenance.Verification, error) { - u, r, g, err := c.ResolveChartVersionAndGetRepo(ref, version) + u, g, err := c.ResolveChartVersion(ref, version) if err != nil { return "", nil, err } @@ -104,7 +105,7 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven // If provenance is requested, verify it. ver := &provenance.Verification{} if c.Verify > VerifyNever { - body, err := r.Client.Get(u.String() + ".prov") + body, err := g.Get(u.String() + ".prov") if err != nil { if c.Verify == VerifyAlways { return destfile, ver, fmt.Errorf("Failed to fetch provenance %q", u.String()+".prov") @@ -144,28 +145,14 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven // * If version is empty, this will return the URL for the latest version // * If no version can be found, an error is returned func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, getter.Getter, error) { - u, r, _, err := c.ResolveChartVersionAndGetRepo(ref, version) - if r != nil { - return u, r.Client, err - } - return u, nil, err -} - -// ResolveChartVersionAndGetRepo is the same as the ResolveChartVersion method, but returns the chart repositoryy. -func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*url.URL, *repo.ChartRepository, *getter.HttpGetter, error) { u, err := url.Parse(ref) if err != nil { - return nil, nil, nil, fmt.Errorf("invalid chart URL format: %s", ref) + return nil, nil, fmt.Errorf("invalid chart URL format: %s", ref) } rf, err := repo.LoadRepositoriesFile(c.HelmHome.RepositoryFile()) if err != nil { - return u, nil, nil, err - } - - g, err := getter.NewHTTPGetter(ref, "", "", "") - if err != nil { - return u, nil, nil, err + return u, nil, err } if u.IsAbs() && len(u.Host) > 0 && len(u.Path) > 0 { @@ -180,23 +167,26 @@ func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*u // If there is no special config, return the default HTTP client and // swallow the error. if err == ErrNoOwnerRepo { - r := &repo.ChartRepository{} - r.Client = g - g.SetCredentials(c.getRepoCredentials(r)) - return u, r, g, nil + getterConstructor, err := c.Getters.ByScheme(u.Scheme) + if err != nil { + return u, nil, err + } + getter, err := getterConstructor(ref, "", "", "") + return u, getter, err } - return u, nil, nil, err + return u, nil, err } r, err := repo.NewChartRepository(rc, c.Getters) + c.setCredentials(r) // If we get here, we don't need to go through the next phase of looking // up the URL. We have it already. So we just return. - return u, r, g, err + return u, r.Client, err } // See if it's of the form: repo/path_to_chart p := strings.SplitN(u.Path, "/", 2) if len(p) < 2 { - return u, nil, nil, fmt.Errorf("Non-absolute URLs should be in form of repo_name/path_to_chart, got: %s", u) + return u, nil, fmt.Errorf("Non-absolute URLs should be in form of repo_name/path_to_chart, got: %s", u) } repoName := p[0] @@ -204,56 +194,59 @@ func (c *ChartDownloader) ResolveChartVersionAndGetRepo(ref, version string) (*u rc, err := pickChartRepositoryConfigByName(repoName, rf.Repositories) if err != nil { - return u, nil, nil, err + return u, nil, err } r, err := repo.NewChartRepository(rc, c.Getters) if err != nil { - return u, nil, nil, err + return u, nil, err } - g.SetCredentials(c.getRepoCredentials(r)) + c.setCredentials(r) // 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 { - return u, r, g, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err) + return u, r.Client, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err) } cv, err := i.Get(chartName, version) if err != nil { - return u, r, g, fmt.Errorf("chart %q matching %s not found in %s index. (try 'helm repo update'). %s", chartName, version, r.Config.Name, err) + return u, r.Client, fmt.Errorf("chart %q matching %s not found in %s index. (try 'helm repo update'). %s", chartName, version, r.Config.Name, err) } if len(cv.URLs) == 0 { - return u, r, g, fmt.Errorf("chart %q has no downloadable URLs", ref) + return u, r.Client, fmt.Errorf("chart %q has no downloadable URLs", ref) } // TODO: Seems that picking first URL is not fully correct u, err = url.Parse(cv.URLs[0]) if err != nil { - return u, r, g, fmt.Errorf("invalid chart URL format: %s", ref) + return u, r.Client, fmt.Errorf("invalid chart URL format: %s", ref) } // If the URL is relative (no scheme), prepend the chart repo's base URL if !u.IsAbs() { repoURL, err := url.Parse(rc.URL) if err != nil { - return repoURL, r, nil, err + return repoURL, r.Client, err } q := repoURL.Query() // We need a trailing slash for ResolveReference to work, but make sure there isn't already one repoURL.Path = strings.TrimSuffix(repoURL.Path, "/") + "/" u = repoURL.ResolveReference(u) u.RawQuery = q.Encode() - g, err := getter.NewHTTPGetter(rc.URL, "", "", "") - if err != nil { - return repoURL, r, nil, err - } - g.SetCredentials(c.getRepoCredentials(r)) - return u, r, g, err + return u, r.Client, err } - return u, r, g, nil + return u, r.Client, nil +} + +// If HttpGetter is used, this method sets the configured repository credentials on the HttpGetter. +func (c *ChartDownloader) setCredentials(r *repo.ChartRepository) { + var t *getter.HttpGetter + if reflect.TypeOf(r.Client) == reflect.TypeOf(t) { + r.Client.(*getter.HttpGetter).SetCredentials(c.getRepoCredentials(r)) + } } // If this ChartDownloader is not configured to use credentials, and the chart repository sent as an argument is, diff --git a/pkg/repo/chartrepo.go b/pkg/repo/chartrepo.go index bf03a68bb..ba1e6f4ff 100644 --- a/pkg/repo/chartrepo.go +++ b/pkg/repo/chartrepo.go @@ -22,6 +22,7 @@ import ( "net/url" "os" "path/filepath" + "reflect" "strings" "github.com/ghodss/yaml" @@ -119,12 +120,9 @@ func (r *ChartRepository) DownloadIndexFile(cachePath string) error { parsedURL.Path = strings.TrimSuffix(parsedURL.Path, "/") + "/index.yaml" indexURL = parsedURL.String() - g, err := getter.NewHTTPGetter(indexURL, r.Config.CertFile, r.Config.KeyFile, r.Config.CAFile) - if err != nil { - return err - } - g.SetCredentials(r.Config.Username, r.Config.Password) - resp, err := g.Get(indexURL) + + r.setCredentials() + resp, err := r.Client.Get(indexURL) if err != nil { return err } @@ -152,6 +150,14 @@ func (r *ChartRepository) DownloadIndexFile(cachePath string) error { return ioutil.WriteFile(cp, index, 0644) } +// If HttpGetter is used, this method sets the configured repository credentials on the HttpGetter. +func (r *ChartRepository) setCredentials() { + var t *getter.HttpGetter + if reflect.TypeOf(r.Client) == reflect.TypeOf(t) { + r.Client.(*getter.HttpGetter).SetCredentials(r.Config.Username, r.Config.Password) + } +} + // Index generates an index for the chart repository and writes an index.yaml file. func (r *ChartRepository) Index() error { err := r.generateIndex() From f0d78180d1b5b26955c70b80c4e38553b316d9ea Mon Sep 17 00:00:00 2001 From: Julien Bordellier Date: Wed, 25 Apr 2018 17:02:32 +0200 Subject: [PATCH 199/221] Change tiller's Dockerfile to use USER nobody + upgrades to alpine:3.7 --- rootfs/Dockerfile | 8 ++++---- rootfs/Dockerfile.experimental | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rootfs/Dockerfile b/rootfs/Dockerfile index 53757cd8d..ca5ad2225 100644 --- a/rootfs/Dockerfile +++ b/rootfs/Dockerfile @@ -12,15 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.3 +FROM alpine:3.7 RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/* ENV HOME /tmp -COPY tiller /tiller +COPY tiller /bin/tiller EXPOSE 44134 - -CMD ["/tiller"] +USER nobody +ENTRYPOINT ["/bin/tiller"] diff --git a/rootfs/Dockerfile.experimental b/rootfs/Dockerfile.experimental index 990bcde51..66a218477 100644 --- a/rootfs/Dockerfile.experimental +++ b/rootfs/Dockerfile.experimental @@ -12,15 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.3 +FROM alpine:3.7 RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/* ENV HOME /tmp -COPY tiller /tiller +COPY tiller /bin/tiller EXPOSE 44134 - -CMD ["/tiller", "--experimental-release"] +USER nobody +ENTRYPOINT ["/bin/tiller", "--experimental-release"] From d9395bcc0668429a48cdfe8ff2389bb9d00f4e0e Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Wed, 25 Apr 2018 14:55:05 -0700 Subject: [PATCH 200/221] remove need for type reflection --- pkg/downloader/chart_downloader.go | 6 ++---- pkg/repo/chartrepo.go | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go index 6861a8270..59b9d4d75 100644 --- a/pkg/downloader/chart_downloader.go +++ b/pkg/downloader/chart_downloader.go @@ -23,7 +23,6 @@ import ( "net/url" "os" "path/filepath" - "reflect" "strings" "k8s.io/helm/pkg/getter" @@ -243,9 +242,8 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, ge // If HttpGetter is used, this method sets the configured repository credentials on the HttpGetter. func (c *ChartDownloader) setCredentials(r *repo.ChartRepository) { - var t *getter.HttpGetter - if reflect.TypeOf(r.Client) == reflect.TypeOf(t) { - r.Client.(*getter.HttpGetter).SetCredentials(c.getRepoCredentials(r)) + if t, ok := r.Client.(*getter.HttpGetter); ok { + t.SetCredentials(c.getRepoCredentials(r)) } } diff --git a/pkg/repo/chartrepo.go b/pkg/repo/chartrepo.go index ba1e6f4ff..438f66d7c 100644 --- a/pkg/repo/chartrepo.go +++ b/pkg/repo/chartrepo.go @@ -22,7 +22,6 @@ import ( "net/url" "os" "path/filepath" - "reflect" "strings" "github.com/ghodss/yaml" @@ -152,9 +151,8 @@ func (r *ChartRepository) DownloadIndexFile(cachePath string) error { // If HttpGetter is used, this method sets the configured repository credentials on the HttpGetter. func (r *ChartRepository) setCredentials() { - var t *getter.HttpGetter - if reflect.TypeOf(r.Client) == reflect.TypeOf(t) { - r.Client.(*getter.HttpGetter).SetCredentials(r.Config.Username, r.Config.Password) + if t, ok := r.Client.(*getter.HttpGetter); ok { + t.SetCredentials(r.Config.Username, r.Config.Password) } } From c67fab5934bb76ccd7ab2420a4d2fc8da4ae4af1 Mon Sep 17 00:00:00 2001 From: Julien Bordellier Date: Thu, 26 Apr 2018 10:41:54 +0200 Subject: [PATCH 201/221] docs(helm): update Globs examples to work correctly --- docs/chart_template_guide/accessing_files.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/chart_template_guide/accessing_files.md b/docs/chart_template_guide/accessing_files.md index 250fd9520..11747d4f0 100644 --- a/docs/chart_template_guide/accessing_files.md +++ b/docs/chart_template_guide/accessing_files.md @@ -119,9 +119,10 @@ You have multiple options with Globs: ```yaml -{{ range $path := .Files.Glob "**.yaml" }} -{{ $path }}: | -{{ .Files.Get $path }} +{{ $root := . }} +{{ range $path, $bytes := .Files.Glob "**.yaml" }} +{{ $path }}: |- +{{ $root.Files.Get $path }} {{ end }} ``` @@ -129,7 +130,7 @@ Or ```yaml {{ range $path, $bytes := .Files.Glob "foo/*" }} -{{ $path }}: '{{ b64enc $bytes }}' +{{ $path.base }}: '{{ $root.Files.Get $path | b64enc }}' {{ end }} ``` From f7f686f7d065218ef6df3fbb75ce6348e699a0f3 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Fri, 27 Apr 2018 12:30:46 -0700 Subject: [PATCH 202/221] Revert "toYaml - Fix #3470 and #3410's trailing \n issues" --- pkg/chartutil/files.go | 2 +- pkg/chartutil/files_test.go | 8 ++++---- pkg/strvals/parser.go | 2 +- pkg/strvals/parser_test.go | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go index b71ef5759..a09bb8f43 100644 --- a/pkg/chartutil/files.go +++ b/pkg/chartutil/files.go @@ -175,7 +175,7 @@ func ToYaml(v interface{}) string { // Swallow errors inside of a template. return "" } - return strings.TrimSuffix(string(data), "\n") + return string(data) } // FromYaml converts a YAML document into a map[string]interface{}. diff --git a/pkg/chartutil/files_test.go b/pkg/chartutil/files_test.go index 5cec35883..731c82e6f 100644 --- a/pkg/chartutil/files_test.go +++ b/pkg/chartutil/files_test.go @@ -72,10 +72,10 @@ func TestToConfig(t *testing.T) { f := NewFiles(getTestFiles()) out := f.Glob("**/captain.txt").AsConfig() - as.Equal("captain.txt: The Captain", out) + as.Equal("captain.txt: The Captain\n", out) out = f.Glob("ship/**").AsConfig() - as.Equal("captain.txt: The Captain\nstowaway.txt: Legatt", out) + as.Equal("captain.txt: The Captain\nstowaway.txt: Legatt\n", out) } func TestToSecret(t *testing.T) { @@ -84,7 +84,7 @@ func TestToSecret(t *testing.T) { f := NewFiles(getTestFiles()) out := f.Glob("ship/**").AsSecrets() - as.Equal("captain.txt: VGhlIENhcHRhaW4=\nstowaway.txt: TGVnYXR0", out) + as.Equal("captain.txt: VGhlIENhcHRhaW4=\nstowaway.txt: TGVnYXR0\n", out) } func TestLines(t *testing.T) { @@ -99,7 +99,7 @@ func TestLines(t *testing.T) { } func TestToYaml(t *testing.T) { - expect := "foo: bar" + expect := "foo: bar\n" v := struct { Foo string `json:"foo"` }{ diff --git a/pkg/strvals/parser.go b/pkg/strvals/parser.go index 8d20c3bc3..90670a4dd 100644 --- a/pkg/strvals/parser.go +++ b/pkg/strvals/parser.go @@ -36,7 +36,7 @@ func ToYAML(s string) (string, error) { return "", err } d, err := yaml.Marshal(m) - return strings.TrimSuffix(string(d), "\n"), err + return string(d), err } // Parse parses a set line. diff --git a/pkg/strvals/parser_test.go b/pkg/strvals/parser_test.go index 482377c32..c897cf0a7 100644 --- a/pkg/strvals/parser_test.go +++ b/pkg/strvals/parser_test.go @@ -370,7 +370,7 @@ func TestToYAML(t *testing.T) { if err != nil { t.Fatal(err) } - expect := "name: value" + expect := "name: value\n" if o != expect { t.Errorf("Expected %q, got %q", expect, o) } From 4d1a401a9fb52cfbad97c31a9d038935434b413c Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Fri, 27 Apr 2018 15:33:48 -0700 Subject: [PATCH 203/221] Revert "Fix tiller deployment on RBAC clusters" --- cmd/helm/installer/install.go | 4 +--- cmd/helm/installer/install_test.go | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/cmd/helm/installer/install.go b/cmd/helm/installer/install.go index 0abd6774b..becf412a1 100644 --- a/cmd/helm/installer/install.go +++ b/cmd/helm/installer/install.go @@ -176,7 +176,6 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) { return nil, err } } - automountServiceAccountToken := opts.ServiceAccount != "" d := &v1beta1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Namespace: opts.Namespace, @@ -190,8 +189,7 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) { Labels: labels, }, Spec: v1.PodSpec{ - ServiceAccountName: opts.ServiceAccount, - AutomountServiceAccountToken: &automountServiceAccountToken, + ServiceAccountName: opts.ServiceAccount, Containers: []v1.Container{ { Name: "tiller", diff --git a/cmd/helm/installer/install_test.go b/cmd/helm/installer/install_test.go index 80219505a..dbb7143e3 100644 --- a/cmd/helm/installer/install_test.go +++ b/cmd/helm/installer/install_test.go @@ -96,9 +96,6 @@ func TestDeploymentManifestForServiceAccount(t *testing.T) { if got := d.Spec.Template.Spec.ServiceAccountName; got != tt.serviceAccount { t.Errorf("%s: expected service account value %q, got %q", tt.name, tt.serviceAccount, got) } - if got := *d.Spec.Template.Spec.AutomountServiceAccountToken; got != (tt.serviceAccount != "") { - t.Errorf("%s: unexpected automountServiceAccountToken = %t for serviceAccount %q", tt.name, got, tt.serviceAccount) - } } } From 07bebe6bff7885cafc800c063e52bf4669ed1c93 Mon Sep 17 00:00:00 2001 From: AdamDang Date: Sun, 29 Apr 2018 13:46:46 +0800 Subject: [PATCH 204/221] Typo fix: evalutes->evaluates --- pkg/ignore/rules.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/ignore/rules.go b/pkg/ignore/rules.go index 76f45fc7a..185d289bb 100644 --- a/pkg/ignore/rules.go +++ b/pkg/ignore/rules.go @@ -77,7 +77,7 @@ func (r *Rules) Len() int { return len(r.patterns) } -// Ignore evalutes the file at the given path, and returns true if it should be ignored. +// Ignore evaluates the file at the given path, and returns true if it should be ignored. // // Ignore evaluates path against the rules in order. Evaluation stops when a match // is found. Matching a negative rule will stop evaluation. From ddb536aa7a9287a6bf45994f4430891d00c1f529 Mon Sep 17 00:00:00 2001 From: AdamDang Date: Mon, 7 May 2018 00:15:35 +0800 Subject: [PATCH 205/221] Typo fix: usa helm->use helm usa helm->use helm --- docs/securing_installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/securing_installation.md b/docs/securing_installation.md index 9f74f6049..4083bf188 100644 --- a/docs/securing_installation.md +++ b/docs/securing_installation.md @@ -53,7 +53,7 @@ This situation may change in the future. While the community has several methods In the default installation the gRPC endpoint that Tiller offers is available inside the cluster (not external to the cluster) without authentication configuration applied. Without applying authentication, any process in the cluster can use the gRPC endpoint to perform operations inside the cluster. In a local or secured private cluster, this enables rapid usage and is normal. (When running outside the cluster, Helm authenticates through the Kubernetes API server to reach Tiller, leveraging existing Kubernetes authentication support.) -Shared and production clusters -- for the most part -- should use Helm 2.7.2 at a minimum and configure TLS for each Tiller gRPC endpoint to ensure that within the cluster usage of gRPC endpoints is only for the properly authenticated identity for that endpoint. Doing so enables any number of Tiller instances to be deployed in any number of namespaces and yet no unauthenticated usage of any gRPC endpoint is possible. Finally, usa Helm `init` with the `--tiller-tls-verify` option to install Tiller with TLS enabled and to verify remote certificates, and all other Helm commands should use the `--tls` option. +Shared and production clusters -- for the most part -- should use Helm 2.7.2 at a minimum and configure TLS for each Tiller gRPC endpoint to ensure that within the cluster usage of gRPC endpoints is only for the properly authenticated identity for that endpoint. Doing so enables any number of Tiller instances to be deployed in any number of namespaces and yet no unauthenticated usage of any gRPC endpoint is possible. Finally, use Helm `init` with the `--tiller-tls-verify` option to install Tiller with TLS enabled and to verify remote certificates, and all other Helm commands should use the `--tls` option. For more information about the proper steps to configure Tiller and use Helm properly with TLS configured, see [Using SSL between Helm and Tiller](tiller_ssl.md). From 0699ec4248f3809b16b0e486f1aacf498c9a88c5 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Fri, 11 May 2018 12:09:38 -0600 Subject: [PATCH 206/221] feat(tiller): support CRD installation (#3982) This adds support for installing CRDs well before any other resource kinds are installed. This PR introduces a new hook, `crd-install`, that fires before manifests are even validated. It is used to install a CRD before any other part of a chart is installed. Currently, this hook is _only implemented for install_. That means we currently cannot add new CRDs during `helm upgrade`, nor can they be rolled back. This is the safest configuration, as the update/rollback cycle gets very challenging when CRDs are added and removed. --- _proto/hapi/release/hook.proto | 1 + _proto/hapi/services/tiller.proto | 2 + cmd/helm/install.go | 51 +++++---- docs/charts_hooks.md | 61 +++++++++- docs/helm/helm_install.md | 3 +- pkg/helm/client.go | 1 + pkg/helm/option.go | 9 ++ pkg/hooks/hooks.go | 1 + pkg/proto/hapi/release/hook.pb.go | 58 +++++----- pkg/proto/hapi/services/tiller.pb.go | 165 ++++++++++++++------------- pkg/tiller/hooks.go | 6 +- pkg/tiller/release_install.go | 43 ++++++- pkg/tiller/release_install_test.go | 82 +++++++++++++ pkg/tiller/release_server.go | 21 ++-- pkg/tiller/release_server_test.go | 19 +++ 15 files changed, 378 insertions(+), 145 deletions(-) diff --git a/_proto/hapi/release/hook.proto b/_proto/hapi/release/hook.proto index f0332ecb8..0d96dd9ae 100644 --- a/_proto/hapi/release/hook.proto +++ b/_proto/hapi/release/hook.proto @@ -34,6 +34,7 @@ message Hook { POST_ROLLBACK = 8; RELEASE_TEST_SUCCESS = 9; RELEASE_TEST_FAILURE = 10; + CRD_INSTALL = 11; } enum DeletePolicy { SUCCEEDED = 0; diff --git a/_proto/hapi/services/tiller.proto b/_proto/hapi/services/tiller.proto index 5897676ab..8daef0cb3 100644 --- a/_proto/hapi/services/tiller.proto +++ b/_proto/hapi/services/tiller.proto @@ -271,6 +271,8 @@ message InstallReleaseRequest { // wait, if true, will wait until all Pods, PVCs, and Services are in a ready state // before marking the release as successful. It will wait for as long as timeout bool wait = 9; + + bool disable_crd_hook = 10; } // InstallReleaseResponse is the response from a release installation. diff --git a/cmd/helm/install.go b/cmd/helm/install.go index d52dbc667..2dafd85ba 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -106,28 +106,29 @@ charts in a repository, use 'helm search'. ` type installCmd struct { - name string - namespace string - valueFiles valueFiles - chartPath string - dryRun bool - disableHooks bool - replace bool - verify bool - keyring string - out io.Writer - client helm.Interface - values []string - stringValues []string - nameTemplate string - version string - timeout int64 - wait bool - repoURL string - username string - password string - devel bool - depUp bool + name string + namespace string + valueFiles valueFiles + chartPath string + dryRun bool + disableHooks bool + disableCRDHook bool + replace bool + verify bool + keyring string + out io.Writer + client helm.Interface + values []string + stringValues []string + nameTemplate string + version string + timeout int64 + wait bool + repoURL string + username string + password string + devel bool + depUp bool certFile string keyFile string @@ -190,6 +191,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command { f.StringVar(&inst.namespace, "namespace", "", "namespace to install the release into. Defaults to the current kube config namespace.") f.BoolVar(&inst.dryRun, "dry-run", false, "simulate an install") f.BoolVar(&inst.disableHooks, "no-hooks", false, "prevent hooks from running during install") + f.BoolVar(&inst.disableCRDHook, "no-crd-hook", false, "prevent CRD hooks from running, but run other hooks") f.BoolVar(&inst.replace, "replace", false, "re-use the given name, even if that name is already used. This is unsafe in production") f.StringArrayVar(&inst.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&inst.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") @@ -273,6 +275,7 @@ func (i *installCmd) run() error { helm.InstallDryRun(i.dryRun), helm.InstallReuseName(i.replace), helm.InstallDisableHooks(i.disableHooks), + helm.InstallDisableCRDHook(i.disableCRDHook), helm.InstallTimeout(i.timeout), helm.InstallWait(i.wait)) if err != nil { @@ -287,6 +290,10 @@ func (i *installCmd) run() error { // If this is a dry run, we can't display status. if i.dryRun { + // This is special casing to avoid breaking backward compatibility: + if res.Release.Info.Description != "Dry run complete" { + fmt.Fprintf(os.Stdout, "WARNING: %s\n", res.Release.Info.Description) + } return nil } diff --git a/docs/charts_hooks.md b/docs/charts_hooks.md index 4142f2ce0..f51749f57 100644 --- a/docs/charts_hooks.md +++ b/docs/charts_hooks.md @@ -16,6 +16,17 @@ Hooks work like regular templates, but they have special annotations that cause Helm to utilize them differently. In this section, we cover the basic usage pattern for hooks. +Hooks are declared as an annotation in the metadata section of a manifest: + +```yaml +apiVersion: ... +kind: .... +metadata: + annotations: + "helm.sh/hook": "pre-install" +# ... +``` + ## The Available Hooks The following hooks are defined: @@ -36,6 +47,8 @@ The following hooks are defined: rendered, but before any resources have been rolled back. - post-rollback: Executes on a rollback request after all resources have been modified. +- crd-install: Adds CRD resources before any other checks are run. This is used + only on CRD definitions that are used by other manifests in the chart. ## Hooks and the Release Lifecycle @@ -62,7 +75,7 @@ hooks, the lifecycle is altered like this: Kubernetes) 5. Tiller sorts hooks by weight (assigning a weight of 0 by default) and by name for those hooks with the same weight in ascending order. 6. Tiller then loads the hook with the lowest weight first (negative to positive) -7. Tiller waits until the hook is "Ready" +7. Tiller waits until the hook is "Ready" (except for CRDs) 8. Tiller loads the resulting resources into Kubernetes. Note that if the `--wait` flag is set, Tiller will wait until all resources are in a ready state and will not run the `post-install` hook until they are ready. @@ -185,6 +198,52 @@ 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. +### Defining a CRD with the `crd-install` Hook + +Custom Resource Definitions (CRDs) are a special kind in Kubernetes. They provide +a way to define other kinds. + +On occasion, a chart needs to both define a kind and then use it. This is done +with the `crd-install` hook. + +The `crd-install` hook is executed very early during an installation, before +the rest of the manifests are verified. CRDs can be annotated with this hook so +that they are installed before any instances of that CRD are referenced. In this +way, when verification happens later, the CRDs will be available. + +Here is an example of defining a CRD with a hook, and an instance of the CRD: + +```yaml +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com + annotations: + "helm.sh/hook": crd-install +spec: + group: stable.example.com + version: v1 + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab + shortNames: + - ct +``` + +And: + +```yaml +apiVersion: stable.example.com/v1 +kind: CronTab +metadata: + name: {{ .Release.Name }}-inst +``` + +Both of these can now be in the same chart, provided that the CRD is correctly +annotated. + ### Automatically delete hook from previous release When helm release being updated it is possible, that hook resource already exists in cluster. By default helm will try to create resource and fail with `"... already exists"` error. diff --git a/docs/helm/helm_install.md b/docs/helm/helm_install.md index 25ccea1bd..9f1ad86b0 100644 --- a/docs/helm/helm_install.md +++ b/docs/helm/helm_install.md @@ -84,6 +84,7 @@ helm install [CHART] -n, --name string release name. If unspecified, it will autogenerate one for you --name-template string specify template used to name the release --namespace string namespace to install the release into. Defaults to the current kube config namespace. + --no-crd-hook prevent CRD hooks from running, but run other hooks --no-hooks prevent hooks from running during install --password string chart repository password where to locate the requested chart --replace re-use the given name, even if that name is already used. This is unsafe in production @@ -117,4 +118,4 @@ helm install [CHART] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 20-Mar-2018 +###### Auto generated by spf13/cobra on 27-Apr-2018 diff --git a/pkg/helm/client.go b/pkg/helm/client.go index 43e9f4daf..465ca0af8 100644 --- a/pkg/helm/client.go +++ b/pkg/helm/client.go @@ -97,6 +97,7 @@ func (h *Client) InstallReleaseFromChart(chart *chart.Chart, ns string, opts ... req.Namespace = ns req.DryRun = reqOpts.dryRun req.DisableHooks = reqOpts.disableHooks + req.DisableCrdHook = reqOpts.disableCRDHook req.ReuseName = reqOpts.reuseName ctx := NewContext() diff --git a/pkg/helm/option.go b/pkg/helm/option.go index 3381e3f80..602e1e3a3 100644 --- a/pkg/helm/option.go +++ b/pkg/helm/option.go @@ -51,6 +51,8 @@ type options struct { force bool // if set, skip running hooks disableHooks bool + // if set, skip CRD hook only + disableCRDHook bool // name of release releaseName string // tls.Config to use for rpc if tls enabled @@ -295,6 +297,13 @@ func InstallDisableHooks(disable bool) InstallOption { } } +// InstallDisableCRDHook disables CRD hook during installation. +func InstallDisableCRDHook(disable bool) InstallOption { + return func(opts *options) { + opts.disableCRDHook = disable + } +} + // InstallReuseName will (if true) instruct Tiller to re-use an existing name. func InstallReuseName(reuse bool) InstallOption { return func(opts *options) { diff --git a/pkg/hooks/hooks.go b/pkg/hooks/hooks.go index 80f838368..64118333d 100644 --- a/pkg/hooks/hooks.go +++ b/pkg/hooks/hooks.go @@ -41,6 +41,7 @@ const ( PostRollback = "post-rollback" ReleaseTestSuccess = "test-success" ReleaseTestFailure = "test-failure" + CRDInstall = "crd-install" ) // Type of policy for deleting the hook diff --git a/pkg/proto/hapi/release/hook.pb.go b/pkg/proto/hapi/release/hook.pb.go index 00fa5c188..0a44165c8 100644 --- a/pkg/proto/hapi/release/hook.pb.go +++ b/pkg/proto/hapi/release/hook.pb.go @@ -52,6 +52,7 @@ const ( Hook_POST_ROLLBACK Hook_Event = 8 Hook_RELEASE_TEST_SUCCESS Hook_Event = 9 Hook_RELEASE_TEST_FAILURE Hook_Event = 10 + Hook_CRD_INSTALL Hook_Event = 11 ) var Hook_Event_name = map[int32]string{ @@ -66,6 +67,7 @@ var Hook_Event_name = map[int32]string{ 8: "POST_ROLLBACK", 9: "RELEASE_TEST_SUCCESS", 10: "RELEASE_TEST_FAILURE", + 11: "CRD_INSTALL", } var Hook_Event_value = map[string]int32{ "UNKNOWN": 0, @@ -79,6 +81,7 @@ var Hook_Event_value = map[string]int32{ "POST_ROLLBACK": 8, "RELEASE_TEST_SUCCESS": 9, "RELEASE_TEST_FAILURE": 10, + "CRD_INSTALL": 11, } func (x Hook_Event) String() string { @@ -199,33 +202,34 @@ func init() { func init() { proto.RegisterFile("hapi/release/hook.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 445 bytes of a gzipped FileDescriptorProto + // 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, 0x13, 0x41, 0x47, 0xcf, 0xdb, 0x6e, 0x9a, 0x76, 0xe3, 0xcb, 0x19, 0x9f, 0x7c, + 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, 0x0f, 0xec, 0x3f, 0xe8, 0x0f, 0x6a, 0x76, 0x45, 0x7b, - 0x49, 0xfb, 0x36, 0xf3, 0xcd, 0x37, 0xc3, 0x0c, 0x0b, 0xef, 0x77, 0x49, 0x99, 0x4e, 0x8f, 0x22, - 0x13, 0x49, 0x25, 0xa6, 0xbb, 0xa2, 0xd8, 0x5b, 0xe5, 0xb1, 0xa8, 0x0b, 0xda, 0x97, 0x05, 0xab, - 0x29, 0x0c, 0x1f, 0xb6, 0x45, 0xb1, 0xcd, 0xc4, 0x54, 0xd5, 0x9e, 0x4f, 0x2f, 0xd3, 0x3a, 0x3d, - 0x88, 0xaa, 0x4e, 0x0e, 0xe5, 0x59, 0x1f, 0xff, 0xd2, 0x41, 0x9f, 0x17, 0xc5, 0x9e, 0x52, 0xd0, - 0xf3, 0xe4, 0x20, 0x98, 0x36, 0xd2, 0x26, 0x5d, 0xae, 0x62, 0xc9, 0xf6, 0x69, 0xbe, 0x61, 0xb7, - 0x67, 0x26, 0x63, 0xc9, 0xca, 0xa4, 0xde, 0xb1, 0xd6, 0x99, 0xc9, 0x98, 0x0e, 0xa1, 0x73, 0x48, - 0xf2, 0xf4, 0x45, 0x54, 0x35, 0xd3, 0x15, 0xbf, 0xe6, 0xf4, 0x03, 0x18, 0xe2, 0xbb, 0xc8, 0xeb, - 0x8a, 0xb5, 0x47, 0xad, 0xc9, 0xe0, 0x91, 0x59, 0xaf, 0x17, 0xb4, 0xe4, 0xb7, 0x2d, 0x94, 0x02, - 0x6f, 0x3c, 0xfa, 0x09, 0x3a, 0x59, 0x52, 0xd5, 0xf1, 0xf1, 0x94, 0x33, 0x63, 0xa4, 0x4d, 0x7a, - 0x8f, 0x43, 0xeb, 0x7c, 0x86, 0x75, 0x39, 0xc3, 0x8a, 0x2e, 0x67, 0x70, 0x53, 0xba, 0xfc, 0x94, - 0xd3, 0x77, 0x60, 0xfc, 0x10, 0xe9, 0x76, 0x57, 0x33, 0x73, 0xa4, 0x4d, 0xda, 0xbc, 0xc9, 0xe8, - 0x1c, 0xee, 0x37, 0x22, 0x13, 0xb5, 0x88, 0xcb, 0x22, 0x4b, 0xbf, 0xa5, 0xa2, 0x62, 0x1d, 0xb5, - 0xc9, 0xc3, 0x7f, 0x36, 0x71, 0x95, 0xb9, 0x92, 0xe2, 0x4f, 0x3e, 0xd8, 0xfc, 0xcd, 0x52, 0x51, - 0x8d, 0x7f, 0x6b, 0xd0, 0x56, 0xab, 0xd2, 0x1e, 0x98, 0x6b, 0x7f, 0xe9, 0x07, 0x5f, 0x7c, 0x72, - 0x43, 0xef, 0xa1, 0xb7, 0xe2, 0x18, 0x2f, 0xfc, 0x30, 0xb2, 0x3d, 0x8f, 0x68, 0x94, 0x40, 0x7f, - 0x15, 0x84, 0xd1, 0x95, 0xdc, 0xd2, 0x01, 0x80, 0x54, 0x5c, 0xf4, 0x30, 0x42, 0xd2, 0x52, 0x2d, - 0xd2, 0x68, 0x80, 0x7e, 0x99, 0xb1, 0x5e, 0x7d, 0xe6, 0xb6, 0x8b, 0xa4, 0x7d, 0x9d, 0x71, 0x21, - 0x86, 0x22, 0x1c, 0x63, 0x1e, 0x78, 0xde, 0xcc, 0x76, 0x96, 0xc4, 0xa4, 0x6f, 0xe0, 0x4e, 0x39, - 0x57, 0xd4, 0xa1, 0x0c, 0xde, 0x72, 0xf4, 0xd0, 0x0e, 0x31, 0x8e, 0x30, 0x8c, 0xe2, 0x70, 0xed, - 0x38, 0x18, 0x86, 0xa4, 0xfb, 0x4f, 0xe5, 0xc9, 0x5e, 0x78, 0x6b, 0x8e, 0x04, 0xc6, 0x0e, 0xf4, - 0x5f, 0x9f, 0x4d, 0xef, 0xa0, 0xab, 0xda, 0xd0, 0x45, 0x97, 0xdc, 0x50, 0x00, 0x43, 0xba, 0xe8, - 0x12, 0x4d, 0x0e, 0x99, 0xe1, 0x53, 0xc0, 0x31, 0x9e, 0x07, 0xc1, 0x32, 0x76, 0x38, 0xda, 0xd1, - 0x22, 0xf0, 0xc9, 0xed, 0xac, 0xfb, 0xd5, 0x6c, 0x7e, 0xe4, 0xb3, 0xa1, 0x5e, 0xe9, 0xe3, 0x9f, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x13, 0x64, 0x75, 0x6c, 0xa3, 0x02, 0x00, 0x00, + 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, } diff --git a/pkg/proto/hapi/services/tiller.pb.go b/pkg/proto/hapi/services/tiller.pb.go index 37535aac7..4d23bcdad 100644 --- a/pkg/proto/hapi/services/tiller.pb.go +++ b/pkg/proto/hapi/services/tiller.pb.go @@ -599,7 +599,8 @@ type InstallReleaseRequest struct { Timeout int64 `protobuf:"varint,8,opt,name=timeout" json:"timeout,omitempty"` // wait, if true, will wait until all Pods, PVCs, and Services are in a ready state // before marking the release as successful. It will wait for as long as timeout - Wait bool `protobuf:"varint,9,opt,name=wait" json:"wait,omitempty"` + Wait bool `protobuf:"varint,9,opt,name=wait" json:"wait,omitempty"` + DisableCrdHook bool `protobuf:"varint,10,opt,name=disable_crd_hook,json=disableCrdHook" json:"disable_crd_hook,omitempty"` } func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} } @@ -670,6 +671,13 @@ func (m *InstallReleaseRequest) GetWait() bool { return false } +func (m *InstallReleaseRequest) GetDisableCrdHook() bool { + if m != nil { + return m.DisableCrdHook + } + return false +} + // InstallReleaseResponse is the response from a release installation. type InstallReleaseResponse struct { Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` @@ -1368,82 +1376,83 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("hapi/services/tiller.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 1217 bytes of a gzipped FileDescriptorProto + // 1235 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdd, 0x6e, 0xe3, 0xc4, - 0x17, 0xaf, 0xf3, 0x9d, 0x93, 0x36, 0xff, 0x74, 0x9a, 0xb6, 0xae, 0xff, 0x0b, 0x2a, 0x46, 0xb0, - 0xd9, 0x85, 0x4d, 0x21, 0x70, 0x83, 0x84, 0x90, 0xba, 0xdd, 0xa8, 0x2d, 0x94, 0xae, 0xe4, 0x6c, - 0x17, 0x09, 0x01, 0x91, 0x9b, 0x4c, 0x5a, 0xb3, 0x8e, 0x27, 0x78, 0xc6, 0x65, 0x7b, 0xcb, 0x1d, - 0x8f, 0xc2, 0x5b, 0xf0, 0x1e, 0x5c, 0xc2, 0x83, 0x20, 0xcf, 0x87, 0xeb, 0x49, 0xed, 0xd6, 0xf4, - 0x26, 0x9e, 0x99, 0xf3, 0xfd, 0x3b, 0x67, 0xce, 0x9c, 0x80, 0x75, 0xe9, 0x2e, 0xbc, 0x3d, 0x8a, - 0xc3, 0x2b, 0x6f, 0x82, 0xe9, 0x1e, 0xf3, 0x7c, 0x1f, 0x87, 0xfd, 0x45, 0x48, 0x18, 0x41, 0xdd, - 0x98, 0xd6, 0x57, 0xb4, 0xbe, 0xa0, 0x59, 0x5b, 0x5c, 0x62, 0x72, 0xe9, 0x86, 0x4c, 0xfc, 0x0a, - 0x6e, 0x6b, 0x3b, 0x7d, 0x4e, 0x82, 0x99, 0x77, 0x21, 0x09, 0xc2, 0x44, 0x88, 0x7d, 0xec, 0x52, - 0xac, 0xbe, 0x9a, 0x90, 0xa2, 0x79, 0xc1, 0x8c, 0x48, 0xc2, 0xff, 0x35, 0x02, 0xc3, 0x94, 0x8d, - 0xc3, 0x28, 0x90, 0xc4, 0x1d, 0x8d, 0x48, 0x99, 0xcb, 0x22, 0xaa, 0x19, 0xbb, 0xc2, 0x21, 0xf5, - 0x48, 0xa0, 0xbe, 0x82, 0x66, 0xff, 0x59, 0x82, 0x8d, 0x13, 0x8f, 0x32, 0x47, 0x08, 0x52, 0x07, - 0xff, 0x12, 0x61, 0xca, 0x50, 0x17, 0xaa, 0xbe, 0x37, 0xf7, 0x98, 0x69, 0xec, 0x1a, 0xbd, 0xb2, - 0x23, 0x36, 0x68, 0x0b, 0x6a, 0x64, 0x36, 0xa3, 0x98, 0x99, 0xa5, 0x5d, 0xa3, 0xd7, 0x74, 0xe4, - 0x0e, 0x7d, 0x05, 0x75, 0x4a, 0x42, 0x36, 0x3e, 0xbf, 0x36, 0xcb, 0xbb, 0x46, 0xaf, 0x3d, 0xf8, - 0xa0, 0x9f, 0x85, 0x53, 0x3f, 0xb6, 0x34, 0x22, 0x21, 0xeb, 0xc7, 0x3f, 0xcf, 0xaf, 0x9d, 0x1a, - 0xe5, 0xdf, 0x58, 0xef, 0xcc, 0xf3, 0x19, 0x0e, 0xcd, 0x8a, 0xd0, 0x2b, 0x76, 0xe8, 0x10, 0x80, - 0xeb, 0x25, 0xe1, 0x14, 0x87, 0x66, 0x95, 0xab, 0xee, 0x15, 0x50, 0xfd, 0x32, 0xe6, 0x77, 0x9a, - 0x54, 0x2d, 0xd1, 0x97, 0xb0, 0x2a, 0x20, 0x19, 0x4f, 0xc8, 0x14, 0x53, 0xb3, 0xb6, 0x5b, 0xee, - 0xb5, 0x07, 0x3b, 0x42, 0x95, 0x82, 0x7f, 0x24, 0x40, 0x3b, 0x20, 0x53, 0xec, 0xb4, 0x04, 0x7b, - 0xbc, 0xa6, 0xe8, 0x11, 0x34, 0x03, 0x77, 0x8e, 0xe9, 0xc2, 0x9d, 0x60, 0xb3, 0xce, 0x3d, 0xbc, - 0x39, 0xb0, 0x7f, 0x82, 0x86, 0x32, 0x6e, 0x0f, 0xa0, 0x26, 0x42, 0x43, 0x2d, 0xa8, 0x9f, 0x9d, - 0x7e, 0x73, 0xfa, 0xf2, 0xbb, 0xd3, 0xce, 0x0a, 0x6a, 0x40, 0xe5, 0x74, 0xff, 0xdb, 0x61, 0xc7, - 0x40, 0xeb, 0xb0, 0x76, 0xb2, 0x3f, 0x7a, 0x35, 0x76, 0x86, 0x27, 0xc3, 0xfd, 0xd1, 0xf0, 0x45, - 0xa7, 0x64, 0xbf, 0x0b, 0xcd, 0xc4, 0x67, 0x54, 0x87, 0xf2, 0xfe, 0xe8, 0x40, 0x88, 0xbc, 0x18, - 0x8e, 0x0e, 0x3a, 0x86, 0xfd, 0xbb, 0x01, 0x5d, 0x3d, 0x45, 0x74, 0x41, 0x02, 0x8a, 0xe3, 0x1c, - 0x4d, 0x48, 0x14, 0x24, 0x39, 0xe2, 0x1b, 0x84, 0xa0, 0x12, 0xe0, 0xb7, 0x2a, 0x43, 0x7c, 0x1d, - 0x73, 0x32, 0xc2, 0x5c, 0x9f, 0x67, 0xa7, 0xec, 0x88, 0x0d, 0xfa, 0x14, 0x1a, 0x32, 0x74, 0x6a, - 0x56, 0x76, 0xcb, 0xbd, 0xd6, 0x60, 0x53, 0x07, 0x44, 0x5a, 0x74, 0x12, 0x36, 0xfb, 0x10, 0xb6, - 0x0f, 0xb1, 0xf2, 0x44, 0xe0, 0xa5, 0x2a, 0x26, 0xb6, 0xeb, 0xce, 0x31, 0x77, 0x26, 0xb6, 0xeb, - 0xce, 0x31, 0x32, 0xa1, 0x2e, 0xcb, 0x8d, 0xbb, 0x53, 0x75, 0xd4, 0xd6, 0x66, 0x60, 0xde, 0x56, - 0x24, 0xe3, 0xca, 0xd2, 0xf4, 0x21, 0x54, 0xe2, 0x9b, 0xc0, 0xd5, 0xb4, 0x06, 0x48, 0xf7, 0xf3, - 0x38, 0x98, 0x11, 0x87, 0xd3, 0xf5, 0x54, 0x95, 0x97, 0x53, 0x75, 0x94, 0xb6, 0x7a, 0x40, 0x02, - 0x86, 0x03, 0xf6, 0x30, 0xff, 0x4f, 0x60, 0x27, 0x43, 0x93, 0x0c, 0x60, 0x0f, 0xea, 0xd2, 0x35, - 0xae, 0x2d, 0x17, 0x57, 0xc5, 0x65, 0xff, 0x5d, 0x82, 0xee, 0xd9, 0x62, 0xea, 0x32, 0xac, 0x48, - 0x77, 0x38, 0xf5, 0x18, 0xaa, 0xbc, 0xa3, 0x48, 0x2c, 0xd6, 0x85, 0x6e, 0xd1, 0x76, 0x0e, 0xe2, - 0x5f, 0x47, 0xd0, 0xd1, 0x53, 0xa8, 0x5d, 0xb9, 0x7e, 0x84, 0x29, 0x07, 0x22, 0x41, 0x4d, 0x72, - 0xf2, 0x76, 0xe4, 0x48, 0x0e, 0xb4, 0x0d, 0xf5, 0x69, 0x78, 0x1d, 0xf7, 0x13, 0x7e, 0x05, 0x1b, - 0x4e, 0x6d, 0x1a, 0x5e, 0x3b, 0x51, 0x80, 0xde, 0x87, 0xb5, 0xa9, 0x47, 0xdd, 0x73, 0x1f, 0x8f, - 0x2f, 0x09, 0x79, 0x43, 0xf9, 0x2d, 0x6c, 0x38, 0xab, 0xf2, 0xf0, 0x28, 0x3e, 0x43, 0x56, 0x5c, - 0x49, 0x93, 0x10, 0xbb, 0x0c, 0x9b, 0x35, 0x4e, 0x4f, 0xf6, 0x31, 0x86, 0xcc, 0x9b, 0x63, 0x12, - 0x31, 0x7e, 0x75, 0xca, 0x8e, 0xda, 0xa2, 0xf7, 0x60, 0x35, 0xc4, 0x14, 0xb3, 0xb1, 0xf4, 0xb2, - 0xc1, 0x25, 0x5b, 0xfc, 0xec, 0xb5, 0x70, 0x0b, 0x41, 0xe5, 0x57, 0xd7, 0x63, 0x66, 0x93, 0x93, - 0xf8, 0x5a, 0x88, 0x45, 0x14, 0x2b, 0x31, 0x50, 0x62, 0x11, 0xc5, 0x52, 0xac, 0x0b, 0xd5, 0x19, - 0x09, 0x27, 0xd8, 0x6c, 0x71, 0x9a, 0xd8, 0xd8, 0x47, 0xb0, 0xb9, 0x04, 0xf2, 0x43, 0xf3, 0xf5, - 0x8f, 0x01, 0x5b, 0x0e, 0xf1, 0xfd, 0x73, 0x77, 0xf2, 0xa6, 0x40, 0xc6, 0x52, 0xe0, 0x96, 0xee, - 0x06, 0xb7, 0x9c, 0x01, 0x6e, 0xaa, 0x08, 0x2b, 0x5a, 0x11, 0x6a, 0xb0, 0x57, 0xf3, 0x61, 0xaf, - 0xe9, 0xb0, 0x2b, 0x4c, 0xeb, 0x29, 0x4c, 0x13, 0xc0, 0x1a, 0x69, 0xc0, 0xbe, 0x86, 0xed, 0x5b, - 0x51, 0x3e, 0x14, 0xb2, 0x3f, 0x4a, 0xb0, 0x79, 0x1c, 0x50, 0xe6, 0xfa, 0xfe, 0x12, 0x62, 0x49, - 0x3d, 0x1b, 0x85, 0xeb, 0xb9, 0xf4, 0x5f, 0xea, 0xb9, 0xac, 0x41, 0xae, 0xf2, 0x53, 0x49, 0xe5, - 0xa7, 0x50, 0x8d, 0x6b, 0x9d, 0xa5, 0xb6, 0xd4, 0x59, 0xd0, 0x3b, 0x00, 0xa2, 0x28, 0xb9, 0x72, - 0x01, 0x6d, 0x93, 0x9f, 0x9c, 0xca, 0x46, 0xa2, 0xb2, 0xd1, 0xc8, 0xce, 0x46, 0xaa, 0xc2, 0xed, - 0x63, 0xd8, 0x5a, 0x86, 0xea, 0xa1, 0xb0, 0xff, 0x66, 0xc0, 0xf6, 0x59, 0xe0, 0x65, 0x02, 0x9f, - 0x55, 0xaa, 0xb7, 0xa0, 0x28, 0x65, 0x40, 0xd1, 0x85, 0xea, 0x22, 0x0a, 0x2f, 0xb0, 0x84, 0x56, - 0x6c, 0xd2, 0x31, 0x56, 0xb4, 0x18, 0xed, 0x31, 0x98, 0xb7, 0x7d, 0x78, 0x60, 0x44, 0xb1, 0xd7, - 0xc9, 0x4b, 0xd0, 0x14, 0x5d, 0xdf, 0xde, 0x80, 0xf5, 0x43, 0xcc, 0x5e, 0x8b, 0x6b, 0x21, 0xc3, - 0xb3, 0x87, 0x80, 0xd2, 0x87, 0x37, 0xf6, 0xe4, 0x91, 0x6e, 0x4f, 0x8d, 0x45, 0x8a, 0x5f, 0x71, - 0xd9, 0x5f, 0x70, 0xdd, 0x47, 0x1e, 0x65, 0x24, 0xbc, 0xbe, 0x0b, 0xba, 0x0e, 0x94, 0xe7, 0xee, - 0x5b, 0xf9, 0x50, 0xc4, 0x4b, 0xfb, 0x90, 0x7b, 0x90, 0x88, 0x4a, 0x0f, 0xd2, 0xcf, 0xae, 0x51, - 0xec, 0xd9, 0xfd, 0x01, 0xd0, 0x2b, 0x9c, 0x4c, 0x00, 0xf7, 0xbc, 0x58, 0x2a, 0x09, 0x25, 0xbd, - 0xd0, 0x4c, 0xa8, 0x4f, 0x7c, 0xec, 0x06, 0xd1, 0x42, 0xa6, 0x4d, 0x6d, 0xed, 0x1f, 0x61, 0x43, - 0xd3, 0x2e, 0xfd, 0x8c, 0xe3, 0xa1, 0x17, 0x52, 0x7b, 0xbc, 0x44, 0x9f, 0x43, 0x4d, 0x8c, 0x45, - 0x5c, 0x77, 0x7b, 0xf0, 0x48, 0xf7, 0x9b, 0x2b, 0x89, 0x02, 0x39, 0x47, 0x39, 0x92, 0x77, 0xf0, - 0x57, 0x03, 0xda, 0xea, 0xa1, 0x17, 0x43, 0x1b, 0xf2, 0x60, 0x35, 0x3d, 0xd1, 0xa0, 0x27, 0xf9, - 0x33, 0xdd, 0xd2, 0x60, 0x6a, 0x3d, 0x2d, 0xc2, 0x2a, 0x22, 0xb0, 0x57, 0x3e, 0x31, 0x10, 0x85, - 0xce, 0xf2, 0xa0, 0x81, 0x9e, 0x65, 0xeb, 0xc8, 0x99, 0x6c, 0xac, 0x7e, 0x51, 0x76, 0x65, 0x16, - 0x5d, 0xf1, 0x9a, 0xd1, 0xa7, 0x03, 0x74, 0xaf, 0x1a, 0x7d, 0x20, 0xb1, 0xf6, 0x0a, 0xf3, 0x27, - 0x76, 0x7f, 0x86, 0x35, 0xed, 0x85, 0x43, 0x39, 0x68, 0x65, 0xcd, 0x1a, 0xd6, 0x47, 0x85, 0x78, - 0x13, 0x5b, 0x73, 0x68, 0xeb, 0x4d, 0x0a, 0xe5, 0x28, 0xc8, 0xec, 0xfa, 0xd6, 0xc7, 0xc5, 0x98, - 0x13, 0x73, 0x14, 0x3a, 0xcb, 0x3d, 0x24, 0x2f, 0x8f, 0x39, 0xfd, 0x2e, 0x2f, 0x8f, 0x79, 0xad, - 0xc9, 0x5e, 0x41, 0x2e, 0xc0, 0x4d, 0x0b, 0x41, 0x8f, 0x73, 0x13, 0xa2, 0x77, 0x1e, 0xab, 0x77, - 0x3f, 0x63, 0x62, 0x62, 0x01, 0xff, 0x5b, 0x7a, 0x63, 0x51, 0x0e, 0x34, 0xd9, 0x03, 0x87, 0xf5, - 0xac, 0x20, 0xf7, 0x52, 0x50, 0xb2, 0x2b, 0xdd, 0x11, 0x94, 0xde, 0xf2, 0xee, 0x08, 0x6a, 0xa9, - 0xc1, 0xd9, 0x2b, 0xc8, 0x83, 0xb6, 0x13, 0x05, 0xd2, 0x74, 0xdc, 0x16, 0x50, 0x8e, 0xf4, 0xed, - 0xae, 0x66, 0x3d, 0x29, 0xc0, 0x79, 0x73, 0xbf, 0x9f, 0xc3, 0xf7, 0x0d, 0xc5, 0x7a, 0x5e, 0xe3, - 0xff, 0x69, 0x3f, 0xfb, 0x37, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x7c, 0x9c, 0x49, 0xc1, 0x0f, 0x00, - 0x00, + 0x17, 0xaf, 0xf3, 0x9d, 0x93, 0x6e, 0xfe, 0xd9, 0x69, 0xda, 0xba, 0xfe, 0x2f, 0xa8, 0x18, 0xc1, + 0x66, 0x17, 0x36, 0x85, 0xc0, 0x0d, 0x12, 0x42, 0xea, 0x66, 0xa3, 0xb6, 0x50, 0xba, 0x92, 0xb3, + 0x5d, 0x24, 0x04, 0x44, 0x6e, 0x32, 0x69, 0xcd, 0x3a, 0x76, 0xf0, 0x8c, 0xcb, 0xf6, 0x96, 0x3b, + 0xde, 0x8a, 0x77, 0xe0, 0x92, 0x4b, 0x78, 0x10, 0x34, 0x5f, 0xae, 0x27, 0xb5, 0x5b, 0xd3, 0x9b, + 0x78, 0x66, 0xce, 0xf7, 0xef, 0x9c, 0x39, 0x73, 0x02, 0xd6, 0x85, 0xbb, 0xf4, 0xf6, 0x08, 0x8e, + 0x2e, 0xbd, 0x29, 0x26, 0x7b, 0xd4, 0xf3, 0x7d, 0x1c, 0xf5, 0x97, 0x51, 0x48, 0x43, 0xd4, 0x65, + 0xb4, 0xbe, 0xa2, 0xf5, 0x05, 0xcd, 0xda, 0xe2, 0x12, 0xd3, 0x0b, 0x37, 0xa2, 0xe2, 0x57, 0x70, + 0x5b, 0xdb, 0xe9, 0xf3, 0x30, 0x98, 0x7b, 0xe7, 0x92, 0x20, 0x4c, 0x44, 0xd8, 0xc7, 0x2e, 0xc1, + 0xea, 0xab, 0x09, 0x29, 0x9a, 0x17, 0xcc, 0x43, 0x49, 0xf8, 0xbf, 0x46, 0xa0, 0x98, 0xd0, 0x49, + 0x14, 0x07, 0x92, 0xb8, 0xa3, 0x11, 0x09, 0x75, 0x69, 0x4c, 0x34, 0x63, 0x97, 0x38, 0x22, 0x5e, + 0x18, 0xa8, 0xaf, 0xa0, 0xd9, 0x7f, 0x94, 0x60, 0xe3, 0xd8, 0x23, 0xd4, 0x11, 0x82, 0xc4, 0xc1, + 0xbf, 0xc4, 0x98, 0x50, 0xd4, 0x85, 0xaa, 0xef, 0x2d, 0x3c, 0x6a, 0x1a, 0xbb, 0x46, 0xaf, 0xec, + 0x88, 0x0d, 0xda, 0x82, 0x5a, 0x38, 0x9f, 0x13, 0x4c, 0xcd, 0xd2, 0xae, 0xd1, 0x6b, 0x3a, 0x72, + 0x87, 0xbe, 0x82, 0x3a, 0x09, 0x23, 0x3a, 0x39, 0xbb, 0x32, 0xcb, 0xbb, 0x46, 0xaf, 0x3d, 0xf8, + 0xa0, 0x9f, 0x85, 0x53, 0x9f, 0x59, 0x1a, 0x87, 0x11, 0xed, 0xb3, 0x9f, 0xe7, 0x57, 0x4e, 0x8d, + 0xf0, 0x2f, 0xd3, 0x3b, 0xf7, 0x7c, 0x8a, 0x23, 0xb3, 0x22, 0xf4, 0x8a, 0x1d, 0x3a, 0x00, 0xe0, + 0x7a, 0xc3, 0x68, 0x86, 0x23, 0xb3, 0xca, 0x55, 0xf7, 0x0a, 0xa8, 0x7e, 0xc9, 0xf8, 0x9d, 0x26, + 0x51, 0x4b, 0xf4, 0x25, 0xac, 0x0b, 0x48, 0x26, 0xd3, 0x70, 0x86, 0x89, 0x59, 0xdb, 0x2d, 0xf7, + 0xda, 0x83, 0x1d, 0xa1, 0x4a, 0xc1, 0x3f, 0x16, 0xa0, 0x0d, 0xc3, 0x19, 0x76, 0x5a, 0x82, 0x9d, + 0xad, 0x09, 0x7a, 0x04, 0xcd, 0xc0, 0x5d, 0x60, 0xb2, 0x74, 0xa7, 0xd8, 0xac, 0x73, 0x0f, 0xaf, + 0x0f, 0xec, 0x9f, 0xa0, 0xa1, 0x8c, 0xdb, 0x03, 0xa8, 0x89, 0xd0, 0x50, 0x0b, 0xea, 0xa7, 0x27, + 0xdf, 0x9c, 0xbc, 0xfc, 0xee, 0xa4, 0xb3, 0x86, 0x1a, 0x50, 0x39, 0xd9, 0xff, 0x76, 0xd4, 0x31, + 0xd0, 0x43, 0x78, 0x70, 0xbc, 0x3f, 0x7e, 0x35, 0x71, 0x46, 0xc7, 0xa3, 0xfd, 0xf1, 0xe8, 0x45, + 0xa7, 0x64, 0xbf, 0x0b, 0xcd, 0xc4, 0x67, 0x54, 0x87, 0xf2, 0xfe, 0x78, 0x28, 0x44, 0x5e, 0x8c, + 0xc6, 0xc3, 0x8e, 0x61, 0xff, 0x6e, 0x40, 0x57, 0x4f, 0x11, 0x59, 0x86, 0x01, 0xc1, 0x2c, 0x47, + 0xd3, 0x30, 0x0e, 0x92, 0x1c, 0xf1, 0x0d, 0x42, 0x50, 0x09, 0xf0, 0x5b, 0x95, 0x21, 0xbe, 0x66, + 0x9c, 0x34, 0xa4, 0xae, 0xcf, 0xb3, 0x53, 0x76, 0xc4, 0x06, 0x7d, 0x0a, 0x0d, 0x19, 0x3a, 0x31, + 0x2b, 0xbb, 0xe5, 0x5e, 0x6b, 0xb0, 0xa9, 0x03, 0x22, 0x2d, 0x3a, 0x09, 0x9b, 0x7d, 0x00, 0xdb, + 0x07, 0x58, 0x79, 0x22, 0xf0, 0x52, 0x15, 0xc3, 0xec, 0xba, 0x0b, 0xcc, 0x9d, 0x61, 0x76, 0xdd, + 0x05, 0x46, 0x26, 0xd4, 0x65, 0xb9, 0x71, 0x77, 0xaa, 0x8e, 0xda, 0xda, 0x14, 0xcc, 0x9b, 0x8a, + 0x64, 0x5c, 0x59, 0x9a, 0x3e, 0x84, 0x0a, 0xbb, 0x09, 0x5c, 0x4d, 0x6b, 0x80, 0x74, 0x3f, 0x8f, + 0x82, 0x79, 0xe8, 0x70, 0xba, 0x9e, 0xaa, 0xf2, 0x6a, 0xaa, 0x0e, 0xd3, 0x56, 0x87, 0x61, 0x40, + 0x71, 0x40, 0xef, 0xe7, 0xff, 0x31, 0xec, 0x64, 0x68, 0x92, 0x01, 0xec, 0x41, 0x5d, 0xba, 0xc6, + 0xb5, 0xe5, 0xe2, 0xaa, 0xb8, 0xec, 0xbf, 0x4b, 0xd0, 0x3d, 0x5d, 0xce, 0x5c, 0x8a, 0x15, 0xe9, + 0x16, 0xa7, 0x1e, 0x43, 0x95, 0x77, 0x14, 0x89, 0xc5, 0x43, 0xa1, 0x5b, 0xb4, 0x9d, 0x21, 0xfb, + 0x75, 0x04, 0x1d, 0x3d, 0x85, 0xda, 0xa5, 0xeb, 0xc7, 0x98, 0x70, 0x20, 0x12, 0xd4, 0x24, 0x27, + 0x6f, 0x47, 0x8e, 0xe4, 0x40, 0xdb, 0x50, 0x9f, 0x45, 0x57, 0xac, 0x9f, 0xf0, 0x2b, 0xd8, 0x70, + 0x6a, 0xb3, 0xe8, 0xca, 0x89, 0x03, 0xf4, 0x3e, 0x3c, 0x98, 0x79, 0xc4, 0x3d, 0xf3, 0xf1, 0xe4, + 0x22, 0x0c, 0xdf, 0x10, 0x7e, 0x0b, 0x1b, 0xce, 0xba, 0x3c, 0x3c, 0x64, 0x67, 0xc8, 0x62, 0x95, + 0x34, 0x8d, 0xb0, 0x4b, 0xb1, 0x59, 0xe3, 0xf4, 0x64, 0xcf, 0x30, 0xa4, 0xde, 0x02, 0x87, 0x31, + 0xe5, 0x57, 0xa7, 0xec, 0xa8, 0x2d, 0x7a, 0x0f, 0xd6, 0x23, 0x4c, 0x30, 0x9d, 0x48, 0x2f, 0x1b, + 0x5c, 0xb2, 0xc5, 0xcf, 0x5e, 0x0b, 0xb7, 0x10, 0x54, 0x7e, 0x75, 0x3d, 0x6a, 0x36, 0x39, 0x89, + 0xaf, 0x85, 0x58, 0x4c, 0xb0, 0x12, 0x03, 0x25, 0x16, 0x13, 0x2c, 0xc5, 0xba, 0x50, 0x9d, 0x87, + 0xd1, 0x14, 0x9b, 0x2d, 0x4e, 0x13, 0x1b, 0xfb, 0x10, 0x36, 0x57, 0x40, 0xbe, 0x6f, 0xbe, 0xfe, + 0x31, 0x60, 0xcb, 0x09, 0x7d, 0xff, 0xcc, 0x9d, 0xbe, 0x29, 0x90, 0xb1, 0x14, 0xb8, 0xa5, 0xdb, + 0xc1, 0x2d, 0x67, 0x80, 0x9b, 0x2a, 0xc2, 0x8a, 0x56, 0x84, 0x1a, 0xec, 0xd5, 0x7c, 0xd8, 0x6b, + 0x3a, 0xec, 0x0a, 0xd3, 0x7a, 0x0a, 0xd3, 0x04, 0xb0, 0x46, 0x1a, 0xb0, 0xaf, 0x61, 0xfb, 0x46, + 0x94, 0xf7, 0x85, 0xec, 0xcf, 0x12, 0x6c, 0x1e, 0x05, 0x84, 0xba, 0xbe, 0xbf, 0x82, 0x58, 0x52, + 0xcf, 0x46, 0xe1, 0x7a, 0x2e, 0xfd, 0x97, 0x7a, 0x2e, 0x6b, 0x90, 0xab, 0xfc, 0x54, 0x52, 0xf9, + 0x29, 0x54, 0xe3, 0x5a, 0x67, 0xa9, 0xad, 0x74, 0x16, 0xf4, 0x0e, 0x80, 0x28, 0x4a, 0xae, 0x5c, + 0x40, 0xdb, 0xe4, 0x27, 0x27, 0xb2, 0x91, 0xa8, 0x6c, 0x34, 0xb2, 0xb3, 0x91, 0xae, 0xf0, 0x1e, + 0x74, 0x94, 0x3f, 0xd3, 0x68, 0xc6, 0x7d, 0x92, 0x55, 0xde, 0x96, 0xe7, 0xc3, 0x68, 0xc6, 0xbc, + 0xb2, 0x8f, 0x60, 0x6b, 0x15, 0xd4, 0xfb, 0x26, 0xe8, 0x37, 0x03, 0xb6, 0x4f, 0x03, 0x2f, 0x33, + 0x45, 0x59, 0x45, 0x7d, 0x03, 0xb4, 0x52, 0x06, 0x68, 0x5d, 0xa8, 0x2e, 0xe3, 0xe8, 0x1c, 0xcb, + 0x24, 0x88, 0x4d, 0x1a, 0x8d, 0x8a, 0x86, 0x86, 0x3d, 0x01, 0xf3, 0xa6, 0x0f, 0xf7, 0x8c, 0x88, + 0x79, 0x9d, 0xbc, 0x19, 0x4d, 0xf1, 0x3e, 0xd8, 0x1b, 0xf0, 0xf0, 0x00, 0xd3, 0xd7, 0xe2, 0x02, + 0xc9, 0xf0, 0xec, 0x11, 0xa0, 0xf4, 0xe1, 0xb5, 0x3d, 0x79, 0xa4, 0xdb, 0x53, 0x03, 0x94, 0xe2, + 0x57, 0x5c, 0xf6, 0x17, 0x5c, 0xf7, 0xa1, 0x47, 0x68, 0x18, 0x5d, 0xdd, 0x06, 0x5d, 0x07, 0xca, + 0x0b, 0xf7, 0xad, 0x7c, 0x52, 0xd8, 0xd2, 0x3e, 0xe0, 0x1e, 0x24, 0xa2, 0xd2, 0x83, 0xf4, 0x03, + 0x6d, 0x14, 0x7b, 0xa0, 0x7f, 0x00, 0xf4, 0x0a, 0x27, 0xb3, 0xc2, 0x1d, 0x6f, 0x9b, 0x4a, 0x42, + 0x49, 0x2f, 0x49, 0x13, 0xea, 0x53, 0x1f, 0xbb, 0x41, 0xbc, 0x94, 0x69, 0x53, 0x5b, 0xfb, 0x47, + 0xd8, 0xd0, 0xb4, 0x4b, 0x3f, 0x59, 0x3c, 0xe4, 0x5c, 0x6a, 0x67, 0x4b, 0xf4, 0x39, 0xd4, 0xc4, + 0x00, 0xc5, 0x75, 0xb7, 0x07, 0x8f, 0x74, 0xbf, 0xb9, 0x92, 0x38, 0x90, 0x13, 0x97, 0x23, 0x79, + 0x07, 0x7f, 0x35, 0xa0, 0xad, 0x46, 0x02, 0x31, 0xde, 0x21, 0x0f, 0xd6, 0xd3, 0xb3, 0x0f, 0x7a, + 0x92, 0x3f, 0xfd, 0xad, 0x8c, 0xb0, 0xd6, 0xd3, 0x22, 0xac, 0x22, 0x02, 0x7b, 0xed, 0x13, 0x03, + 0x11, 0xe8, 0xac, 0x8e, 0x24, 0xe8, 0x59, 0xb6, 0x8e, 0x9c, 0x19, 0xc8, 0xea, 0x17, 0x65, 0x57, + 0x66, 0xd1, 0x25, 0xaf, 0x19, 0x7d, 0x8e, 0x40, 0x77, 0xaa, 0xd1, 0x47, 0x17, 0x6b, 0xaf, 0x30, + 0x7f, 0x62, 0xf7, 0x67, 0x78, 0xa0, 0xbd, 0x85, 0x28, 0x07, 0xad, 0xac, 0xa9, 0xc4, 0xfa, 0xa8, + 0x10, 0x6f, 0x62, 0x6b, 0x01, 0x6d, 0xbd, 0x49, 0xa1, 0x1c, 0x05, 0x99, 0xef, 0x83, 0xf5, 0x71, + 0x31, 0xe6, 0xc4, 0x1c, 0x81, 0xce, 0x6a, 0x0f, 0xc9, 0xcb, 0x63, 0x4e, 0xbf, 0xcb, 0xcb, 0x63, + 0x5e, 0x6b, 0xb2, 0xd7, 0x90, 0x0b, 0x70, 0xdd, 0x42, 0xd0, 0xe3, 0xdc, 0x84, 0xe8, 0x9d, 0xc7, + 0xea, 0xdd, 0xcd, 0x98, 0x98, 0x58, 0xc2, 0xff, 0x56, 0x5e, 0x63, 0x94, 0x03, 0x4d, 0xf6, 0x68, + 0x62, 0x3d, 0x2b, 0xc8, 0xbd, 0x12, 0x94, 0xec, 0x4a, 0xb7, 0x04, 0xa5, 0xb7, 0xbc, 0x5b, 0x82, + 0x5a, 0x69, 0x70, 0xf6, 0x1a, 0xf2, 0xa0, 0xed, 0xc4, 0x81, 0x34, 0xcd, 0xda, 0x02, 0xca, 0x91, + 0xbe, 0xd9, 0xd5, 0xac, 0x27, 0x05, 0x38, 0xaf, 0xef, 0xf7, 0x73, 0xf8, 0xbe, 0xa1, 0x58, 0xcf, + 0x6a, 0xfc, 0xdf, 0xef, 0x67, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x5d, 0xc3, 0xd5, 0x55, 0xeb, + 0x0f, 0x00, 0x00, } diff --git a/pkg/tiller/hooks.go b/pkg/tiller/hooks.go index e1e965d08..2dd085ed7 100644 --- a/pkg/tiller/hooks.go +++ b/pkg/tiller/hooks.go @@ -42,6 +42,7 @@ var events = map[string]release.Hook_Event{ hooks.PostRollback: release.Hook_POST_ROLLBACK, hooks.ReleaseTestSuccess: release.Hook_RELEASE_TEST_SUCCESS, hooks.ReleaseTestFailure: release.Hook_RELEASE_TEST_FAILURE, + hooks.CRDInstall: release.Hook_CRD_INSTALL, } // deletePolices represents a mapping between the key in the annotation for label deleting policy and its real meaning @@ -137,10 +138,6 @@ func (file *manifestFile) sort(result *result) error { return e } - if entry.Version != "" && !file.apis.Has(entry.Version) { - return fmt.Errorf("apiVersion %q in %s is not available", entry.Version, file.path) - } - if !hasAnyAnnotation(entry) { result.generic = append(result.generic, Manifest{ Name: file.path, @@ -199,7 +196,6 @@ func (file *manifestFile) sort(result *result) error { } }) } - return nil } diff --git a/pkg/tiller/release_install.go b/pkg/tiller/release_install.go index 8e7fd3acd..0b8f4da5b 100644 --- a/pkg/tiller/release_install.go +++ b/pkg/tiller/release_install.go @@ -127,20 +127,59 @@ func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re rel.Info.Status.Notes = notesTxt } - err = validateManifest(s.env.KubeClient, req.Namespace, manifestDoc.Bytes()) - return rel, err + return rel, nil +} + +func hasCRDHook(hs []*release.Hook) bool { + for _, h := range hs { + for _, e := range h.Events { + if e == events[hooks.CRDInstall] { + return true + } + } + } + return false } // performRelease runs a release. func (s *ReleaseServer) performRelease(r *release.Release, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) { res := &services.InstallReleaseResponse{Release: r} + manifestDoc := []byte(r.Manifest) if req.DryRun { s.Log("dry run for %s", r.Name) + + if !req.DisableCrdHook && hasCRDHook(r.Hooks) { + s.Log("validation skipped because CRD hook is present") + res.Release.Info.Description = "Validation skipped because CRDs are not installed" + return res, nil + } + + // Here's the problem with dry runs and CRDs: We can't install a CRD + // during a dry run, which means it cannot be validated. + if err := validateManifest(s.env.KubeClient, req.Namespace, manifestDoc); err != nil { + return res, err + } + res.Release.Info.Description = "Dry run complete" return res, nil } + // crd-install hooks + if !req.DisableHooks && !req.DisableCrdHook { + if err := s.execHook(r.Hooks, r.Name, r.Namespace, hooks.CRDInstall, req.Timeout); err != nil { + fmt.Printf("Finished installing CRD: %s", err) + return res, err + } + } else { + s.Log("CRD install hooks disabled for %s", req.Name) + } + + // Because the CRDs are installed, they are used for validation during this step. + if err := validateManifest(s.env.KubeClient, req.Namespace, manifestDoc); err != nil { + return res, fmt.Errorf("validation failed: %s", err) + } + // pre-install hooks if !req.DisableHooks { if err := s.execHook(r.Hooks, r.Name, r.Namespace, hooks.PreInstall, req.Timeout); err != nil { diff --git a/pkg/tiller/release_install_test.go b/pkg/tiller/release_install_test.go index 2f21dc46b..a244e4b72 100644 --- a/pkg/tiller/release_install_test.go +++ b/pkg/tiller/release_install_test.go @@ -22,11 +22,44 @@ import ( "testing" "k8s.io/helm/pkg/helm" + "k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/services" "k8s.io/helm/pkg/version" ) +func TestHasCRDHook(t *testing.T) { + tests := []struct { + hooks []*release.Hook + expect bool + }{ + { + hooks: []*release.Hook{ + {Events: []release.Hook_Event{release.Hook_PRE_DELETE}}, + }, + expect: false, + }, + { + hooks: []*release.Hook{ + {Events: []release.Hook_Event{release.Hook_CRD_INSTALL}}, + }, + expect: true, + }, + { + hooks: []*release.Hook{ + {Events: []release.Hook_Event{release.Hook_PRE_UPGRADE, release.Hook_CRD_INSTALL}}, + }, + expect: true, + }, + } + + for i, tt := range tests { + if tt.expect != hasCRDHook(tt.hooks) { + t.Errorf("test %d: expected %t, got %t", i, tt.expect, !tt.expect) + } + } +} + func TestInstallRelease(t *testing.T) { c := helm.NewContext() rs := rsFixture() @@ -335,6 +368,55 @@ func TestInstallRelease_NoHooks(t *testing.T) { } } +func TestInstallRelease_CRDInstallHook(t *testing.T) { + c := helm.NewContext() + rs := rsFixture() + rs.env.Releases.Create(releaseStub()) + + req := installRequest() + req.Chart.Templates = append(req.Chart.Templates, &chart.Template{ + Name: "templates/crdhook", + Data: []byte(manifestWithCRDHook), + }) + + res, err := rs.InstallRelease(c, req) + if err != nil { + t.Errorf("Failed install: %s", err) + } + + // The new hook should have been pulled from the manifest. + if l := len(res.Release.Hooks); l != 2 { + t.Fatalf("expected 2 hooks, got %d", l) + } + + expect := "Install complete" + if got := res.Release.Info.Description; got != expect { + t.Errorf("Expected Description to be %q, got %q", expect, got) + } +} + +func TestInstallRelease_DryRunCRDInstallHook(t *testing.T) { + c := helm.NewContext() + rs := rsFixture() + rs.env.Releases.Create(releaseStub()) + + req := installRequest(withDryRun()) + req.Chart.Templates = append(req.Chart.Templates, &chart.Template{ + Name: "templates/crdhook", + Data: []byte(manifestWithCRDHook), + }) + + res, err := rs.InstallRelease(c, req) + if err != nil { + t.Errorf("Failed install: %s", err) + } + + expect := "Validation skipped because CRDs are not installed" + if res.Release.Info.Description != expect { + t.Errorf("Expected Description %q, got %q", expect, res.Release.Info.Description) + } +} + func TestInstallRelease_FailedHooks(t *testing.T) { c := helm.NewContext() rs := rsFixture() diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index 7c4bc62cf..1a2b3c4da 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -363,7 +363,7 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin executingHooks = sortByHookWeight(executingHooks) for _, h := range executingHooks { - if err := s.deleteHookIfShouldBeDeletedByDeletePolicy(h, hooks.BeforeHookCreation, name, namespace, hook, kubeCli); err != nil { + if err := s.deleteHookByPolicy(h, hooks.BeforeHookCreation, name, namespace, hook, kubeCli); err != nil { return err } @@ -376,14 +376,17 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin b.Reset() b.WriteString(h.Manifest) - if err := kubeCli.WatchUntilReady(namespace, b, timeout, false); err != nil { - s.Log("warning: Release %s %s %s could not complete: %s", name, hook, h.Path, err) - // If a hook is failed, checkout the annotation of the hook to determine whether the hook should be deleted - // under failed condition. If so, then clear the corresponding resource object in the hook - if err := s.deleteHookIfShouldBeDeletedByDeletePolicy(h, hooks.HookFailed, name, namespace, hook, kubeCli); err != nil { + // We can't watch CRDs + if hook != hooks.CRDInstall { + if err := kubeCli.WatchUntilReady(namespace, b, timeout, false); err != nil { + s.Log("warning: Release %s %s %s could not complete: %s", name, hook, h.Path, err) + // If a hook is failed, checkout the annotation of the hook to determine whether the hook should be deleted + // under failed condition. If so, then clear the corresponding resource object in the hook + if err := s.deleteHookByPolicy(h, hooks.HookFailed, name, namespace, hook, kubeCli); err != nil { + return err + } return err } - return err } } @@ -391,7 +394,7 @@ func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook strin // If all hooks are succeeded, checkout the annotation of each hook to determine whether the hook should be deleted // under succeeded condition. If so, then clear the corresponding resource object in each hook for _, h := range executingHooks { - if err := s.deleteHookIfShouldBeDeletedByDeletePolicy(h, hooks.HookSucceeded, name, namespace, hook, kubeCli); err != nil { + if err := s.deleteHookByPolicy(h, hooks.HookSucceeded, name, namespace, hook, kubeCli); err != nil { return err } h.LastRun = timeconv.Now() @@ -418,7 +421,7 @@ func validateReleaseName(releaseName string) error { return nil } -func (s *ReleaseServer) deleteHookIfShouldBeDeletedByDeletePolicy(h *release.Hook, policy string, name, namespace, hook string, kubeCli environment.KubeClient) error { +func (s *ReleaseServer) deleteHookByPolicy(h *release.Hook, policy string, name, namespace, hook string, kubeCli environment.KubeClient) error { 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) diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index 73ba08f67..96cb84a75 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -55,6 +55,25 @@ metadata: data: name: value` +var manifestWithCRDHook = ` +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com + annotations: + "helm.sh/hook": crd-install +spec: + group: stable.example.com + version: v1 + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab + shortNames: + - ct +` + var manifestWithTestHook = `kind: Pod metadata: name: finding-nemo, From 26943763a14b50f516e8a0642b4aad8c6589636c Mon Sep 17 00:00:00 2001 From: Gabriel Silva Vinha Date: Fri, 11 May 2018 15:10:26 -0300 Subject: [PATCH 207/221] Upgrade moniker version (#4034) --- glide.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/glide.yaml b/glide.yaml index ce5d0e8c2..fc3dcc37d 100644 --- a/glide.yaml +++ b/glide.yaml @@ -18,6 +18,7 @@ import: - package: github.com/Masterminds/semver version: ~1.3.1 - package: github.com/technosophos/moniker + version: ~0.2 - package: github.com/golang/protobuf version: 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9 subpackages: From b831efdf5853dceb0249eaf441024d115b5cb633 Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Fri, 11 May 2018 12:12:42 -0700 Subject: [PATCH 208/221] fix(kube): run schema validation on BuildUnstructured --- pkg/kube/client.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index e4c6b6a9f..926174ef1 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -139,6 +139,7 @@ func (c *Client) BuildUnstructured(namespace string, reader io.Reader) (Result, NamespaceParam(namespace). DefaultNamespace(). Stream(reader, ""). + Schema(c.validator()). Flatten(). Do().Infos() return result, scrubValidationError(err) From 32bd9d82e860427e7685df8732b16a5dfc6dfa86 Mon Sep 17 00:00:00 2001 From: Doug Winter Date: Fri, 11 May 2018 20:25:04 +0100 Subject: [PATCH 209/221] Support values files on remote servers with self-signed certs / client cert authentication (#4003) * support tls for values file access - uses --ca-file / --cert-file / --key-file * also for upgrade command --- cmd/helm/install.go | 10 +++++----- cmd/helm/template.go | 2 +- cmd/helm/upgrade.go | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 2dafd85ba..d1c24c213 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -220,7 +220,7 @@ func (i *installCmd) run() error { i.namespace = defaultNamespace() } - rawVals, err := vals(i.valueFiles, i.values, i.stringValues) + rawVals, err := vals(i.valueFiles, i.values, i.stringValues, i.certFile, i.keyFile, i.caFile) if err != nil { return err } @@ -335,7 +335,7 @@ func mergeValues(dest map[string]interface{}, src map[string]interface{}) map[st // vals merges values from files specified via -f/--values and // directly via --set or --set-string, marshaling them to YAML -func vals(valueFiles valueFiles, values []string, stringValues []string) ([]byte, error) { +func vals(valueFiles valueFiles, values []string, stringValues []string, CertFile, KeyFile, CAFile string) ([]byte, error) { base := map[string]interface{}{} // User specified a values files via -f/--values @@ -347,7 +347,7 @@ func vals(valueFiles valueFiles, values []string, stringValues []string) ([]byte if strings.TrimSpace(filePath) == "-" { bytes, err = ioutil.ReadAll(os.Stdin) } else { - bytes, err = readFile(filePath) + bytes, err = readFile(filePath, CertFile, KeyFile, CAFile) } if err != nil { @@ -512,7 +512,7 @@ func checkDependencies(ch *chart.Chart, reqs *chartutil.Requirements) error { } //readFile load a file from the local directory or a remote file with a url. -func readFile(filePath string) ([]byte, error) { +func readFile(filePath, CertFile, KeyFile, CAFile string) ([]byte, error) { u, _ := url.Parse(filePath) p := getter.All(settings) @@ -523,7 +523,7 @@ func readFile(filePath string) ([]byte, error) { return ioutil.ReadFile(filePath) } - getter, err := getterConstructor(filePath, "", "", "") + getter, err := getterConstructor(filePath, CertFile, KeyFile, CAFile) if err != nil { return []byte{}, err } diff --git a/cmd/helm/template.go b/cmd/helm/template.go index fc1f44392..458df87b5 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -130,7 +130,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error { t.namespace = defaultNamespace() } // get combined values and create config - rawVals, err := vals(t.valueFiles, t.values, t.stringValues) + rawVals, err := vals(t.valueFiles, t.values, t.stringValues, "", "", "") if err != nil { return err } diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 66c4a3657..4dd433a39 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -195,7 +195,7 @@ func (u *upgradeCmd) run() error { } } - rawVals, err := vals(u.valueFiles, u.values, u.stringValues) + rawVals, err := vals(u.valueFiles, u.values, u.stringValues, u.certFile, u.keyFile, u.caFile) if err != nil { return err } From f2abb2ae1409ef0c897bd5f7a943561b17af0b3a Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Sat, 12 May 2018 17:37:09 -0700 Subject: [PATCH 210/221] fix lint warning --- pkg/downloader/manager.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go index 89a839b54..9ee1f6f6d 100644 --- a/pkg/downloader/manager.go +++ b/pkg/downloader/manager.go @@ -99,11 +99,7 @@ func (m *Manager) Build() error { } // Now we need to fetch every package here into charts/ - if err := m.downloadAll(lock.Dependencies); err != nil { - return err - } - - return nil + return m.downloadAll(lock.Dependencies) } // Update updates a local charts directory. From e52c7dbf921f8633068c3a7031a6cb6793b01d98 Mon Sep 17 00:00:00 2001 From: Matthew Fisher Date: Mon, 14 May 2018 11:44:49 -0700 Subject: [PATCH 211/221] replace with a link to the latest releases page This removes a step required every time we release Helm, making it simpler to cut a new release. --- README.md | 7 +------ docs/release_checklist.md | 25 ------------------------- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/README.md b/README.md index fb2e16bce..fc091056e 100644 --- a/README.md +++ b/README.md @@ -32,12 +32,7 @@ Think of it like apt/yum/homebrew for Kubernetes. ## Install -Binary downloads of the Helm client can be found at the following links: - -- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.2-darwin-amd64.tar.gz) -- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.2-linux-amd64.tar.gz) -- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.2-linux-386.tar.gz) -- [Windows](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.2-windows-amd64.tar.gz) +Binary downloads of the Helm client can be found on [the latest Releases page](https://github.com/kubernetes/helm/releases/latest). Unpack the `helm` binary and add it to your PATH and you are good to go! diff --git a/docs/release_checklist.md b/docs/release_checklist.md index 26506985c..d678e7748 100644 --- a/docs/release_checklist.md +++ b/docs/release_checklist.md @@ -94,31 +94,6 @@ index 2109a0a..6f5a1a4 100644 BuildMetadata = "unreleased" ``` -The README stores links to the latest release for helm. We want to change the version to the first release candidate which we are releasing (more on that in step 5). - -```shell -$ git diff README.md -diff --git a/README.md b/README.md -index 022afd79..547839e2 100644 ---- a/README.md -+++ b/README.md -@@ -34,10 +34,10 @@ Think of it like apt/yum/homebrew for Kubernetes. - - Binary downloads of the Helm client can be found at the following links: - --- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-darwin-amd64.tar.gz) --- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-linux-amd64.tar.gz) --- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-linux-386.tar.gz) --- [Windows](https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-windows-amd64.tar.gz) -+- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-darwin-amd64.tar.gz) -+- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-linux-amd64.tar.gz) -+- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-linux-386.tar.gz) -+- [Windows](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-windows-amd64.tar.gz) - - Unpack the `helm` binary and add it to your PATH and you are good to go! - macOS/[homebrew](https://brew.sh/) users can also use `brew install kubernetes-helm`. -``` - For patch releases, the old version number will be the latest patch release, so just bump the patch number, incrementing Z by one. ```shell From 51f92b47877bcc36401dacc6b624eecff8a8931d Mon Sep 17 00:00:00 2001 From: AdamDang Date: Wed, 16 May 2018 00:31:05 +0800 Subject: [PATCH 212/221] Typo fix: mach->match mach->match --- pkg/chartutil/requirements.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/chartutil/requirements.go b/pkg/chartutil/requirements.go index 546160b0c..6ef6508d9 100644 --- a/pkg/chartutil/requirements.go +++ b/pkg/chartutil/requirements.go @@ -45,7 +45,7 @@ var ( type Dependency struct { // Name is the name of the dependency. // - // This must mach the name in the dependency's Chart.yaml. + // This must match the name in the dependency's Chart.yaml. Name string `json:"name"` // Version is the version (range) of this chart. // From 931c80edea0301a068b93a6782a8000a619dcb79 Mon Sep 17 00:00:00 2001 From: James Meickle Date: Tue, 15 May 2018 12:43:28 -0400 Subject: [PATCH 213/221] Don't request Tiller version in installer This makes the script hang for quite a while if it can't connect to Tiller to retrieve this information that isn't being used anyways. --- scripts/get | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/get b/scripts/get index 943ca4158..af0960abf 100755 --- a/scripts/get +++ b/scripts/get @@ -92,7 +92,7 @@ checkDesiredVersion() { # if it needs to be changed. checkHelmInstalledVersion() { if [[ -f "${HELM_INSTALL_DIR}/${PROJECT_NAME}" ]]; then - local version=$(helm version | grep '^Client' | cut -d'"' -f2) + local version=$(helm version -c | grep '^Client' | cut -d'"' -f2) if [[ "$version" == "$TAG" ]]; then echo "Helm ${version} is already ${DESIRED_VERSION:-latest}" return 0 From 89c29f3ff107bd107a3a115c69e41bcf89422bc0 Mon Sep 17 00:00:00 2001 From: AdamDang Date: Thu, 17 May 2018 00:05:06 +0800 Subject: [PATCH 214/221] Update capabilities.go --- pkg/chartutil/capabilities.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/chartutil/capabilities.go b/pkg/chartutil/capabilities.go index c87c0368e..d26aa1707 100644 --- a/pkg/chartutil/capabilities.go +++ b/pkg/chartutil/capabilities.go @@ -42,7 +42,7 @@ var ( type Capabilities struct { // List of all supported API versions APIVersions VersionSet - // KubeVerison is the Kubernetes version + // KubeVersion is the Kubernetes version KubeVersion *version.Info // TillerVersion is the Tiller version // From 4f36bbf2bd56dec4a7254706e9bc6d70b7185bd0 Mon Sep 17 00:00:00 2001 From: Yeni Capote Diaz Date: Sun, 20 May 2018 23:26:45 -0700 Subject: [PATCH 215/221] removed --install option from --namespace. --- cmd/helm/lint.go | 2 +- docs/helm/helm_lint.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/helm/lint.go b/cmd/helm/lint.go index 63f11c062..c81468e50 100644 --- a/cmd/helm/lint.go +++ b/cmd/helm/lint.go @@ -73,7 +73,7 @@ func newLintCmd(out io.Writer) *cobra.Command { cmd.Flags().VarP(&l.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)") cmd.Flags().StringArrayVar(&l.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") cmd.Flags().StringArrayVar(&l.sValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") - cmd.Flags().StringVar(&l.namespace, "namespace", "default", "namespace to install the release into (only used if --install is set)") + cmd.Flags().StringVar(&l.namespace, "namespace", "default", "namespace to put the release into") cmd.Flags().BoolVar(&l.strict, "strict", false, "fail on lint warnings") return cmd diff --git a/docs/helm/helm_lint.md b/docs/helm/helm_lint.md index 596edf2bb..c10322efd 100644 --- a/docs/helm/helm_lint.md +++ b/docs/helm/helm_lint.md @@ -21,7 +21,7 @@ helm lint [flags] PATH ### Options ``` - --namespace string namespace to install the release into (only used if --install is set) (default "default") + --namespace string namespace to put the release into (default "default") --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --strict fail on lint warnings @@ -42,4 +42,4 @@ helm lint [flags] PATH ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 9-Mar-2018 +###### Auto generated by spf13/cobra on 20-May-2018 From 43b19dccbee45dcf77a047fabb1aa051ff346d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Bergstr=C3=B6m?= Date: Tue, 22 May 2018 16:24:19 +0200 Subject: [PATCH 216/221] Add helm template --is-upgrade Useful for toggling .Release.IsInstall / .Release.IsUpgrade which in turn may cause templates to render differently. --- cmd/helm/template.go | 28 +++++++++++-------- cmd/helm/template_test.go | 14 ++++++++++ .../charts/subchart1/templates/service.yaml | 2 ++ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/cmd/helm/template.go b/cmd/helm/template.go index 458df87b5..7e3eb48a7 100644 --- a/cmd/helm/template.go +++ b/cmd/helm/template.go @@ -63,18 +63,19 @@ To render just one template in a chart, use '-x': ` type templateCmd struct { - namespace string - valueFiles valueFiles - chartPath string - out io.Writer - values []string - stringValues []string - nameTemplate string - showNotes bool - releaseName string - renderFiles []string - kubeVersion string - outputDir string + namespace string + valueFiles valueFiles + chartPath string + out io.Writer + values []string + stringValues []string + nameTemplate string + showNotes bool + releaseName string + releaseIsUpgrade bool + renderFiles []string + kubeVersion string + outputDir string } func newTemplateCmd(out io.Writer) *cobra.Command { @@ -93,6 +94,7 @@ func newTemplateCmd(out io.Writer) *cobra.Command { f := cmd.Flags() f.BoolVar(&t.showNotes, "notes", false, "show the computed NOTES.txt file as well") f.StringVarP(&t.releaseName, "name", "n", "RELEASE-NAME", "release name") + f.BoolVar(&t.releaseIsUpgrade, "is-upgrade", false, "set .Release.IsUpgrade instead of .Release.IsInstall") f.StringArrayVarP(&t.renderFiles, "execute", "x", []string{}, "only execute the given templates") f.VarP(&t.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)") f.StringVar(&t.namespace, "namespace", "", "namespace to install the release into") @@ -159,6 +161,8 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error { } options := chartutil.ReleaseOptions{ Name: t.releaseName, + IsInstall: !t.releaseIsUpgrade, + IsUpgrade: t.releaseIsUpgrade, Time: timeconv.Now(), Namespace: t.namespace, } diff --git a/cmd/helm/template_test.go b/cmd/helm/template_test.go index cad42db16..d15dc5666 100644 --- a/cmd/helm/template_test.go +++ b/cmd/helm/template_test.go @@ -107,6 +107,20 @@ func TestTemplateCmd(t *testing.T) { expectKey: "subchart1/templates/service.yaml", expectValue: "release-name: \"test\"", }, + { + name: "check_release_is_install", + desc: "verify --is-upgrade toggles .Release.IsInstall", + args: []string{subchart1ChartPath, "--is-upgrade=false"}, + expectKey: "subchart1/templates/service.yaml", + expectValue: "release-is-install: \"true\"", + }, + { + name: "check_release_is_upgrade", + desc: "verify --is-upgrade toggles .Release.IsUpgrade", + args: []string{subchart1ChartPath, "--is-upgrade", "true"}, + expectKey: "subchart1/templates/service.yaml", + expectValue: "release-is-upgrade: \"true\"", + }, { name: "check_notes", desc: "verify --notes shows notes", diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/templates/service.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/service.yaml index 3835a3d0b..e06d19b90 100644 --- a/pkg/chartutil/testdata/subpop/charts/subchart1/templates/service.yaml +++ b/pkg/chartutil/testdata/subpop/charts/subchart1/templates/service.yaml @@ -6,6 +6,8 @@ metadata: chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" namespace: "{{ .Release.Namespace }}" release-name: "{{ .Release.Name }}" + release-is-upgrade: "{{ .Release.IsUpgrade }}" + release-is-install: "{{ .Release.IsInstall }}" kube-version/major: "{{ .Capabilities.KubeVersion.Major }}" kube-version/minor: "{{ .Capabilities.KubeVersion.Minor }}" kube-version/gitversion: "v{{ .Capabilities.KubeVersion.Major }}.{{ .Capabilities.KubeVersion.Minor }}.0" From 93e8f0a694e18b1c1310a193c01f874648d898df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Bergstr=C3=B6m?= Date: Tue, 22 May 2018 16:45:37 +0200 Subject: [PATCH 217/221] make docs recipe for target 'verify-docs' failed --- docs/helm/helm_template.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/helm/helm_template.md b/docs/helm/helm_template.md index 3a4e9ce4a..cdc8a84a6 100644 --- a/docs/helm/helm_template.md +++ b/docs/helm/helm_template.md @@ -26,6 +26,7 @@ helm template [flags] CHART ``` -x, --execute stringArray only execute the given templates + --is-upgrade set .Release.IsUpgrade instead of .Release.IsInstall --kube-version string kubernetes version used as Capabilities.KubeVersion.Major/Minor (default "1.9") -n, --name string release name (default "RELEASE-NAME") --name-template string specify template used to name the release @@ -51,4 +52,4 @@ helm template [flags] CHART ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 9-Mar-2018 +###### Auto generated by spf13/cobra on 22-May-2018 From 20fe27c0dec8029760d9ade1f02eb1905d89813f Mon Sep 17 00:00:00 2001 From: Ryan Hartje Date: Wed, 23 May 2018 11:43:56 -0400 Subject: [PATCH 218/221] adding docs for GKE for helm 2 --- docs/kubernetes_distros.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/kubernetes_distros.md b/docs/kubernetes_distros.md index 8b80519ec..bb14043da 100644 --- a/docs/kubernetes_distros.md +++ b/docs/kubernetes_distros.md @@ -18,8 +18,9 @@ Hyperkube you may need to do some manual configuration. ## GKE -Google's GKE hosted Kubernetes platform is known to work with Helm, and requires -no additional configuration. +Google's GKE hosted Kubernetes platform enables RBAC by default. You will need to create a service account for tiller, and use the --service-account flag when initializing the helm server. + +See [Tiller and role-based access control](https://docs.helm.sh/using_helm/#role-based-access-control) for more information. ## Ubuntu with 'kubeadm' @@ -48,4 +49,3 @@ Helm Client and Helm Server (Tiller) are pre-installed with [Platform9 Managed K Helm (both client and server) has been tested and is working on Mesospheres DC/OS 1.11 Kubernetes platform, and requires no additional configuration. - From 8415e2716c31df14aa859a9b3e692f02c154a878 Mon Sep 17 00:00:00 2001 From: Shubham Jain Date: Thu, 24 May 2018 18:19:51 +0530 Subject: [PATCH 219/221] docs(helm): Added double quotes to example In the current version of helm (2.8.2), there needs to be double quotes around the value to support escaping special characters. --- docs/using_helm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/using_helm.md b/docs/using_helm.md index 6bf7bc40a..0d15637d4 100755 --- a/docs/using_helm.md +++ b/docs/using_helm.md @@ -285,7 +285,7 @@ servers: ``` Sometimes you need to use special characters in your `--set` lines. You can use -a backslash to escape the characters; `--set name=value1\,value2` will become: +a backslash to escape the characters; `--set name="value1\,value2"` will become: ```yaml name: "value1,value2" From 215abe9fd42571a99f42cb03737461208b418a1e Mon Sep 17 00:00:00 2001 From: mf-lit Date: Thu, 24 May 2018 16:41:11 +0100 Subject: [PATCH 220/221] Update tiller_ssl.md Add -days parameter to openssl signing commands for clarity. Also add some related troubleshooting steps. --- docs/tiller_ssl.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/tiller_ssl.md b/docs/tiller_ssl.md index d7f0166c4..6db195507 100644 --- a/docs/tiller_ssl.md +++ b/docs/tiller_ssl.md @@ -148,10 +148,10 @@ $ openssl req -key helm.key.pem -new -sha256 -out helm.csr.pem (In rare cases, we've had to add the `-nodes` flag when generating the request.) -Now we sign each of these CSRs with the CA certificate we created: +Now we sign each of these CSRs with the CA certificate we created (adjust the days parameter to suit your requirements): ```console -$ openssl x509 -req -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -in tiller.csr.pem -out tiller.cert.pem +$ openssl x509 -req -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -in tiller.csr.pem -out tiller.cert.pem -days 365 Signature ok subject=/C=US/ST=CO/L=Boulder/O=Tiller Server/CN=tiller-server Getting CA Private Key @@ -161,7 +161,7 @@ Enter pass phrase for ca.key.pem: And again for the client certificate: ```console -$ openssl x509 -req -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -in helm.csr.pem -out helm.cert.pem +$ openssl x509 -req -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -in helm.csr.pem -out helm.cert.pem -days 365 ``` At this point, the important files for us are these: @@ -284,6 +284,13 @@ the host name that Helm connects to matches the host name on the certificate. In some cases this is awkward, since Helm will connect over localhost, or the FQDN is not available for public resolution. +*If I use `--tls-verify` on the client, I get `Error: x509: certificate has expired or is not yet valid`* + +Your helm certificate has expired, you need to sign a new certificate using your private key and the CA (and consider increasing the number of days) + +If your tiller certificate has expired, you'll need to sign a new certificate, base64 encode it and update the Tiller Secret: +`kubectl edit secret tiller-secret` + ## References https://github.com/denji/golang-tls From af37c6715ad2e39c2bbb542730a39194341de423 Mon Sep 17 00:00:00 2001 From: Michelle Noorali Date: Thu, 24 May 2018 12:14:09 -0700 Subject: [PATCH 221/221] update security vulnerability email --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 34b4f8b16..868090005 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ The Kubernetes Helm project accepts contributions via GitHub pull requests. This Most of the time, when you find a bug in Helm, it should be reported using [GitHub issues](https://github.com/kubernetes/helm/issues). However, if you are reporting a _security vulnerability_, please email a report to -[helm-security@deis.com](mailto:helm-security@deis.com). This will give +[cncf-kubernetes-helm-security@lists.cncf.io](mailto:cncf-kubernetes-helm-security@lists.cncf.io). This will give us a chance to try to fix the issue before it is exploited in the wild. ## Contributor License Agreements