Merge remote-tracking branch 'origin/master' into m

pull/3580/head
Chad Ostler 8 years ago
commit ff30e6f427

@ -4,7 +4,7 @@ jobs:
working_directory: /go/src/k8s.io/helm working_directory: /go/src/k8s.io/helm
parallelism: 3 parallelism: 3
docker: docker:
- image: golang:1.8 - image: golang:1.10
environment: environment:
PROJECT_NAME: "kubernetes-helm" PROJECT_NAME: "kubernetes-helm"
steps: steps:

@ -5,7 +5,7 @@ The Kubernetes Helm project accepts contributions via GitHub pull requests. This
## Reporting a Security Issue ## Reporting a Security Issue
Most of the time, when you find a bug in Helm, it should be reported Most of the time, when you find a bug in Helm, it should be reported
using [GitHub issues](github.com/kubernetes/helm/issues). However, if using [GitHub issues](https://github.com/kubernetes/helm/issues). However, if
you are reporting a _security vulnerability_, please email a report to you are reporting a _security vulnerability_, please email a report to
[helm-security@deis.com](mailto:helm-security@deis.com). This will give [helm-security@deis.com](mailto:helm-security@deis.com). This will give
us a chance to try to fix the issue before it is exploited in the wild. us a chance to try to fix the issue before it is exploited in the wild.

@ -57,7 +57,7 @@ func newDeleteCmd(c helm.Interface, out io.Writer) *cobra.Command {
SuggestFor: []string{"remove", "rm"}, SuggestFor: []string{"remove", "rm"},
Short: "given a release name, delete the release from Kubernetes", Short: "given a release name, delete the release from Kubernetes",
Long: deleteDesc, Long: deleteDesc,
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 { if len(args) == 0 {
return errors.New("command 'delete' requires a release name") return errors.New("command 'delete' requires a release name")

@ -57,7 +57,7 @@ func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
Use: "get [flags] RELEASE_NAME", Use: "get [flags] RELEASE_NAME",
Short: "download a named release", Short: "download a named release",
Long: getHelp, Long: getHelp,
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 { if len(args) == 0 {
return errReleaseRequired return errReleaseRequired

@ -47,7 +47,7 @@ func newGetHooksCmd(client helm.Interface, out io.Writer) *cobra.Command {
Use: "hooks [flags] RELEASE_NAME", Use: "hooks [flags] RELEASE_NAME",
Short: "download all hooks for a named release", Short: "download all hooks for a named release",
Long: getHooksHelp, Long: getHooksHelp,
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 { if len(args) == 0 {
return errReleaseRequired return errReleaseRequired

@ -49,7 +49,7 @@ func newGetManifestCmd(client helm.Interface, out io.Writer) *cobra.Command {
Use: "manifest [flags] RELEASE_NAME", Use: "manifest [flags] RELEASE_NAME",
Short: "download the manifest for a named release", Short: "download the manifest for a named release",
Long: getManifestHelp, Long: getManifestHelp,
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 { if len(args) == 0 {
return errReleaseRequired return errReleaseRequired

@ -47,7 +47,7 @@ func newGetValuesCmd(client helm.Interface, out io.Writer) *cobra.Command {
Use: "values [flags] RELEASE_NAME", Use: "values [flags] RELEASE_NAME",
Short: "download the values file for a named release", Short: "download the values file for a named release",
Long: getValuesHelp, Long: getValuesHelp,
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 { if len(args) == 0 {
return errReleaseRequired return errReleaseRequired

@ -165,7 +165,7 @@ func markDeprecated(cmd *cobra.Command, notice string) *cobra.Command {
return cmd return cmd
} }
func setupConnection(c *cobra.Command, args []string) error { func setupConnection() error {
if settings.TillerHost == "" { if settings.TillerHost == "" {
config, client, err := getKubeClient(settings.KubeContext) config, client, err := getKubeClient(settings.KubeContext)
if err != nil { if err != nil {
@ -266,7 +266,7 @@ func ensureHelmClient(h helm.Interface) helm.Interface {
} }
func newClient() helm.Interface { func newClient() helm.Interface {
options := []helm.Option{helm.Host(settings.TillerHost)} options := []helm.Option{helm.Host(settings.TillerHost), helm.ConnectTimeout(settings.TillerConnectionTimeout)}
if tlsVerify || tlsEnable { if tlsVerify || tlsEnable {
if tlsCaCertFile == "" { if tlsCaCertFile == "" {

@ -61,7 +61,7 @@ func newHistoryCmd(c helm.Interface, w io.Writer) *cobra.Command {
Long: historyHelp, Long: historyHelp,
Short: "fetch release history", Short: "fetch release history",
Aliases: []string{"hist"}, Aliases: []string{"hist"},
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
switch { switch {
case len(args) == 0: case len(args) == 0:

@ -23,6 +23,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
@ -33,6 +34,7 @@ import (
"k8s.io/helm/pkg/getter" "k8s.io/helm/pkg/getter"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/helm/helmpath" "k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/helm/portforwarder"
"k8s.io/helm/pkg/repo" "k8s.io/helm/pkg/repo"
) )
@ -86,6 +88,7 @@ type initCmd struct {
kubeClient kubernetes.Interface kubeClient kubernetes.Interface
serviceAccount string serviceAccount string
maxHistory int maxHistory int
replicas int
wait bool wait bool
} }
@ -130,6 +133,7 @@ func newInitCmd(out io.Writer) *cobra.Command {
f.BoolVar(&i.opts.EnableHostNetwork, "net-host", false, "install Tiller with net=host") f.BoolVar(&i.opts.EnableHostNetwork, "net-host", false, "install Tiller with net=host")
f.StringVar(&i.serviceAccount, "service-account", "", "name of service account") f.StringVar(&i.serviceAccount, "service-account", "", "name of service account")
f.IntVar(&i.maxHistory, "history-max", 0, "limit the maximum number of revisions saved per release. Use 0 for no limit.") f.IntVar(&i.maxHistory, "history-max", 0, "limit the maximum number of revisions saved per release. Use 0 for no limit.")
f.IntVar(&i.replicas, "replicas", 1, "amount of tiller instances to run on the cluster")
f.StringVar(&i.opts.NodeSelectors, "node-selectors", "", "labels to specify the node on which Tiller is installed (app=tiller,helm=rocks)") f.StringVar(&i.opts.NodeSelectors, "node-selectors", "", "labels to specify the node on which Tiller is installed (app=tiller,helm=rocks)")
f.VarP(&i.opts.Output, "output", "o", "skip installation and output Tiller's manifest in specified format (json or yaml)") f.VarP(&i.opts.Output, "output", "o", "skip installation and output Tiller's manifest in specified format (json or yaml)")
@ -175,6 +179,7 @@ func (i *initCmd) run() error {
i.opts.ForceUpgrade = i.forceUpgrade i.opts.ForceUpgrade = i.forceUpgrade
i.opts.ServiceAccount = i.serviceAccount i.opts.ServiceAccount = i.serviceAccount
i.opts.MaxHistory = i.maxHistory i.opts.MaxHistory = i.maxHistory
i.opts.Replicas = i.replicas
writeYAMLManifest := func(apiVersion, kind, body string, first, last bool) error { writeYAMLManifest := func(apiVersion, kind, body string, first, last bool) error {
w := i.out w := i.out
@ -307,11 +312,13 @@ func (i *initCmd) run() error {
"(Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)") "(Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)")
} }
} else { } else {
fmt.Fprintln(i.out, "\nTiller (the Helm server-side component) has been installed into your Kubernetes Cluster.\n\n"+
"Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.\n"+
"For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation")
}
if err := i.ping(); err != nil { if err := i.ping(); err != nil {
return err return err
} }
fmt.Fprintln(i.out, "\nTiller (the Helm server-side component) has been installed into your Kubernetes Cluster.")
}
} else { } else {
fmt.Fprintln(i.out, "Not installing Tiller due to 'client-only' flag having been set") fmt.Fprintln(i.out, "Not installing Tiller due to 'client-only' flag having been set")
} }
@ -322,6 +329,19 @@ func (i *initCmd) run() error {
func (i *initCmd) ping() error { func (i *initCmd) ping() error {
if i.wait { if i.wait {
_, kubeClient, err := getKubeClient(settings.KubeContext)
if err != nil {
return err
}
if !watchTillerUntilReady(settings.TillerNamespace, kubeClient, settings.TillerConnectionTimeout) {
return fmt.Errorf("tiller was not found. polling deadline exceeded")
}
// establish a connection to Tiller now that we've effectively guaranteed it's available
if err := setupConnection(); err != nil {
return err
}
i.client = newClient()
if err := i.client.PingTiller(); err != nil { if err := i.client.PingTiller(); err != nil {
return fmt.Errorf("could not ping Tiller: %s", err) return fmt.Errorf("could not ping Tiller: %s", err)
} }
@ -362,11 +382,11 @@ func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) err
if fi, err := os.Stat(repoFile); err != nil { if fi, err := os.Stat(repoFile); err != nil {
fmt.Fprintf(out, "Creating %s \n", repoFile) fmt.Fprintf(out, "Creating %s \n", repoFile)
f := repo.NewRepoFile() f := repo.NewRepoFile()
sr, err := initStableRepo(home.CacheIndex(stableRepository), out, skipRefresh) sr, err := initStableRepo(home.CacheIndex(stableRepository), out, skipRefresh, home)
if err != nil { if err != nil {
return err return err
} }
lr, err := initLocalRepo(home.LocalRepository(localRepositoryIndexFile), home.CacheIndex("local"), out) lr, err := initLocalRepo(home.LocalRepository(localRepositoryIndexFile), home.CacheIndex("local"), out, home)
if err != nil { if err != nil {
return err return err
} }
@ -381,7 +401,7 @@ func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) err
return nil return nil
} }
func initStableRepo(cacheFile string, out io.Writer, skipRefresh bool) (*repo.Entry, error) { func initStableRepo(cacheFile string, out io.Writer, skipRefresh bool, home helmpath.Home) (*repo.Entry, error) {
fmt.Fprintf(out, "Adding %s repo with URL: %s \n", stableRepository, stableRepositoryURL) fmt.Fprintf(out, "Adding %s repo with URL: %s \n", stableRepository, stableRepositoryURL)
c := repo.Entry{ c := repo.Entry{
Name: stableRepository, Name: stableRepository,
@ -406,7 +426,7 @@ func initStableRepo(cacheFile string, out io.Writer, skipRefresh bool) (*repo.En
return &c, nil return &c, nil
} }
func initLocalRepo(indexFile, cacheFile string, out io.Writer) (*repo.Entry, error) { func initLocalRepo(indexFile, cacheFile string, out io.Writer, home helmpath.Home) (*repo.Entry, error) {
if fi, err := os.Stat(indexFile); err != nil { if fi, err := os.Stat(indexFile); err != nil {
fmt.Fprintf(out, "Adding %s repo with URL: %s \n", localRepository, localRepositoryURL) fmt.Fprintf(out, "Adding %s repo with URL: %s \n", localRepository, localRepositoryURL)
i := repo.NewIndexFile() i := repo.NewIndexFile()
@ -415,7 +435,9 @@ func initLocalRepo(indexFile, cacheFile string, out io.Writer) (*repo.Entry, err
} }
//TODO: take this out and replace with helm update functionality //TODO: take this out and replace with helm update functionality
createLink(indexFile, cacheFile) if err := createLink(indexFile, cacheFile, home); err != nil {
return nil, err
}
} else if fi.IsDir() { } else if fi.IsDir() {
return nil, fmt.Errorf("%s must be a file, not a directory", indexFile) return nil, fmt.Errorf("%s must be a file, not a directory", indexFile)
} }
@ -438,3 +460,34 @@ func ensureRepoFileFormat(file string, out io.Writer) error {
return nil return nil
} }
// watchTillerUntilReady waits for the tiller pod to become available. This is useful in situations where we
// want to wait before we call New().
//
// Returns true if it exists. If the timeout was reached and it could not find the pod, it returns false.
func watchTillerUntilReady(namespace string, client kubernetes.Interface, timeout int64) bool {
deadlinePollingChan := time.NewTimer(time.Duration(timeout) * time.Second).C
checkTillerPodTicker := time.NewTicker(500 * time.Millisecond)
doneChan := make(chan bool)
defer checkTillerPodTicker.Stop()
go func() {
for range checkTillerPodTicker.C {
_, err := portforwarder.GetTillerPodName(client.CoreV1(), namespace)
if err == nil {
doneChan <- true
break
}
}
}()
for {
select {
case <-deadlinePollingChan:
return false
case <-doneChan:
return true
}
}
}

@ -20,8 +20,10 @@ package main
import ( import (
"os" "os"
"k8s.io/helm/pkg/helm/helmpath"
) )
func createLink(indexFile, cacheFile string) { func createLink(indexFile, cacheFile string, home helmpath.Home) error {
os.Symlink(indexFile, cacheFile) return os.Symlink(indexFile, cacheFile)
} }

@ -20,8 +20,10 @@ package main
import ( import (
"os" "os"
"k8s.io/helm/pkg/helm/helmpath"
) )
func createLink(indexFile, cacheFile string) { func createLink(indexFile, cacheFile string, home helmpath.Home) error {
os.Link(indexFile, cacheFile) return os.Link(indexFile, cacheFile)
} }

@ -153,7 +153,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
Use: "install [CHART]", Use: "install [CHART]",
Short: "install a chart archive", Short: "install a chart archive",
Long: installDesc, Long: installDesc,
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if err := checkArgsLength(len(args), "chart name"); err != nil { if err := checkArgsLength(len(args), "chart name"); err != nil {
return err return err

@ -183,6 +183,7 @@ func generateDeployment(opts *Options) (*v1beta1.Deployment, error) {
Labels: labels, Labels: labels,
}, },
Spec: v1beta1.DeploymentSpec{ Spec: v1beta1.DeploymentSpec{
Replicas: opts.getReplicas(),
Template: v1.PodTemplateSpec{ Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Labels: labels, Labels: labels,

@ -211,6 +211,10 @@ func TestInstall(t *testing.T) {
if ports != 2 { if ports != 2 {
t.Errorf("expected ports = 2, got '%d'", ports) t.Errorf("expected ports = 2, got '%d'", ports)
} }
replicas := obj.Spec.Replicas
if int(*replicas) != 1 {
t.Errorf("expected replicas = 1, got '%d'", replicas)
}
return true, obj, nil return true, obj, nil
}) })
fc.AddReactor("create", "services", func(action testcore.Action) (bool, runtime.Object, error) { fc.AddReactor("create", "services", func(action testcore.Action) (bool, runtime.Object, error) {
@ -236,6 +240,29 @@ func TestInstall(t *testing.T) {
} }
} }
func TestInstallHA(t *testing.T) {
image := "gcr.io/kubernetes-helm/tiller:v2.0.0"
fc := &fake.Clientset{}
fc.AddReactor("create", "deployments", func(action testcore.Action) (bool, runtime.Object, error) {
obj := action.(testcore.CreateAction).GetObject().(*v1beta1.Deployment)
replicas := obj.Spec.Replicas
if int(*replicas) != 2 {
t.Errorf("expected replicas = 2, got '%d'", replicas)
}
return true, obj, nil
})
opts := &Options{
Namespace: v1.NamespaceDefault,
ImageSpec: image,
Replicas: 2,
}
if err := Install(fc, opts); err != nil {
t.Errorf("unexpected error: %#+v", err)
}
}
func TestInstall_WithTLS(t *testing.T) { func TestInstall_WithTLS(t *testing.T) {
image := "gcr.io/kubernetes-helm/tiller:v2.0.0" image := "gcr.io/kubernetes-helm/tiller:v2.0.0"
name := "tiller-secret" name := "tiller-secret"

@ -81,6 +81,11 @@ type Options struct {
// Less than or equal to zero means no limit. // Less than or equal to zero means no limit.
MaxHistory int MaxHistory int
// Replicas sets the amount of Tiller replicas to start
//
// Less than or equals to 1 means 1.
Replicas int
// NodeSelectors determine which nodes Tiller can land on. // NodeSelectors determine which nodes Tiller can land on.
NodeSelectors string NodeSelectors string
@ -109,6 +114,14 @@ func (opts *Options) pullPolicy() v1.PullPolicy {
return v1.PullIfNotPresent return v1.PullIfNotPresent
} }
func (opts *Options) getReplicas() *int32 {
replicas := int32(1)
if opts.Replicas > 1 {
replicas = int32(opts.Replicas)
}
return &replicas
}
func (opts *Options) tls() bool { return opts.EnableTLS || opts.VerifyTLS } func (opts *Options) tls() bool { return opts.EnableTLS || opts.VerifyTLS }
// valuesMap returns user set values in map format // valuesMap returns user set values in map format

@ -88,7 +88,7 @@ func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
Short: "list releases", Short: "list releases",
Long: listHelp, Long: listHelp,
Aliases: []string{"ls"}, Aliases: []string{"ls"},
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 { if len(args) > 0 {
list.filter = strings.Join(args, " ") list.filter = strings.Join(args, " ")

@ -17,41 +17,35 @@ limitations under the License.
package main package main
import ( import (
"bytes" "io"
"regexp"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/release"
) )
func TestListCmd(t *testing.T) { func TestListCmd(t *testing.T) {
tests := []struct { tests := []releaseCase{
name string
args []string
resp []*release.Release
expected string
err bool
}{
{ {
name: "with a release", name: "with a release",
resp: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
}, },
expected: "thomas-guide", expected: "thomas-guide",
}, },
{ {
name: "list", name: "list",
args: []string{}, rels: []*release.Release{
resp: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas"}),
}, },
expected: "NAME \tREVISION\tUPDATED \tSTATUS \tCHART \tNAMESPACE\natlas\t1 \t(.*)\tDEPLOYED\tfoo-0.1.0-beta.1\tdefault \n", expected: "NAME \tREVISION\tUPDATED \tSTATUS \tCHART \tNAMESPACE\natlas\t1 \t(.*)\tDEPLOYED\tfoo-0.1.0-beta.1\tdefault \n",
}, },
{ {
name: "list, one deployed, one failed", name: "list, one deployed, one failed",
args: []string{"-q"}, flags: []string{"-q"},
resp: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_FAILED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_FAILED}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
}, },
@ -59,8 +53,8 @@ func TestListCmd(t *testing.T) {
}, },
{ {
name: "with a release, multiple flags", name: "with a release, multiple flags",
args: []string{"--deleted", "--deployed", "--failed", "-q"}, flags: []string{"--deleted", "--deployed", "--failed", "-q"},
resp: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
}, },
@ -70,8 +64,8 @@ func TestListCmd(t *testing.T) {
}, },
{ {
name: "with a release, multiple flags", name: "with a release, multiple flags",
args: []string{"--all", "-q"}, flags: []string{"--all", "-q"},
resp: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
}, },
@ -80,8 +74,8 @@ func TestListCmd(t *testing.T) {
}, },
{ {
name: "with a release, multiple flags, deleting", name: "with a release, multiple flags, deleting",
args: []string{"--all", "-q"}, flags: []string{"--all", "-q"},
resp: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETING}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETING}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
}, },
@ -90,8 +84,8 @@ func TestListCmd(t *testing.T) {
}, },
{ {
name: "namespace defined, multiple flags", name: "namespace defined, multiple flags",
args: []string{"--all", "-q", "--namespace test123"}, flags: []string{"--all", "-q", "--namespace test123"},
resp: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Namespace: "test123"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Namespace: "test123"}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Namespace: "test321"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Namespace: "test321"}),
}, },
@ -100,8 +94,8 @@ func TestListCmd(t *testing.T) {
}, },
{ {
name: "with a pending release, multiple flags", name: "with a pending release, multiple flags",
args: []string{"--all", "-q"}, flags: []string{"--all", "-q"},
resp: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_PENDING_INSTALL}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_PENDING_INSTALL}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
}, },
@ -109,8 +103,8 @@ func TestListCmd(t *testing.T) {
}, },
{ {
name: "with a pending release, pending flag", name: "with a pending release, pending flag",
args: []string{"--pending", "-q"}, flags: []string{"--pending", "-q"},
resp: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_PENDING_INSTALL}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_PENDING_INSTALL}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "wild-idea", StatusCode: release.Status_PENDING_UPGRADE}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "wild-idea", StatusCode: release.Status_PENDING_UPGRADE}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-maps", StatusCode: release.Status_PENDING_ROLLBACK}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-maps", StatusCode: release.Status_PENDING_ROLLBACK}),
@ -120,7 +114,7 @@ func TestListCmd(t *testing.T) {
}, },
{ {
name: "with old releases", name: "with old releases",
resp: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_FAILED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_FAILED}),
}, },
@ -128,21 +122,7 @@ func TestListCmd(t *testing.T) {
}, },
} }
var buf bytes.Buffer runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command {
for _, tt := range tests { return newListCmd(c, out)
c := &helm.FakeClient{ })
Rels: tt.resp,
}
cmd := newListCmd(c, &buf)
cmd.ParseFlags(tt.args)
err := cmd.RunE(cmd, tt.args)
if (err != nil) != tt.err {
t.Errorf("%q. expected error: %v, got %v", tt.name, tt.err, err)
}
re := regexp.MustCompile(tt.expected)
if !re.Match(buf.Bytes()) {
t.Errorf("%q. expected\n%q\ngot\n%q", tt.name, tt.expected, buf.String())
}
buf.Reset()
}
} }

@ -103,7 +103,7 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) {
if _, err := processParent(cmd, args); err != nil { if _, err := processParent(cmd, args); err != nil {
return err return err
} }
return setupConnection(cmd, args) return setupConnection()
} }
} }

@ -51,7 +51,7 @@ func newReleaseTestCmd(c helm.Interface, out io.Writer) *cobra.Command {
Use: "test [RELEASE]", Use: "test [RELEASE]",
Short: "test a release", Short: "test a release",
Long: releaseTestDesc, Long: releaseTestDesc,
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if err := checkArgsLength(len(args), "release name"); err != nil { if err := checkArgsLength(len(args), "release name"); err != nil {
return err return err

@ -58,7 +58,7 @@ func newResetCmd(client helm.Interface, out io.Writer) *cobra.Command {
Short: "uninstalls Tiller from a cluster", Short: "uninstalls Tiller from a cluster",
Long: resetDesc, Long: resetDesc,
PreRunE: func(cmd *cobra.Command, args []string) error { PreRunE: func(cmd *cobra.Command, args []string) error {
if err := setupConnection(cmd, args); !d.force && err != nil { if err := setupConnection(); !d.force && err != nil {
return err return err
} }
return nil return nil

@ -57,7 +57,7 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
Use: "rollback [flags] [RELEASE] [REVISION]", Use: "rollback [flags] [RELEASE] [REVISION]",
Short: "roll back a release to a previous revision", Short: "roll back a release to a previous revision",
Long: rollbackDesc, Long: rollbackDesc,
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if err := checkArgsLength(len(args), "release name", "revision number"); err != nil { if err := checkArgsLength(len(args), "release name", "revision number"); err != nil {
return err return err

@ -146,11 +146,11 @@ func (i *Index) SearchLiteral(term string, threshold int) []*Result {
term = strings.ToLower(term) term = strings.ToLower(term)
buf := []*Result{} buf := []*Result{}
for k, v := range i.lines { for k, v := range i.lines {
k = strings.ToLower(k) lk := strings.ToLower(k)
v = strings.ToLower(v) lv := strings.ToLower(v)
res := strings.Index(v, term) res := strings.Index(lv, term)
if score := i.calcScore(res, v); res != -1 && score < threshold { if score := i.calcScore(res, lv); res != -1 && score < threshold {
parts := strings.Split(k, verSep) // Remove version, if it is there. parts := strings.Split(lk, verSep) // Remove version, if it is there.
buf = append(buf, &Result{Name: parts[0], Score: score, Chart: i.charts[k]}) buf = append(buf, &Result{Name: parts[0], Score: score, Chart: i.charts[k]})
} }
} }

@ -91,10 +91,10 @@ var indexfileEntries = map[string]repo.ChartVersions{
}, },
}, },
{ {
URLs: []string{"http://example.com/charts/santa-maria-1.2.2.tgz"}, URLs: []string{"http://example.com/charts/santa-maria-1.2.2-rc-1.tgz"},
Metadata: &chart.Metadata{ Metadata: &chart.Metadata{
Name: "santa-maria", Name: "santa-maria",
Version: "1.2.2", Version: "1.2.2-RC-1",
Description: "Three boat", Description: "Three boat",
}, },
}, },

@ -63,7 +63,7 @@ func newStatusCmd(client helm.Interface, out io.Writer) *cobra.Command {
Use: "status [flags] RELEASE_NAME", Use: "status [flags] RELEASE_NAME",
Short: "displays the status of the named release", Short: "displays the status of the named release",
Long: statusHelp, Long: statusHelp,
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 { if len(args) == 0 {
return errReleaseRequired return errReleaseRequired

@ -91,7 +91,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
Use: "upgrade [RELEASE] [CHART]", Use: "upgrade [RELEASE] [CHART]",
Short: "upgrade a release", Short: "upgrade a release",
Long: upgradeDesc, Long: upgradeDesc,
PreRunE: setupConnection, PreRunE: func(_ *cobra.Command, _ []string) error { return setupConnection() },
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if err := checkArgsLength(len(args), "release name", "chart path"); err != nil { if err := checkArgsLength(len(args), "release name", "chart path"); err != nil {
return err return err

@ -76,7 +76,7 @@ func newVersionCmd(c helm.Interface, out io.Writer) *cobra.Command {
if version.showServer { if version.showServer {
// We do this manually instead of in PreRun because we only // We do this manually instead of in PreRun because we only
// need a tunnel if server version is requested. // need a tunnel if server version is requested.
setupConnection(cmd, args) setupConnection()
} }
version.client = ensureHelmClient(version.client) version.client = ensureHelmClient(version.client)
return version.run() return version.run()

@ -33,6 +33,8 @@ import (
goprom "github.com/grpc-ecosystem/go-grpc-prometheus" goprom "github.com/grpc-ecosystem/go-grpc-prometheus"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/health"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/keepalive" "google.golang.org/grpc/keepalive"
"k8s.io/helm/pkg/kube" "k8s.io/helm/pkg/kube"
@ -113,6 +115,9 @@ func main() {
func start() { func start() {
healthSrv := health.NewServer()
healthSrv.SetServingStatus("Tiller", healthpb.HealthCheckResponse_NOT_SERVING)
clientset, err := kube.New(nil).ClientSet() clientset, err := kube.New(nil).ClientSet()
if err != nil { if err != nil {
logger.Fatalf("Cannot initialize Kubernetes connection: %s", err) logger.Fatalf("Cannot initialize Kubernetes connection: %s", err)
@ -168,6 +173,7 @@ func start() {
})) }))
rootServer = tiller.NewServer(opts...) rootServer = tiller.NewServer(opts...)
healthpb.RegisterHealthServer(rootServer, healthSrv)
lstn, err := net.Listen("tcp", *grpcAddr) lstn, err := net.Listen("tcp", *grpcAddr)
if err != nil { if err != nil {
@ -207,6 +213,8 @@ func start() {
} }
}() }()
healthSrv.SetServingStatus("Tiller", healthpb.HealthCheckResponse_SERVING)
select { select {
case err := <-srvErrCh: case err := <-srvErrCh:
logger.Fatalf("Server died: %s", err) logger.Fatalf("Server died: %s", err)

@ -4,7 +4,7 @@ In the previous section we looked at the built-in objects that Helm templates of
- The `values.yaml` file in the chart - The `values.yaml` file in the chart
- If this is a subchart, the `values.yaml` file of a parent chart - If this is a subchart, the `values.yaml` file of a parent chart
- A values file if passed into `helm install` or `helm update` with the `-f` flag (`helm install -f myvals.yaml ./mychart`) - A values file if passed into `helm install` or `helm upgrade` with the `-f` flag (`helm install -f myvals.yaml ./mychart`)
- Individual parameters passed with `--set` (such as `helm install --set foo=bar ./mychart`) - Individual parameters passed with `--set` (such as `helm install --set foo=bar ./mychart`)
The list above is in order of specificity: `values.yaml` is the default, which can be overridden by a parent chart's `values.yaml`, which can in turn be overridden by a user-supplied values file, which can in turn be overridden by `--set` parameters. The list above is in order of specificity: `values.yaml` is the default, which can be overridden by a parent chart's `values.yaml`, which can in turn be overridden by a user-supplied values file, which can in turn be overridden by `--set` parameters.

@ -2,7 +2,7 @@
A chart contains a number of Kubernetes resources and components that work together. As a chart author, you may want to write some tests that validate that your chart works as expected when it is installed. These tests also help the chart consumer understand what your chart is supposed to do. A chart contains a number of Kubernetes resources and components that work together. As a chart author, you may want to write some tests that validate that your chart works as expected when it is installed. These tests also help the chart consumer understand what your chart is supposed to do.
A **test** in a helm chart lives under the `templates/` directory and is a pod definition that specifies a container with a given command to run. The container should exit successfully (exit 0) for a test to be considered a success. The pod definition must contain one of the helm test hook annotations: `helm.sh/hooks: test-success` or `helm.sh/hooks: test-failure`. A **test** in a helm chart lives under the `templates/` directory and is a pod definition that specifies a container with a given command to run. The container should exit successfully (exit 0) for a test to be considered a success. The pod definition must contain one of the helm test hook annotations: `helm.sh/hook: test-success` or `helm.sh/hook: test-failure`.
Example tests: Example tests:
- Validate that your configuration from the values.yaml file was properly injected. - Validate that your configuration from the values.yaml file was properly injected.

@ -850,7 +850,7 @@ considerations in mind:
- The `Chart.yaml` will be overwritten by the generator. - The `Chart.yaml` will be overwritten by the generator.
- Users will expect to modify such a chart's contents, so documentation - Users will expect to modify such a chart's contents, so documentation
should indicate how users can do so. should indicate how users can do so.
- All occurances of `<CHARTNAME>` will be replaced with the specified chart - All occurences of `<CHARTNAME>` will be replaced with the specified chart
name so that starter charts can be used as templates. name so that starter charts can be used as templates.
Currently the only way to add a chart to `$HELM_HOME/starters` is to manually Currently the only way to add a chart to `$HELM_HOME/starters` is to manually

@ -1,7 +1,7 @@
name: nginx name: nginx
description: A basic NGINX HTTP server description: A basic NGINX HTTP server
version: 0.1.0 version: 0.1.0
kubeVersion: >= 1.2.0 kubeVersion: ">=1.2.0"
keywords: keywords:
- http - http
- nginx - nginx

@ -36,6 +36,7 @@ Environment:
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
@ -67,4 +68,4 @@ Environment:
* [helm verify](helm_verify.md) - verify that a chart at the given path has been signed and is valid * [helm 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 * [helm version](helm_version.md) - print the client/server version information
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -28,10 +28,11 @@ helm completion SHELL
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -47,10 +47,11 @@ helm create NAME
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -38,10 +38,11 @@ helm delete [flags] RELEASE_NAME [...]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -61,6 +61,7 @@ for this case.
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
@ -70,4 +71,4 @@ for this case.
* [helm dependency list](helm_dependency_list.md) - list the dependencies for the given chart * [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 * [helm dependency update](helm_dependency_update.md) - update charts/ based on the contents of requirements.yaml
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -34,10 +34,11 @@ helm dependency build [flags] CHART
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm dependency](helm_dependency.md) - manage a chart's dependencies * [helm dependency](helm_dependency.md) - manage a chart's dependencies
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -26,10 +26,11 @@ helm dependency list [flags] CHART
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm dependency](helm_dependency.md) - manage a chart's dependencies * [helm dependency](helm_dependency.md) - manage a chart's dependencies
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -39,10 +39,11 @@ helm dependency update [flags] CHART
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm dependency](helm_dependency.md) - manage a chart's dependencies * [helm dependency](helm_dependency.md) - manage a chart's dependencies
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -48,10 +48,11 @@ helm fetch [flags] [chart URL | repo/chartname] [...]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -40,6 +40,7 @@ helm get [flags] RELEASE_NAME
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
@ -49,4 +50,4 @@ helm get [flags] RELEASE_NAME
* [helm get manifest](helm_get_manifest.md) - download the manifest for a named release * [helm get 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 * [helm get values](helm_get_values.md) - download the values file for a named release
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -33,10 +33,11 @@ helm get hooks [flags] RELEASE_NAME
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm get](helm_get.md) - download a named release * [helm get](helm_get.md) - download a named release
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -35,10 +35,11 @@ helm get manifest [flags] RELEASE_NAME
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm get](helm_get.md) - download a named release * [helm get](helm_get.md) - download a named release
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -32,10 +32,11 @@ helm get values [flags] RELEASE_NAME
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm get](helm_get.md) - download a named release * [helm get](helm_get.md) - download a named release
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -44,10 +44,11 @@ helm history [flags] RELEASE_NAME
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -21,10 +21,11 @@ helm home
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -43,6 +43,7 @@ helm init
--node-selectors string labels to specify the node on which Tiller is installed (app=tiller,helm=rocks) --node-selectors string labels to specify the node on which Tiller is installed (app=tiller,helm=rocks)
-o, --output OutputFormat skip installation and output Tiller's manifest in specified format (json or yaml) -o, --output OutputFormat skip installation and output Tiller's manifest in specified format (json or yaml)
--override stringArray override values for the Tiller Deployment manifest (can specify multiple or separate values with commas: key1=val1,key2=val2) --override stringArray override values for the Tiller Deployment manifest (can specify multiple or separate values with commas: key1=val1,key2=val2)
--replicas int amount of tiller instances to run on the cluster (default 1)
--service-account string name of service account --service-account string name of service account
--skip-refresh do not refresh (download) the local repository cache --skip-refresh do not refresh (download) the local repository cache
--stable-repo-url string URL for stable repository (default "https://kubernetes-charts.storage.googleapis.com") --stable-repo-url string URL for stable repository (default "https://kubernetes-charts.storage.googleapis.com")
@ -63,10 +64,11 @@ helm init
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -35,6 +35,7 @@ helm inspect [CHART]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
@ -43,4 +44,4 @@ helm inspect [CHART]
* [helm inspect chart](helm_inspect_chart.md) - shows inspect chart * [helm inspect chart](helm_inspect_chart.md) - shows inspect chart
* [helm inspect values](helm_inspect_values.md) - shows inspect values * [helm inspect values](helm_inspect_values.md) - shows inspect values
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -33,10 +33,11 @@ helm inspect chart [CHART]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm inspect](helm_inspect.md) - inspect a chart * [helm inspect](helm_inspect.md) - inspect a chart
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -33,10 +33,11 @@ helm inspect values [CHART]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm inspect](helm_inspect.md) - inspect a chart * [helm inspect](helm_inspect.md) - inspect a chart
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -102,10 +102,11 @@ helm install [CHART]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -34,10 +34,11 @@ helm lint [flags] PATH
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -66,10 +66,11 @@ helm list [flags] [FILTER]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -40,10 +40,11 @@ helm package [flags] [CHART_PATH] [...]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -16,6 +16,7 @@ Manage client-side Helm plugins.
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
@ -26,4 +27,4 @@ Manage client-side Helm plugins.
* [helm plugin remove](helm_plugin_remove.md) - remove one or more 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 * [helm plugin update](helm_plugin_update.md) - update one or more Helm plugins
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -29,10 +29,11 @@ helm plugin install [options] <path|url>...
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -18,10 +18,11 @@ helm plugin list
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -18,10 +18,11 @@ helm plugin remove <plugin>...
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -18,10 +18,11 @@ helm plugin update <plugin>...
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins * [helm plugin](helm_plugin.md) - add, list, or remove Helm plugins
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -20,6 +20,7 @@ Example usage:
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
@ -31,4 +32,4 @@ Example usage:
* [helm repo remove](helm_repo_remove.md) - remove a chart repository * [helm repo remove](helm_repo_remove.md) - remove a chart repository
* [helm repo update](helm_repo_update.md) - update information of available charts locally from chart repositories * [helm repo update](helm_repo_update.md) - update information of available charts locally from chart repositories
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -27,10 +27,11 @@ helm repo add [flags] [NAME] [URL]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -34,10 +34,11 @@ helm repo index [flags] [DIR]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -18,10 +18,11 @@ helm repo list [flags]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -18,10 +18,11 @@ helm repo remove [flags] [NAME]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -24,10 +24,11 @@ helm repo update
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories * [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -34,10 +34,11 @@ helm reset
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 8-Feb-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -40,10 +40,11 @@ helm rollback [flags] [RELEASE] [REVISION]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -31,10 +31,11 @@ helm search [keyword]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -39,10 +39,11 @@ helm serve
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -39,10 +39,11 @@ helm status [flags] RELEASE_NAME
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -43,10 +43,11 @@ helm template [flags] CHART
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -35,10 +35,11 @@ helm test [RELEASE]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -70,10 +70,11 @@ helm upgrade [RELEASE] [CHART]
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -33,10 +33,11 @@ helm verify [flags] PATH
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jan-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -48,10 +48,11 @@ helm version
--home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm") --home string location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
--host string address of Tiller. Overrides $HELM_HOST --host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use --kube-context string name of the kubeconfig context to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300)
--tiller-namespace string namespace of Tiller (default "kube-system") --tiller-namespace string namespace of Tiller (default "kube-system")
``` ```
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 11-Feb-2018 ###### Auto generated by spf13/cobra on 8-Mar-2018

@ -52,6 +52,12 @@ $ helm package --sign --key 'helm signing key' --keyring path/to/keyring.secret
**TIP:** for GnuPG users, your secret keyring is in `~/.gnupg/secring.gpg`. You can **TIP:** for GnuPG users, your secret keyring is in `~/.gnupg/secring.gpg`. You can
use `gpg --list-secret-keys` to list the keys you have. use `gpg --list-secret-keys` to list the keys you have.
**Warning:** the GnuPG v2 store your secret keyring using a new format 'kbx' on the default location '~/.gnupg/pubring.kbx'. Please use the following command to convert your keyring to the legacy gpg format:
```
$ gpg --export-secret-keys >~/.gnupg/secring.gpg
```
At this point, you should see both `mychart-0.1.0.tgz` and `mychart-0.1.0.tgz.prov`. At this point, you should see both `mychart-0.1.0.tgz` and `mychart-0.1.0.tgz.prov`.
Both files should eventually be uploaded to your desired chart repository. Both files should eventually be uploaded to your desired chart repository.

@ -41,6 +41,8 @@ or [pull request](https://github.com/kubernetes/helm/pulls).
- [helm-github](https://github.com/sagansystems/helm-github) - Plugin to install Helm Charts from Github repositories - [helm-github](https://github.com/sagansystems/helm-github) - Plugin to install Helm Charts from Github repositories
- [helm-monitor](https://github.com/ContainerSolutions/helm-monitor) - Plugin to monitor a release and rollback based on Prometheus/ElasticSearch query - [helm-monitor](https://github.com/ContainerSolutions/helm-monitor) - Plugin to monitor a release and rollback based on Prometheus/ElasticSearch query
- [helm-k8comp](https://github.com/cststack/k8comp) - Plugin to create Helm Charts from hiera using k8comp - [helm-k8comp](https://github.com/cststack/k8comp) - Plugin to create Helm Charts from hiera using k8comp
- [helm-hashtag](https://github.com/balboah/helm-hashtag) - Plugin for tracking docker tag hash digests as values
- [helm-unittest](https://github.com/lrills/helm-unittest) - Plugin for unit testing chart locally with YAML
We also encourage GitHub authors to use the [helm-plugin](https://github.com/search?q=topic%3Ahelm-plugin&type=Repositories) We also encourage GitHub authors to use the [helm-plugin](https://github.com/search?q=topic%3Ahelm-plugin&type=Repositories)
tag on their plugin repositories. tag on their plugin repositories.
@ -57,6 +59,7 @@ Tools layered on top of Helm or Tiller.
- [Rudder](https://github.com/AcalephStorage/rudder) - RESTful (JSON) proxy for Tiller's API - [Rudder](https://github.com/AcalephStorage/rudder) - RESTful (JSON) proxy for Tiller's API
- [Helmfile](https://github.com/roboll/helmfile) - Helmfile is a declarative spec for deploying helm charts - [Helmfile](https://github.com/roboll/helmfile) - Helmfile is a declarative spec for deploying helm charts
- [Autohelm](https://github.com/reactiveops/autohelm) - Autohelm is _another_ simple declarative spec for deploying helm charts. Written in python and supports git urls as a source for helm charts. - [Autohelm](https://github.com/reactiveops/autohelm) - Autohelm is _another_ simple declarative spec for deploying helm charts. Written in python and supports git urls as a source for helm charts.
- [Helmsman](https://github.com/Praqma/helmsman) - Helmsman is a helm-charts-as-code tool which enables installing/upgrading/protecting/moving/deleting releases from version controlled desired state files (described in a simple TOML format).
- [Schelm](https://github.com/databus23/schelm) - Render a Helm manifest to a directory - [Schelm](https://github.com/databus23/schelm) - Render a Helm manifest to a directory
- [Drone.io Helm Plugin](http://plugins.drone.io/ipedrazas/drone-helm/) - Run Helm inside of the Drone CI/CD system - [Drone.io Helm Plugin](http://plugins.drone.io/ipedrazas/drone-helm/) - Run Helm inside of the Drone CI/CD system
- [Cog](https://github.com/ohaiwalt/cog-helm) - Helm chart to deploy Cog on Kubernetes - [Cog](https://github.com/ohaiwalt/cog-helm) - Helm chart to deploy Cog on Kubernetes
@ -65,6 +68,7 @@ Tools layered on top of Helm or Tiller.
- [Armada](https://github.com/att-comdev/armada) - Manage prefixed releases throughout various Kubernetes namespaces, and removes completed jobs for complex deployments. Used by the [Openstack-Helm](https://github.com/openstack/openstack-helm) team. - [Armada](https://github.com/att-comdev/armada) - Manage prefixed releases throughout various Kubernetes namespaces, and removes completed jobs for complex deployments. Used by the [Openstack-Helm](https://github.com/openstack/openstack-helm) team.
- [ChartMuseum](https://github.com/chartmuseum/chartmuseum) - Helm Chart Repository with support for Amazon S3 and Google Cloud Storage - [ChartMuseum](https://github.com/chartmuseum/chartmuseum) - Helm Chart Repository with support for Amazon S3 and Google Cloud Storage
- [Helm.NET](https://github.com/qmfrederik/helm) - A .NET client for Tiller's API - [Helm.NET](https://github.com/qmfrederik/helm) - A .NET client for Tiller's API
- [Codefresh](https://codefresh.io) - Kubernetes native CI/CD and management platform with UI dashboards for managing Helm charts and releases
## Helm Included ## Helm Included

10
glide.lock generated

@ -1,5 +1,5 @@
hash: c4a1f6e380baf38d371d428fa5c8f7b2363663d811c728e982300692287a58e4 hash: d93f565214b112cf8560e9cd2da2f3ab7852a1f19544569fc112bd4fb2d1d506
updated: 2018-02-02T20:15:49.706602Z updated: 2018-03-08T14:06:06.497394911-08:00
imports: imports:
- name: cloud.google.com/go - name: cloud.google.com/go
version: 3b1ae45394a234c385be014e9a488f2bb6eef821 version: 3b1ae45394a234c385be014e9a488f2bb6eef821
@ -147,7 +147,7 @@ imports:
- name: github.com/go-openapi/swag - name: github.com/go-openapi/swag
version: f3f9494671f93fcff853e3c6e9e948b3eb71e590 version: f3f9494671f93fcff853e3c6e9e948b3eb71e590
- name: github.com/gobwas/glob - name: github.com/gobwas/glob
version: bea32b9cd2d6f55753d94a28e959b13f0244797a version: 5ccd90ef52e1e632236f7326478d4faa74f99438
subpackages: subpackages:
- compiler - compiler
- match - match
@ -168,7 +168,7 @@ imports:
subpackages: subpackages:
- lru - lru
- name: github.com/golang/protobuf - name: github.com/golang/protobuf
version: 4bd1920723d7b7c925de087aa32e2187708897f7 version: 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9
subpackages: subpackages:
- proto - proto
- ptypes - ptypes
@ -378,6 +378,8 @@ imports:
- credentials - credentials
- grpclb/grpc_lb_v1/messages - grpclb/grpc_lb_v1/messages
- grpclog - grpclog
- health
- health/grpc_health_v1
- internal - internal
- keepalive - keepalive
- metadata - metadata

@ -19,7 +19,7 @@ import:
version: ~1.3.1 version: ~1.3.1
- package: github.com/technosophos/moniker - package: github.com/technosophos/moniker
- package: github.com/golang/protobuf - package: github.com/golang/protobuf
version: 4bd1920723d7b7c925de087aa32e2187708897f7 version: 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9
subpackages: subpackages:
- proto - proto
- ptypes/any - ptypes/any
@ -53,7 +53,7 @@ import:
vcs: git vcs: git
- package: k8s.io/kubernetes - package: k8s.io/kubernetes
version: ~1.9.2 version: 1.9.2
- package: k8s.io/client-go - package: k8s.io/client-go
version: ~6.0.0 version: ~6.0.0
- package: k8s.io/api - package: k8s.io/api

@ -70,6 +70,12 @@ func SaveDir(c *chart.Chart, dest string) error {
// Save files // Save files
for _, f := range c.Files { for _, f := range c.Files {
n := filepath.Join(outdir, f.TypeUrl) n := filepath.Join(outdir, f.TypeUrl)
d := filepath.Dir(n)
if err := os.MkdirAll(d, 0755); err != nil {
return err
}
if err := ioutil.WriteFile(n, f.Value, 0755); err != nil { if err := ioutil.WriteFile(n, f.Value, 0755); err != nil {
return err return err
} }

@ -22,6 +22,7 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/golang/protobuf/ptypes/any"
"k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/proto/hapi/chart"
) )
@ -40,6 +41,9 @@ func TestSave(t *testing.T) {
Values: &chart.Config{ Values: &chart.Config{
Raw: "ship: Pequod", Raw: "ship: Pequod",
}, },
Files: []*any.Any{
{TypeUrl: "scheherazade/shahryar.txt", Value: []byte("1,001 Nights")},
},
} }
where, err := Save(c, tmp) where, err := Save(c, tmp)
@ -64,6 +68,9 @@ func TestSave(t *testing.T) {
if c2.Values.Raw != c.Values.Raw { if c2.Values.Raw != c.Values.Raw {
t.Fatal("Values data did not match") t.Fatal("Values data did not match")
} }
if len(c2.Files) != 1 || c2.Files[0].TypeUrl != "scheherazade/shahryar.txt" {
t.Fatal("Files data did not match")
}
} }
func TestSaveDir(t *testing.T) { func TestSaveDir(t *testing.T) {
@ -81,6 +88,9 @@ func TestSaveDir(t *testing.T) {
Values: &chart.Config{ Values: &chart.Config{
Raw: "ship: Pequod", Raw: "ship: Pequod",
}, },
Files: []*any.Any{
{TypeUrl: "scheherazade/shahryar.txt", Value: []byte("1,001 Nights")},
},
} }
if err := SaveDir(c, tmp); err != nil { if err := SaveDir(c, tmp); err != nil {
@ -98,4 +108,7 @@ func TestSaveDir(t *testing.T) {
if c2.Values.Raw != c.Values.Raw { if c2.Values.Raw != c.Values.Raw {
t.Fatal("Values data did not match") t.Fatal("Values data did not match")
} }
if len(c2.Files) != 1 || c2.Files[0].TypeUrl != "scheherazade/shahryar.txt" {
t.Fatal("Files data did not match")
}
} }

@ -76,6 +76,7 @@ func newHTTPGetter(URL, CertFile, KeyFile, CAFile string) (Getter, error) {
client.client = &http.Client{ client.client = &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: tlsConf, TLSClientConfig: tlsConf,
Proxy: http.ProxyFromEnvironment,
}, },
} }
} else { } else {

@ -26,6 +26,7 @@ import (
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive" "google.golang.org/grpc/keepalive"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
@ -353,7 +354,7 @@ func (h *Client) connect(ctx context.Context) (conn *grpc.ClientConn, err error)
default: default:
opts = append(opts, grpc.WithInsecure()) opts = append(opts, grpc.WithInsecure())
} }
ctx, cancel := context.WithTimeout(ctx, 5*time.Second) ctx, cancel := context.WithTimeout(ctx, h.opts.connectTimeout)
defer cancel() defer cancel()
if conn, err = grpc.DialContext(ctx, h.opts.host, opts...); err != nil { if conn, err = grpc.DialContext(ctx, h.opts.host, opts...); err != nil {
return nil, err return nil, err
@ -520,6 +521,17 @@ func (h *Client) ping(ctx context.Context) error {
} }
defer c.Close() defer c.Close()
rlc := rls.NewReleaseServiceClient(c) healthClient := healthpb.NewHealthClient(c)
return rlc.PingTiller(ctx) resp, err := healthClient.Check(ctx, &healthpb.HealthCheckRequest{Service: "Tiller"})
if err != nil {
return err
}
switch resp.GetStatus() {
case healthpb.HealthCheckResponse_SERVING:
return nil
case healthpb.HealthCheckResponse_NOT_SERVING:
return fmt.Errorf("tiller is not serving requests at this time, Please try again later")
default:
return fmt.Errorf("tiller healthcheck returned an unknown status")
}
} }

@ -39,6 +39,8 @@ var DefaultHelmHome = filepath.Join(homedir.HomeDir(), ".helm")
type EnvSettings struct { type EnvSettings struct {
// TillerHost is the host and port of Tiller. // TillerHost is the host and port of Tiller.
TillerHost string TillerHost string
// TillerConnectionTimeout is the duration (in seconds) helm will wait to establish a connection to tiller.
TillerConnectionTimeout int64
// TillerNamespace is the namespace in which Tiller runs. // TillerNamespace is the namespace in which Tiller runs.
TillerNamespace string TillerNamespace string
// Home is the local path to the Helm home directory. // Home is the local path to the Helm home directory.
@ -56,6 +58,7 @@ func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.KubeContext, "kube-context", "", "name of the kubeconfig context to use") fs.StringVar(&s.KubeContext, "kube-context", "", "name of the kubeconfig context to use")
fs.BoolVar(&s.Debug, "debug", false, "enable verbose output") fs.BoolVar(&s.Debug, "debug", false, "enable verbose output")
fs.StringVar(&s.TillerNamespace, "tiller-namespace", "kube-system", "namespace of Tiller") fs.StringVar(&s.TillerNamespace, "tiller-namespace", "kube-system", "namespace of Tiller")
fs.Int64Var(&s.TillerConnectionTimeout, "tiller-connection-timeout", int64(300), "the duration (in seconds) Helm will wait to establish a connection to tiller")
} }
// Init sets values from the environment. // Init sets values from the environment.

@ -194,7 +194,7 @@ var MockHookTemplate = `apiVersion: v1
kind: Job kind: Job
metadata: metadata:
annotations: annotations:
"helm.sh/hooks": pre-install "helm.sh/hook": pre-install
` `
// MockManifest is the manifest used for all mock release objects. // MockManifest is the manifest used for all mock release objects.

@ -18,6 +18,7 @@ package helm
import ( import (
"crypto/tls" "crypto/tls"
"time"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -78,6 +79,8 @@ type options struct {
reuseValues bool reuseValues bool
// release test options are applied directly to the test release history request // release test options are applied directly to the test release history request
testReq rls.TestReleaseRequest testReq rls.TestReleaseRequest
// connectTimeout specifies the time duration Helm will wait to establish a connection to tiller
connectTimeout time.Duration
} }
// Host specifies the host address of the Tiller release server, (default = ":44134"). // Host specifies the host address of the Tiller release server, (default = ":44134").
@ -180,6 +183,13 @@ func ReleaseName(name string) InstallOption {
} }
} }
// ConnectTimeout specifies the duration (in seconds) Helm will wait to establish a connection to tiller
func ConnectTimeout(timeout int64) Option {
return func(opts *options) {
opts.connectTimeout = time.Duration(timeout) * time.Second
}
}
// InstallTimeout specifies the number of seconds before kubernetes calls timeout // InstallTimeout specifies the number of seconds before kubernetes calls timeout
func InstallTimeout(timeout int64) InstallOption { func InstallTimeout(timeout int64) InstallOption {
return func(opts *options) { return func(opts *options) {

@ -30,12 +30,12 @@ import (
) )
var ( var (
tillerPodLabels labels.Set = labels.Set{"app": "helm", "name": "tiller"} tillerPodLabels = labels.Set{"app": "helm", "name": "tiller"}
) )
// New creates a new and initialized tunnel. // New creates a new and initialized tunnel.
func New(namespace string, client kubernetes.Interface, config *rest.Config) (*kube.Tunnel, error) { func New(namespace string, client kubernetes.Interface, config *rest.Config) (*kube.Tunnel, error) {
podName, err := getTillerPodName(client.CoreV1(), namespace) podName, err := GetTillerPodName(client.CoreV1(), namespace)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -44,7 +44,8 @@ func New(namespace string, client kubernetes.Interface, config *rest.Config) (*k
return t, t.ForwardPort() return t, t.ForwardPort()
} }
func getTillerPodName(client corev1.PodsGetter, namespace string) (string, error) { // GetTillerPodName fetches the name of tiller pod running in the given namespace.
func GetTillerPodName(client corev1.PodsGetter, namespace string) (string, error) {
selector := tillerPodLabels.AsSelector() selector := tillerPodLabels.AsSelector()
pod, err := getFirstRunningPod(client, namespace, selector) pod, err := getFirstRunningPod(client, namespace, selector)
if err != nil { if err != nil {

@ -76,7 +76,7 @@ func TestGetFirstPod(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
client := fake.NewSimpleClientset(&v1.PodList{Items: tt.pods}) client := fake.NewSimpleClientset(&v1.PodList{Items: tt.pods})
name, err := getTillerPodName(client.Core(), v1.NamespaceDefault) name, err := GetTillerPodName(client.Core(), v1.NamespaceDefault)
if (err != nil) != tt.err { if (err != nil) != tt.err {
t.Errorf("%q. expected error: %v, got %v", tt.name, tt.err, err) t.Errorf("%q. expected error: %v, got %v", tt.name, tt.err, err)
} }

@ -107,7 +107,7 @@ type Metadata struct {
// Annotations are additional mappings uninterpreted by Tiller, // Annotations are additional mappings uninterpreted by Tiller,
// made available for inspection by other applications. // made available for inspection by other applications.
Annotations map[string]string `protobuf:"bytes,16,rep,name=annotations" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` Annotations map[string]string `protobuf:"bytes,16,rep,name=annotations" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
// KubeVersion is a SemVer constraints on what version of Kubernetes is required. // KubeVersion is a SemVer constraint specifying the version of Kubernetes required.
KubeVersion string `protobuf:"bytes,17,opt,name=kubeVersion" json:"kubeVersion,omitempty"` KubeVersion string `protobuf:"bytes,17,opt,name=kubeVersion" json:"kubeVersion,omitempty"`
} }
@ -244,32 +244,33 @@ func init() {
func init() { proto.RegisterFile("hapi/chart/metadata.proto", fileDescriptor2) } func init() { proto.RegisterFile("hapi/chart/metadata.proto", fileDescriptor2) }
var fileDescriptor2 = []byte{ var fileDescriptor2 = []byte{
// 427 bytes of a gzipped FileDescriptorProto // 435 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0x5d, 0x6b, 0xdb, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0x5d, 0x6b, 0xd4, 0x40,
0x14, 0x9d, 0x9b, 0x38, 0x89, 0xaf, 0xd7, 0xcd, 0xbb, 0x8c, 0xa2, 0x95, 0x31, 0x4c, 0xd8, 0x20, 0x14, 0x35, 0xcd, 0x66, 0x77, 0x73, 0x63, 0x35, 0x0e, 0x52, 0xc6, 0x22, 0x12, 0x16, 0x85, 0x7d,
0x4f, 0x29, 0x6c, 0x30, 0xca, 0x1e, 0x06, 0x1b, 0x94, 0x3e, 0x6c, 0x4d, 0x87, 0xd9, 0x07, 0xec, 0xda, 0x82, 0xbe, 0x14, 0x1f, 0x04, 0x85, 0x52, 0x41, 0xbb, 0x95, 0xe0, 0x07, 0xf8, 0x36, 0x4d,
0x4d, 0xb5, 0x2f, 0x8d, 0x48, 0x2c, 0x19, 0x49, 0xe9, 0xc8, 0xaf, 0xd8, 0x5f, 0x1e, 0x92, 0xad, 0x2e, 0xdd, 0x61, 0x93, 0x99, 0x30, 0x99, 0xad, 0xec, 0xaf, 0xf0, 0x2f, 0xcb, 0xdc, 0x64, 0x9a,
0xda, 0x19, 0x7d, 0xbb, 0xe7, 0x1c, 0xdd, 0x23, 0x1d, 0xdd, 0x0b, 0x2f, 0xd6, 0xbc, 0x11, 0x67, 0xac, 0xf4, 0xed, 0x9e, 0x73, 0x66, 0xce, 0xcc, 0xbd, 0xf7, 0xc0, 0x8b, 0x8d, 0x68, 0xe4, 0x59,
0xe5, 0x9a, 0x6b, 0x7b, 0x56, 0x93, 0xe5, 0x15, 0xb7, 0x7c, 0xd9, 0x68, 0x65, 0x15, 0x82, 0x93, 0xb1, 0x11, 0xc6, 0x9e, 0xd5, 0x68, 0x45, 0x29, 0xac, 0x58, 0x35, 0x46, 0x5b, 0xcd, 0xc0, 0x49,
0x96, 0x5e, 0x9a, 0xbf, 0x07, 0xb8, 0xe2, 0x42, 0x5a, 0x2e, 0x24, 0x69, 0x44, 0x18, 0x4b, 0x5e, 0x2b, 0x92, 0x16, 0x9f, 0x01, 0xae, 0x84, 0x54, 0x56, 0x48, 0x85, 0x86, 0x31, 0x98, 0x28, 0x51,
0x13, 0x8b, 0xf2, 0x68, 0x91, 0x14, 0xbe, 0xc6, 0xe7, 0x10, 0x53, 0xcd, 0xc5, 0x96, 0x1d, 0x79, 0x23, 0x0f, 0xb2, 0x60, 0x19, 0xe7, 0x54, 0xb3, 0xe7, 0x10, 0x61, 0x2d, 0x64, 0xc5, 0x8f, 0x88,
0xb2, 0x05, 0xf3, 0xbf, 0x31, 0xcc, 0xae, 0x3a, 0xdb, 0x07, 0xdb, 0x10, 0xc6, 0x6b, 0x55, 0x53, 0xec, 0x00, 0x4b, 0x21, 0xdc, 0x99, 0x8a, 0x87, 0xc4, 0xb9, 0x72, 0xf1, 0x37, 0x82, 0xf9, 0x55,
0xd7, 0xe5, 0x6b, 0x64, 0x30, 0x35, 0x6a, 0xa7, 0x4b, 0x32, 0x6c, 0x94, 0x8f, 0x16, 0x49, 0x11, 0xff, 0xd0, 0x83, 0x46, 0x0c, 0x26, 0x1b, 0x5d, 0x63, 0xef, 0x43, 0x35, 0xe3, 0x30, 0x6b, 0xf5,
0xa0, 0x53, 0xee, 0x48, 0x1b, 0xa1, 0x24, 0x1b, 0xfb, 0x86, 0x00, 0x31, 0x87, 0xb4, 0x22, 0x53, 0xce, 0x14, 0xd8, 0xf2, 0x30, 0x0b, 0x97, 0x71, 0xee, 0xa1, 0x53, 0xee, 0xd0, 0xb4, 0x52, 0x2b,
0x6a, 0xd1, 0x58, 0xa7, 0xc6, 0x5e, 0x1d, 0x52, 0x78, 0x0a, 0xb3, 0x0d, 0xed, 0xff, 0x28, 0x5d, 0x3e, 0xa1, 0x0b, 0x1e, 0xb2, 0x0c, 0x92, 0x12, 0xdb, 0xc2, 0xc8, 0xc6, 0x3a, 0x35, 0x22, 0x75,
0x19, 0x36, 0xf1, 0xb6, 0xf7, 0x18, 0xcf, 0x21, 0xad, 0xef, 0xe3, 0x19, 0x36, 0xcd, 0x47, 0x8b, 0x4c, 0xb1, 0x53, 0x98, 0x6f, 0x71, 0xff, 0x47, 0x9b, 0xb2, 0xe5, 0x53, 0xb2, 0xbd, 0xc7, 0xec,
0xf4, 0xed, 0xc9, 0xb2, 0xff, 0x80, 0x65, 0x9f, 0xbe, 0x18, 0x1e, 0xc5, 0x13, 0x98, 0x90, 0xbc, 0x1c, 0x92, 0xfa, 0xbe, 0xe1, 0x96, 0xcf, 0xb2, 0x70, 0x99, 0xbc, 0x3d, 0x59, 0x0d, 0x23, 0x59,
0x15, 0x92, 0xd8, 0xcc, 0x5f, 0xd9, 0x21, 0x97, 0x4b, 0x94, 0x4a, 0xb2, 0xa4, 0xcd, 0xe5, 0x6a, 0x0d, 0xf3, 0xc8, 0xc7, 0x47, 0xd9, 0x09, 0x4c, 0x51, 0xdd, 0x4a, 0x85, 0x7c, 0x4e, 0x4f, 0xf6,
0x7c, 0x05, 0xc0, 0x1b, 0xf1, 0xb3, 0x0b, 0x00, 0x5e, 0x19, 0x30, 0xf8, 0x12, 0x92, 0x52, 0xc9, 0xc8, 0xf5, 0x25, 0x0b, 0xad, 0x78, 0xdc, 0xf5, 0xe5, 0x6a, 0xf6, 0x0a, 0x40, 0x34, 0xf2, 0x67,
0x4a, 0xf8, 0x04, 0xa9, 0x97, 0x7b, 0xc2, 0x39, 0x5a, 0x7e, 0x6b, 0xd8, 0xe3, 0xd6, 0xd1, 0xd5, 0xdf, 0x00, 0x90, 0x32, 0x62, 0xd8, 0x4b, 0x88, 0x0b, 0xad, 0x4a, 0x49, 0x1d, 0x24, 0x24, 0x0f,
0xad, 0x63, 0x13, 0x1c, 0x8f, 0x83, 0x63, 0x60, 0x9c, 0x5e, 0x51, 0xa3, 0xa9, 0xe4, 0x96, 0x2a, 0x84, 0x73, 0xb4, 0xe2, 0xb6, 0xe5, 0x8f, 0x3b, 0x47, 0x57, 0x77, 0x8e, 0x8d, 0x77, 0x3c, 0xf6,
0xf6, 0x24, 0x8f, 0x16, 0xb3, 0x62, 0xc0, 0xe0, 0x6b, 0x38, 0xb6, 0x62, 0xbb, 0x25, 0x1d, 0x2c, 0x8e, 0x9e, 0x71, 0x7a, 0x89, 0x8d, 0xc1, 0x42, 0x58, 0x2c, 0xf9, 0x93, 0x2c, 0x58, 0xce, 0xf3,
0x9e, 0x7a, 0x8b, 0x43, 0x12, 0x2f, 0x21, 0xe5, 0x52, 0x2a, 0xcb, 0xdd, 0x3b, 0x0c, 0xcb, 0xfc, 0x11, 0xc3, 0x5e, 0xc3, 0xb1, 0x95, 0x55, 0x85, 0xc6, 0x5b, 0x3c, 0x25, 0x8b, 0x43, 0x92, 0x5d,
0xef, 0xbc, 0x39, 0xf8, 0x9d, 0xb0, 0x39, 0x9f, 0xfa, 0x73, 0x17, 0xd2, 0xea, 0x7d, 0x31, 0xec, 0x42, 0x22, 0x94, 0xd2, 0x56, 0xb8, 0x7f, 0xb4, 0x3c, 0xa5, 0xe9, 0xbc, 0x39, 0x98, 0x8e, 0xcf,
0x74, 0x43, 0xda, 0xec, 0x6e, 0x28, 0x5c, 0xf6, 0xac, 0x1d, 0xd2, 0x80, 0x3a, 0xfd, 0x08, 0xd9, 0xd2, 0xc7, 0xe1, 0xdc, 0x85, 0xb2, 0x66, 0x9f, 0x8f, 0x6f, 0xba, 0x25, 0x6d, 0x77, 0x37, 0xe8,
0xff, 0x16, 0x98, 0xc1, 0x68, 0x43, 0xfb, 0x6e, 0x6b, 0x5c, 0xe9, 0x76, 0xed, 0x8e, 0x6f, 0x77, 0x1f, 0x7b, 0xd6, 0x2d, 0x69, 0x44, 0x9d, 0x7e, 0x80, 0xf4, 0x7f, 0x0b, 0x97, 0xaa, 0x2d, 0xee,
0x61, 0x6b, 0x5a, 0xf0, 0xe1, 0xe8, 0x3c, 0x9a, 0xe7, 0x30, 0xb9, 0x68, 0x07, 0x90, 0xc2, 0xf4, 0xfb, 0xd4, 0xb8, 0xd2, 0xa5, 0xef, 0x4e, 0x54, 0x3b, 0x9f, 0x9a, 0x0e, 0xbc, 0x3f, 0x3a, 0x0f,
0xc7, 0xea, 0xcb, 0xea, 0xfa, 0xd7, 0x2a, 0x7b, 0x84, 0x09, 0xc4, 0x97, 0xd7, 0xdf, 0xbf, 0x7d, 0x16, 0x19, 0x4c, 0x2f, 0xba, 0x05, 0x24, 0x30, 0xfb, 0xb1, 0xfe, 0xb2, 0xbe, 0xfe, 0xb5, 0x4e,
0xcd, 0xa2, 0xcf, 0xd3, 0xdf, 0xb1, 0x7f, 0xf3, 0xcd, 0xc4, 0x6f, 0xf9, 0xbb, 0x7f, 0x01, 0x00, 0x1f, 0xb1, 0x18, 0xa2, 0xcb, 0xeb, 0xef, 0xdf, 0xbe, 0xa6, 0xc1, 0xa7, 0xd9, 0xef, 0x88, 0xfe,
0x00, 0xff, 0xff, 0x7f, 0xc1, 0xec, 0x3d, 0x02, 0x03, 0x00, 0x00, 0x7c, 0x33, 0xa5, 0xdc, 0xbf, 0xfb, 0x17, 0x00, 0x00, 0xff, 0xff, 0x36, 0xf9, 0x0d, 0xa6, 0x14,
0x03, 0x00, 0x00,
} }

@ -6,9 +6,19 @@ Package release is a generated protocol buffer package.
It is generated from these files: It is generated from these files:
hapi/release/hook.proto hapi/release/hook.proto
hapi/release/info.proto
hapi/release/release.proto
hapi/release/status.proto
hapi/release/test_run.proto
hapi/release/test_suite.proto
It has these top-level messages: It has these top-level messages:
Hook Hook
Info
Release
Status
TestRun
TestSuite
*/ */
package release package release

@ -275,7 +275,7 @@ type GetReleaseStatusResponse struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
// Info contains information about the release. // Info contains information about the release.
Info *hapi_release4.Info `protobuf:"bytes,2,opt,name=info" json:"info,omitempty"` Info *hapi_release4.Info `protobuf:"bytes,2,opt,name=info" json:"info,omitempty"`
// Namesapce the release was released into // Namespace the release was released into
Namespace string `protobuf:"bytes,3,opt,name=namespace" json:"namespace,omitempty"` Namespace string `protobuf:"bytes,3,opt,name=namespace" json:"namespace,omitempty"`
} }
@ -949,8 +949,6 @@ type ReleaseServiceClient interface {
GetHistory(ctx context.Context, in *GetHistoryRequest, opts ...grpc.CallOption) (*GetHistoryResponse, error) GetHistory(ctx context.Context, in *GetHistoryRequest, opts ...grpc.CallOption) (*GetHistoryResponse, error)
// RunReleaseTest executes the tests defined of a named release // RunReleaseTest executes the tests defined of a named release
RunReleaseTest(ctx context.Context, in *TestReleaseRequest, opts ...grpc.CallOption) (ReleaseService_RunReleaseTestClient, error) RunReleaseTest(ctx context.Context, in *TestReleaseRequest, opts ...grpc.CallOption) (ReleaseService_RunReleaseTestClient, error)
// PingTiller sends a test/ping signal to Tiller to ensure that it's up
PingTiller(ctx context.Context) error
} }
type releaseServiceClient struct { type releaseServiceClient struct {
@ -1080,14 +1078,6 @@ func (c *releaseServiceClient) RunReleaseTest(ctx context.Context, in *TestRelea
return x, nil return x, nil
} }
func (c *releaseServiceClient) PingTiller(ctx context.Context) error {
err := grpc.Invoke(ctx, "/hapi.services.tiller.ReleaseService/PingTiller", "Ping", nil, c.cc, grpc.FailFast(false))
if err != nil {
return err
}
return nil
}
type ReleaseService_RunReleaseTestClient interface { type ReleaseService_RunReleaseTestClient interface {
Recv() (*TestReleaseResponse, error) Recv() (*TestReleaseResponse, error)
grpc.ClientStream grpc.ClientStream
@ -1310,10 +1300,6 @@ func _ReleaseService_RunReleaseTest_Handler(srv interface{}, stream grpc.ServerS
return srv.(ReleaseServiceServer).RunReleaseTest(m, &releaseServiceRunReleaseTestServer{stream}) return srv.(ReleaseServiceServer).RunReleaseTest(m, &releaseServiceRunReleaseTestServer{stream})
} }
func _ReleaseService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
return "Pong", nil
}
type ReleaseService_RunReleaseTestServer interface { type ReleaseService_RunReleaseTestServer interface {
Send(*TestReleaseResponse) error Send(*TestReleaseResponse) error
grpc.ServerStream grpc.ServerStream
@ -1363,10 +1349,6 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{
MethodName: "GetHistory", MethodName: "GetHistory",
Handler: _ReleaseService_GetHistory_Handler, Handler: _ReleaseService_GetHistory_Handler,
}, },
{
MethodName: "PingTiller",
Handler: _ReleaseService_Ping_Handler,
},
}, },
Streams: []grpc.StreamDesc{ Streams: []grpc.StreamDesc{
{ {

@ -129,6 +129,10 @@ func (s *Storage) Deployed(name string) (*rspb.Release, error) {
return nil, err return nil, err
} }
if len(ls) == 0 {
return nil, fmt.Errorf("%q has no deployed releases", name)
}
return ls[0], err return ls[0], err
} }

@ -18,6 +18,7 @@ package tiller
import ( import (
"fmt" "fmt"
"strings"
ctx "golang.org/x/net/context" ctx "golang.org/x/net/context"
@ -37,6 +38,10 @@ func (s *ReleaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease
s.Log("preparing update for %s", req.Name) s.Log("preparing update for %s", req.Name)
currentRelease, updatedRelease, err := s.prepareUpdate(req) currentRelease, updatedRelease, err := s.prepareUpdate(req)
if err != nil { if err != nil {
if req.Force {
// Use the --force, Luke.
return s.performUpdateForce(req)
}
return nil, err return nil, err
} }
@ -137,6 +142,113 @@ func (s *ReleaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*rele
return currentRelease, updatedRelease, err return currentRelease, updatedRelease, err
} }
// performUpdateForce performs the same action as a `helm delete && helm install --replace`.
func (s *ReleaseServer) performUpdateForce(req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) {
// find the last release with the given name
oldRelease, err := s.env.Releases.Last(req.Name)
if err != nil {
return nil, err
}
newRelease, err := s.prepareRelease(&services.InstallReleaseRequest{
Chart: req.Chart,
Values: req.Values,
DryRun: req.DryRun,
Name: req.Name,
DisableHooks: req.DisableHooks,
Namespace: oldRelease.Namespace,
ReuseName: true,
Timeout: req.Timeout,
Wait: req.Wait,
})
res := &services.UpdateReleaseResponse{Release: newRelease}
if err != nil {
s.Log("failed update prepare step: %s", err)
// On dry run, append the manifest contents to a failed release. This is
// a stop-gap until we can revisit an error backchannel post-2.0.
if req.DryRun && strings.HasPrefix(err.Error(), "YAML parse error") {
err = fmt.Errorf("%s\n%s", err, newRelease.Manifest)
}
return res, err
}
// From here on out, the release is considered to be in Status_DELETING or Status_DELETED
// state. There is no turning back.
oldRelease.Info.Status.Code = release.Status_DELETING
oldRelease.Info.Deleted = timeconv.Now()
oldRelease.Info.Description = "Deletion in progress (or silently failed)"
s.recordRelease(oldRelease, true)
// pre-delete hooks
if !req.DisableHooks {
if err := s.execHook(oldRelease.Hooks, oldRelease.Name, oldRelease.Namespace, hooks.PreDelete, req.Timeout); err != nil {
return res, err
}
} else {
s.Log("hooks disabled for %s", req.Name)
}
// delete manifests from the old release
_, errs := s.ReleaseModule.Delete(oldRelease, nil, s.env)
oldRelease.Info.Status.Code = release.Status_DELETED
oldRelease.Info.Description = "Deletion complete"
s.recordRelease(oldRelease, true)
if len(errs) > 0 {
es := make([]string, 0, len(errs))
for _, e := range errs {
s.Log("error: %v", e)
es = append(es, e.Error())
}
return res, fmt.Errorf("Upgrade --force successfully deleted the previous release, but encountered %d error(s) and cannot continue: %s", len(es), strings.Join(es, "; "))
}
// post-delete hooks
if !req.DisableHooks {
if err := s.execHook(oldRelease.Hooks, oldRelease.Name, oldRelease.Namespace, hooks.PostDelete, req.Timeout); err != nil {
return res, err
}
}
// pre-install hooks
if !req.DisableHooks {
if err := s.execHook(newRelease.Hooks, newRelease.Name, newRelease.Namespace, hooks.PreInstall, req.Timeout); err != nil {
return res, err
}
}
// update new release with next revision number so as to append to the old release's history
newRelease.Version = oldRelease.Version + 1
s.recordRelease(newRelease, false)
if err := s.ReleaseModule.Update(oldRelease, newRelease, req, s.env); err != nil {
msg := fmt.Sprintf("Upgrade %q failed: %s", newRelease.Name, err)
s.Log("warning: %s", msg)
newRelease.Info.Status.Code = release.Status_FAILED
newRelease.Info.Description = msg
s.recordRelease(newRelease, true)
return res, err
}
// post-install hooks
if !req.DisableHooks {
if err := s.execHook(newRelease.Hooks, newRelease.Name, newRelease.Namespace, hooks.PostInstall, req.Timeout); err != nil {
msg := fmt.Sprintf("Release %q failed post-install: %s", newRelease.Name, err)
s.Log("warning: %s", msg)
newRelease.Info.Status.Code = release.Status_FAILED
newRelease.Info.Description = msg
s.recordRelease(newRelease, true)
return res, err
}
}
newRelease.Info.Status.Code = release.Status_DEPLOYED
newRelease.Info.Description = "Upgrade complete"
s.recordRelease(newRelease, true)
return res, nil
}
func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.Release, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) { func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.Release, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) {
res := &services.UpdateReleaseResponse{Release: updatedRelease} res := &services.UpdateReleaseResponse{Release: updatedRelease}

@ -225,9 +225,9 @@ func TestUpdateReleaseFailure(t *testing.T) {
compareStoredAndReturnedRelease(t, *rs, *res) compareStoredAndReturnedRelease(t, *rs, *res)
edesc := "Upgrade \"angry-panda\" failed: Failed update in kube client" expectedDescription := "Upgrade \"angry-panda\" failed: Failed update in kube client"
if got := res.Release.Info.Description; got != edesc { if got := res.Release.Info.Description; got != expectedDescription {
t.Errorf("Expected description %q, got %q", edesc, got) t.Errorf("Expected description %q, got %q", expectedDescription, got)
} }
oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version) oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version)
@ -239,6 +239,50 @@ func TestUpdateReleaseFailure(t *testing.T) {
} }
} }
func TestUpdateReleaseFailure_Force(t *testing.T) {
c := helm.NewContext()
rs := rsFixture()
rel := namedReleaseStub("forceful-luke", release.Status_FAILED)
rs.env.Releases.Create(rel)
rs.Log = t.Logf
req := &services.UpdateReleaseRequest{
Name: rel.Name,
DisableHooks: true,
Chart: &chart.Chart{
Metadata: &chart.Metadata{Name: "hello"},
Templates: []*chart.Template{
{Name: "templates/something", Data: []byte("text: 'Did you ever hear the tragedy of Darth Plagueis the Wise? I thought not. Its not a story the Jedi would tell you. Its a Sith legend. Darth Plagueis was a Dark Lord of the Sith, so powerful and so wise he could use the Force to influence the Midichlorians to create life... He had such a knowledge of the Dark Side that he could even keep the ones he cared about from dying. The Dark Side of the Force is a pathway to many abilities some consider to be unnatural. He became so powerful... The only thing he was afraid of was losing his power, which eventually, of course, he did. Unfortunately, he taught his apprentice everything he knew, then his apprentice killed him in his sleep. Ironic. He could save others from death, but not himself.'")},
},
},
Force: true,
}
res, err := rs.UpdateRelease(c, req)
if err != nil {
t.Errorf("Expected successful update, got %v", err)
}
if updatedStatus := res.Release.Info.Status.Code; updatedStatus != release.Status_DEPLOYED {
t.Errorf("Expected DEPLOYED release. Got %d", updatedStatus)
}
compareStoredAndReturnedRelease(t, *rs, *res)
expectedDescription := "Upgrade complete"
if got := res.Release.Info.Description; got != expectedDescription {
t.Errorf("Expected description %q, got %q", expectedDescription, got)
}
oldRelease, err := rs.env.Releases.Get(rel.Name, rel.Version)
if err != nil {
t.Errorf("Expected to be able to get previous release")
}
if oldStatus := oldRelease.Info.Status.Code; oldStatus != release.Status_DELETED {
t.Errorf("Expected Deleted status on previous Release version. Got %v", oldStatus)
}
}
func TestUpdateReleaseNoHooks(t *testing.T) { func TestUpdateReleaseNoHooks(t *testing.T) {
c := helm.NewContext() c := helm.NewContext()
rs := rsFixture() rs := rsFixture()

Loading…
Cancel
Save