diff --git a/README.md b/README.md index 27da73961..4972e7b5b 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,9 @@ 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.4.1-darwin-amd64.tar.gz) -- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.4.1-linux-amd64.tar.gz) -- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.4.1-linux-386.tar.gz) +- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.4.2-darwin-amd64.tar.gz) +- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.4.2-linux-amd64.tar.gz) +- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.4.2-linux-386.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`. diff --git a/circle.yml b/circle.yml index fc9279ef3..5b30c8be4 100644 --- a/circle.yml +++ b/circle.yml @@ -3,7 +3,7 @@ machine: - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 environment: - GOVERSION: "1.8.1" + GOVERSION: "1.8.3" GOPATH: "${HOME}/.go_workspace" WORKDIR: "${GOPATH}/src/k8s.io/helm" PROJECT_NAME: "kubernetes-helm" diff --git a/cmd/helm/create_test.go b/cmd/helm/create_test.go index a49d3cfa9..d45843eda 100644 --- a/cmd/helm/create_test.go +++ b/cmd/helm/create_test.go @@ -87,7 +87,7 @@ func TestCreateStarterCmd(t *testing.T) { if err != nil { t.Fatal(err) } - old := helmpath.Home(environment.DefaultHelmHome()) + old := helmpath.Home(environment.DefaultHelmHome) settings.Home = thome defer func() { settings.Home = old diff --git a/cmd/helm/delete.go b/cmd/helm/delete.go index 2390573d9..67ab4379c 100755 --- a/cmd/helm/delete.go +++ b/cmd/helm/delete.go @@ -52,12 +52,12 @@ func newDeleteCmd(c helm.Interface, out io.Writer) *cobra.Command { } cmd := &cobra.Command{ - Use: "delete [flags] RELEASE_NAME [...]", - Aliases: []string{"del"}, - SuggestFor: []string{"remove", "rm"}, - Short: "given a release name, delete the release from Kubernetes", - Long: deleteDesc, - PersistentPreRunE: setupConnection, + Use: "delete [flags] RELEASE_NAME [...]", + Aliases: []string{"del"}, + SuggestFor: []string{"remove", "rm"}, + Short: "given a release name, delete the release from Kubernetes", + Long: deleteDesc, + PreRunE: 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/fetch_test.go b/cmd/helm/fetch_test.go index 3958a6e25..4d81ed38e 100644 --- a/cmd/helm/fetch_test.go +++ b/cmd/helm/fetch_test.go @@ -34,7 +34,7 @@ func TestFetchCmd(t *testing.T) { if err != nil { t.Fatal(err) } - old := helmpath.Home(environment.DefaultHelmHome()) + old := helmpath.Home(environment.DefaultHelmHome) settings.Home = hh defer func() { settings.Home = old diff --git a/cmd/helm/get.go b/cmd/helm/get.go index b540d24fe..fc5871f46 100644 --- a/cmd/helm/get.go +++ b/cmd/helm/get.go @@ -54,10 +54,10 @@ func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command { } cmd := &cobra.Command{ - Use: "get [flags] RELEASE_NAME", - Short: "download a named release", - Long: getHelp, - PersistentPreRunE: setupConnection, + Use: "get [flags] RELEASE_NAME", + Short: "download a named release", + Long: getHelp, + PreRunE: 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 ff5d3f130..7e08921ba 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -19,7 +19,6 @@ package main // import "k8s.io/helm/cmd/helm" import ( "errors" "fmt" - "io" "io/ioutil" "log" "os" @@ -40,23 +39,16 @@ import ( "k8s.io/helm/pkg/tlsutil" ) -const ( - localRepoIndexFilePath = "index.yaml" -) - var ( tlsCaCertFile string // path to TLS CA certificate file tlsCertFile string // path to TLS certificate file tlsKeyFile string // path to TLS key file tlsVerify bool // enable TLS and verify remote certificates tlsEnable bool // enable TLS -) -var ( - kubeContext string - settings helm_env.EnvSettings - // TODO refactor out this global var + kubeContext string tillerTunnel *kube.Tunnel + settings helm_env.EnvSettings ) var globalUsage = `The Kubernetes package manager @@ -83,34 +75,58 @@ Environment: $KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config") ` -func newRootCmd(out io.Writer) *cobra.Command { +func setFlagFromEnv(name, envar string, cmd *cobra.Command) { + if cmd.Flags().Changed(name) { + return + } + if v, ok := os.LookupEnv(envar); ok { + cmd.Flags().Set(name, v) + } +} + +func setFlagsFromEnv(flags map[string]string, cmd *cobra.Command) { + for name, envar := range flags { + setFlagFromEnv(name, envar, cmd) + } +} + +func addRootFlags(cmd *cobra.Command) { + pf := cmd.PersistentFlags() + pf.StringVar((*string)(&settings.Home), "home", helm_env.DefaultHelmHome, "location of your Helm config. Overrides $HELM_HOME") + pf.StringVar(&settings.TillerHost, "host", "", "address of tiller. Overrides $HELM_HOST") + pf.StringVar(&kubeContext, "kube-context", "", "name of the kubeconfig context to use") + pf.BoolVar(&settings.Debug, "debug", false, "enable verbose output") + pf.StringVar(&settings.TillerNamespace, "tiller-namespace", tiller_env.DefaultTillerNamespace, "namespace of tiller") +} + +func initRootFlags(cmd *cobra.Command) { + setFlagsFromEnv(map[string]string{ + "debug": helm_env.DebugEnvVar, + "home": helm_env.HomeEnvVar, + "host": helm_env.HostEnvVar, + "tiller-namespace": tiller_env.TillerNamespaceEnvVar, + }, cmd.Root()) + + tlsCaCertFile = os.ExpandEnv(tlsCaCertFile) + tlsCertFile = os.ExpandEnv(tlsCertFile) + tlsKeyFile = os.ExpandEnv(tlsKeyFile) +} + +func newRootCmd() *cobra.Command { cmd := &cobra.Command{ Use: "helm", Short: "The Helm package manager for Kubernetes.", Long: globalUsage, SilenceUsage: true, - PersistentPreRun: func(cmd *cobra.Command, args []string) { - tlsCaCertFile = os.ExpandEnv(tlsCaCertFile) - tlsCertFile = os.ExpandEnv(tlsCertFile) - tlsKeyFile = os.ExpandEnv(tlsKeyFile) + PersistentPreRun: func(cmd *cobra.Command, _ []string) { + initRootFlags(cmd) }, - PersistentPostRun: func(cmd *cobra.Command, args []string) { + PersistentPostRun: func(*cobra.Command, []string) { teardown() }, } - p := cmd.PersistentFlags() - p.StringVar((*string)(&settings.Home), "home", helm_env.DefaultHelmHome(), "location of your Helm config. Overrides $HELM_HOME") - p.StringVar(&settings.TillerHost, "host", helm_env.DefaultHelmHost(), "address of tiller. Overrides $HELM_HOST") - p.StringVar(&kubeContext, "kube-context", "", "name of the kubeconfig context to use") - p.BoolVar(&settings.Debug, "debug", false, "enable verbose output") - p.StringVar(&settings.TillerNamespace, "tiller-namespace", tiller_env.GetTillerNamespace(), "namespace of tiller") - - if os.Getenv(helm_env.PluginDisableEnvVar) != "1" { - settings.PlugDirs = os.Getenv(helm_env.PluginEnvVar) - if settings.PlugDirs == "" { - settings.PlugDirs = settings.Home.Plugins() - } - } + addRootFlags(cmd) + out := cmd.OutOrStdout() cmd.AddCommand( // chart commands @@ -163,7 +179,7 @@ func init() { } func main() { - cmd := newRootCmd(os.Stdout) + cmd := newRootCmd() if err := cmd.Execute(); err != nil { os.Exit(1) } diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index cf70b3f74..d3078dae0 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -23,6 +23,7 @@ import ( "io/ioutil" "math/rand" "os" + "path/filepath" "regexp" "sync" "testing" @@ -321,7 +322,7 @@ func ensureTestHome(home helmpath.Home, t *testing.T) error { } } - localRepoIndexFile := home.LocalRepository(localRepoIndexFilePath) + localRepoIndexFile := home.LocalRepository(localRepositoryIndexFile) if fi, err := os.Stat(localRepoIndexFile); err != nil { i := repo.NewIndexFile() if err := i.WriteFile(localRepoIndexFile, 0644); err != nil { @@ -337,3 +338,79 @@ func ensureTestHome(home helmpath.Home, t *testing.T) error { t.Logf("$HELM_HOME has been configured at %s.\n", settings.Home.String()) return nil } + +func TestRootCmd(t *testing.T) { + oldhome := os.Getenv("HELM_HOME") + defer os.Setenv("HELM_HOME", oldhome) + + tests := []struct { + name string + args []string + envars map[string]string + home string + }{ + { + name: "defaults", + args: []string{"home"}, + home: filepath.Join(os.Getenv("HOME"), "/.helm"), + }, + { + name: "with --home set", + args: []string{"--home", "/foo"}, + home: "/foo", + }, + { + name: "subcommands with --home set", + args: []string{"home", "--home", "/foo"}, + home: "/foo", + }, + { + name: "with $HELM_HOME set", + args: []string{"home"}, + envars: map[string]string{"HELM_HOME": "/bar"}, + home: "/bar", + }, + { + name: "subcommands with $HELM_HOME set", + args: []string{"home"}, + envars: map[string]string{"HELM_HOME": "/bar"}, + home: "/bar", + }, + { + name: "with $HELM_HOME and --home set", + args: []string{"home", "--home", "/foo"}, + envars: map[string]string{"HELM_HOME": "/bar"}, + home: "/foo", + }, + } + + // ensure not set locally + os.Unsetenv("HELM_HOME") + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + defer os.Unsetenv("HELM_HOME") + + for k, v := range tt.envars { + os.Setenv(k, v) + } + + cmd := newRootCmd() + cmd.SetOutput(ioutil.Discard) + cmd.SetArgs(tt.args) + cmd.Run = func(*cobra.Command, []string) {} + if err := cmd.Execute(); err != nil { + t.Errorf("unexpected error: %s", err) + } + + if settings.Home.String() != tt.home { + t.Errorf("expected home %q, got %q", tt.home, settings.Home) + } + homeFlag := cmd.Flag("home").Value.String() + homeFlag = os.ExpandEnv(homeFlag) + if homeFlag != tt.home { + t.Errorf("expected home %q, got %q", tt.home, homeFlag) + } + }) + } +} diff --git a/cmd/helm/history.go b/cmd/helm/history.go index 21c444dab..08f1656f5 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -56,11 +56,11 @@ func newHistoryCmd(c helm.Interface, w io.Writer) *cobra.Command { his := &historyCmd{out: w, helmc: c} cmd := &cobra.Command{ - Use: "history [flags] RELEASE_NAME", - Long: historyHelp, - Short: "fetch release history", - Aliases: []string{"hist"}, - PersistentPreRunE: setupConnection, + Use: "history [flags] RELEASE_NAME", + Long: historyHelp, + Short: "fetch release history", + Aliases: []string{"hist"}, + PreRunE: setupConnection, RunE: func(cmd *cobra.Command, args []string) error { switch { case len(args) == 0: diff --git a/cmd/helm/home.go b/cmd/helm/home.go index 25809b521..e96edd7a1 100644 --- a/cmd/helm/home.go +++ b/cmd/helm/home.go @@ -35,7 +35,7 @@ func newHomeCmd(out io.Writer) *cobra.Command { Long: longHomeHelp, Run: func(cmd *cobra.Command, args []string) { h := settings.Home - fmt.Fprintf(out, "%s\n", h) + fmt.Fprintln(out, h) if settings.Debug { fmt.Fprintf(out, "Repository: %s\n", h.Repository()) fmt.Fprintf(out, "RepositoryFile: %s\n", h.RepositoryFile()) @@ -47,6 +47,5 @@ func newHomeCmd(out io.Writer) *cobra.Command { } }, } - return cmd } diff --git a/cmd/helm/init.go b/cmd/helm/init.go index 9f4237af2..e915248d2 100644 --- a/cmd/helm/init.go +++ b/cmd/helm/init.go @@ -54,8 +54,9 @@ To dump a manifest containing the Tiller deployment YAML, combine the ` const ( - stableRepository = "stable" - localRepository = "local" + stableRepository = "stable" + localRepository = "local" + localRepositoryIndexFile = "index.yaml" ) var ( @@ -296,7 +297,7 @@ func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) err if err != nil { return err } - lr, err := initLocalRepo(home.LocalRepository(localRepoIndexFilePath), home.CacheIndex("local")) + lr, err := initLocalRepo(home.LocalRepository(localRepositoryIndexFile), home.CacheIndex("local")) if err != nil { return err } diff --git a/cmd/helm/init_test.go b/cmd/helm/init_test.go index 2d6c07320..e4622dad4 100644 --- a/cmd/helm/init_test.go +++ b/cmd/helm/init_test.go @@ -214,7 +214,7 @@ func TestEnsureHome(t *testing.T) { t.Errorf("%s should not be a directory", fi) } - if fi, err := os.Stat(hh.LocalRepository(localRepoIndexFilePath)); err != nil { + if fi, err := os.Stat(hh.LocalRepository(localRepositoryIndexFile)); err != nil { t.Errorf("%s", err) } else if fi.IsDir() { t.Errorf("%s should not be a directory", fi) diff --git a/cmd/helm/install.go b/cmd/helm/install.go index c51786f90..f438ebe04 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -148,10 +148,10 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command { } cmd := &cobra.Command{ - Use: "install [CHART]", - Short: "install a chart archive", - Long: installDesc, - PersistentPreRunE: setupConnection, + Use: "install [CHART]", + Short: "install a chart archive", + Long: installDesc, + PreRunE: 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/installer/install.go b/cmd/helm/installer/install.go index 12f026e5b..21010e0f3 100644 --- a/cmd/helm/installer/install.go +++ b/cmd/helm/installer/install.go @@ -166,6 +166,9 @@ func generateDeployment(opts *Options) *v1beta1.Deployment { }, }, HostNetwork: opts.EnableHostNetwork, + NodeSelector: map[string]string{ + "beta.kubernetes.io/os": "linux", + }, }, }, }, diff --git a/cmd/helm/list.go b/cmd/helm/list.go index 0919a1c3b..391e83e20 100644 --- a/cmd/helm/list.go +++ b/cmd/helm/list.go @@ -82,11 +82,11 @@ func newListCmd(client helm.Interface, out io.Writer) *cobra.Command { } cmd := &cobra.Command{ - Use: "list [flags] [FILTER]", - Short: "list releases", - Long: listHelp, - Aliases: []string{"ls"}, - PersistentPreRunE: setupConnection, + Use: "list [flags] [FILTER]", + Short: "list releases", + Long: listHelp, + Aliases: []string{"ls"}, + PreRunE: 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 af4e2f2bf..ee773cb4b 100644 --- a/cmd/helm/load_plugins.go +++ b/cmd/helm/load_plugins.go @@ -25,19 +25,10 @@ import ( "github.com/spf13/cobra" - "k8s.io/helm/pkg/helm/helmpath" + helm_env "k8s.io/helm/pkg/helm/environment" "k8s.io/helm/pkg/plugin" ) -const pluginEnvVar = "HELM_PLUGIN" - -func pluginDirs(home helmpath.Home) string { - if dirs := os.Getenv(pluginEnvVar); dirs != "" { - return dirs - } - return home.Plugins() -} - // loadPlugins loads plugins into the command list. // // This follows a different pattern than the other commands because it has @@ -46,16 +37,25 @@ func pluginDirs(home helmpath.Home) string { func loadPlugins(baseCmd *cobra.Command, out io.Writer) { // If HELM_NO_PLUGINS is set to 1, do not load plugins. - if settings.PlugDirs == "" { + if os.Getenv(helm_env.PluginDisableEnvVar) == "1" { return } - found, err := findPlugins(settings.PlugDirs) + found, err := findPlugins(settings.PluginDirs()) if err != nil { fmt.Fprintf(os.Stderr, "failed to load plugins: %s", err) return } + processParent := func(cmd *cobra.Command, args []string) ([]string, error) { + k, u := manuallyProcessArgs(args) + if err := cmd.Parent().ParseFlags(k); err != nil { + return nil, err + } + initRootFlags(cmd) + return u, nil + } + // Now we create commands for all of these. for _, plug := range found { plug := plug @@ -69,9 +69,8 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) { Short: md.Usage, Long: md.Description, RunE: func(cmd *cobra.Command, args []string) error { - - k, u := manuallyProcessArgs(args) - if err := cmd.Parent().ParseFlags(k); err != nil { + u, err := processParent(cmd, args) + if err != nil { return err } @@ -99,10 +98,9 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) { } if md.UseTunnel { - c.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { + c.PreRunE = func(cmd *cobra.Command, args []string) error { // Parse the parent flag, but not the local flags. - k, _ := manuallyProcessArgs(args) - if err := c.Parent().ParseFlags(k); err != nil { + if _, err := processParent(cmd, args); err != nil { return err } return setupConnection(cmd, args) diff --git a/cmd/helm/package.go b/cmd/helm/package.go index 9ca853ad3..e5ab3643d 100644 --- a/cmd/helm/package.go +++ b/cmd/helm/package.go @@ -30,6 +30,8 @@ import ( "golang.org/x/crypto/ssh/terminal" "k8s.io/helm/pkg/chartutil" + "k8s.io/helm/pkg/downloader" + "k8s.io/helm/pkg/getter" "k8s.io/helm/pkg/helm/helmpath" "k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/provenance" @@ -48,13 +50,14 @@ Versioned chart archives are used by Helm package repositories. ` type packageCmd struct { - save bool - sign bool - path string - key string - keyring string - version string - destination string + save bool + sign bool + path string + key string + keyring string + version string + destination string + dependencyUpdate bool out io.Writer home helmpath.Home @@ -99,6 +102,7 @@ func newPackageCmd(out io.Writer) *cobra.Command { f.StringVar(&pkg.keyring, "keyring", defaultKeyring(), "location of a public keyring") f.StringVar(&pkg.version, "version", "", "set the version on the chart to this semver version") f.StringVarP(&pkg.destination, "destination", "d", ".", "location to write the chart.") + f.BoolVarP(&pkg.dependencyUpdate, "dependency-update", "u", false, `update dependencies from "requirements.yaml" to dir "charts/" before packaging`) return cmd } @@ -109,6 +113,21 @@ func (p *packageCmd) run(cmd *cobra.Command, args []string) error { return err } + if p.dependencyUpdate { + downloadManager := &downloader.Manager{ + Out: p.out, + ChartPath: path, + HelmHome: settings.Home, + Keyring: p.keyring, + Getters: getter.All(settings), + Debug: settings.Debug, + } + + if err := downloadManager.Update(); err != nil { + return err + } + } + ch, err := chartutil.LoadDir(path) if err != nil { return err diff --git a/cmd/helm/plugin_list.go b/cmd/helm/plugin_list.go index 0bf9acbc8..e7618f38a 100644 --- a/cmd/helm/plugin_list.go +++ b/cmd/helm/plugin_list.go @@ -44,11 +44,8 @@ func newPluginListCmd(out io.Writer) *cobra.Command { } func (pcmd *pluginListCmd) run() error { - plugdirs := pluginDirs(pcmd.home) - - debug("pluginDirs: %s", plugdirs) - - plugins, err := findPlugins(plugdirs) + debug("pluginDirs: %s", settings.PluginDirs()) + plugins, err := findPlugins(settings.PluginDirs()) if err != nil { return err } diff --git a/cmd/helm/plugin_remove.go b/cmd/helm/plugin_remove.go index e7e522d51..83bc863bf 100644 --- a/cmd/helm/plugin_remove.go +++ b/cmd/helm/plugin_remove.go @@ -59,9 +59,8 @@ func (pcmd *pluginRemoveCmd) complete(args []string) error { } func (pcmd *pluginRemoveCmd) run() error { - plugdirs := pluginDirs(pcmd.home) - debug("loading installed plugins from %s", plugdirs) - plugins, err := findPlugins(plugdirs) + debug("loading installed plugins from %s", settings.PluginDirs()) + plugins, err := findPlugins(settings.PluginDirs()) if err != nil { return err } diff --git a/cmd/helm/plugin_test.go b/cmd/helm/plugin_test.go index 095de7063..77ef00c5d 100644 --- a/cmd/helm/plugin_test.go +++ b/cmd/helm/plugin_test.go @@ -23,6 +23,7 @@ import ( "strings" "testing" + helm_env "k8s.io/helm/pkg/helm/environment" "k8s.io/helm/pkg/helm/helmpath" "k8s.io/helm/pkg/plugin" @@ -71,7 +72,6 @@ func TestLoadPlugins(t *testing.T) { settings.Home = old }() hh := settings.Home - settings.PlugDirs = hh.Plugins() out := bytes.NewBuffer(nil) cmd := &cobra.Command{} @@ -139,12 +139,11 @@ func TestLoadPlugins(t *testing.T) { func TestLoadPlugins_HelmNoPlugins(t *testing.T) { // Set helm home to point to testdata old := settings.Home - oldPlugDirs := settings.PlugDirs settings.Home = "testdata/helmhome" - settings.PlugDirs = "" + os.Setenv(helm_env.PluginDisableEnvVar, "1") defer func() { settings.Home = old - settings.PlugDirs = oldPlugDirs + os.Unsetenv(helm_env.PluginDisableEnvVar) }() out := bytes.NewBuffer(nil) @@ -161,7 +160,6 @@ func TestSetupEnv(t *testing.T) { name := "pequod" settings.Home = helmpath.Home("testdata/helmhome") base := filepath.Join(settings.Home.Plugins(), name) - settings.PlugDirs = settings.Home.Plugins() settings.Debug = true defer func() { settings.Debug = false diff --git a/cmd/helm/plugin_update.go b/cmd/helm/plugin_update.go index e4fbe18df..2e19a2175 100644 --- a/cmd/helm/plugin_update.go +++ b/cmd/helm/plugin_update.go @@ -61,9 +61,8 @@ func (pcmd *pluginUpdateCmd) complete(args []string) error { func (pcmd *pluginUpdateCmd) run() error { installer.Debug = settings.Debug - plugdirs := pluginDirs(pcmd.home) - debug("loading installed plugins from %s", plugdirs) - plugins, err := findPlugins(plugdirs) + debug("loading installed plugins from %s", settings.PluginDirs()) + plugins, err := findPlugins(settings.PluginDirs()) if err != nil { return err } diff --git a/cmd/helm/release_testing.go b/cmd/helm/release_testing.go index a196f7809..1aadd4de3 100644 --- a/cmd/helm/release_testing.go +++ b/cmd/helm/release_testing.go @@ -48,10 +48,10 @@ func newReleaseTestCmd(c helm.Interface, out io.Writer) *cobra.Command { } cmd := &cobra.Command{ - Use: "test [RELEASE]", - Short: "test a release", - Long: releaseTestDesc, - PersistentPreRunE: setupConnection, + Use: "test [RELEASE]", + Short: "test a release", + Long: releaseTestDesc, + PreRunE: 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/repo_update.go b/cmd/helm/repo_update.go index 9ba42caf5..5e710a267 100644 --- a/cmd/helm/repo_update.go +++ b/cmd/helm/repo_update.go @@ -55,7 +55,7 @@ func newRepoUpdateCmd(out io.Writer) *cobra.Command { cmd := &cobra.Command{ Use: "update", Aliases: []string{"up"}, - Short: "update information on available charts in the chart repositories", + Short: "update information of available charts locally from chart repositories", Long: updateDesc, RunE: func(cmd *cobra.Command, args []string) error { u.home = settings.Home diff --git a/cmd/helm/reset.go b/cmd/helm/reset.go index 654765cd3..a8d4fa056 100644 --- a/cmd/helm/reset.go +++ b/cmd/helm/reset.go @@ -57,7 +57,7 @@ func newResetCmd(client helm.Interface, out io.Writer) *cobra.Command { Use: "reset", Short: "uninstalls Tiller from a cluster", Long: resetDesc, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + PreRunE: func(cmd *cobra.Command, args []string) error { if err := setupConnection(cmd, args); !d.force && err != nil { return err } diff --git a/cmd/helm/rollback.go b/cmd/helm/rollback.go index b6c031c56..95c27e2a5 100644 --- a/cmd/helm/rollback.go +++ b/cmd/helm/rollback.go @@ -30,7 +30,7 @@ const rollbackDesc = ` This command rolls back a release to a previous revision. The first argument of the rollback command is the name of a release, and the -second is a revision (version) number. To see revision numbers, run +second is a revision (version) number. To see revision numbers, run 'helm history RELEASE'. ` @@ -54,10 +54,10 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command { } cmd := &cobra.Command{ - Use: "rollback [flags] [RELEASE] [REVISION]", - Short: "roll back a release to a previous revision", - Long: rollbackDesc, - PersistentPreRunE: setupConnection, + Use: "rollback [flags] [RELEASE] [REVISION]", + Short: "roll back a release to a previous revision", + Long: rollbackDesc, + PreRunE: 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 b635e6186..36269c4b1 100644 --- a/cmd/helm/status.go +++ b/cmd/helm/status.go @@ -57,10 +57,10 @@ func newStatusCmd(client helm.Interface, out io.Writer) *cobra.Command { } cmd := &cobra.Command{ - Use: "status [flags] RELEASE_NAME", - Short: "displays the status of the named release", - Long: statusHelp, - PersistentPreRunE: setupConnection, + Use: "status [flags] RELEASE_NAME", + Short: "displays the status of the named release", + Long: statusHelp, + PreRunE: 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 3c0a780f1..3be680a9f 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -91,10 +91,10 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command { } cmd := &cobra.Command{ - Use: "upgrade [RELEASE] [CHART]", - Short: "upgrade a release", - Long: upgradeDesc, - PersistentPreRunE: setupConnection, + Use: "upgrade [RELEASE] [CHART]", + Short: "upgrade a release", + Long: upgradeDesc, + PreRunE: 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/docs/chart_best_practices/index.md b/docs/chart_best_practices/README.md similarity index 100% rename from docs/chart_best_practices/index.md rename to docs/chart_best_practices/README.md diff --git a/docs/chart_repository_faq.md b/docs/chart_repository_faq.md index e11194b23..78e47a461 100644 --- a/docs/chart_repository_faq.md +++ b/docs/chart_repository_faq.md @@ -10,6 +10,8 @@ send us a pull request. **Q: Why do I get a `unsupported protocol scheme ""` error when trying to fetch a chart from my custom repo?** -A: This is likely caused by you creating your chart repo index without specifying the `--url` flag. +A: (Helm < 2.5.0) This is likely caused by you creating your chart repo index without specifying the `--url` flag. Try recreating your `index.yaml` file with a command like `heml repo index --url http://my-repo/charts .`, and then re-uploading it to your custom charts repo. + +This behavior was changed in Helm 2.5.0. diff --git a/docs/chart_template_guide/named_templates.md b/docs/chart_template_guide/named_templates.md index daea98b19..1dc9c7618 100644 --- a/docs/chart_template_guide/named_templates.md +++ b/docs/chart_template_guide/named_templates.md @@ -170,87 +170,6 @@ metadata: Now `{{ .Chart.Name }}` resolves to `mychart`, and `{{ .Chart.Version }}` resolves to `0.1.0`. -## Creating override-able sections with `block` - -Say we want to create a template in our `_helpers.tpl` file, but then override part of its behavior in our template. This is what blocks are for. Sometimes we don't want to just insert a template with `template`, but we want to sketch out a default and let another template override our default. This makes it possible for one chart to define a base template, but allow another chart to strategically override some of its behavior. - -Blocks are declared like this: - -```yaml -{{ block "NAME" PIPELINE }} -{{ end }} -``` - -Here, "NAME" is the name that a `define` block can use to override it, and PIPELINE is the pipeline that will set the scope. So let's rewrite our `labels:` section to use this strategy. We'll create a basic labels section in our `_helpers.tpl` file, but add some extra labels in the `configmap.yaml` template. - -Let's start with `_helpers.tpl`: - -```yaml -{{- define "my_labels" }} - labels: - chart: {{ .Chart.Name }} - version: {{ .Chart.Version }} - {{ block "my_extra_labels" . }}extras: false{{ end }} -{{- end }} -``` - -Inside of our `my_labels` template, we now declare a block called `my_extra_labels`. By default, this section will have one extra label: `extras: false`. If we were to execute this using the same `configmap.yaml` file from last time, we'd get this: - -```yaml -# Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: tinseled-womba-configmap - labels: - chart: mychart - version: 0.1.0 - extras: false -data: - myvalue: "Hello World" - drink: "coffee" - food: "pizza" -``` - -But inside of our `configmap.yaml` template, we can override `my_extra_labels`: - -```yaml -{{- define "my_extra_labels" }}chart: {{ .Chart.Name }}{{ end -}} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap - {{- template "my_labels" . }} -data: - myvalue: "Hello World" - {{- range $key, $val := .Values.favorite }} - {{ $key }}: {{ $val | quote }} - {{- end }} -``` - -On the first line, we redefine `my_extra_labels` to include `chart: {{ .Chart.Name }}`. If we -run this, we will get: - -```yaml -# Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: ignorant-scorp-configmap - labels: - chart: mychart - version: 0.1.0 - chart: mychart -data: - myvalue: "Hello World" - drink: "coffee" - food: "pizza" -``` - -Gone is the `extras: false` section, since that part of the template is now overridden by our new template, which placed `chart: mychart` into the output. - -Blocks are not frequently used in Helm charts. But they do provide one mechanism for creating "abstract" charts, and then selectively overriding parts of the abstract template with concrete implementations. - ## The `include` function Say we've defined a simple template that looks like this: diff --git a/docs/chart_template_guide/subcharts_and_globals.md b/docs/chart_template_guide/subcharts_and_globals.md index 69d828c11..26e9a60cb 100644 --- a/docs/chart_template_guide/subcharts_and_globals.md +++ b/docs/chart_template_guide/subcharts_and_globals.md @@ -175,57 +175,33 @@ Globals are useful for passing information like this, though it does take some p ## Sharing Templates with Subcharts -Parent charts and subcharts can share templates. This can become very powerful when coupled with `block`s. For example, we can define a `block` in the `subchart` ConfigMap like this: +Parent charts and subcharts can share templates. Any defined block in any chart is +available to other charts. -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-cfgmap2 - {{block "labels" . }}from: mysubchart{{ end }} -data: - dessert: {{ .Values.dessert }} - salad: {{ .Values.global.salad }} -``` - -Running this would produce: - -```yaml -# Source: mychart/charts/mysubchart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: gaudy-mastiff-cfgmap2 - from: mysubchart -data: - dessert: ice cream - salad: caesar -``` - -Note that the `from:` line says `mysubchart`. In a previous section, we created `mychart/templates/_helpers.tpl`. Let's define a new named template there called `labels` to match the declaration on the block above. +For example, we can define a simple template like this: ```yaml {{- define "labels" }}from: mychart{{ end }} ``` -Recall how the labels on templates are _globally shared_. That means that if we create a block named `labels` in one chart, and then define an override named `labels` in another chart, the override will be applied. +Recall how the labels on templates are _globally shared_. Thus, the `labels` chart +can be included from any other chart. -Now if we do a `helm install --dry-run --debug mychart`, it will override the block: +While chart developers have a choice between `include` and `template`, one advantage +of using `include` is that `include` can dynamically reference templates: ```yaml -# Source: mychart/charts/mysubchart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: nasal-cheetah-cfgmap2 - from: mychart -data: - dessert: ice cream - salad: caesar +{{ include $mytemplate }} ``` -Now `from:` is set to `mychart` because the block was overridden. +The above will dereference `$mytemplate`. The `template` function, in contrast, +will only accept a string literal. + +## Avoid Using Blocks -Using this method, you can write flexible "base" charts that can be added as subcharts to many different charts, and which will support selective overriding using blocks. +The Go template language provides a `block` keyword that allows developers to provide +a default implementation which is overridden later. In Helm charts, blocks are not +the best tool for overriding because it if multiple implementations of the same block +are provided, the one selected is unpredictable. -This section of the guide has focused on subcharts. We've seen how to inherit values, how to use global values, and how to override templates with blocks. In the next section we will turn to debugging, and learn how to catch errors in templates. +The suggestion is to instead use `include`. diff --git a/docs/chart_tests.md b/docs/chart_tests.md index c0632c03c..4311ffaeb 100644 --- a/docs/chart_tests.md +++ b/docs/chart_tests.md @@ -1,6 +1,6 @@ # Chart Tests -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 charts works as expected when it is installed. These tests also help the chart consumer understand what your chart is supposed to do. +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 definiton must contain one of the helm test hook annotations: `helm.sh/hooks: test-success` or `helm.sh/hooks: test-failure`. @@ -17,12 +17,12 @@ You can run the pre-defined tests in Helm on a release using the command `helm t In Helm, there are two test hooks: `test-success` and `test-failure` -`test-success` indiciates that test pod should complete successfully. In other words, the containers in the pod should exit 0. -`test-failure` is a way to assert that a test pod should not complete successfully. If the containers in the pod do not exit 0, that indiciates success. +`test-success` indicates that test pod should complete successfully. In other words, the containers in the pod should exit 0. +`test-failure` is a way to assert that a test pod should not complete successfully. If the containers in the pod do not exit 0, that indicates success. ## Example Test -Here is an example of a helm test pod definition in an example maraidb chart: +Here is an example of a helm test pod definition in an example mariadb chart: ``` mariadb/ diff --git a/docs/charts.md b/docs/charts.md index d63df1720..071eb4980 100644 --- a/docs/charts.md +++ b/docs/charts.md @@ -234,11 +234,11 @@ team. In addition to the other fields above, each requirements entry may contain the optional field `alias`. -Adding an alias for a dependency chart would add another copy -of the chart as a new depdendency using alias as name of new dependency. +Adding an alias for a dependency chart would put +a chart in dependencies using alias as name of new dependency. -One can use `alias` in cases where they need multiple copies of same chart -as dependencies all independent of one another. +One can use `alias` in cases where they need to access a chart +with other name(s). ```` # parentchart/requirements.yaml @@ -246,16 +246,21 @@ dependencies: - name: subchart repository: http://localhost:10191 version: 0.1.0 - alias: - - one-more-subchart - - another-subchart + alias: new-subchart-1 + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + alias: new-subchart-2 + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 ```` In the above example we will get 3 depenendencies in all for `parentchart` ``` subchart -one-more-subchart -another-subchart +new-subchart-1 +new-subchart-2 ``` Manual way of achieving this is copy/pasting same chart in diff --git a/docs/charts_tips_and_tricks.md b/docs/charts_tips_and_tricks.md index 01d9ea83c..0ed1ab83e 100644 --- a/docs/charts_tips_and_tricks.md +++ b/docs/charts_tips_and_tricks.md @@ -78,7 +78,7 @@ Go provides a way for setting template options to control behavior when a map is indexed with a key that's not present in the map. This is typically set with template.Options("missingkey=option"), where option can be default, zero, or error. While setting this option to error will -stop execution with an arror, this would apply to every missing key in the +stop execution with an error, this would apply to every missing key in the map. There may be situations where a chart developer wants to enforce this behavior for select values in the values.yml file. diff --git a/docs/examples/alpine/README.md b/docs/examples/alpine/README.md index 3c32de5db..eb4fb9571 100644 --- a/docs/examples/alpine/README.md +++ b/docs/examples/alpine/README.md @@ -1,4 +1,4 @@ -#Alpine: A simple Helm chart +# Alpine: A simple Helm chart Run a single pod of Alpine Linux. diff --git a/docs/helm/helm.md b/docs/helm/helm.md index 4cc3289d3..4567049da 100644 --- a/docs/helm/helm.md +++ b/docs/helm/helm.md @@ -33,7 +33,7 @@ Environment: ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -66,4 +66,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 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_completion.md b/docs/helm/helm_completion.md index 7b63a91d8..4b7c540a1 100644 --- a/docs/helm/helm_completion.md +++ b/docs/helm/helm_completion.md @@ -25,7 +25,7 @@ helm completion SHELL ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -34,4 +34,4 @@ helm completion SHELL ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_create.md b/docs/helm/helm_create.md index 79704c3d1..8284be8ff 100644 --- a/docs/helm/helm_create.md +++ b/docs/helm/helm_create.md @@ -44,7 +44,7 @@ helm create NAME ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -53,4 +53,4 @@ helm create NAME ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_delete.md b/docs/helm/helm_delete.md index cee3bcb87..0d15b9d02 100644 --- a/docs/helm/helm_delete.md +++ b/docs/helm/helm_delete.md @@ -35,7 +35,7 @@ helm delete [flags] RELEASE_NAME [...] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -44,4 +44,4 @@ helm delete [flags] RELEASE_NAME [...] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_dependency.md b/docs/helm/helm_dependency.md index c824c73b3..629a27d38 100644 --- a/docs/helm/helm_dependency.md +++ b/docs/helm/helm_dependency.md @@ -58,7 +58,7 @@ for this case. ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -70,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 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_dependency_build.md b/docs/helm/helm_dependency_build.md index 2bd2cb3ed..9c5d6af78 100644 --- a/docs/helm/helm_dependency_build.md +++ b/docs/helm/helm_dependency_build.md @@ -31,7 +31,7 @@ helm dependency build [flags] CHART ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -40,4 +40,4 @@ helm dependency build [flags] CHART ### SEE ALSO * [helm dependency](helm_dependency.md) - manage a chart's dependencies -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_dependency_list.md b/docs/helm/helm_dependency_list.md index 57f89c20c..ec5e861fd 100644 --- a/docs/helm/helm_dependency_list.md +++ b/docs/helm/helm_dependency_list.md @@ -23,7 +23,7 @@ helm dependency list [flags] CHART ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -32,4 +32,4 @@ helm dependency list [flags] CHART ### SEE ALSO * [helm dependency](helm_dependency.md) - manage a chart's dependencies -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_dependency_update.md b/docs/helm/helm_dependency_update.md index 6c07aaf54..8fb8fd2d1 100644 --- a/docs/helm/helm_dependency_update.md +++ b/docs/helm/helm_dependency_update.md @@ -36,7 +36,7 @@ helm dependency update [flags] CHART ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -45,4 +45,4 @@ helm dependency update [flags] CHART ### SEE ALSO * [helm dependency](helm_dependency.md) - manage a chart's dependencies -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_fetch.md b/docs/helm/helm_fetch.md index b6a424569..a95781997 100644 --- a/docs/helm/helm_fetch.md +++ b/docs/helm/helm_fetch.md @@ -45,7 +45,7 @@ helm fetch [flags] [chart URL | repo/chartname] [...] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -54,4 +54,4 @@ helm fetch [flags] [chart URL | repo/chartname] [...] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_get.md b/docs/helm/helm_get.md index a8c3699a1..efa3c458a 100644 --- a/docs/helm/helm_get.md +++ b/docs/helm/helm_get.md @@ -37,7 +37,7 @@ helm get [flags] RELEASE_NAME ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -49,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 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_get_hooks.md b/docs/helm/helm_get_hooks.md index 9c15ab3dc..d2fad8b69 100644 --- a/docs/helm/helm_get_hooks.md +++ b/docs/helm/helm_get_hooks.md @@ -25,7 +25,7 @@ helm get hooks [flags] RELEASE_NAME ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -34,4 +34,4 @@ helm get hooks [flags] RELEASE_NAME ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_get_manifest.md b/docs/helm/helm_get_manifest.md index f4346ea9e..053ef652d 100644 --- a/docs/helm/helm_get_manifest.md +++ b/docs/helm/helm_get_manifest.md @@ -27,7 +27,7 @@ helm get manifest [flags] RELEASE_NAME ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -36,4 +36,4 @@ helm get manifest [flags] RELEASE_NAME ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_get_values.md b/docs/helm/helm_get_values.md index f86b7e574..5cdcbd7d2 100644 --- a/docs/helm/helm_get_values.md +++ b/docs/helm/helm_get_values.md @@ -24,7 +24,7 @@ helm get values [flags] RELEASE_NAME ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -33,4 +33,4 @@ helm get values [flags] RELEASE_NAME ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_history.md b/docs/helm/helm_history.md index e735a1f1c..590c8a684 100644 --- a/docs/helm/helm_history.md +++ b/docs/helm/helm_history.md @@ -40,7 +40,7 @@ helm history [flags] RELEASE_NAME ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -49,4 +49,4 @@ helm history [flags] RELEASE_NAME ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_home.md b/docs/helm/helm_home.md index b2b37b0b4..683142f71 100644 --- a/docs/helm/helm_home.md +++ b/docs/helm/helm_home.md @@ -18,7 +18,7 @@ helm home ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -27,4 +27,4 @@ helm home ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_init.md b/docs/helm/helm_init.md index 5329fde3b..2d498c554 100644 --- a/docs/helm/helm_init.md +++ b/docs/helm/helm_init.md @@ -54,7 +54,7 @@ helm init ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -63,4 +63,4 @@ helm init ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_inspect.md b/docs/helm/helm_inspect.md index 9b72f646d..30f09a72f 100644 --- a/docs/helm/helm_inspect.md +++ b/docs/helm/helm_inspect.md @@ -32,7 +32,7 @@ helm inspect [CHART] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -43,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 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_inspect_chart.md b/docs/helm/helm_inspect_chart.md index 178702d7b..5e49e282b 100644 --- a/docs/helm/helm_inspect_chart.md +++ b/docs/helm/helm_inspect_chart.md @@ -30,7 +30,7 @@ helm inspect chart [CHART] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -39,4 +39,4 @@ helm inspect chart [CHART] ### SEE ALSO * [helm inspect](helm_inspect.md) - inspect a chart -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_inspect_values.md b/docs/helm/helm_inspect_values.md index e388e3c7a..f49215975 100644 --- a/docs/helm/helm_inspect_values.md +++ b/docs/helm/helm_inspect_values.md @@ -30,7 +30,7 @@ helm inspect values [CHART] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -39,4 +39,4 @@ helm inspect values [CHART] ### SEE ALSO * [helm inspect](helm_inspect.md) - inspect a chart -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_install.md b/docs/helm/helm_install.md index 859df2ef1..f8e0885ff 100644 --- a/docs/helm/helm_install.md +++ b/docs/helm/helm_install.md @@ -97,7 +97,7 @@ helm install [CHART] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -106,4 +106,4 @@ helm install [CHART] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_lint.md b/docs/helm/helm_lint.md index a7fad58d1..61e6737c4 100644 --- a/docs/helm/helm_lint.md +++ b/docs/helm/helm_lint.md @@ -28,7 +28,7 @@ helm lint [flags] PATH ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -37,4 +37,4 @@ helm lint [flags] PATH ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_list.md b/docs/helm/helm_list.md index 5ccfdfdca..a69f5ba2c 100644 --- a/docs/helm/helm_list.md +++ b/docs/helm/helm_list.md @@ -61,7 +61,7 @@ helm list [flags] [FILTER] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -70,4 +70,4 @@ helm list [flags] [FILTER] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_package.md b/docs/helm/helm_package.md index a7b69f6b9..595ec5564 100644 --- a/docs/helm/helm_package.md +++ b/docs/helm/helm_package.md @@ -23,6 +23,7 @@ helm package [flags] [CHART_PATH] [...] ### Options ``` + -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") @@ -35,7 +36,7 @@ helm package [flags] [CHART_PATH] [...] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -44,4 +45,4 @@ helm package [flags] [CHART_PATH] [...] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 5-Jun-2017 diff --git a/docs/helm/helm_plugin.md b/docs/helm/helm_plugin.md index d4d0ee08b..b38f3e013 100644 --- a/docs/helm/helm_plugin.md +++ b/docs/helm/helm_plugin.md @@ -13,7 +13,7 @@ Manage client-side Helm plugins. ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -26,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 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_plugin_install.md b/docs/helm/helm_plugin_install.md index 13581c055..7b4f8904e 100644 --- a/docs/helm/helm_plugin_install.md +++ b/docs/helm/helm_plugin_install.md @@ -21,7 +21,7 @@ helm plugin install [options] ... ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -30,4 +30,4 @@ helm plugin install [options] ... ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_plugin_list.md b/docs/helm/helm_plugin_list.md index 4448a5a04..53f37b8d0 100644 --- a/docs/helm/helm_plugin_list.md +++ b/docs/helm/helm_plugin_list.md @@ -15,7 +15,7 @@ helm plugin list ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -24,4 +24,4 @@ helm plugin list ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_plugin_remove.md b/docs/helm/helm_plugin_remove.md index 4ae04b286..0559f395c 100644 --- a/docs/helm/helm_plugin_remove.md +++ b/docs/helm/helm_plugin_remove.md @@ -15,7 +15,7 @@ helm plugin remove ... ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -24,4 +24,4 @@ helm plugin remove ... ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_plugin_update.md b/docs/helm/helm_plugin_update.md index 6f59cd4b2..c0dac090a 100644 --- a/docs/helm/helm_plugin_update.md +++ b/docs/helm/helm_plugin_update.md @@ -15,7 +15,7 @@ helm plugin update ... ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -24,4 +24,4 @@ helm plugin update ... ### SEE ALSO * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_repo.md b/docs/helm/helm_repo.md index d0d015569..3378a1850 100644 --- a/docs/helm/helm_repo.md +++ b/docs/helm/helm_repo.md @@ -17,7 +17,7 @@ Example usage: ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -29,6 +29,6 @@ Example usage: * [helm repo index](helm_repo_index.md) - generate an index file given a directory containing packaged charts * [helm repo list](helm_repo_list.md) - list chart repositories * [helm repo remove](helm_repo_remove.md) - remove a chart repository -* [helm repo update](helm_repo_update.md) - update information on available charts in the chart repositories +* [helm repo update](helm_repo_update.md) - update information of available charts locally from chart repositories -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_repo_add.md b/docs/helm/helm_repo_add.md index c7b2a41ef..f7f3e8727 100644 --- a/docs/helm/helm_repo_add.md +++ b/docs/helm/helm_repo_add.md @@ -24,7 +24,7 @@ helm repo add [flags] [NAME] [URL] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -33,4 +33,4 @@ helm repo add [flags] [NAME] [URL] ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_repo_index.md b/docs/helm/helm_repo_index.md index 7a33052a3..79c8ee608 100644 --- a/docs/helm/helm_repo_index.md +++ b/docs/helm/helm_repo_index.md @@ -31,7 +31,7 @@ helm repo index [flags] [DIR] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -40,4 +40,4 @@ helm repo index [flags] [DIR] ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_repo_list.md b/docs/helm/helm_repo_list.md index 7966592cb..4f8f2e1dd 100644 --- a/docs/helm/helm_repo_list.md +++ b/docs/helm/helm_repo_list.md @@ -15,7 +15,7 @@ helm repo list [flags] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -24,4 +24,4 @@ helm repo list [flags] ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_repo_remove.md b/docs/helm/helm_repo_remove.md index 705fd8e89..075b15fce 100644 --- a/docs/helm/helm_repo_remove.md +++ b/docs/helm/helm_repo_remove.md @@ -15,7 +15,7 @@ helm repo remove [flags] [NAME] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -24,4 +24,4 @@ helm repo remove [flags] [NAME] ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_repo_update.md b/docs/helm/helm_repo_update.md index b54ad3dda..3758f822f 100644 --- a/docs/helm/helm_repo_update.md +++ b/docs/helm/helm_repo_update.md @@ -1,6 +1,6 @@ ## helm repo update -update information on available charts in the chart repositories +update information of available charts locally from chart repositories ### Synopsis @@ -21,7 +21,7 @@ helm repo update ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -30,4 +30,4 @@ helm repo update ### SEE ALSO * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_reset.md b/docs/helm/helm_reset.md index 1d6fea9c9..bc3299d48 100644 --- a/docs/helm/helm_reset.md +++ b/docs/helm/helm_reset.md @@ -31,7 +31,7 @@ helm reset ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -40,4 +40,4 @@ helm reset ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_rollback.md b/docs/helm/helm_rollback.md index 7e59a67c8..3a3ed1a24 100644 --- a/docs/helm/helm_rollback.md +++ b/docs/helm/helm_rollback.md @@ -9,7 +9,7 @@ roll back a release to a previous revision This command rolls back a release to a previous revision. The first argument of the rollback command is the name of a release, and the -second is a revision (version) number. To see revision numbers, run +second is a revision (version) number. To see revision numbers, run 'helm history RELEASE'. @@ -37,7 +37,7 @@ helm rollback [flags] [RELEASE] [REVISION] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -46,4 +46,4 @@ helm rollback [flags] [RELEASE] [REVISION] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_search.md b/docs/helm/helm_search.md index 68f2f16be..48579c5b8 100644 --- a/docs/helm/helm_search.md +++ b/docs/helm/helm_search.md @@ -28,7 +28,7 @@ helm search [keyword] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -37,4 +37,4 @@ helm search [keyword] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_serve.md b/docs/helm/helm_serve.md index 71aaf26c5..1a317e9e4 100644 --- a/docs/helm/helm_serve.md +++ b/docs/helm/helm_serve.md @@ -36,7 +36,7 @@ helm serve ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -45,4 +45,4 @@ helm serve ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_status.md b/docs/helm/helm_status.md index 62a99796c..a737d7a64 100644 --- a/docs/helm/helm_status.md +++ b/docs/helm/helm_status.md @@ -35,7 +35,7 @@ helm status [flags] RELEASE_NAME ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -44,4 +44,4 @@ helm status [flags] RELEASE_NAME ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_test.md b/docs/helm/helm_test.md index 578737578..8d7b39a59 100644 --- a/docs/helm/helm_test.md +++ b/docs/helm/helm_test.md @@ -32,7 +32,7 @@ helm test [RELEASE] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -41,4 +41,4 @@ helm test [RELEASE] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_upgrade.md b/docs/helm/helm_upgrade.md index c36c3ae5a..1fbefcba3 100644 --- a/docs/helm/helm_upgrade.md +++ b/docs/helm/helm_upgrade.md @@ -67,7 +67,7 @@ helm upgrade [RELEASE] [CHART] ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -76,4 +76,4 @@ helm upgrade [RELEASE] [CHART] ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_verify.md b/docs/helm/helm_verify.md index 83c33844b..10ddab059 100644 --- a/docs/helm/helm_verify.md +++ b/docs/helm/helm_verify.md @@ -30,7 +30,7 @@ helm verify [flags] PATH ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -39,4 +39,4 @@ helm verify [flags] PATH ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/helm/helm_version.md b/docs/helm/helm_version.md index f0aa4f8ca..16e2f5b92 100644 --- a/docs/helm/helm_version.md +++ b/docs/helm/helm_version.md @@ -44,7 +44,7 @@ helm version ``` --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") + --home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.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") @@ -53,4 +53,4 @@ helm version ### SEE ALSO * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 26-May-2017 +###### Auto generated by spf13/cobra on 29-May-2017 diff --git a/docs/man/man1/helm_repo_update.1 b/docs/man/man1/helm_repo_update.1 index 2c0b9d338..42bf511dd 100644 --- a/docs/man/man1/helm_repo_update.1 +++ b/docs/man/man1/helm_repo_update.1 @@ -5,7 +5,7 @@ .SH NAME .PP -helm\-repo\-update \- update information on available charts in the chart repositories +helm\-repo\-update \- update information of available charts locally from chart repositories .SH SYNOPSIS diff --git a/docs/related.md b/docs/related.md index 6e5b267bf..4787bc7cd 100644 --- a/docs/related.md +++ b/docs/related.md @@ -54,6 +54,7 @@ Tools layered on top of Helm or Tiller. - [Cog](https://github.com/ohaiwalt/cog-helm) - Helm chart to deploy Cog on Kubernetes - [Monocular](https://github.com/helm/monocular) - Web UI for Helm Chart repositories - [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. ## Helm Included diff --git a/docs/using_helm.md b/docs/using_helm.md index ef7753101..e6b1b2b65 100755 --- a/docs/using_helm.md +++ b/docs/using_helm.md @@ -215,12 +215,13 @@ You can then override any of these settings in a YAML formatted file, and then pass that file during installation. ```console -$ echo 'mariadbUser: user0' > config.yaml +$ echo '{mariadbUser: user0, mariadbDatabase: user0db}' > config.yaml $ helm install -f config.yaml stable/mariadb ``` -The above will set the default MariaDB user to `user0`, but accept all -the rest of the defaults for that chart. +The above will create a default MariaDB user with the name `user0`, and +grant this user access to a newly created `user0db` database, but will +accept all the rest of the defaults for that chart. There are two ways to pass configuration data during install: @@ -355,7 +356,7 @@ is not a full list of cli flags. To see a description of all flags, just run This defaults to 300 (5 minutes) - `--wait`: Waits until all Pods are in a ready state, PVCs are bound, Deployments have minimum (`Desired` minus `maxUnavailable`) Pods in ready state and - Services have and IP address (and Ingress if a `LoadBalancer`) before + Services have an IP address (and Ingress if a `LoadBalancer`) before marking the release as successful. It will wait for as long as the `--timeout` value. If timeout is reached, the release will be marked as `FAILED`. @@ -473,6 +474,15 @@ Note: The `stable` repository is managed on the [Kubernetes Charts GitHub repository](https://github.com/kubernetes/charts). That project accepts chart source code, and (after audit) packages those for you. +## Tiller, Namespaces and RBAC +In some cases you may wish to scope Tiller or deploy multiple Tillers to a single cluster. Here are some best practices when operating in those circumstances. + +1. Tiller can be [installed](install.md) into any namespace. By default, it is installed into kube-system. You can run multiple Tillers provided they each run in their own namespace. +2. Limiting Tiller to only be able to install into specific namespaces and/or resource types is controlled by Kubernetes [RBAC](https://kubernetes.io/docs/admin/authorization/rbac/) roles and rolebindings. +3. Release names are unique PER TILLER INSTANCE. +4. Charts should only contain resources that exist in a single namespace. +5. It is not recommended to have multiple Tillers configured to manage resources in the same namespace. + ## Conclusion This chapter has covered the basic usage patterns of the `helm` client, diff --git a/pkg/chartutil/requirements.go b/pkg/chartutil/requirements.go index 5a7f5fe78..fbd686b91 100644 --- a/pkg/chartutil/requirements.go +++ b/pkg/chartutil/requirements.go @@ -66,7 +66,7 @@ type Dependency struct { // string or pair of child/parent sublist items. ImportValues []interface{} `json:"import-values"` // Alias usable alias to be used for the chart - Alias []string `json:"alias"` + Alias string `json:"alias"` } // ErrNoRequirementsFile to detect error condition @@ -218,7 +218,7 @@ func ProcessRequirementsTags(reqs *Requirements, cvals Values) { } -func copyChartAsAlias(charts []*chart.Chart, dependentChart, aliasChart string) *chart.Chart { +func getAliasDependency(charts []*chart.Chart, aliasChart *Dependency) *chart.Chart { var chartFound chart.Chart for _, existingChart := range charts { if existingChart == nil { @@ -227,13 +227,17 @@ func copyChartAsAlias(charts []*chart.Chart, dependentChart, aliasChart string) if existingChart.Metadata == nil { continue } - if existingChart.Metadata.Name != dependentChart { + if existingChart.Metadata.Name != aliasChart.Name { + continue + } + if existingChart.Metadata.Version != aliasChart.Version { continue } - chartFound = *existingChart newMetadata := *existingChart.Metadata - newMetadata.Name = aliasChart + if aliasChart.Alias != "" { + newMetadata.Name = aliasChart.Alias + } chartFound.Metadata = &newMetadata return &chartFound } @@ -253,19 +257,16 @@ func ProcessRequirementsEnabled(c *chart.Chart, v *chart.Config) error { return nil } + var chartDependencies []*chart.Chart for _, req := range reqs.Dependencies { - for _, alias := range req.Alias { - aliasDependency := copyChartAsAlias(c.Dependencies, req.Name, alias) - if aliasDependency == nil { - break - } - c.Dependencies = append(c.Dependencies, aliasDependency) - origReqName := req.Name - req.Name = alias - reqs.Dependencies = append(reqs.Dependencies, req) - req.Name = origReqName + if chartDependency := getAliasDependency(c.Dependencies, req); chartDependency != nil { + chartDependencies = append(chartDependencies, chartDependency) + } + if req.Alias != "" { + req.Name = req.Alias } } + c.Dependencies = chartDependencies // set all to true for _, lr := range reqs.Dependencies { @@ -361,22 +362,17 @@ func getParents(c *chart.Chart, out []*chart.Chart) []*chart.Chart { } // processImportValues merges values from child to parent based on the chart's dependencies' ImportValues field. -func processImportValues(c *chart.Chart, v *chart.Config) error { +func processImportValues(c *chart.Chart) error { reqs, err := LoadRequirements(c) if err != nil { return err } - // combine chart values and its dependencies' values - cvals, err := CoalesceValues(c, v) + // combine chart values and empty config to get Values + cvals, err := CoalesceValues(c, &chart.Config{}) if err != nil { return err } - nv := v.GetValues() - b := make(map[string]interface{}, len(nv)) - // convert values to map - for kk, vvv := range nv { - b[kk] = vvv - } + b := make(map[string]interface{}, 0) // import values from each dependency if specified in import-values for _, r := range reqs.Dependencies { if len(r.ImportValues) > 0 { @@ -431,10 +427,10 @@ func processImportValues(c *chart.Chart, v *chart.Config) error { } // ProcessRequirementsImportValues imports specified chart values from child to parent. -func ProcessRequirementsImportValues(c *chart.Chart, v *chart.Config) error { +func ProcessRequirementsImportValues(c *chart.Chart) error { pc := getParents(c, nil) for i := len(pc) - 1; i >= 0; i-- { - processImportValues(pc[i], v) + processImportValues(pc[i]) } return nil diff --git a/pkg/chartutil/requirements_test.go b/pkg/chartutil/requirements_test.go index f67bea46e..65d59e52f 100644 --- a/pkg/chartutil/requirements_test.go +++ b/pkg/chartutil/requirements_test.go @@ -282,7 +282,7 @@ func TestProcessRequirementsImportValues(t *testing.T) { } func verifyRequirementsImportValues(t *testing.T, c *chart.Chart, v *chart.Config, e map[string]string) { - err := ProcessRequirementsImportValues(c, v) + err := ProcessRequirementsImportValues(c) if err != nil { t.Errorf("Error processing import values requirements %v", err) } @@ -321,22 +321,36 @@ func verifyRequirementsImportValues(t *testing.T, c *chart.Chart, v *chart.Confi } } -func TestCopyChartAsAlias(t *testing.T) { +func TestGetAliasDependency(t *testing.T) { c, err := Load("testdata/frobnitz") if err != nil { t.Fatalf("Failed to load testdata: %s", err) } - - if aliasChart := copyChartAsAlias(c.Dependencies, "mariners", "another-mariner"); aliasChart != nil { - t.Fatalf("expected no chart but got %s", aliasChart.Metadata.Name) + req, err := LoadRequirements(c) + if err != nil { + t.Fatalf("Failed to load requirement for testdata: %s", err) + } + if len(req.Dependencies) == 0 { + t.Fatalf("There are no requirements to test") } - aliasChart := copyChartAsAlias(c.Dependencies, "mariner", "another-mariner") + // Success case + aliasChart := getAliasDependency(c.Dependencies, req.Dependencies[0]) if aliasChart == nil { - t.Fatal("Failed to find dependent chart") + t.Fatalf("Failed to get dependency chart for alias %s", req.Dependencies[0].Name) + } + if req.Dependencies[0].Alias != "" { + if aliasChart.Metadata.Name != req.Dependencies[0].Alias { + t.Fatalf("Dependency chart name should be %s but got %s", req.Dependencies[0].Alias, aliasChart.Metadata.Name) + } + } else if aliasChart.Metadata.Name != req.Dependencies[0].Name { + t.Fatalf("Dependency chart name should be %s but got %s", req.Dependencies[0].Name, aliasChart.Metadata.Name) } - if aliasChart.Metadata.Name != "another-mariner" { - t.Fatal(`Failed to update chart-name for alias "dependent chart`) + + // Failure case + req.Dependencies[0].Name = "something-else" + if aliasChart := getAliasDependency(c.Dependencies, req.Dependencies[0]); aliasChart != nil { + t.Fatalf("expected no chart but got %s", aliasChart.Metadata.Name) } } @@ -364,15 +378,15 @@ func TestDependentChartAliases(t *testing.T) { t.Fatalf("Cannot load requirements for test chart, %v", err) } - var expectedDependencyCharts int - for _, reqmt := range reqmts.Dependencies { - expectedDependencyCharts++ - if len(reqmt.Alias) >= 0 { - expectedDependencyCharts += len(reqmt.Alias) - } - } - if len(c.Dependencies) != expectedDependencyCharts { - t.Fatalf("Expected number of chart dependencies %d, but got %d", expectedDependencyCharts, len(c.Dependencies)) + // var expectedDependencyCharts int + // for _, reqmt := range reqmts.Dependencies { + // expectedDependencyCharts++ + // if len(reqmt.Alias) >= 0 { + // expectedDependencyCharts += len(reqmt.Alias) + // } + // } + if len(c.Dependencies) != len(reqmts.Dependencies) { + t.Fatalf("Expected number of chart dependencies %d, but got %d", len(reqmts.Dependencies), len(c.Dependencies)) } } diff --git a/pkg/chartutil/testdata/dependent-chart-alias/requirements.yaml b/pkg/chartutil/testdata/dependent-chart-alias/requirements.yaml index 2e41105c7..aab6cddf7 100644 --- a/pkg/chartutil/testdata/dependent-chart-alias/requirements.yaml +++ b/pkg/chartutil/testdata/dependent-chart-alias/requirements.yaml @@ -5,6 +5,8 @@ dependencies: - name: mariner version: "4.3.2" repository: https://example.com/charts - alias: - - mariners1 - - mariners2 + alias: mariners2 + - name: mariner + version: "4.3.2" + repository: https://example.com/charts + alias: mariners1 diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go index 122d0b125..15e97f6a1 100644 --- a/pkg/downloader/chart_downloader.go +++ b/pkg/downloader/chart_downloader.go @@ -215,6 +215,12 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, ge 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() { + u, err = url.Parse(rc.URL + "/" + u.Path) + return u, r.Client, err + } + return u, r.Client, nil } diff --git a/pkg/downloader/chart_downloader_test.go b/pkg/downloader/chart_downloader_test.go index c50c905b1..4049b7979 100644 --- a/pkg/downloader/chart_downloader_test.go +++ b/pkg/downloader/chart_downloader_test.go @@ -42,6 +42,7 @@ func TestResolveChartRef(t *testing.T) { {name: "full URL, with authentication", ref: "http://username:password@example.com/foo-1.2.3.tgz", expect: "http://username:password@example.com/foo-1.2.3.tgz"}, {name: "reference, testing repo", ref: "testing/alpine", expect: "http://example.com/alpine-1.2.3.tgz"}, {name: "reference, version, testing repo", ref: "testing/alpine", version: "0.2.0", expect: "http://example.com/alpine-0.2.0.tgz"}, + {name: "reference, version, malformed repo", ref: "malformed/alpine", version: "1.2.3", expect: "http://dl.example.com/alpine-1.2.3.tgz"}, {name: "full URL, HTTPS, irrelevant version", ref: "https://example.com/foo-1.2.3.tgz", version: "0.1.0", expect: "https://example.com/foo-1.2.3.tgz", fail: true}, {name: "full URL, file", ref: "file:///foo-1.2.3.tgz", fail: true}, {name: "invalid", ref: "invalid-1.2.3", fail: true}, diff --git a/pkg/downloader/testdata/helmhome/repository/cache/malformed-index.yaml b/pkg/downloader/testdata/helmhome/repository/cache/malformed-index.yaml new file mode 100644 index 000000000..1956e9f83 --- /dev/null +++ b/pkg/downloader/testdata/helmhome/repository/cache/malformed-index.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +entries: + alpine: + - name: alpine + urls: + - alpine-1.2.3.tgz + checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d + home: https://k8s.io/helm + sources: + - https://github.com/kubernetes/helm + version: 1.2.3 + description: Deploy a basic Alpine Linux pod + keywords: [] + maintainers: [] + engine: "" + icon: "" diff --git a/pkg/downloader/testdata/helmhome/repository/repositories.yaml b/pkg/downloader/testdata/helmhome/repository/repositories.yaml index 200f370bd..9b0cfe972 100644 --- a/pkg/downloader/testdata/helmhome/repository/repositories.yaml +++ b/pkg/downloader/testdata/helmhome/repository/repositories.yaml @@ -8,3 +8,5 @@ repositories: url: "http://username:password@example.com" - name: kubernetes-charts url: "http://example.com/charts" + - name: malformed + url: "http://dl.example.com" diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 85b6bd30d..3d348fb41 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -20,6 +20,7 @@ import ( "bytes" "fmt" "path" + "sort" "strings" "text/template" @@ -181,8 +182,14 @@ func (e *Engine) render(tpls map[string]renderable) (map[string]string, error) { funcMap := e.alterFuncMap(t) + // We want to parse the templates in a predictable order. The order favors + // higher-level (in file system) templates over deeply nested templates. + keys := sortTemplates(tpls) + files := []string{} - for fname, r := range tpls { + //for fname, r := range tpls { + for _, fname := range keys { + r := tpls[fname] t = t.New(fname).Funcs(funcMap) if _, err := t.Parse(r.tpl); err != nil { return map[string]string{}, fmt.Errorf("parse error in %q: %s", fname, err) @@ -215,6 +222,30 @@ func (e *Engine) render(tpls map[string]renderable) (map[string]string, error) { return rendered, nil } +func sortTemplates(tpls map[string]renderable) []string { + keys := make([]string, len(tpls)) + i := 0 + for key := range tpls { + keys[i] = key + i++ + } + sort.Sort(sort.Reverse(byPathLen(keys))) + return keys +} + +type byPathLen []string + +func (p byPathLen) Len() int { return len(p) } +func (p byPathLen) Swap(i, j int) { p[j], p[i] = p[i], p[j] } +func (p byPathLen) Less(i, j int) bool { + a, b := p[i], p[j] + ca, cb := strings.Count(a, "/"), strings.Count(b, "/") + if ca == cb { + return strings.Compare(a, b) == -1 + } + return ca < cb +} + // allTemplates returns all templates for a chart and its dependencies. // // As it goes, it also prepares the values in a scope-sensitive manner. diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index f821b2de5..88118c420 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -27,6 +27,37 @@ import ( "github.com/golang/protobuf/ptypes/any" ) +func TestSortTemplates(t *testing.T) { + tpls := map[string]renderable{ + "/mychart/templates/foo.tpl": {}, + "/mychart/templates/charts/foo/charts/bar/templates/foo.tpl": {}, + "/mychart/templates/bar.tpl": {}, + "/mychart/templates/charts/foo/templates/bar.tpl": {}, + "/mychart/templates/_foo.tpl": {}, + "/mychart/templates/charts/foo/templates/foo.tpl": {}, + "/mychart/templates/charts/bar/templates/foo.tpl": {}, + } + got := sortTemplates(tpls) + if len(got) != len(tpls) { + t.Fatal("Sorted results are missing templates") + } + + expect := []string{ + "/mychart/templates/charts/foo/charts/bar/templates/foo.tpl", + "/mychart/templates/charts/foo/templates/foo.tpl", + "/mychart/templates/charts/foo/templates/bar.tpl", + "/mychart/templates/charts/bar/templates/foo.tpl", + "/mychart/templates/foo.tpl", + "/mychart/templates/bar.tpl", + "/mychart/templates/_foo.tpl", + } + for i, e := range expect { + if got[i] != e { + t.Errorf("expected %q, got %q at index %d\n\tExp: %#v\n\tGot: %#v", e, got[i], i, expect, got) + } + } +} + func TestEngine(t *testing.T) { e := New() diff --git a/pkg/getter/plugingetter.go b/pkg/getter/plugingetter.go index ff893421e..c747eef7f 100644 --- a/pkg/getter/plugingetter.go +++ b/pkg/getter/plugingetter.go @@ -29,7 +29,7 @@ import ( // collectPlugins scans for getter plugins. // This will load plugins according to the environment. func collectPlugins(settings environment.EnvSettings) (Providers, error) { - plugins, err := plugin.FindPlugins(settings.PlugDirs) + plugins, err := plugin.FindPlugins(settings.PluginDirs()) if err != nil { return nil, err } diff --git a/pkg/getter/plugingetter_test.go b/pkg/getter/plugingetter_test.go index 27079351a..f1fe9bf29 100644 --- a/pkg/getter/plugingetter_test.go +++ b/pkg/getter/plugingetter_test.go @@ -32,9 +32,8 @@ func hh(debug bool) environment.EnvSettings { } hp := helmpath.Home(apath) return environment.EnvSettings{ - Home: hp, - PlugDirs: hp.Plugins(), - Debug: debug, + Home: hp, + Debug: debug, } } diff --git a/pkg/helm/client.go b/pkg/helm/client.go index a921a548d..7e41b89bc 100644 --- a/pkg/helm/client.go +++ b/pkg/helm/client.go @@ -98,7 +98,7 @@ func (h *Client) InstallReleaseFromChart(chart *chart.Chart, ns string, opts ... if err != nil { return nil, err } - err = chartutil.ProcessRequirementsImportValues(req.Chart, req.Values) + err = chartutil.ProcessRequirementsImportValues(req.Chart) if err != nil { return nil, err } @@ -173,7 +173,7 @@ func (h *Client) UpdateReleaseFromChart(rlsName string, chart *chart.Chart, opts if err != nil { return nil, err } - err = chartutil.ProcessRequirementsImportValues(req.Chart, req.Values) + err = chartutil.ProcessRequirementsImportValues(req.Chart) if err != nil { return nil, err } diff --git a/pkg/helm/environment/environment.go b/pkg/helm/environment/environment.go index f65f90ac7..2092450e1 100644 --- a/pkg/helm/environment/environment.go +++ b/pkg/helm/environment/environment.go @@ -38,20 +38,12 @@ const ( PluginDisableEnvVar = "HELM_NO_PLUGINS" // HostEnvVar is the HELM_HOST environment variable key. HostEnvVar = "HELM_HOST" + // DebugEnvVar is the HELM_DEBUG environment variable key. + DebugEnvVar = "HELM_DEBUG" ) -// DefaultHelmHome gets the configured HELM_HOME, or returns the default. -func DefaultHelmHome() string { - if home := os.Getenv(HomeEnvVar); home != "" { - return home - } - return filepath.Join(os.Getenv("HOME"), ".helm") -} - -// DefaultHelmHost returns the configured HELM_HOST or an empty string. -func DefaultHelmHost() string { - return os.Getenv(HostEnvVar) -} +// DefaultHelmHome is the default HELM_HOME. +var DefaultHelmHome = filepath.Join("$HOME", ".helm") // EnvSettings describes all of the environment settings. type EnvSettings struct { @@ -61,8 +53,14 @@ type EnvSettings struct { TillerNamespace string // Home is the local path to the Helm home directory. Home helmpath.Home - // PluginDirs is the path to the plugin directories. - PlugDirs string // Debug indicates whether or not Helm is running in Debug mode. Debug bool } + +// PluginDirs is the path to the plugin directories. +func (s EnvSettings) PluginDirs() string { + if d := os.Getenv(PluginEnvVar); d != "" { + return d + } + return s.Home.Plugins() +} diff --git a/pkg/helm/helmpath/helmhome.go b/pkg/helm/helmpath/helmhome.go index d3023dcba..c9aad70c6 100644 --- a/pkg/helm/helmpath/helmhome.go +++ b/pkg/helm/helmpath/helmhome.go @@ -17,6 +17,7 @@ package helmpath import ( "fmt" + "os" "path/filepath" ) @@ -29,12 +30,12 @@ type Home string // // Implements fmt.Stringer. func (h Home) String() string { - return string(h) + return os.ExpandEnv(string(h)) } // Path returns Home with elements appended. func (h Home) Path(elem ...string) string { - p := []string{string(h)} + p := []string{h.String()} p = append(p, elem...) return filepath.Join(p...) } diff --git a/pkg/helm/helmpath/helmhome_unix_test.go b/pkg/helm/helmpath/helmhome_unix_test.go index cca303d29..9c31a9c07 100644 --- a/pkg/helm/helmpath/helmhome_unix_test.go +++ b/pkg/helm/helmpath/helmhome_unix_test.go @@ -38,3 +38,9 @@ func TestHelmHome(t *testing.T) { isEq(t, hh.CacheIndex("t"), "/r/repository/cache/t-index.yaml") isEq(t, hh.Starters(), "/r/starters") } + +func TestHelmHome_expand(t *testing.T) { + if Home("$HOME").String() == "$HOME" { + t.Error("expected variable expansion") + } +} diff --git a/pkg/plugin/plugin.go b/pkg/plugin/plugin.go index 8bde6ad24..75d808701 100644 --- a/pkg/plugin/plugin.go +++ b/pkg/plugin/plugin.go @@ -179,7 +179,7 @@ func SetupPluginEnv(settings helm_env.EnvSettings, // Set vars that may not have been set, and save client the // trouble of re-parsing. - helm_env.PluginEnvVar: settings.PlugDirs, + helm_env.PluginEnvVar: settings.PluginDirs(), helm_env.HomeEnvVar: settings.Home.String(), // Set vars that convey common information. diff --git a/pkg/resolver/resolver_test.go b/pkg/resolver/resolver_test.go index 9453a979f..b87022b93 100644 --- a/pkg/resolver/resolver_test.go +++ b/pkg/resolver/resolver_test.go @@ -146,7 +146,7 @@ func TestResolve(t *testing.T) { } func TestHashReq(t *testing.T) { - expect := "sha256:917e251ddba291096889f81eb7de713ab4e1afbbb07c576dfd7d66ba9300b12b" + expect := "sha256:45b06fcc4496c705bf3d634f8a2ff84e6a6f0bdcaf010614b8886572d1e52b99" req := &chartutil.Requirements{ Dependencies: []*chartutil.Dependency{ {Name: "alpine", Version: "0.1.0", Repository: "http://localhost:8879/charts"}, diff --git a/pkg/tiller/environment/environment.go b/pkg/tiller/environment/environment.go index 713699aca..de0dbe33d 100644 --- a/pkg/tiller/environment/environment.go +++ b/pkg/tiller/environment/environment.go @@ -24,7 +24,6 @@ package environment import ( "io" - "os" "time" "k8s.io/helm/pkg/chartutil" @@ -44,14 +43,6 @@ const TillerNamespaceEnvVar = "TILLER_NAMESPACE" // DefaultTillerNamespace is the default namespace for tiller. const DefaultTillerNamespace = "kube-system" -// GetTillerNamespace returns the right tiller namespace. -func GetTillerNamespace() string { - if ns := os.Getenv(TillerNamespaceEnvVar); ns != "" { - return ns - } - return DefaultTillerNamespace -} - // GoTplEngine is the name of the Go template engine, as registered in the EngineYard. const GoTplEngine = "gotpl" diff --git a/pkg/tiller/hooks.go b/pkg/tiller/hooks.go index b26243479..996253384 100644 --- a/pkg/tiller/hooks.go +++ b/pkg/tiller/hooks.go @@ -51,96 +51,149 @@ type manifest struct { head *util.SimpleHead } -// sortManifests takes a map of filename/YAML contents and sorts them into hook types. +type result struct { + hooks []*release.Hook + generic []manifest +} + +type manifestFile struct { + entries map[string]string + path string + apis chartutil.VersionSet +} + +// sortManifests takes a map of filename/YAML contents, splits the file +// by manifest entries, and sorts the entries into hook types. // // The resulting hooks struct will be populated with all of the generated hooks. // Any file that does not declare one of the hook types will be placed in the // 'generic' bucket. // -// To determine hook type, this looks for a YAML structure like this: -// -// kind: SomeKind -// apiVersion: v1 -// metadata: -// annotations: -// helm.sh/hook: pre-install -// -// Where HOOK_NAME is one of the known hooks. -// -// If a file declares more than one hook, it will be copied into all of the applicable -// hook buckets. (Note: label keys are not unique within the labels section). -// // Files that do not parse into the expected format are simply placed into a map and // returned. func sortManifests(files map[string]string, apis chartutil.VersionSet, sort SortOrder) ([]*release.Hook, []manifest, error) { - hs := []*release.Hook{} - generic := []manifest{} + result := &result{} + + for filePath, c := range files { - for n, c := range files { // Skip partials. We could return these as a separate map, but there doesn't // seem to be any need for that at this time. - if strings.HasPrefix(path.Base(n), "_") { + if strings.HasPrefix(path.Base(filePath), "_") { continue } - // Skip empty files, and log this. + // Skip empty files and log this. if len(strings.TrimSpace(c)) == 0 { - log.Printf("info: manifest %q is empty. Skipping.", n) + log.Printf("info: manifest %q is empty. Skipping.", filePath) continue } - var sh util.SimpleHead - err := yaml.Unmarshal([]byte(c), &sh) + manifestFile := &manifestFile{ + entries: util.SplitManifests(c), + path: filePath, + apis: apis, + } + + if err := manifestFile.sort(result); err != nil { + return result.hooks, result.generic, err + } + } + + return result.hooks, sortByKind(result.generic, sort), nil +} + +// sort takes a manifestFile object which may contain multiple resource definition +// entries and sorts each entry by hook types, and saves the resulting hooks and +// generic manifests (or non-hooks) to the result struct. +// +// To determine hook type, it looks for a YAML structure like this: +// +// kind: SomeKind +// apiVersion: v1 +// metadata: +// annotations: +// helm.sh/hook: pre-install +// +func (file *manifestFile) sort(result *result) error { + for _, m := range file.entries { + var entry util.SimpleHead + err := yaml.Unmarshal([]byte(m), &entry) if err != nil { - e := fmt.Errorf("YAML parse error on %s: %s", n, err) - return hs, generic, e + e := fmt.Errorf("YAML parse error on %s: %s", file.path, err) + return e } - if sh.Version != "" && !apis.Has(sh.Version) { - return hs, generic, fmt.Errorf("apiVersion %q in %s is not available", sh.Version, n) + if entry.Version != "" && !file.apis.Has(entry.Version) { + return fmt.Errorf("apiVersion %q in %s is not available", entry.Version, file.path) } - if sh.Metadata == nil || sh.Metadata.Annotations == nil || len(sh.Metadata.Annotations) == 0 { - generic = append(generic, manifest{name: n, content: c, head: &sh}) + if !hasAnyAnnotation(entry) { + result.generic = append(result.generic, manifest{ + name: file.path, + content: m, + head: &entry, + }) continue } - hookTypes, ok := sh.Metadata.Annotations[hooks.HookAnno] + hookTypes, ok := entry.Metadata.Annotations[hooks.HookAnno] if !ok { - generic = append(generic, manifest{name: n, content: c, head: &sh}) + result.generic = append(result.generic, manifest{ + name: file.path, + content: m, + head: &entry, + }) continue } - hws, _ := sh.Metadata.Annotations[hooks.HookWeightAnno] - hw, err := strconv.Atoi(hws) - if err != nil { - hw = 0 - } + hw := calculateHookWeight(entry) h := &release.Hook{ - Name: sh.Metadata.Name, - Kind: sh.Kind, - Path: n, - Manifest: c, + Name: entry.Metadata.Name, + Kind: entry.Kind, + Path: file.path, + Manifest: m, Events: []release.Hook_Event{}, - Weight: int32(hw), + Weight: hw, } - isHook := false + isKnownHook := false for _, hookType := range strings.Split(hookTypes, ",") { hookType = strings.ToLower(strings.TrimSpace(hookType)) e, ok := events[hookType] if ok { - isHook = true + isKnownHook = true h.Events = append(h.Events, e) } } - if !isHook { + if !isKnownHook { log.Printf("info: skipping unknown hook: %q", hookTypes) continue } - hs = append(hs, h) + + result.hooks = append(result.hooks, h) + } + + return nil +} + +func hasAnyAnnotation(entry util.SimpleHead) bool { + if entry.Metadata == nil || + entry.Metadata.Annotations == nil || + len(entry.Metadata.Annotations) == 0 { + return false } - return hs, sortByKind(generic, sort), nil + + return true +} + +func calculateHookWeight(entry util.SimpleHead) int32 { + hws, _ := entry.Metadata.Annotations[hooks.HookWeightAnno] + hw, err := strconv.Atoi(hws) + if err != nil { + hw = 0 + } + + return int32(hw) } diff --git a/pkg/tiller/hooks_test.go b/pkg/tiller/hooks_test.go index 823e7469c..eabdc7eac 100644 --- a/pkg/tiller/hooks_test.go +++ b/pkg/tiller/hooks_test.go @@ -17,6 +17,7 @@ limitations under the License. package tiller import ( + "reflect" "testing" "github.com/ghodss/yaml" @@ -29,17 +30,17 @@ import ( func TestSortManifests(t *testing.T) { data := []struct { - name string + name []string path string - kind string - hooks []release.Hook_Event + kind []string + hooks map[string][]release.Hook_Event manifest string }{ { - name: "first", + name: []string{"first"}, path: "one", - kind: "Job", - hooks: []release.Hook_Event{release.Hook_PRE_INSTALL}, + kind: []string{"Job"}, + hooks: map[string][]release.Hook_Event{"first": {release.Hook_PRE_INSTALL}}, manifest: `apiVersion: v1 kind: Job metadata: @@ -51,10 +52,10 @@ metadata: `, }, { - name: "second", + name: []string{"second"}, path: "two", - kind: "ReplicaSet", - hooks: []release.Hook_Event{release.Hook_POST_INSTALL}, + kind: []string{"ReplicaSet"}, + hooks: map[string][]release.Hook_Event{"second": {release.Hook_POST_INSTALL}}, manifest: `kind: ReplicaSet apiVersion: v1beta1 metadata: @@ -63,10 +64,10 @@ metadata: "helm.sh/hook": post-install `, }, { - name: "third", + name: []string{"third"}, path: "three", - kind: "ReplicaSet", - hooks: []release.Hook_Event{}, + kind: []string{"ReplicaSet"}, + hooks: map[string][]release.Hook_Event{"third": nil}, manifest: `kind: ReplicaSet apiVersion: v1beta1 metadata: @@ -75,22 +76,21 @@ metadata: "helm.sh/hook": no-such-hook `, }, { - name: "fourth", + name: []string{"fourth"}, path: "four", - kind: "Pod", - hooks: []release.Hook_Event{}, + kind: []string{"Pod"}, + hooks: map[string][]release.Hook_Event{"fourth": nil}, manifest: `kind: Pod apiVersion: v1 metadata: name: fourth annotations: - nothing: here -`, + nothing: here`, }, { - name: "fifth", + name: []string{"fifth"}, path: "five", - kind: "ReplicaSet", - hooks: []release.Hook_Event{release.Hook_POST_DELETE, release.Hook_POST_INSTALL}, + kind: []string{"ReplicaSet"}, + hooks: map[string][]release.Hook_Event{"fifth": {release.Hook_POST_DELETE, release.Hook_POST_INSTALL}}, manifest: `kind: ReplicaSet apiVersion: v1beta1 metadata: @@ -100,19 +100,39 @@ metadata: `, }, { // Regression test: files with an underscore in the base name should be skipped. - name: "sixth", + name: []string{"sixth"}, path: "six/_six", - kind: "ReplicaSet", - hooks: []release.Hook_Event{}, + kind: []string{"ReplicaSet"}, + hooks: map[string][]release.Hook_Event{"sixth": nil}, manifest: `invalid manifest`, // This will fail if partial is not skipped. }, { // Regression test: files with no content should be skipped. - name: "seventh", + name: []string{"seventh"}, path: "seven", - kind: "ReplicaSet", - hooks: []release.Hook_Event{}, + kind: []string{"ReplicaSet"}, + hooks: map[string][]release.Hook_Event{"seventh": nil}, manifest: "", }, + { + name: []string{"eighth", "example-test"}, + path: "eight", + kind: []string{"ConfigMap", "Pod"}, + hooks: map[string][]release.Hook_Event{"eighth": nil, "example-test": {release.Hook_RELEASE_TEST_SUCCESS}}, + manifest: `kind: ConfigMap +apiVersion: v1 +metadata: + name: eighth +data: + name: value +--- +apiVersion: v1 +kind: Pod +metadata: + name: example-test + annotations: + "helm.sh/hook": test-success +`, + }, } manifests := make(map[string]string, len(data)) @@ -126,12 +146,12 @@ metadata: } // This test will fail if 'six' or 'seven' was added. - if len(generic) != 1 { - t.Errorf("Expected 1 generic manifest, got %d", len(generic)) + if len(generic) != 2 { + t.Errorf("Expected 2 generic manifests, got %d", len(generic)) } - if len(hs) != 3 { - t.Errorf("Expected 3 hooks, got %d", len(hs)) + if len(hs) != 4 { + t.Errorf("Expected 4 hooks, got %d", len(hs)) } for _, out := range hs { @@ -142,17 +162,30 @@ metadata: if out.Path != expect.path { t.Errorf("Expected path %s, got %s", expect.path, out.Path) } - if out.Name != expect.name { - t.Errorf("Expected name %s, got %s", expect.name, out.Name) + nameFound := false + for _, expectedName := range expect.name { + if out.Name == expectedName { + nameFound = true + } } - if out.Kind != expect.kind { - t.Errorf("Expected kind %s, got %s", expect.kind, out.Kind) + if !nameFound { + t.Errorf("Got unexpected name %s", out.Name) } - for i := 0; i < len(out.Events); i++ { - if out.Events[i] != expect.hooks[i] { - t.Errorf("Expected event %d, got %d", expect.hooks[i], out.Events[i]) + kindFound := false + for _, expectedKind := range expect.kind { + if out.Kind == expectedKind { + kindFound = true } } + if !kindFound { + t.Errorf("Got unexpected kind %s", out.Kind) + } + + expectedHooks := expect.hooks[out.Name] + if !reflect.DeepEqual(expectedHooks, out.Events) { + t.Errorf("expected events: %v but got: %v", expectedHooks, out.Events) + } + } } if !found { @@ -161,27 +194,40 @@ metadata: } // Verify the sort order - sorted := make([]manifest, len(data)) - for i, s := range data { - var sh util.SimpleHead - err := yaml.Unmarshal([]byte(s.manifest), &sh) - if err != nil { - // This is expected for manifests that are corrupt or empty. - t.Log(err) - } - sorted[i] = manifest{ - content: s.manifest, - name: s.name, - head: &sh, + sorted := []manifest{} + for _, s := range data { + manifests := util.SplitManifests(s.manifest) + mCount := 0 + for _, m := range manifests { + name := s.name[mCount] + + var sh util.SimpleHead + err := yaml.Unmarshal([]byte(m), &sh) + if err != nil { + // This is expected for manifests that are corrupt or empty. + t.Log(err) + } + + //only keep track of non-hook manifests + if err == nil && s.hooks[name] == nil { + another := manifest{ + content: m, + name: name, + head: &sh, + } + sorted = append(sorted, another) + } + + mCount++ } } + sorted = sortByKind(sorted, InstallOrder) for i, m := range generic { if m.content != sorted[i].content { t.Errorf("Expected %q, got %q", m.content, sorted[i].content) } } - } func TestVersionSet(t *testing.T) { diff --git a/pkg/tiller/release_content.go b/pkg/tiller/release_content.go index 13470bf8d..7586eb2d8 100644 --- a/pkg/tiller/release_content.go +++ b/pkg/tiller/release_content.go @@ -28,7 +28,7 @@ func (s *ReleaseServer) GetReleaseContent(c ctx.Context, req *services.GetReleas } if req.Version <= 0 { - rel, err := s.env.Releases.Deployed(req.Name) + rel, err := s.env.Releases.Last(req.Name) return &services.GetReleaseContentResponse{Release: rel}, err } diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index 6fd2100b0..8425a58f5 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -47,8 +47,7 @@ metadata: annotations: "helm.sh/hook": post-install,pre-delete data: - name: value -` + name: value` var manifestWithTestHook = ` apiVersion: v1 @@ -81,8 +80,7 @@ metadata: annotations: "helm.sh/hook": post-upgrade,pre-upgrade data: - name: value -` + name: value` var manifestWithRollbackHooks = `apiVersion: v1 kind: ConfigMap diff --git a/pkg/tiller/release_uninstall.go b/pkg/tiller/release_uninstall.go index 8f7846d68..54971ee6e 100644 --- a/pkg/tiller/release_uninstall.go +++ b/pkg/tiller/release_uninstall.go @@ -30,12 +30,6 @@ import ( // UninstallRelease deletes all of the resources associated with this release, and marks the release DELETED. func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallReleaseRequest) (*services.UninstallReleaseResponse, error) { - err := s.env.Releases.LockRelease(req.Name) - if err != nil { - return nil, err - } - defer s.env.Releases.UnlockRelease(req.Name) - if !ValidName.MatchString(req.Name) { s.Log("uninstall: Release not found: %s", req.Name) return nil, errMissingRelease @@ -45,6 +39,12 @@ func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallR return nil, fmt.Errorf("release name %q exceeds max length of %d", req.Name, releaseNameMaxLen) } + err := s.env.Releases.LockRelease(req.Name) + if err != nil { + return nil, err + } + defer s.env.Releases.UnlockRelease(req.Name) + rels, err := s.env.Releases.History(req.Name) if err != nil { s.Log("uninstall: Release not loaded: %s", req.Name)