Merge branch 'master' of github.com:helm/helm

pull/4392/head
Bob Aman 7 years ago
commit bb67576baa
No known key found for this signature in database
GPG Key ID: B54B66D451D49893

@ -53,7 +53,7 @@ An issue that we are not sure we will be doing will not be added to any mileston
A milestone (and hence release) is considered done when all outstanding issues/PRs have been closed or moved to another milestone. A milestone (and hence release) is considered done when all outstanding issues/PRs have been closed or moved to another milestone.
## Semver ## Semantic Versioning
Helm maintains a strong commitment to backward compatibility. All of our changes to protocols and formats are backward compatible from Helm 2.0 until Helm 3.0. No features, flags, or commands are removed or substantially modified (other than bug fixes). Helm maintains a strong commitment to backward compatibility. All of our changes to protocols and formats are backward compatible from Helm 2.0 until Helm 3.0. No features, flags, or commands are removed or substantially modified (other than bug fixes).

@ -2,7 +2,7 @@ DOCKER_REGISTRY ?= gcr.io
IMAGE_PREFIX ?= kubernetes-helm IMAGE_PREFIX ?= kubernetes-helm
SHORT_NAME ?= tiller SHORT_NAME ?= tiller
SHORT_NAME_RUDDER ?= rudder SHORT_NAME_RUDDER ?= rudder
TARGETS ?= darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le windows/amd64 TARGETS ?= darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le linux/s390x windows/amd64
DIST_DIRS = find * -type d -exec DIST_DIRS = find * -type d -exec
APP = helm APP = helm

@ -28,3 +28,4 @@ emeritus:
- migmartri - migmartri
- seh - seh
- vaikas-google - vaikas-google
- rimusz

@ -1,7 +1,7 @@
# Kubernetes Helm # Kubernetes Helm
[![CircleCI](https://circleci.com/gh/kubernetes/helm.svg?style=svg)](https://circleci.com/gh/kubernetes/helm) [![CircleCI](https://circleci.com/gh/helm/helm.svg?style=svg)](https://circleci.com/gh/helm/helm)
[![Go Report Card](https://goreportcard.com/badge/github.com/kubernetes/helm)](https://goreportcard.com/report/github.com/kubernetes/helm) [![Go Report Card](https://goreportcard.com/badge/github.com/helm/helm)](https://goreportcard.com/report/github.com/helm/helm)
[![GoDoc](https://godoc.org/github.com/kubernetes/helm?status.svg)](https://godoc.org/github.com/kubernetes/helm) [![GoDoc](https://godoc.org/github.com/kubernetes/helm?status.svg)](https://godoc.org/github.com/kubernetes/helm)
Helm is a tool for managing Kubernetes charts. Charts are packages of Helm is a tool for managing Kubernetes charts. Charts are packages of
@ -9,7 +9,7 @@ pre-configured Kubernetes resources.
Use Helm to: Use Helm to:
- Find and use [popular software packaged as Kubernetes charts](https://github.com/kubernetes/charts) - Find and use [popular software packaged as Kubernetes charts](https://github.com/helm/charts)
- Share your own applications as Kubernetes charts - Share your own applications as Kubernetes charts
- Create reproducible builds of your Kubernetes applications - Create reproducible builds of your Kubernetes applications
- Intelligently manage your Kubernetes manifest files - Intelligently manage your Kubernetes manifest files
@ -32,7 +32,7 @@ Think of it like apt/yum/homebrew for Kubernetes.
## Install ## Install
Binary downloads of the Helm client can be found on [the latest Releases page](https://github.com/kubernetes/helm/releases/latest). Binary downloads of the Helm client can be found on [the latest Releases page](https://github.com/helm/helm/releases/latest).
Unpack the `helm` binary and add it to your PATH and you are good to go! Unpack the `helm` binary and add it to your PATH and you are good to go!
@ -52,7 +52,7 @@ Get started with the [Quick Start guide](https://docs.helm.sh/using_helm/#quicks
## Roadmap ## Roadmap
The [Helm roadmap uses Github milestones](https://github.com/kubernetes/helm/milestones) to track the progress of the project. The [Helm roadmap uses Github milestones](https://github.com/helm/helm/milestones) to track the progress of the project.
## Community, discussion, contribution, and support ## Community, discussion, contribution, and support

@ -0,0 +1,20 @@
# Defined below are the security contacts for this repo.
#
# They are the contact point for the Product Security Team to reach out
# to for triaging and handling of incoming issues.
#
# The below names agree to abide by the
# [Embargo Policy](https://github.com/kubernetes/sig-release/blob/master/security-release-process-documentation/security-release-process.md#embargo-policy)
# and will be removed and replaced if they violate that agreement.
#
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
# INSTRUCTIONS AT https://github.com/kubernetes/helm/blob/master/CONTRIBUTING.md#reporting-a-security-issue
adamreese
bacongobbler
mattfarina
michelleN
prydonius
SlickNik
technosophos
thomastaylor312

@ -89,7 +89,7 @@ service ReleaseService {
// //
// Releases can be retrieved in chunks by setting limit and offset. // Releases can be retrieved in chunks by setting limit and offset.
// //
// Releases can be sorted according to a few pre-determined sort stategies. // Releases can be sorted according to a few pre-determined sort strategies.
message ListReleasesRequest { message ListReleasesRequest {
// Limit is the maximum number of releases to be returned. // Limit is the maximum number of releases to be returned.
int64 limit = 1; int64 limit = 1;
@ -209,6 +209,8 @@ message UpdateReleaseRequest {
bool reuse_values = 10; bool reuse_values = 10;
// Force resource update through delete/recreate if needed. // Force resource update through delete/recreate if needed.
bool force = 11; bool force = 11;
// Description, if set, will set the description for the updated release
string description = 12;
} }
// UpdateReleaseResponse is the response to an update request. // UpdateReleaseResponse is the response to an update request.
@ -234,6 +236,8 @@ message RollbackReleaseRequest {
bool wait = 7; bool wait = 7;
// Force resource update through delete/recreate if needed. // Force resource update through delete/recreate if needed.
bool force = 8; bool force = 8;
// Description, if set, will set the description for the rollback
string description = 9;
} }
// RollbackReleaseResponse is the response to an update request. // RollbackReleaseResponse is the response to an update request.
@ -260,10 +264,10 @@ message InstallReleaseRequest {
// DisableHooks causes the server to skip running any hooks for the install. // DisableHooks causes the server to skip running any hooks for the install.
bool disable_hooks = 5; bool disable_hooks = 5;
// Namepace is the kubernetes namespace of the release. // Namespace is the kubernetes namespace of the release.
string namespace = 6; string namespace = 6;
// ReuseName requests that Tiller re-uses a name, instead of erroring out. // Reuse_name requests that Tiller re-uses a name, instead of erroring out.
bool reuse_name = 7; bool reuse_name = 7;
// timeout specifies the max amount of time any kubernetes client command can run. // timeout specifies the max amount of time any kubernetes client command can run.
@ -273,6 +277,9 @@ message InstallReleaseRequest {
bool wait = 9; bool wait = 9;
bool disable_crd_hook = 10; bool disable_crd_hook = 10;
// Description, if set, will set the description for the installed release
string description = 11;
} }
// InstallReleaseResponse is the response from a release installation. // InstallReleaseResponse is the response from a release installation.
@ -290,6 +297,8 @@ message UninstallReleaseRequest {
bool purge = 3; bool purge = 3;
// timeout specifies the max amount of time any kubernetes client command can run. // timeout specifies the max amount of time any kubernetes client command can run.
int64 timeout = 4; int64 timeout = 4;
// Description, if set, will set the description for the uninnstalled release
string description = 5;
} }
// UninstallReleaseResponse represents a successful response to an uninstall request. // UninstallReleaseResponse represents a successful response to an uninstall request.

@ -40,6 +40,7 @@ type deleteCmd struct {
disableHooks bool disableHooks bool
purge bool purge bool
timeout int64 timeout int64
description string
out io.Writer out io.Writer
client helm.Interface client helm.Interface
@ -81,6 +82,7 @@ func newDeleteCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&del.disableHooks, "no-hooks", false, "prevent hooks from running during deletion") f.BoolVar(&del.disableHooks, "no-hooks", false, "prevent hooks from running during deletion")
f.BoolVar(&del.purge, "purge", false, "remove the release from the store and make its name free for later use") f.BoolVar(&del.purge, "purge", false, "remove the release from the store and make its name free for later use")
f.Int64Var(&del.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)") f.Int64Var(&del.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.StringVar(&del.description, "description", "", "specify a description for the release")
return cmd return cmd
} }
@ -91,6 +93,7 @@ func (d *deleteCmd) run() error {
helm.DeleteDisableHooks(d.disableHooks), helm.DeleteDisableHooks(d.disableHooks),
helm.DeletePurge(d.purge), helm.DeletePurge(d.purge),
helm.DeleteTimeout(d.timeout), helm.DeleteTimeout(d.timeout),
helm.DeleteDescription(d.description),
} }
res, err := d.client.DeleteRelease(d.name, opts...) res, err := d.client.DeleteRelease(d.name, opts...)
if res != nil && res.Info != "" { if res != nil && res.Info != "" {

@ -61,6 +61,14 @@ func TestDelete(t *testing.T) {
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}),
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})},
}, },
{
name: "delete with description",
args: []string{"aeneas"},
flags: []string{"--description", "foo"},
expected: "",
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}),
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})},
},
{ {
name: "delete without release", name: "delete without release",
args: []string{}, args: []string{},

@ -148,9 +148,14 @@ func init() {
func main() { func main() {
cmd := newRootCmd(os.Args[1:]) cmd := newRootCmd(os.Args[1:])
if err := cmd.Execute(); err != nil { if err := cmd.Execute(); err != nil {
switch e := err.(type) {
case pluginError:
os.Exit(e.code)
default:
os.Exit(1) os.Exit(1)
} }
} }
}
func markDeprecated(cmd *cobra.Command, notice string) *cobra.Command { func markDeprecated(cmd *cobra.Command, notice string) *cobra.Command {
cmd.Deprecated = notice cmd.Deprecated = notice
@ -159,7 +164,7 @@ func markDeprecated(cmd *cobra.Command, notice string) *cobra.Command {
func setupConnection() error { func setupConnection() error {
if settings.TillerHost == "" { if settings.TillerHost == "" {
config, client, err := getKubeClient(settings.KubeContext) config, client, err := getKubeClient(settings.KubeContext, settings.KubeConfig)
if err != nil { if err != nil {
return err return err
} }
@ -213,8 +218,8 @@ func prettyError(err error) error {
} }
// configForContext creates a Kubernetes REST client configuration for a given kubeconfig context. // configForContext creates a Kubernetes REST client configuration for a given kubeconfig context.
func configForContext(context string) (*rest.Config, error) { func configForContext(context string, kubeconfig string) (*rest.Config, error) {
config, err := kube.GetConfig(context).ClientConfig() config, err := kube.GetConfig(context, kubeconfig).ClientConfig()
if err != nil { if err != nil {
return nil, fmt.Errorf("could not get Kubernetes config for context %q: %s", context, err) return nil, fmt.Errorf("could not get Kubernetes config for context %q: %s", context, err)
} }
@ -222,8 +227,8 @@ func configForContext(context string) (*rest.Config, error) {
} }
// getKubeClient creates a Kubernetes config and client for a given kubeconfig context. // getKubeClient creates a Kubernetes config and client for a given kubeconfig context.
func getKubeClient(context string) (*rest.Config, kubernetes.Interface, error) { func getKubeClient(context string, kubeconfig string) (*rest.Config, kubernetes.Interface, error) {
config, err := configForContext(context) config, err := configForContext(context, kubeconfig)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -237,8 +242,8 @@ func getKubeClient(context string) (*rest.Config, kubernetes.Interface, error) {
// getInternalKubeClient creates a Kubernetes config and an "internal" client for a given kubeconfig context. // getInternalKubeClient creates a Kubernetes config and an "internal" client for a given kubeconfig context.
// //
// Prefer the similar getKubeClient if you don't need to use such an internal client. // Prefer the similar getKubeClient if you don't need to use such an internal client.
func getInternalKubeClient(context string) (internalclientset.Interface, error) { func getInternalKubeClient(context string, kubeconfig string) (internalclientset.Interface, error) {
config, err := configForContext(context) config, err := configForContext(context, kubeconfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -294,7 +294,7 @@ func (i *initCmd) run() error {
if !i.clientOnly { if !i.clientOnly {
if i.kubeClient == nil { if i.kubeClient == nil {
_, c, err := getKubeClient(settings.KubeContext) _, c, err := getKubeClient(settings.KubeContext, settings.KubeConfig)
if err != nil { if err != nil {
return fmt.Errorf("could not get kubernetes client: %s", err) return fmt.Errorf("could not get kubernetes client: %s", err)
} }
@ -317,10 +317,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"+ fmt.Fprintln(i.out, "\nTiller (the Helm server-side component) has been installed into your Kubernetes Cluster.")
"Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.\n"+ if !i.tlsVerify {
fmt.Fprintln(i.out, "\nPlease note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.\n"+
"To prevent this, run `helm init` with the --tiller-tls-verify flag.\n"+
"For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation") "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
} }
@ -334,7 +337,7 @@ 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) _, kubeClient, err := getKubeClient(settings.KubeContext, settings.KubeConfig)
if err != nil { if err != nil {
return err return err
} }

@ -50,8 +50,10 @@ The install argument must be a chart reference, a path to a packaged chart,
a path to an unpacked chart directory or a URL. a path to an unpacked chart directory or a URL.
To override values in a chart, use either the '--values' flag and pass in a file To override values in a chart, use either the '--values' flag and pass in a file
or use the '--set' flag and pass configuration from the command line, to force or use the '--set' flag and pass configuration from the command line. To force string
a string value use '--set-string'. values in '--set', use '--set-string' instead. In case a value is large and therefore
you want not to use neither '--values' nor '--set', use '--set-file' to read the
single large value from file.
$ helm install -f myvalues.yaml ./redis $ helm install -f myvalues.yaml ./redis
@ -63,6 +65,9 @@ or
$ helm install --set-string long_int=1234567890 ./redis $ helm install --set-string long_int=1234567890 ./redis
or
$ helm install --set-file multiline_text=path/to/textfile
You can specify the '--values'/'-f' flag multiple times. The priority will be given to the You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
last (right-most) file specified. For example, if both myvalues.yaml and override.yaml last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
contained a key called 'Test', the value set in override.yaml would take precedence: contained a key called 'Test', the value set in override.yaml would take precedence:
@ -120,6 +125,7 @@ type installCmd struct {
client helm.Interface client helm.Interface
values []string values []string
stringValues []string stringValues []string
fileValues []string
nameTemplate string nameTemplate string
version string version string
timeout int64 timeout int64
@ -129,6 +135,7 @@ type installCmd struct {
password string password string
devel bool devel bool
depUp bool depUp bool
description string
certFile string certFile string
keyFile string keyFile string
@ -195,6 +202,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&inst.replace, "replace", false, "re-use the given name, even if that name is already used. This is unsafe in production") f.BoolVar(&inst.replace, "replace", false, "re-use the given name, even if that name is already used. This is unsafe in production")
f.StringArrayVar(&inst.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&inst.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&inst.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&inst.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&inst.fileValues, "set-file", []string{}, "set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)")
f.StringVar(&inst.nameTemplate, "name-template", "", "specify template used to name the release") f.StringVar(&inst.nameTemplate, "name-template", "", "specify template used to name the release")
f.BoolVar(&inst.verify, "verify", false, "verify the package before installing it") f.BoolVar(&inst.verify, "verify", false, "verify the package before installing it")
f.StringVar(&inst.keyring, "keyring", defaultKeyring(), "location of public keys used for verification") f.StringVar(&inst.keyring, "keyring", defaultKeyring(), "location of public keys used for verification")
@ -209,6 +217,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.StringVar(&inst.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") f.StringVar(&inst.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&inst.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.") f.BoolVar(&inst.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
f.BoolVar(&inst.depUp, "dep-up", false, "run helm dependency update before installing the chart") f.BoolVar(&inst.depUp, "dep-up", false, "run helm dependency update before installing the chart")
f.StringVar(&inst.description, "description", "", "specify a description for the release")
return cmd return cmd
} }
@ -220,7 +229,7 @@ func (i *installCmd) run() error {
i.namespace = defaultNamespace() i.namespace = defaultNamespace()
} }
rawVals, err := vals(i.valueFiles, i.values, i.stringValues, i.certFile, i.keyFile, i.caFile) rawVals, err := vals(i.valueFiles, i.values, i.stringValues, i.fileValues, i.certFile, i.keyFile, i.caFile)
if err != nil { if err != nil {
return err return err
} }
@ -258,6 +267,12 @@ func (i *installCmd) run() error {
if err := man.Update(); err != nil { if err := man.Update(); err != nil {
return prettyError(err) return prettyError(err)
} }
// Update all dependencies which are present in /charts.
chartRequested, err = chartutil.Load(i.chartPath)
if err != nil {
return prettyError(err)
}
} else { } else {
return prettyError(err) return prettyError(err)
} }
@ -277,7 +292,8 @@ func (i *installCmd) run() error {
helm.InstallDisableHooks(i.disableHooks), helm.InstallDisableHooks(i.disableHooks),
helm.InstallDisableCRDHook(i.disableCRDHook), helm.InstallDisableCRDHook(i.disableCRDHook),
helm.InstallTimeout(i.timeout), helm.InstallTimeout(i.timeout),
helm.InstallWait(i.wait)) helm.InstallWait(i.wait),
helm.InstallDescription(i.description))
if err != nil { if err != nil {
return prettyError(err) return prettyError(err)
} }
@ -334,8 +350,8 @@ func mergeValues(dest map[string]interface{}, src map[string]interface{}) map[st
} }
// vals merges values from files specified via -f/--values and // vals merges values from files specified via -f/--values and
// directly via --set or --set-string, marshaling them to YAML // directly via --set or --set-string or --set-file, marshaling them to YAML
func vals(valueFiles valueFiles, values []string, stringValues []string, CertFile, KeyFile, CAFile string) ([]byte, error) { func vals(valueFiles valueFiles, values []string, stringValues []string, fileValues []string, CertFile, KeyFile, CAFile string) ([]byte, error) {
base := map[string]interface{}{} base := map[string]interface{}{}
// User specified a values files via -f/--values // User specified a values files via -f/--values
@ -375,6 +391,17 @@ func vals(valueFiles valueFiles, values []string, stringValues []string, CertFil
} }
} }
// User specified a value via --set-file
for _, value := range fileValues {
reader := func(rs []rune) (interface{}, error) {
bytes, err := readFile(string(rs), CertFile, KeyFile, CAFile)
return string(bytes), err
}
if err := strvals.ParseIntoFile(value, base, reader); err != nil {
return []byte{}, fmt.Errorf("failed parsing --set-file data: %s", err)
}
}
return yaml.Marshal(base) return yaml.Marshal(base)
} }
@ -482,7 +509,7 @@ func generateName(nameTemplate string) (string, error) {
} }
func defaultNamespace() string { func defaultNamespace() string {
if ns, _, err := kube.GetConfig(settings.KubeContext).Namespace(); err == nil { if ns, _, err := kube.GetConfig(settings.KubeContext, settings.KubeConfig).Namespace(); err == nil {
return ns return ns
} }
return "default" return "default"

@ -115,6 +115,13 @@ func TestInstall(t *testing.T) {
expected: "FOOBAR", expected: "FOOBAR",
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "FOOBAR"}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "FOOBAR"}),
}, },
{
name: "install with custom description",
args: []string{"testdata/testcharts/alpine"},
flags: []string{"--name", "virgil", "--description", "foobar"},
expected: "virgil",
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil", Description: "foobar"}),
},
// Install, perform chart verification along the way. // Install, perform chart verification along the way.
{ {
name: "install with verification, missing provenance", name: "install with verification, missing provenance",

@ -50,7 +50,7 @@ type Options struct {
// Force allows to force upgrading tiller if deployed version is greater than current version // Force allows to force upgrading tiller if deployed version is greater than current version
ForceUpgrade bool ForceUpgrade bool
// ImageSpec indentifies the image Tiller will use when deployed. // ImageSpec identifies the image Tiller will use when deployed.
// //
// Valid if and only if UseCanary is false. // Valid if and only if UseCanary is false.
ImageSpec string ImageSpec string

@ -47,6 +47,7 @@ type lintCmd struct {
valueFiles valueFiles valueFiles valueFiles
values []string values []string
sValues []string sValues []string
fValues []string
namespace string namespace string
strict bool strict bool
paths []string paths []string
@ -73,6 +74,7 @@ func newLintCmd(out io.Writer) *cobra.Command {
cmd.Flags().VarP(&l.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)") cmd.Flags().VarP(&l.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
cmd.Flags().StringArrayVar(&l.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") cmd.Flags().StringArrayVar(&l.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
cmd.Flags().StringArrayVar(&l.sValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") cmd.Flags().StringArrayVar(&l.sValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
cmd.Flags().StringArrayVar(&l.fValues, "set-file", []string{}, "set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)")
cmd.Flags().StringVar(&l.namespace, "namespace", "default", "namespace to put the release into") cmd.Flags().StringVar(&l.namespace, "namespace", "default", "namespace to put the release into")
cmd.Flags().BoolVar(&l.strict, "strict", false, "fail on lint warnings") cmd.Flags().BoolVar(&l.strict, "strict", false, "fail on lint warnings")
@ -172,6 +174,12 @@ func lintChart(path string, vals []byte, namespace string, strict bool) (support
return lint.All(chartPath, vals, namespace, strict), nil return lint.All(chartPath, vals, namespace, strict), nil
} }
// vals merges values from files specified via -f/--values and
// directly via --set or --set-string or --set-file, marshaling them to YAML
//
// This func is implemented intentionally and separately from the `vals` func for the `install` and `upgrade` comammdsn.
// Compared to the alternative func, this func lacks the parameters for tls opts - ca key, cert, and ca cert.
// That's because this command, `lint`, is explicitly forbidden from making server connections.
func (l *lintCmd) vals() ([]byte, error) { func (l *lintCmd) vals() ([]byte, error) {
base := map[string]interface{}{} base := map[string]interface{}{}
@ -204,5 +212,16 @@ func (l *lintCmd) vals() ([]byte, error) {
} }
} }
// User specified a value via --set-file
for _, value := range l.fValues {
reader := func(rs []rune) (interface{}, error) {
bytes, err := ioutil.ReadFile(string(rs))
return string(bytes), err
}
if err := strvals.ParseIntoFile(value, base, reader); err != nil {
return []byte{}, fmt.Errorf("failed parsing --set-file data: %s", err)
}
}
return yaml.Marshal(base) return yaml.Marshal(base)
} }

@ -17,10 +17,12 @@ limitations under the License.
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"io" "io"
"strings" "strings"
"github.com/ghodss/yaml"
"github.com/gosuri/uitable" "github.com/gosuri/uitable"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -75,6 +77,22 @@ type listCmd struct {
pending bool pending bool
client helm.Interface client helm.Interface
colWidth uint colWidth uint
output string
}
type listResult struct {
Next string
Releases []listRelease
}
type listRelease struct {
Name string
Revision int32
Updated string
Status string
Chart string
AppVersion string
Namespace string
} }
func newListCmd(client helm.Interface, out io.Writer) *cobra.Command { func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
@ -114,6 +132,7 @@ func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&list.pending, "pending", false, "show pending releases") f.BoolVar(&list.pending, "pending", false, "show pending releases")
f.StringVar(&list.namespace, "namespace", "", "show releases within a specific namespace") f.StringVar(&list.namespace, "namespace", "", "show releases within a specific namespace")
f.UintVar(&list.colWidth, "col-width", 60, "specifies the max column width of output") f.UintVar(&list.colWidth, "col-width", 60, "specifies the max column width of output")
f.StringVar(&list.output, "output", "", "output the specified format (json or yaml)")
// TODO: Do we want this as a feature of 'helm list'? // TODO: Do we want this as a feature of 'helm list'?
//f.BoolVar(&list.superseded, "history", true, "show historical releases") //f.BoolVar(&list.superseded, "history", true, "show historical releases")
@ -147,24 +166,21 @@ func (l *listCmd) run() error {
if err != nil { if err != nil {
return prettyError(err) return prettyError(err)
} }
if res == nil {
if len(res.GetReleases()) == 0 {
return nil return nil
} }
if res.Next != "" && !l.short { rels := filterList(res.GetReleases())
fmt.Fprintf(l.out, "\tnext: %s\n", res.Next)
}
rels := filterList(res.Releases) result := getListResult(rels, res.Next)
if l.short { output, err := formatResult(l.output, l.short, result, l.colWidth)
for _, r := range rels {
fmt.Fprintln(l.out, r.Name) if err != nil {
} return prettyError(err)
return nil
} }
fmt.Fprintln(l.out, formatList(rels, l.colWidth))
fmt.Fprintln(l.out, output)
return nil return nil
} }
@ -233,23 +249,98 @@ func (l *listCmd) statusCodes() []release.Status_Code {
return status return status
} }
func formatList(rels []*release.Release, colWidth uint) string { func getListResult(rels []*release.Release, next string) listResult {
table := uitable.New() listReleases := []listRelease{}
table.MaxColWidth = colWidth
table.AddRow("NAME", "REVISION", "UPDATED", "STATUS", "CHART", "APP VERSION", "NAMESPACE")
for _, r := range rels { for _, r := range rels {
md := r.GetChart().GetMetadata() md := r.GetChart().GetMetadata()
c := fmt.Sprintf("%s-%s", md.GetName(), md.GetVersion())
t := "-" t := "-"
if tspb := r.GetInfo().GetLastDeployed(); tspb != nil { if tspb := r.GetInfo().GetLastDeployed(); tspb != nil {
t = timeconv.String(tspb) t = timeconv.String(tspb)
} }
s := r.GetInfo().GetStatus().GetCode().String()
v := r.GetVersion() lr := listRelease{
a := md.GetAppVersion() Name: r.GetName(),
n := r.GetNamespace() Revision: r.GetVersion(),
table.AddRow(r.GetName(), v, t, s, c, a, n) Updated: t,
Status: r.GetInfo().GetStatus().GetCode().String(),
Chart: fmt.Sprintf("%s-%s", md.GetName(), md.GetVersion()),
AppVersion: md.GetAppVersion(),
Namespace: r.GetNamespace(),
} }
return table.String() listReleases = append(listReleases, lr)
}
return listResult{
Releases: listReleases,
Next: next,
}
}
func shortenListResult(result listResult) []string {
names := []string{}
for _, r := range result.Releases {
names = append(names, r.Name)
}
return names
}
func formatResult(format string, short bool, result listResult, colWidth uint) (string, error) {
var output string
var err error
var shortResult []string
var finalResult interface{}
if short {
shortResult = shortenListResult(result)
finalResult = shortResult
} else {
finalResult = result
}
switch format {
case "":
if short {
output = formatTextShort(shortResult)
} else {
output = formatText(result, colWidth)
}
case "json":
o, e := json.Marshal(finalResult)
if e != nil {
err = fmt.Errorf("Failed to Marshal JSON output: %s", e)
} else {
output = string(o)
}
case "yaml":
o, e := yaml.Marshal(finalResult)
if e != nil {
err = fmt.Errorf("Failed to Marshal YAML output: %s", e)
} else {
output = string(o)
}
default:
err = fmt.Errorf("Unknown output format \"%s\"", format)
}
return output, err
}
func formatText(result listResult, colWidth uint) string {
nextOutput := ""
if result.Next != "" {
nextOutput = fmt.Sprintf("\tnext: %s\n", result.Next)
}
table := uitable.New()
table.MaxColWidth = colWidth
table.AddRow("NAME", "REVISION", "UPDATED", "STATUS", "CHART", "APP VERSION", "NAMESPACE")
for _, lr := range result.Releases {
table.AddRow(lr.Name, lr.Revision, lr.Updated, lr.Status, lr.Chart, lr.AppVersion, lr.Namespace)
}
return fmt.Sprintf("%s%s", nextOutput, table.String())
}
func formatTextShort(shortResult []string) string {
return strings.Join(shortResult, "\n")
} }

@ -18,16 +18,18 @@ package main
import ( import (
"io" "io"
"regexp"
"testing" "testing"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"io/ioutil" "io/ioutil"
"os"
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/proto/hapi/chart"
"k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/release"
"os"
) )
func TestListCmd(t *testing.T) { func TestListCmd(t *testing.T) {
@ -46,6 +48,11 @@ func TestListCmd(t *testing.T) {
ch, _ := chartutil.Load(chartPath) ch, _ := chartutil.Load(chartPath)
tests := []releaseCase{ tests := []releaseCase{
{
name: "empty",
rels: []*release.Release{},
expected: "",
},
{ {
name: "with a release", name: "with a release",
rels: []*release.Release{ rels: []*release.Release{
@ -67,6 +74,77 @@ func TestListCmd(t *testing.T) {
}, },
expected: "NAME \tREVISION\tUPDATED \tSTATUS \tCHART \tAPP VERSION\tNAMESPACE\natlas\t1 \t(.*)\tDEPLOYED\tfoo-0.1.0-beta.1\t2.X.A \tdefault \n", expected: "NAME \tREVISION\tUPDATED \tSTATUS \tCHART \tAPP VERSION\tNAMESPACE\natlas\t1 \t(.*)\tDEPLOYED\tfoo-0.1.0-beta.1\t2.X.A \tdefault \n",
}, },
{
name: "with json output",
flags: []string{"--max", "1", "--output", "json"},
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide"}),
},
expected: regexp.QuoteMeta(`{"Next":"atlas-guide","Releases":[{"Name":"thomas-guide","Revision":1,"Updated":"`) + `([^"]*)` + regexp.QuoteMeta(`","Status":"DEPLOYED","Chart":"foo-0.1.0-beta.1","AppVersion":"","Namespace":"default"}]}
`),
},
{
name: "with yaml output",
flags: []string{"--max", "1", "--output", "yaml"},
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide"}),
},
expected: regexp.QuoteMeta(`Next: atlas-guide
Releases:
- AppVersion: ""
Chart: foo-0.1.0-beta.1
Name: thomas-guide
Namespace: default
Revision: 1
Status: DEPLOYED
Updated: `) + `(.*)` + `
`,
},
{
name: "with short json output",
flags: []string{"-q", "--output", "json"},
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas"}),
},
expected: regexp.QuoteMeta(`["atlas"]
`),
},
{
name: "with short yaml output",
flags: []string{"-q", "--output", "yaml"},
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas"}),
},
expected: regexp.QuoteMeta(`- atlas
`),
},
{
name: "with json output without next",
flags: []string{"--output", "json"},
rels: []*release.Release{},
expected: regexp.QuoteMeta(`{"Next":"","Releases":[]}
`),
},
{
name: "with yaml output without next",
flags: []string{"--output", "yaml"},
rels: []*release.Release{},
expected: regexp.QuoteMeta(`Next: ""
Releases: []
`),
},
{
name: "with unknown output format",
flags: []string{"--output", "_unknown_"},
rels: []*release.Release{},
err: true,
expected: regexp.QuoteMeta(``),
},
{ {
name: "list, one deployed, one failed", name: "list, one deployed, one failed",
flags: []string{"-q"}, flags: []string{"-q"},

@ -22,12 +22,18 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/helm/pkg/plugin" "k8s.io/helm/pkg/plugin"
) )
type pluginError struct {
error
code int
}
// loadPlugins loads plugins into the command list. // loadPlugins loads plugins into the command list.
// //
// This follows a different pattern than the other commands because it has // This follows a different pattern than the other commands because it has
@ -87,7 +93,11 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) {
if err := prog.Run(); err != nil { if err := prog.Run(); err != nil {
if eerr, ok := err.(*exec.ExitError); ok { if eerr, ok := err.(*exec.ExitError); ok {
os.Stderr.Write(eerr.Stderr) os.Stderr.Write(eerr.Stderr)
return fmt.Errorf("plugin %q exited with error", md.Name) status := eerr.Sys().(syscall.WaitStatus)
return pluginError{
error: fmt.Errorf("plugin %q exited with error", md.Name),
code: status.ExitStatus(),
}
} }
return err return err
} }

@ -86,7 +86,7 @@ func newResetCmd(client helm.Interface, out io.Writer) *cobra.Command {
// runReset uninstalls tiller from Kubernetes Cluster and deletes local config // runReset uninstalls tiller from Kubernetes Cluster and deletes local config
func (d *resetCmd) run() error { func (d *resetCmd) run() error {
if d.kubeClient == nil { if d.kubeClient == nil {
c, err := getInternalKubeClient(settings.KubeContext) c, err := getInternalKubeClient(settings.KubeContext, settings.KubeConfig)
if err != nil { if err != nil {
return fmt.Errorf("could not get kubernetes client: %s", err) return fmt.Errorf("could not get kubernetes client: %s", err)
} }

@ -45,6 +45,7 @@ type rollbackCmd struct {
client helm.Interface client helm.Interface
timeout int64 timeout int64
wait bool wait bool
description string
} }
func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command { func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
@ -83,6 +84,7 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&rollback.disableHooks, "no-hooks", false, "prevent hooks from running during rollback") f.BoolVar(&rollback.disableHooks, "no-hooks", false, "prevent hooks from running during rollback")
f.Int64Var(&rollback.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)") f.Int64Var(&rollback.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&rollback.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout") f.BoolVar(&rollback.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
f.StringVar(&rollback.description, "description", "", "specify a description for the release")
return cmd return cmd
} }
@ -96,7 +98,8 @@ func (r *rollbackCmd) run() error {
helm.RollbackDisableHooks(r.disableHooks), helm.RollbackDisableHooks(r.disableHooks),
helm.RollbackVersion(r.revision), helm.RollbackVersion(r.revision),
helm.RollbackTimeout(r.timeout), helm.RollbackTimeout(r.timeout),
helm.RollbackWait(r.wait)) helm.RollbackWait(r.wait),
helm.RollbackDescription(r.description))
if err != nil { if err != nil {
return prettyError(err) return prettyError(err)
} }

@ -45,6 +45,12 @@ func TestRollbackCmd(t *testing.T) {
flags: []string{"--wait"}, flags: []string{"--wait"},
expected: "Rollback was a success! Happy Helming!", expected: "Rollback was a success! Happy Helming!",
}, },
{
name: "rollback a release with description",
args: []string{"funny-honey", "1"},
flags: []string{"--description", "foo"},
expected: "Rollback was a success! Happy Helming!",
},
{ {
name: "rollback a release without revision", name: "rollback a release without revision",
args: []string{"funny-honey"}, args: []string{"funny-honey"},

@ -69,6 +69,7 @@ type templateCmd struct {
out io.Writer out io.Writer
values []string values []string
stringValues []string stringValues []string
fileValues []string
nameTemplate string nameTemplate string
showNotes bool showNotes bool
releaseName string releaseName string
@ -100,6 +101,7 @@ func newTemplateCmd(out io.Writer) *cobra.Command {
f.StringVar(&t.namespace, "namespace", "", "namespace to install the release into") f.StringVar(&t.namespace, "namespace", "", "namespace to install the release into")
f.StringArrayVar(&t.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&t.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&t.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&t.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&t.fileValues, "set-file", []string{}, "set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)")
f.StringVar(&t.nameTemplate, "name-template", "", "specify template used to name the release") f.StringVar(&t.nameTemplate, "name-template", "", "specify template used to name the release")
f.StringVar(&t.kubeVersion, "kube-version", defaultKubeVersion, "kubernetes version used as Capabilities.KubeVersion.Major/Minor") f.StringVar(&t.kubeVersion, "kube-version", defaultKubeVersion, "kubernetes version used as Capabilities.KubeVersion.Major/Minor")
f.StringVar(&t.outputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout") f.StringVar(&t.outputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout")
@ -132,7 +134,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
t.namespace = defaultNamespace() t.namespace = defaultNamespace()
} }
// get combined values and create config // get combined values and create config
rawVals, err := vals(t.valueFiles, t.values, t.stringValues, "", "", "") rawVals, err := vals(t.valueFiles, t.values, t.stringValues, t.fileValues, "", "", "")
if err != nil { if err != nil {
return err return err
} }
@ -309,7 +311,7 @@ func writeToFile(outputDir string, name string, data string) error {
defer f.Close() defer f.Close()
_, err = f.WriteString(fmt.Sprintf("##---\n# Source: %s\n%s", name, data)) _, err = f.WriteString(fmt.Sprintf("---\n# Source: %s\n%s", name, data))
if err != nil { if err != nil {
return err return err

@ -68,8 +68,8 @@ func TestTemplateCmd(t *testing.T) {
}, },
{ {
name: "check_execute_non_existent", name: "check_execute_non_existent",
desc: "verify --execute fails on a template that doesnt exist", desc: "verify --execute fails on a template that doesn't exist",
args: []string{subchart1ChartPath, "-x", "templates/thisdoesntexist.yaml"}, args: []string{subchart1ChartPath, "-x", "templates/thisdoesn'texist.yaml"},
expectError: "could not find template", expectError: "could not find template",
}, },
{ {

@ -37,8 +37,10 @@ a packaged chart, or a fully qualified URL. For chart references, the latest
version will be specified unless the '--version' flag is set. version will be specified unless the '--version' flag is set.
To override values in a chart, use either the '--values' flag and pass in a file To override values in a chart, use either the '--values' flag and pass in a file
or use the '--set' flag and pass configuration from the command line, to force string or use the '--set' flag and pass configuration from the command line. To force string
values, use '--set-string'. values in '--set', use '--set-string' instead. In case a value is large and therefore
you want not to use neither '--values' nor '--set', use '--set-file' to read the
single large value from file.
You can specify the '--values'/'-f' flag multiple times. The priority will be given to the You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
last (right-most) file specified. For example, if both myvalues.yaml and override.yaml last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
@ -65,6 +67,7 @@ type upgradeCmd struct {
valueFiles valueFiles valueFiles valueFiles
values []string values []string
stringValues []string stringValues []string
fileValues []string
verify bool verify bool
keyring string keyring string
install bool install bool
@ -78,6 +81,7 @@ type upgradeCmd struct {
username string username string
password string password string
devel bool devel bool
description string
certFile string certFile string
keyFile string keyFile string
@ -121,6 +125,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&upgrade.force, "force", false, "force resource update through delete/recreate if needed") f.BoolVar(&upgrade.force, "force", false, "force resource update through delete/recreate if needed")
f.StringArrayVar(&upgrade.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&upgrade.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&upgrade.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&upgrade.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&upgrade.fileValues, "set-file", []string{}, "set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)")
f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks. DEPRECATED. Use no-hooks") f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks. DEPRECATED. Use no-hooks")
f.BoolVar(&upgrade.disableHooks, "no-hooks", false, "disable pre/post upgrade hooks") f.BoolVar(&upgrade.disableHooks, "no-hooks", false, "disable pre/post upgrade hooks")
f.BoolVar(&upgrade.verify, "verify", false, "verify the provenance of the chart before upgrading") f.BoolVar(&upgrade.verify, "verify", false, "verify the provenance of the chart before upgrading")
@ -139,6 +144,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.StringVar(&upgrade.keyFile, "key-file", "", "identify HTTPS client using this SSL key file") f.StringVar(&upgrade.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&upgrade.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") f.StringVar(&upgrade.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&upgrade.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.") f.BoolVar(&upgrade.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
f.StringVar(&upgrade.description, "description", "", "specify the description to use for the upgrade, rather than the default")
f.MarkDeprecated("disable-hooks", "use --no-hooks instead") f.MarkDeprecated("disable-hooks", "use --no-hooks instead")
@ -187,15 +193,17 @@ func (u *upgradeCmd) run() error {
keyring: u.keyring, keyring: u.keyring,
values: u.values, values: u.values,
stringValues: u.stringValues, stringValues: u.stringValues,
fileValues: u.fileValues,
namespace: u.namespace, namespace: u.namespace,
timeout: u.timeout, timeout: u.timeout,
wait: u.wait, wait: u.wait,
description: u.description,
} }
return ic.run() return ic.run()
} }
} }
rawVals, err := vals(u.valueFiles, u.values, u.stringValues, u.certFile, u.keyFile, u.caFile) rawVals, err := vals(u.valueFiles, u.values, u.stringValues, u.fileValues, u.certFile, u.keyFile, u.caFile)
if err != nil { if err != nil {
return err return err
} }
@ -224,7 +232,8 @@ func (u *upgradeCmd) run() error {
helm.UpgradeTimeout(u.timeout), helm.UpgradeTimeout(u.timeout),
helm.ResetValues(u.resetValues), helm.ResetValues(u.resetValues),
helm.ReuseValues(u.reuseValues), helm.ReuseValues(u.reuseValues),
helm.UpgradeWait(u.wait)) helm.UpgradeWait(u.wait),
helm.UpgradeDescription(u.description))
if err != nil { if err != nil {
return fmt.Errorf("UPGRADE FAILED: %v", prettyError(err)) return fmt.Errorf("UPGRADE FAILED: %v", prettyError(err))
} }

@ -139,6 +139,14 @@ func TestUpgradeCmd(t *testing.T) {
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch})},
}, },
{
name: "install a release with 'upgrade --install' and custom description",
args: []string{"crazy-bunny", chartPath},
flags: []string{"-i", "--description", "foo"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch, Description: "foo"}),
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch, Description: "foo"})},
},
{ {
name: "upgrade a release with wait", name: "upgrade a release with wait",
args: []string{"crazy-bunny", chartPath}, args: []string{"crazy-bunny", chartPath},
@ -147,6 +155,14 @@ func TestUpgradeCmd(t *testing.T) {
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n", expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2})},
}, },
{
name: "upgrade a release with description",
args: []string{"crazy-bunny", chartPath},
flags: []string{"--description", "foo"},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2}),
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2, Description: "foo"})},
},
{ {
name: "upgrade a release with missing dependencies", name: "upgrade a release with missing dependencies",
args: []string{"bonkers-bunny", missingDepsPath}, args: []string{"bonkers-bunny", missingDepsPath},

@ -76,7 +76,10 @@ 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() err := setupConnection()
if err != nil {
return err
}
} }
version.client = ensureHelmClient(version.client) version.client = ensureHelmClient(version.client)
return version.run() return version.run()
@ -115,7 +118,6 @@ func (v *versionCmd) run() error {
} }
fmt.Fprintf(v.out, "Kubernetes: %#v\n", k8sVersion) fmt.Fprintf(v.out, "Kubernetes: %#v\n", k8sVersion)
} }
resp, err := v.client.GetVersion() resp, err := v.client.GetVersion()
if err != nil { if err != nil {
if grpc.Code(err) == codes.Unimplemented { if grpc.Code(err) == codes.Unimplemented {
@ -135,7 +137,7 @@ func (v *versionCmd) run() error {
func getK8sVersion() (*apiVersion.Info, error) { func getK8sVersion() (*apiVersion.Info, error) {
var v *apiVersion.Info var v *apiVersion.Info
_, client, err := getKubeClient(settings.KubeContext) _, client, err := getKubeClient(settings.KubeContext, settings.KubeConfig)
if err != nil { if err != nil {
return v, err return v, err
} }

@ -85,7 +85,7 @@ var (
// rootServer is the root gRPC server. // rootServer is the root gRPC server.
// //
// Each gRPC service registers itself to this server during init(). // Each gRPC service registers itself to this server during start().
rootServer *grpc.Server rootServer *grpc.Server
// env is the default environment. // env is the default environment.

@ -4,14 +4,14 @@ This part of the Best Practices Guide explains general conventions.
## Chart Names ## Chart Names
Chart names should be lower case letters and numbers. Words _may_ be separated with dashes (-): Chart names should be lower case letters and numbers. Dashes (-) are not allowed:
Examples: Examples:
``` ```
drupal drupal
nginx-lego cluster01
aws-cluster-autoscaler aws-cluster-autoscaler #incorrect do not use dashes in the name
``` ```
Neither uppercase letters nor underscores should be used in chart names. Dots should not be used in chart names. Neither uppercase letters nor underscores should be used in chart names. Dots should not be used in chart names.

@ -93,6 +93,7 @@ There are three potential sources of values:
- A chart's `values.yaml` file - A chart's `values.yaml` file
- A values file supplied by `helm install -f` or `helm upgrade -f` - A values file supplied by `helm install -f` or `helm upgrade -f`
- The values passed to a `--set` or `--set-string` flag on `helm install` or `helm upgrade` - The values passed to a `--set` or `--set-string` flag on `helm install` or `helm upgrade`
- The content of a file passed to `--set-file` flag on `helm install` or `helm upgrade`
When designing the structure of your values, keep in mind that users of your When designing the structure of your values, keep in mind that users of your
chart may want to override them via either the `-f` flag or with the `--set` chart may want to override them via either the `-f` flag or with the `--set`

@ -53,10 +53,10 @@ data:
myvalue: "Hello World" myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }} drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }} food: {{ .Values.favorite.food | upper | quote }}
{{ if eq .Values.favorite.drink "coffee" }}mug: true{{ end }} {{ if (.Values.favorite.drink) and eq .Values.favorite.drink "coffee" }}mug: true{{ end }}
``` ```
Since we commented out `drink: coffee` in our last example, the output should not include a `mug: true` flag. But if we add that line back into our `values.yaml` file, the output should look like this: Note that `.Values.favorite.drink` must be defined or else it will throw an error when comparing it to "coffee". Since we commented out `drink: coffee` in our last example, the output should not include a `mug: true` flag. But if we add that line back into our `values.yaml` file, the output should look like this:
```yaml ```yaml
# Source: mychart/templates/configmap.yaml # Source: mychart/templates/configmap.yaml

@ -303,7 +303,6 @@ The `--set` parameter can be used as usual to alter tag and condition values.
```` ````
helm install --set tags.front-end=true --set subchart2.enabled=false helm install --set tags.front-end=true --set subchart2.enabled=false
```` ````
##### Tags and Condition Resolution ##### Tags and Condition Resolution

@ -183,8 +183,7 @@ deterministic executing order. Weights are defined using the following annotatio
``` ```
Hook weights can be positive or negative numbers but must be represented as Hook weights can be positive or negative numbers but must be represented as
strings. When Tiller starts the execution cycle of hooks of a particular Kind it strings. When Tiller starts the execution cycle of hooks of a particular kind (ex. the `pre-install` hooks or `post-install` hooks, etc.) it will sort those hooks in ascending order.
will sort those hooks in ascending order.
It is also possible to define policies that determine when to delete corresponding hook resources. Hook deletion policies are defined using the following annotation: It is also possible to define policies that determine when to delete corresponding hook resources. Hook deletion policies are defined using the following annotation:

@ -106,6 +106,43 @@ For example:
The above will render the template when .Values.foo is defined, but will fail The above will render the template when .Values.foo is defined, but will fail
to render and exit when .Values.foo is undefined. to render and exit when .Values.foo is undefined.
## Using the 'tpl' Function
The `tpl` function allows developers to evaluate strings as templates inside a template.
This is useful to pass a template string as a value to a chart or render external configuration files.
Syntax: `{{ tpl TEMPLATE_STRING VALUES }}`
Examples:
```
# values
template: "{{ .Values.name }}"
name: "Tom"
# template
{{ tpl .Values.template . }}
# output
Tom
```
Rendering a external configuration file:
```
# external configuration file conf/app.conf
firstName={{ .Values.firstName }}
lastName={{ .Values.lastName }}
# values
firstName: Peter
lastName: Parker
# template
{{ tpl (.Files.Get "conf/app.conf") . }}
# output
firstName=Peter
lastName=Parker
```
## Creating Image Pull Secrets ## Creating Image Pull Secrets
Image pull secrets are essentially a combination of _registry_, _username_, and _password_. You may need them in an application you are deploying, but to create them requires running _base64_ a couple of times. We can write a helper template to compose the Docker configuration file for use as the Secret's payload. Here is an example: Image pull secrets are essentially a combination of _registry_, _username_, and _password_. You may need them in an application you are deploying, but to create them requires running _base64_ a couple of times. We can write a helper template to compose the Docker configuration file for use as the Secret's payload. Here is an example:

@ -14,6 +14,5 @@ It simply deploys a single pod running Alpine Linux.
The `nginx` chart shows how to compose several resources into one chart, The `nginx` chart shows how to compose several resources into one chart,
and it illustrates more complex template usage. and it illustrates more complex template usage.
It deploys a `deployment` (which creates a `replica set`), a `config It deploys a `Deployment` (which creates a `ReplicaSet`), a `ConfigMap`, and a `Service`. The replica set starts an nginx pod. The config
map`, and a `service`. The replica set starts an nginx pod. The config
map stores the files that the nginx server can serve. map stores the files that the nginx server can serve.

@ -41,6 +41,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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -28,6 +28,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -47,6 +47,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -20,6 +20,7 @@ helm delete [flags] RELEASE_NAME [...]
### Options ### Options
``` ```
--description string specify a description for the release
--dry-run simulate a delete --dry-run simulate a delete
--no-hooks prevent hooks from running during deletion --no-hooks prevent hooks from running during deletion
--purge remove the release from the store and make its name free for later use --purge remove the release from the store and make its name free for later use
@ -33,6 +34,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -34,6 +34,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -26,6 +26,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -39,6 +39,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -50,6 +50,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -35,6 +35,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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -28,6 +28,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -30,6 +30,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -27,6 +27,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -40,6 +40,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -21,6 +21,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -63,6 +63,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -37,6 +37,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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -35,6 +35,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -33,6 +33,7 @@ helm inspect readme [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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -35,6 +35,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -12,8 +12,10 @@ The install argument must be a chart reference, a path to a packaged chart,
a path to an unpacked chart directory or a URL. a path to an unpacked chart directory or a URL.
To override values in a chart, use either the '--values' flag and pass in a file To override values in a chart, use either the '--values' flag and pass in a file
or use the '--set' flag and pass configuration from the command line, to force or use the '--set' flag and pass configuration from the command line. To force string
a string value use '--set-string'. values in '--set', use '--set-string' instead. In case a value is large and therefore
you want not to use neither '--values' nor '--set', use '--set-file' to read the
single large value from file.
$ helm install -f myvalues.yaml ./redis $ helm install -f myvalues.yaml ./redis
@ -25,6 +27,9 @@ or
$ helm install --set-string long_int=1234567890 ./redis $ helm install --set-string long_int=1234567890 ./redis
or
$ helm install --set-file multiline_text=path/to/textfile
You can specify the '--values'/'-f' flag multiple times. The priority will be given to the You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
last (right-most) file specified. For example, if both myvalues.yaml and override.yaml last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
contained a key called 'Test', the value set in override.yaml would take precedence: contained a key called 'Test', the value set in override.yaml would take precedence:
@ -77,6 +82,7 @@ helm install [CHART]
--ca-file string verify certificates of HTTPS-enabled servers using this CA bundle --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle
--cert-file string identify HTTPS client using this SSL certificate file --cert-file string identify HTTPS client using this SSL certificate file
--dep-up run helm dependency update before installing the chart --dep-up run helm dependency update before installing the chart
--description string specify a description for the release
--devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored. --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
--dry-run simulate an install --dry-run simulate an install
--key-file string identify HTTPS client using this SSL key file --key-file string identify HTTPS client using this SSL key file
@ -90,6 +96,7 @@ helm install [CHART]
--replace re-use the given name, even if that name is already used. This is unsafe in production --replace re-use the given name, even if that name is already used. This is unsafe in production
--repo string chart repository url where to locate the requested chart --repo string chart repository url where to locate the requested chart
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300) --timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
--username string chart repository username where to locate the requested chart --username string chart repository username where to locate the requested chart
@ -106,6 +113,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -23,6 +23,7 @@ helm lint [flags] PATH
``` ```
--namespace string namespace to put the release into (default "default") --namespace string namespace to put the release into (default "default")
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--strict fail on lint warnings --strict fail on lint warnings
-f, --values valueFiles specify values in a YAML file (can specify multiple) (default []) -f, --values valueFiles specify values in a YAML file (can specify multiple) (default [])
@ -35,6 +36,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -49,6 +49,7 @@ helm list [flags] [FILTER]
-m, --max int maximum number of releases to fetch (default 256) -m, --max int maximum number of releases to fetch (default 256)
--namespace string show releases within a specific namespace --namespace string show releases within a specific namespace
-o, --offset string next release name in the list, used to offset from start value -o, --offset string next release name in the list, used to offset from start value
--output string output the specified format (json or yaml)
--pending show pending releases --pending show pending releases
-r, --reverse reverse the sort order -r, --reverse reverse the sort order
-q, --short output short (quiet) listing format -q, --short output short (quiet) listing format
@ -61,6 +62,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -40,6 +40,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -29,6 +29,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -18,6 +18,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -18,6 +18,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -18,6 +18,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -29,6 +29,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -34,6 +34,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -18,6 +18,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -18,6 +18,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -24,6 +24,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -29,6 +29,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -20,6 +20,7 @@ helm rollback [flags] [RELEASE] [REVISION]
### Options ### Options
``` ```
--description string specify a description for the release
--dry-run simulate a rollback --dry-run simulate a rollback
--force force resource update through delete/recreate if needed --force force resource update through delete/recreate if needed
--no-hooks prevent hooks from running during rollback --no-hooks prevent hooks from running during rollback
@ -35,6 +36,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -32,6 +32,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -39,6 +39,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -34,6 +34,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -34,6 +34,7 @@ helm template [flags] CHART
--notes show the computed NOTES.txt file as well --notes show the computed NOTES.txt file as well
--output-dir string writes the executed templates to files in output-dir instead of stdout --output-dir string writes the executed templates to files in output-dir instead of stdout
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-f, --values valueFiles specify values in a YAML file (can specify multiple) (default []) -f, --values valueFiles specify values in a YAML file (can specify multiple) (default [])
``` ```
@ -45,6 +46,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -30,6 +30,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -14,8 +14,10 @@ a packaged chart, or a fully qualified URL. For chart references, the latest
version will be specified unless the '--version' flag is set. version will be specified unless the '--version' flag is set.
To override values in a chart, use either the '--values' flag and pass in a file To override values in a chart, use either the '--values' flag and pass in a file
or use the '--set' flag and pass configuration from the command line, to force string or use the '--set' flag and pass configuration from the command line. To force string
values, use '--set-string'. values in '--set', use '--set-string' instead. In case a value is large and therefore
you want not to use neither '--values' nor '--set', use '--set-file' to read the
single large value from file.
You can specify the '--values'/'-f' flag multiple times. The priority will be given to the You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
last (right-most) file specified. For example, if both myvalues.yaml and override.yaml last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
@ -39,6 +41,7 @@ helm upgrade [RELEASE] [CHART]
``` ```
--ca-file string verify certificates of HTTPS-enabled servers using this CA bundle --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle
--cert-file string identify HTTPS client using this SSL certificate file --cert-file string identify HTTPS client using this SSL certificate file
--description string specify the description to use for the upgrade, rather than the default
--devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored. --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
--dry-run simulate an upgrade --dry-run simulate an upgrade
--force force resource update through delete/recreate if needed --force force resource update through delete/recreate if needed
@ -53,6 +56,7 @@ helm upgrade [RELEASE] [CHART]
--reset-values when upgrading, reset the values to the ones built into the chart --reset-values when upgrading, reset the values to the ones built into the chart
--reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored. --reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored.
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300) --timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
--username string chart repository username where to locate the requested chart --username string chart repository username where to locate the requested chart
@ -69,6 +73,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -33,6 +33,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -43,6 +43,7 @@ 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
--kubeconfig string absolute path to the kubeconfig file to use
--tiller-connection-timeout int the duration (in seconds) Helm will wait to establish a connection to tiller (default 300) --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")
--tls enable TLS connection between Helm and Tiller --tls enable TLS connection between Helm and Tiller

@ -24,6 +24,15 @@ can be manually downloaded and installed.
From there, you should be able to run the client: `helm help`. From there, you should be able to run the client: `helm help`.
### From Snap (Linux)
The Snap package for Helm is maintained by
[Snapcrafters](https://github.com/snapcrafters/helm).
```
$ sudo snap install helm
```
### From Homebrew (macOS) ### From Homebrew (macOS)
Members of the Kubernetes community have contributed a Helm formula build to Members of the Kubernetes community have contributed a Helm formula build to
@ -122,6 +131,7 @@ You can explicitly tell `helm init` to...
- Install a particular image (version) with `--tiller-image` - Install a particular image (version) with `--tiller-image`
- Install to a particular cluster with `--kube-context` - Install to a particular cluster with `--kube-context`
- Install into a particular namespace with `--tiller-namespace` - Install into a particular namespace with `--tiller-namespace`
- Install Tiller with a Service Account with `--service-account` (for [RBAC enabled clusters](securing_installation.md#rbac))
Once Tiller is installed, running `helm version` should show you both Once Tiller is installed, running `helm version` should show you both
the client and server version. (If it shows only the client version, the client and server version. (If it shows only the client version,

@ -14,11 +14,6 @@ Once you have satisfied the pre-requisite and have a service account with the co
### Example: Service account with cluster-admin role ### Example: Service account with cluster-admin role
```console
$ kubectl create serviceaccount tiller --namespace kube-system
serviceaccount "tiller" created
```
In `rbac-config.yaml`: In `rbac-config.yaml`:
```yaml ```yaml
@ -71,7 +66,7 @@ metadata:
name: tiller-manager name: tiller-manager
namespace: tiller-world namespace: tiller-world
rules: rules:
- apiGroups: ["", "extensions", "apps"] - apiGroups: ["", "batch", "extensions", "apps"]
resources: ["*"] resources: ["*"]
verbs: ["*"] verbs: ["*"]
``` ```

@ -16,6 +16,7 @@ or [pull request](https://github.com/kubernetes/helm/pulls).
- [GitLab, Consumer Driven Contracts, Helm and Kubernetes](https://medium.com/@enxebre/gitlab-consumer-driven-contracts-helm-and-kubernetes-b7235a60a1cb#.xwp1y4tgi) - [GitLab, Consumer Driven Contracts, Helm and Kubernetes](https://medium.com/@enxebre/gitlab-consumer-driven-contracts-helm-and-kubernetes-b7235a60a1cb#.xwp1y4tgi)
- [Writing a Helm Chart](https://www.influxdata.com/packaged-kubernetes-deployments-writing-helm-chart/) - [Writing a Helm Chart](https://www.influxdata.com/packaged-kubernetes-deployments-writing-helm-chart/)
- [Creating a Helm Plugin in 3 Steps](http://technosophos.com/2017/03/21/creating-a-helm-plugin.html) - [Creating a Helm Plugin in 3 Steps](http://technosophos.com/2017/03/21/creating-a-helm-plugin.html)
- [Awesome Helm](https://github.com/cdwv/awesome-helm) - List of awesome Helm resources
## Video, Audio, and Podcast ## Video, Audio, and Podcast
@ -38,6 +39,7 @@ or [pull request](https://github.com/kubernetes/helm/pulls).
- [helm-secrets](https://github.com/futuresimple/helm-secrets) - Plugin to manage and store secrets safely - [helm-secrets](https://github.com/futuresimple/helm-secrets) - Plugin to manage and store secrets safely
- [helm-edit](https://github.com/mstrzele/helm-edit) - Plugin for editing release's values - [helm-edit](https://github.com/mstrzele/helm-edit) - Plugin for editing release's values
- [helm-gcs](https://github.com/nouney/helm-gcs) - Plugin to manage repositories on Google Cloud Storage - [helm-gcs](https://github.com/nouney/helm-gcs) - Plugin to manage repositories on Google Cloud Storage
- [helm-cos](https://github.com/imroc/helm-cos) - Plugin to manage repositories on Tencent Cloud Object Storage
- [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

@ -2,9 +2,36 @@
**IMPORTANT**: If your experience deviates from this document, please document the changes to keep it up-to-date. **IMPORTANT**: If your experience deviates from this document, please document the changes to keep it up-to-date.
## Release Meetings
As part of the release process, two of the weekly developer calls will be co-opted
as "release meetings."
### Start of the Release Cycle
The first developer call after a release will be used as the release meeting to
start the next release cycle. During this meeting, the following items must be
identified:
- Release date
- Goals/Objectives for this release
- The release manager (basically whoever is going to cut the release)
- Any other important details for the community
All of this information should be added to the GitHub milestone for the given
release. This should give the community and maintainers a clear set of guidelines
to follow when choosing whether or not to add issues and PRs to a given release.
### End (almost) of the Release Cycle
The developer call closest to two weeks before the scheduled release date will
be used to review any remaining PRs that should be pulled into the release. This
is the place to debate whether or not we should wait before cutting a release and
any other concerns. At the end of this meeting, if the release date has not been
pushed out, the first RC should be cut. Subsequent developer calls in between this
meeting and the release date should have some time set aside to see if any bugs
were found. Once the release date is reached, the final release can be cut
## A Maintainer's Guide to Releasing Helm ## A Maintainer's Guide to Releasing Helm
So you're in charge of a new release for helm? Cool. Here's what to do... So you're in charge of a new release for Helm? Cool. Here's what to do...
![TODO: Nothing](images/nothing.png) ![TODO: Nothing](images/nothing.png)

@ -43,7 +43,7 @@ carefully curated and maintained charts. This chart repository is named
You can see which charts are available by running `helm search`: You can see which charts are available by running `helm search`:
``` ```console
$ helm search $ helm search
NAME VERSION DESCRIPTION NAME VERSION DESCRIPTION
stable/drupal 0.3.2 One of the most versatile open source content m... stable/drupal 0.3.2 One of the most versatile open source content m...
@ -56,7 +56,7 @@ stable/mysql 0.1.0 Chart for MySQL
With no filter, `helm search` shows you all of the available charts. You With no filter, `helm search` shows you all of the available charts. You
can narrow down your results by searching with a filter: can narrow down your results by searching with a filter:
``` ```console
$ helm search mysql $ helm search mysql
NAME VERSION DESCRIPTION NAME VERSION DESCRIPTION
stable/mysql 0.1.0 Chart for MySQL stable/mysql 0.1.0 Chart for MySQL
@ -69,7 +69,7 @@ Why is
`mariadb` in the list? Because its package description relates it to `mariadb` in the list? Because its package description relates it to
MySQL. We can use `helm inspect chart` to see this: MySQL. We can use `helm inspect chart` to see this:
``` ```console
$ helm inspect stable/mariadb $ helm inspect stable/mariadb
Fetched stable/mariadb to mariadb-0.5.1.tgz Fetched stable/mariadb to mariadb-0.5.1.tgz
description: Chart for MariaDB description: Chart for MariaDB
@ -91,7 +91,7 @@ package you want to install, you can use `helm install` to install it.
To install a new package, use the `helm install` command. At its To install a new package, use the `helm install` command. At its
simplest, it takes only one argument: The name of the chart. simplest, it takes only one argument: The name of the chart.
``` ```console
$ helm install stable/mariadb $ helm install stable/mariadb
Fetched stable/mariadb-0.3.0 to /Users/mattbutcher/Code/Go/src/k8s.io/helm/mariadb-0.3.0.tgz Fetched stable/mariadb-0.3.0 to /Users/mattbutcher/Code/Go/src/k8s.io/helm/mariadb-0.3.0.tgz
happy-panda happy-panda
@ -139,7 +139,7 @@ may take a long time to install into the cluster.
To keep track of a release's state, or to re-read configuration To keep track of a release's state, or to re-read configuration
information, you can use `helm status`: information, you can use `helm status`:
``` ```console
$ helm status happy-panda $ helm status happy-panda
Last Deployed: Wed Sep 28 12:32:28 2016 Last Deployed: Wed Sep 28 12:32:28 2016
Namespace: default Namespace: default
@ -227,7 +227,7 @@ There are two ways to pass configuration data during install:
- `--values` (or `-f`): Specify a YAML file with overrides. This can be specified multiple times - `--values` (or `-f`): Specify a YAML file with overrides. This can be specified multiple times
and the rightmost file will take precedence and the rightmost file will take precedence
- `--set`: Specify overrides on the command line. - `--set` (and its variants `--set-string` and `--set-file`): Specify overrides on the command line.
If both are used, `--set` values are merged into `--values` with higher precedence. If both are used, `--set` values are merged into `--values` with higher precedence.
Overrides specified with `--set` are persisted in a configmap. Values that have been Overrides specified with `--set` are persisted in a configmap. Values that have been
@ -304,6 +304,35 @@ Deeply nested data structures can be difficult to express using `--set`. Chart
designers are encouraged to consider the `--set` usage when designing the format designers are encouraged to consider the `--set` usage when designing the format
of a `values.yaml` file. of a `values.yaml` file.
Helm will cast certain values specified with `--set` to integers.
For example, `--set foo=true` results Helm to cast `true` into an int64 value.
In case you want a string, use a `--set`'s variant named `--set-string`. `--set-string foo=true` results in a string value of `"true"`.
`--set-file key=filepath` is another variant of `--set`.
It reads the file and use its content as a value.
An example use case of it is to inject a multi-line text into values without dealing with indentation in YAML.
Say you want to create a [brigade](https://github.com/Azure/brigade) project with certain value containing 5 lines JavaScript code, you might write a `values.yaml` like:
```yaml
defaultScript: |
const { events, Job } = require("brigadier")
function run(e, project) {
console.log("hello default script")
}
events.on("run", run)
```
Being embedded in a YAML, this makes it harder for you to use IDE features and testing framework and so on that supports writing code.
Instead, you can use `--set-file defaultScript=brigade.js` with `brigade.js` containing:
```javascript
const { events, Job } = require("brigadier")
function run(e, project) {
console.log("hello default script")
}
events.on("run", run)
```
### More Installation Methods ### More Installation Methods
The `helm install` command can install from several sources: The `helm install` command can install from several sources:
@ -392,14 +421,14 @@ is not a full list of cli flags. To see a description of all flags, just run
When it is time to uninstall or delete a release from the cluster, use When it is time to uninstall or delete a release from the cluster, use
the `helm delete` command: the `helm delete` command:
``` ```console
$ helm delete happy-panda $ helm delete happy-panda
``` ```
This will remove the release from the cluster. You can see all of your This will remove the release from the cluster. You can see all of your
currently deployed releases with the `helm list` command: currently deployed releases with the `helm list` command:
``` ```console
$ helm list $ helm list
NAME VERSION UPDATED STATUS CHART NAME VERSION UPDATED STATUS CHART
inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0

21
glide.lock generated

@ -1,5 +1,5 @@
hash: 4023a1644d60060fbf2fdbbe5b73cbb4b957eb686ce925640d102db2d1858676 hash: 41304a2eabc68608507c034304ce87cbf76924c90caaafbe42a9be16e6265868
updated: 2018-04-14T11:27:34.604716498-04:00 updated: 2018-06-19T14:50:56.238468981-05:00
imports: imports:
- name: cloud.google.com/go - name: cloud.google.com/go
version: 3b1ae45394a234c385be014e9a488f2bb6eef821 version: 3b1ae45394a234c385be014e9a488f2bb6eef821
@ -89,7 +89,7 @@ imports:
subpackages: subpackages:
- spdy - spdy
- name: github.com/evanphx/json-patch - name: github.com/evanphx/json-patch
version: 944e07253867aacae43c04b2e6a239005443f33a version: 94e38aa1586e8a6c8a75770bddf5ff84c48a106b
- name: github.com/exponent-io/jsonpath - name: github.com/exponent-io/jsonpath
version: d6023ce2651d8eafb5c75bb0c7167536102ec9f5 version: d6023ce2651d8eafb5c75bb0c7167536102ec9f5
- name: github.com/fatih/camelcase - name: github.com/fatih/camelcase
@ -250,7 +250,7 @@ imports:
- name: github.com/spf13/pflag - name: github.com/spf13/pflag
version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7 version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7
- name: github.com/technosophos/moniker - name: github.com/technosophos/moniker
version: ab470f5e105a44d0c87ea21bacd6a335c4816d83 version: a5dbd03a2245d554160e3ae6bfdcf969fe58b431
- name: golang.org/x/crypto - name: golang.org/x/crypto
version: 81e90905daefcd6fd217b62423c0908922eadb30 version: 81e90905daefcd6fd217b62423c0908922eadb30
subpackages: subpackages:
@ -359,9 +359,9 @@ imports:
- json - json
- jwt - jwt
- name: gopkg.in/yaml.v2 - name: gopkg.in/yaml.v2
version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 version: 670d4cfef0544295bc27a114dbac37980d83185a
- name: k8s.io/api - name: k8s.io/api
version: c699ec51538f0cfd4afa8bfcfe1e0779cafbe666 version: 8b7507fac302640dd5f1efbf9643199952cc58db
subpackages: subpackages:
- admission/v1beta1 - admission/v1beta1
- admissionregistration/v1alpha1 - admissionregistration/v1alpha1
@ -398,7 +398,7 @@ imports:
subpackages: subpackages:
- pkg/features - pkg/features
- name: k8s.io/apimachinery - name: k8s.io/apimachinery
version: 54101a56dda9a0962bc48751c058eb4c546dcbb9 version: f6313580a4d36c7c74a3d845dda6e116642c4f90
subpackages: subpackages:
- pkg/api/equality - pkg/api/equality
- pkg/api/errors - pkg/api/errors
@ -455,7 +455,7 @@ imports:
- third_party/forked/golang/netutil - third_party/forked/golang/netutil
- third_party/forked/golang/reflect - third_party/forked/golang/reflect
- name: k8s.io/apiserver - name: k8s.io/apiserver
version: ea53f8588c655568158b4ff53f5ec6fa4ebfc332 version: f7914ed3085badf66a1b6f3a5218ada28f7bd084
subpackages: subpackages:
- pkg/apis/audit - pkg/apis/audit
- pkg/authentication/authenticator - pkg/authentication/authenticator
@ -640,12 +640,12 @@ imports:
- util/retry - util/retry
- util/workqueue - util/workqueue
- name: k8s.io/kube-openapi - name: k8s.io/kube-openapi
version: 50ae88d24ede7b8bad68e23c805b5d3da5c8abaf version: 39cb288412c48cb533ba4be5d6c28620b9a0c1b4
subpackages: subpackages:
- pkg/util/proto - pkg/util/proto
- pkg/util/proto/validation - pkg/util/proto/validation
- name: k8s.io/kubernetes - name: k8s.io/kubernetes
version: baab3992147260d47cb59b9c485a24fdeff2e457 version: 32ac1c9073b132b8ba18aa830f46b77dcceb0723
subpackages: subpackages:
- pkg/api/events - pkg/api/events
- pkg/api/legacyscheme - pkg/api/legacyscheme
@ -767,7 +767,6 @@ imports:
- pkg/client/clientset_generated/internalclientset/typed/settings/internalversion/fake - pkg/client/clientset_generated/internalclientset/typed/settings/internalversion/fake
- pkg/client/clientset_generated/internalclientset/typed/storage/internalversion - pkg/client/clientset_generated/internalclientset/typed/storage/internalversion
- pkg/client/clientset_generated/internalclientset/typed/storage/internalversion/fake - pkg/client/clientset_generated/internalclientset/typed/storage/internalversion/fake
- pkg/client/conditions
- pkg/cloudprovider - pkg/cloudprovider
- pkg/controller - pkg/controller
- pkg/controller/daemon - pkg/controller/daemon

@ -13,7 +13,7 @@ import:
- package: github.com/imdario/mergo - package: github.com/imdario/mergo
version: 6633656539c1639d9d78127b7d47c622b5d7b6dc version: 6633656539c1639d9d78127b7d47c622b5d7b6dc
- package: github.com/Masterminds/sprig - package: github.com/Masterminds/sprig
version: ^2.14.1 version: ^2.15.0
- package: github.com/ghodss/yaml - package: github.com/ghodss/yaml
- package: github.com/Masterminds/semver - package: github.com/Masterminds/semver
version: ~1.3.1 version: ~1.3.1

@ -129,8 +129,8 @@ kind: Ingress
metadata: metadata:
name: {{ $fullName }} name: {{ $fullName }}
labels: labels:
app: {{ template "<CHARTNAME>.name" . }} app: {{ include "<CHARTNAME>.name" . }}
chart: {{ template "<CHARTNAME>.chart" . }} chart: {{ include "<CHARTNAME>.chart" . }}
release: {{ .Release.Name }} release: {{ .Release.Name }}
heritage: {{ .Release.Service }} heritage: {{ .Release.Service }}
{{- with .Values.ingress.annotations }} {{- with .Values.ingress.annotations }}
@ -164,22 +164,22 @@ spec:
const defaultDeployment = `apiVersion: apps/v1beta2 const defaultDeployment = `apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: {{ template "<CHARTNAME>.fullname" . }} name: {{ include "<CHARTNAME>.fullname" . }}
labels: labels:
app: {{ template "<CHARTNAME>.name" . }} app: {{ include "<CHARTNAME>.name" . }}
chart: {{ template "<CHARTNAME>.chart" . }} chart: {{ include "<CHARTNAME>.chart" . }}
release: {{ .Release.Name }} release: {{ .Release.Name }}
heritage: {{ .Release.Service }} heritage: {{ .Release.Service }}
spec: spec:
replicas: {{ .Values.replicaCount }} replicas: {{ .Values.replicaCount }}
selector: selector:
matchLabels: matchLabels:
app: {{ template "<CHARTNAME>.name" . }} app: {{ include "<CHARTNAME>.name" . }}
release: {{ .Release.Name }} release: {{ .Release.Name }}
template: template:
metadata: metadata:
labels: labels:
app: {{ template "<CHARTNAME>.name" . }} app: {{ include "<CHARTNAME>.name" . }}
release: {{ .Release.Name }} release: {{ .Release.Name }}
spec: spec:
containers: containers:
@ -217,10 +217,10 @@ spec:
const defaultService = `apiVersion: v1 const defaultService = `apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: {{ template "<CHARTNAME>.fullname" . }} name: {{ include "<CHARTNAME>.fullname" . }}
labels: labels:
app: {{ template "<CHARTNAME>.name" . }} app: {{ include "<CHARTNAME>.name" . }}
chart: {{ template "<CHARTNAME>.chart" . }} chart: {{ include "<CHARTNAME>.chart" . }}
release: {{ .Release.Name }} release: {{ .Release.Name }}
heritage: {{ .Release.Service }} heritage: {{ .Release.Service }}
spec: spec:
@ -231,7 +231,7 @@ spec:
protocol: TCP protocol: TCP
name: http name: http
selector: selector:
app: {{ template "<CHARTNAME>.name" . }} app: {{ include "<CHARTNAME>.name" . }}
release: {{ .Release.Name }} release: {{ .Release.Name }}
` `
@ -241,16 +241,16 @@ const defaultNotes = `1. Get the application URL by running these commands:
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }} http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }}
{{- end }} {{- end }}
{{- else if contains "NodePort" .Values.service.type }} {{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "<CHARTNAME>.fullname" . }}) export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "<CHARTNAME>.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }} {{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available. NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc -w {{ template "<CHARTNAME>.fullname" . }}' You can watch the status of by running 'kubectl get svc -w {{ include "<CHARTNAME>.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "<CHARTNAME>.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "<CHARTNAME>.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:{{ .Values.service.port }} echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }} {{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "<CHARTNAME>.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ include "<CHARTNAME>.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application" echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80 kubectl port-forward $POD_NAME 8080:80
{{- end }} {{- end }}

@ -81,19 +81,17 @@ func newHTTPGetter(URL, CertFile, KeyFile, CAFile string) (Getter, error) {
// NewHTTPGetter constructs a valid http/https client as HttpGetter // NewHTTPGetter constructs a valid http/https client as HttpGetter
func NewHTTPGetter(URL, CertFile, KeyFile, CAFile string) (*HttpGetter, error) { func NewHTTPGetter(URL, CertFile, KeyFile, CAFile string) (*HttpGetter, error) {
var client HttpGetter var client HttpGetter
tr := &http.Transport{
DisableCompression: true,
}
if (CertFile != "" && KeyFile != "") || CAFile != "" { if (CertFile != "" && KeyFile != "") || CAFile != "" {
tlsConf, err := tlsutil.NewTLSConfig(URL, CertFile, KeyFile, CAFile) tlsConf, err := tlsutil.NewTLSConfig(URL, CertFile, KeyFile, CAFile)
if err != nil { if err != nil {
return &client, fmt.Errorf("can't create TLS config: %s", err.Error()) return &client, fmt.Errorf("can't create TLS config: %s", err.Error())
} }
client.client = &http.Client{ tr.TLSClientConfig = tlsConf
Transport: &http.Transport{ tr.Proxy = http.ProxyFromEnvironment
TLSClientConfig: tlsConf,
Proxy: http.ProxyFromEnvironment,
},
}
} else {
client.client = http.DefaultClient
} }
client.client = &http.Client{Transport: tr}
return &client, nil return &client, nil
} }

@ -16,21 +16,29 @@ limitations under the License.
package getter package getter
import ( import (
"io"
"net/http" "net/http"
"net/http/httptest"
"os"
"path/filepath" "path/filepath"
"strconv"
"testing" "testing"
) )
type TestFileHandler struct{}
func (h *TestFileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
HandleClient(w, r)
}
func TestHTTPGetter(t *testing.T) { func TestHTTPGetter(t *testing.T) {
g, err := newHTTPGetter("http://example.com", "", "", "") g, err := newHTTPGetter("http://example.com", "", "", "")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if hg, ok := g.(*HttpGetter); !ok { if _, ok := g.(*HttpGetter); !ok {
t.Fatal("Expected newHTTPGetter to produce an HttpGetter") t.Fatal("Expected newHTTPGetter to produce an HttpGetter")
} else if hg.client != http.DefaultClient {
t.Fatal("Expected newHTTPGetter to return a default HTTP client.")
} }
// Test with SSL: // Test with SSL:
@ -58,3 +66,42 @@ func TestHTTPGetter(t *testing.T) {
t.Fatal("Expected newHTTPGetter to return a non-default HTTP client") t.Fatal("Expected newHTTPGetter to return a non-default HTTP client")
} }
} }
func HandleClient(writer http.ResponseWriter, request *http.Request) {
f, _ := os.Open("testdata/sssd-0.1.0.tgz")
defer f.Close()
b := make([]byte, 512)
f.Read(b)
//Get the file size
FileStat, _ := f.Stat()
FileSize := strconv.FormatInt(FileStat.Size(), 10)
//Simulating improper header values from bitbucket
writer.Header().Set("Content-Type", "application/x-tar")
writer.Header().Set("Content-Encoding", "gzip")
writer.Header().Set("Content-Length", FileSize)
f.Seek(0, 0)
io.Copy(writer, f)
return
}
func TestHTTPGetterTarDownload(t *testing.T) {
h := &TestFileHandler{}
server := httptest.NewServer(h)
defer server.Close()
g, err := newHTTPGetter(server.URL, "", "", "")
if err != nil {
t.Fatal(err)
}
data, _ := g.Get(server.URL)
mimeType := http.DetectContentType(data.Bytes())
expectedMimeType := "application/x-gzip"
if mimeType != expectedMimeType {
t.Fatalf("Expected response with MIME type %s, but got %s", expectedMimeType, mimeType)
}
}

@ -69,6 +69,7 @@ func (p *pluginGetter) Get(href string) (*bytes.Buffer, error) {
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
prog.Stdout = buf prog.Stdout = buf
prog.Stderr = os.Stderr prog.Stderr = os.Stderr
prog.Stdin = os.Stdin
if err := prog.Run(); err != nil { if err := prog.Run(); err != nil {
if eerr, ok := err.(*exec.ExitError); ok { if eerr, ok := err.(*exec.ExitError); ok {
os.Stderr.Write(eerr.Stderr) os.Stderr.Write(eerr.Stderr)

Binary file not shown.

@ -49,6 +49,8 @@ type EnvSettings struct {
Debug bool Debug bool
// KubeContext is the name of the kubeconfig context. // KubeContext is the name of the kubeconfig context.
KubeContext string KubeContext string
// KubeConfig is the path to an explicit kubeconfig file. This overwrites the value in $KUBECONFIG
KubeConfig string
// TLSCaCertFile is the path to TLS CA certificate file used to verify the Helm client and Tiller server certificates // TLSCaCertFile is the path to TLS CA certificate file used to verify the Helm client and Tiller server certificates
TLSCaCertFile string TLSCaCertFile string
// TLSCertFile is the path to Helm TLS client certificate file for authenticating to Tiller // TLSCertFile is the path to Helm TLS client certificate file for authenticating to Tiller
@ -66,6 +68,7 @@ func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) {
fs.StringVar((*string)(&s.Home), "home", DefaultHelmHome, "location of your Helm config. Overrides $HELM_HOME") fs.StringVar((*string)(&s.Home), "home", DefaultHelmHome, "location of your Helm config. Overrides $HELM_HOME")
fs.StringVar(&s.TillerHost, "host", "", "address of Tiller. Overrides $HELM_HOST") fs.StringVar(&s.TillerHost, "host", "", "address of Tiller. Overrides $HELM_HOST")
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.StringVar(&s.KubeConfig, "kubeconfig", "", "absolute path to the kubeconfig file 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") fs.Int64Var(&s.TillerConnectionTimeout, "tiller-connection-timeout", int64(300), "the duration (in seconds) Helm will wait to establish a connection to tiller")

@ -35,7 +35,7 @@ func TestEnvSettings(t *testing.T) {
envars map[string]string envars map[string]string
// expected values // expected values
home, host, ns, kcontext, plugins string home, host, ns, kcontext, kconfig, plugins string
debug bool debug bool
tlsca, tlscert, tlskey string tlsca, tlscert, tlskey string
tlsenable, tlsverify bool tlsenable, tlsverify bool
@ -52,6 +52,21 @@ func TestEnvSettings(t *testing.T) {
tlsenable: false, tlsenable: false,
tlsverify: false, tlsverify: false,
}, },
{
name: "with flags set",
args: []string{"--home", "/foo", "--host=here", "--debug", "--tiller-namespace=myns", "--kubeconfig", "/bar"},
home: "/foo",
plugins: helmpath.Home("/foo").Plugins(),
host: "here",
ns: "myns",
kconfig: "/bar",
debug: true,
tlsca: helmpath.Home("/foo").TLSCaCert(),
tlscert: helmpath.Home("/foo").TLSCert(),
tlskey: helmpath.Home("/foo").TLSKey(),
tlsenable: false,
tlsverify: false,
},
{ {
name: "with flags set", name: "with flags set",
args: []string{"--home", "/foo", "--host=here", "--debug", "--tiller-namespace=myns"}, args: []string{"--home", "/foo", "--host=here", "--debug", "--tiller-namespace=myns"},
@ -172,6 +187,9 @@ func TestEnvSettings(t *testing.T) {
if settings.KubeContext != tt.kcontext { if settings.KubeContext != tt.kcontext {
t.Errorf("expected kube-context %q, got %q", tt.kcontext, settings.KubeContext) t.Errorf("expected kube-context %q, got %q", tt.kcontext, settings.KubeContext)
} }
if settings.KubeConfig != tt.kconfig {
t.Errorf("expected kubeconfig %q, got %q", tt.kconfig, settings.KubeConfig)
}
if settings.TLSCaCertFile != tt.tlsca { if settings.TLSCaCertFile != tt.tlsca {
t.Errorf("expected tls-ca-cert %q, got %q", tt.tlsca, settings.TLSCaCertFile) t.Errorf("expected tls-ca-cert %q, got %q", tt.tlsca, settings.TLSCaCertFile)
} }

@ -18,7 +18,6 @@ package helm // import "k8s.io/helm/pkg/helm"
import ( import (
"errors" "errors"
"fmt"
"math/rand" "math/rand"
"sync" "sync"
@ -27,6 +26,7 @@ import (
"k8s.io/helm/pkg/proto/hapi/release" "k8s.io/helm/pkg/proto/hapi/release"
rls "k8s.io/helm/pkg/proto/hapi/services" rls "k8s.io/helm/pkg/proto/hapi/services"
"k8s.io/helm/pkg/proto/hapi/version" "k8s.io/helm/pkg/proto/hapi/version"
storage "k8s.io/helm/pkg/storage/driver"
) )
// FakeClient implements Interface // FakeClient implements Interface
@ -49,9 +49,28 @@ var _ Interface = (*FakeClient)(nil)
// ListReleases lists the current releases // ListReleases lists the current releases
func (c *FakeClient) ListReleases(opts ...ReleaseListOption) (*rls.ListReleasesResponse, error) { func (c *FakeClient) ListReleases(opts ...ReleaseListOption) (*rls.ListReleasesResponse, error) {
reqOpts := c.Opts
for _, opt := range opts {
opt(&reqOpts)
}
req := &reqOpts.listReq
rels := c.Rels
count := int64(len(c.Rels))
var next string
limit := req.GetLimit()
// TODO: Handle all other options.
if limit != 0 && limit < count {
rels = rels[:limit]
count = limit
next = c.Rels[limit].GetName()
}
resp := &rls.ListReleasesResponse{ resp := &rls.ListReleasesResponse{
Count: int64(len(c.Rels)), Count: count,
Releases: c.Rels, Releases: rels,
}
if next != "" {
resp.Next = next
} }
return resp, nil return resp, nil
} }
@ -69,6 +88,7 @@ func (c *FakeClient) InstallReleaseFromChart(chart *chart.Chart, ns string, opts
} }
releaseName := c.Opts.instReq.Name releaseName := c.Opts.instReq.Name
releaseDescription := c.Opts.instReq.Description
// Check to see if the release already exists. // Check to see if the release already exists.
rel, err := c.ReleaseStatus(releaseName, nil) rel, err := c.ReleaseStatus(releaseName, nil)
@ -76,8 +96,10 @@ func (c *FakeClient) InstallReleaseFromChart(chart *chart.Chart, ns string, opts
return nil, errors.New("cannot re-use a name that is still in use") return nil, errors.New("cannot re-use a name that is still in use")
} }
release := ReleaseMock(&MockReleaseOptions{Name: releaseName, Namespace: ns}) release := ReleaseMock(&MockReleaseOptions{Name: releaseName, Namespace: ns, Description: releaseDescription})
if !c.Opts.dryRun {
c.Rels = append(c.Rels, release) c.Rels = append(c.Rels, release)
}
return &rls.InstallReleaseResponse{ return &rls.InstallReleaseResponse{
Release: release, Release: release,
@ -95,7 +117,7 @@ func (c *FakeClient) DeleteRelease(rlsName string, opts ...DeleteOption) (*rls.U
} }
} }
return nil, fmt.Errorf("No such release: %s", rlsName) return nil, storage.ErrReleaseNotFound(rlsName)
} }
// GetVersion returns a fake version // GetVersion returns a fake version
@ -139,7 +161,7 @@ func (c *FakeClient) ReleaseStatus(rlsName string, opts ...StatusOption) (*rls.G
}, nil }, nil
} }
} }
return nil, fmt.Errorf("No such release: %s", rlsName) return nil, storage.ErrReleaseNotFound(rlsName)
} }
// ReleaseContent returns the configuration for the matching release name in the fake release client. // ReleaseContent returns the configuration for the matching release name in the fake release client.
@ -151,7 +173,7 @@ func (c *FakeClient) ReleaseContent(rlsName string, opts ...ContentOption) (resp
}, nil }, nil
} }
} }
return resp, fmt.Errorf("No such release: %s", rlsName) return resp, storage.ErrReleaseNotFound(rlsName)
} }
// ReleaseHistory returns a release's revision history. // ReleaseHistory returns a release's revision history.
@ -211,6 +233,7 @@ type MockReleaseOptions struct {
Chart *chart.Chart Chart *chart.Chart
StatusCode release.Status_Code StatusCode release.Status_Code
Namespace string Namespace string
Description string
} }
// ReleaseMock creates a mock release object based on options set by MockReleaseOptions. This function should typically not be used outside of testing. // ReleaseMock creates a mock release object based on options set by MockReleaseOptions. This function should typically not be used outside of testing.
@ -232,6 +255,11 @@ func ReleaseMock(opts *MockReleaseOptions) *release.Release {
namespace = "default" namespace = "default"
} }
description := opts.Description
if description == "" {
description = "Release mock"
}
ch := opts.Chart ch := opts.Chart
if opts.Chart == nil { if opts.Chart == nil {
ch = &chart.Chart{ ch = &chart.Chart{
@ -256,7 +284,7 @@ func ReleaseMock(opts *MockReleaseOptions) *release.Release {
FirstDeployed: &date, FirstDeployed: &date,
LastDeployed: &date, LastDeployed: &date,
Status: &release.Status{Code: scode}, Status: &release.Status{Code: scode},
Description: "Release mock", Description: description,
}, },
Chart: ch, Chart: ch,
Config: &chart.Config{Raw: `name: "value"`}, Config: &chart.Config{Raw: `name: "value"`},

@ -150,6 +150,23 @@ func TestFakeClient_InstallReleaseFromChart(t *testing.T) {
}, },
wantErr: false, wantErr: false,
}, },
{
name: "Add release with description.",
fields: fields{
Rels: []*release.Release{},
},
args: args{
ns: "default",
opts: []InstallOption{ReleaseName("new-release"), InstallDescription("foo-bar")},
},
want: &rls.InstallReleaseResponse{
Release: ReleaseMock(&MockReleaseOptions{Name: "new-release", Description: "foo-bar"}),
},
relsAfter: []*release.Release{
ReleaseMock(&MockReleaseOptions{Name: "new-release", Description: "foo-bar"}),
},
wantErr: false,
},
{ {
name: "Try to add a release where the name already exists.", name: "Try to add a release where the name already exists.",
fields: fields{ fields: fields{

@ -262,6 +262,34 @@ func UpdateValueOverrides(raw []byte) UpdateOption {
} }
} }
// InstallDescription specifies the description for the release
func InstallDescription(description string) InstallOption {
return func(opts *options) {
opts.instReq.Description = description
}
}
// UpgradeDescription specifies the description for the update
func UpgradeDescription(description string) UpdateOption {
return func(opts *options) {
opts.updateReq.Description = description
}
}
// RollbackDescription specifies the description for the release
func RollbackDescription(description string) RollbackOption {
return func(opts *options) {
opts.rollbackReq.Description = description
}
}
// DeleteDescription specifies the description for the release
func DeleteDescription(description string) DeleteOption {
return func(opts *options) {
opts.uninstallReq.Description = description
}
}
// DeleteDisableHooks will disable hooks for a deletion operation. // DeleteDisableHooks will disable hooks for a deletion operation.
func DeleteDisableHooks(disable bool) DeleteOption { func DeleteDisableHooks(disable bool) DeleteOption {
return func(opts *options) { return func(opts *options) {

@ -32,7 +32,7 @@ func isPodReady(pod *v1.Pod) bool {
return isPodReadyConditionTrue(pod.Status) return isPodReadyConditionTrue(pod.Status)
} }
// isPodReady retruns true if a pod is ready; false otherwise. // isPodReadyConditionTrue returns true if a pod is ready; false otherwise.
func isPodReadyConditionTrue(status v1.PodStatus) bool { func isPodReadyConditionTrue(status v1.PodStatus) bool {
condition := getPodReadyCondition(status) condition := getPodReadyCondition(status)
return condition != nil && condition.Status == v1.ConditionTrue return condition != nil && condition.Status == v1.ConditionTrue

@ -16,10 +16,12 @@ limitations under the License.
package kube // import "k8s.io/helm/pkg/kube" package kube // import "k8s.io/helm/pkg/kube"
import "k8s.io/client-go/tools/clientcmd" import (
"k8s.io/client-go/tools/clientcmd"
)
// GetConfig returns a Kubernetes client config for a given context. // GetConfig returns a Kubernetes client config for a given context.
func GetConfig(context string) clientcmd.ClientConfig { func GetConfig(context string, kubeconfig string) clientcmd.ClientConfig {
rules := clientcmd.NewDefaultClientConfigLoadingRules() rules := clientcmd.NewDefaultClientConfigLoadingRules()
rules.DefaultClientConfig = &clientcmd.DefaultClientConfig rules.DefaultClientConfig = &clientcmd.DefaultClientConfig
@ -28,5 +30,10 @@ func GetConfig(context string) clientcmd.ClientConfig {
if context != "" { if context != "" {
overrides.CurrentContext = context overrides.CurrentContext = context
} }
if kubeconfig != "" {
rules.ExplicitPath = kubeconfig
}
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(rules, overrides) return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(rules, overrides)
} }

@ -27,6 +27,9 @@ func createNamespace(client internalclientset.Interface, namespace string) error
ns := &core.Namespace{ ns := &core.Namespace{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: namespace, Name: namespace,
Labels: map[string]string{
"name": namespace,
},
}, },
} }
_, err := client.Core().Namespaces().Create(ns) _, err := client.Core().Namespaces().Create(ns)
@ -40,7 +43,16 @@ func getNamespace(client internalclientset.Interface, namespace string) (*core.N
func ensureNamespace(client internalclientset.Interface, namespace string) error { func ensureNamespace(client internalclientset.Interface, namespace string) error {
_, err := getNamespace(client, namespace) _, err := getNamespace(client, namespace)
if err != nil && errors.IsNotFound(err) { if err != nil && errors.IsNotFound(err) {
return createNamespace(client, namespace) err = createNamespace(client, namespace)
// If multiple commands which run `ensureNamespace` are run in
// parallel, then protect against the race condition in which
// the namespace did not exist when `getNamespace` was executed,
// but did exist when `createNamespace` was executed. If that
// happens, we can just proceed as normal.
if errors.IsAlreadyExists(err) {
return nil
}
} }
return err return err
} }

@ -376,6 +376,8 @@ type UpdateReleaseRequest struct {
ReuseValues bool `protobuf:"varint,10,opt,name=reuse_values,json=reuseValues" json:"reuse_values,omitempty"` ReuseValues bool `protobuf:"varint,10,opt,name=reuse_values,json=reuseValues" json:"reuse_values,omitempty"`
// Force resource update through delete/recreate if needed. // Force resource update through delete/recreate if needed.
Force bool `protobuf:"varint,11,opt,name=force" json:"force,omitempty"` Force bool `protobuf:"varint,11,opt,name=force" json:"force,omitempty"`
// Description, if set, will set the description for the updated release
Description string `protobuf:"bytes,12,opt,name=description" json:"description,omitempty"`
} }
func (m *UpdateReleaseRequest) Reset() { *m = UpdateReleaseRequest{} } func (m *UpdateReleaseRequest) Reset() { *m = UpdateReleaseRequest{} }
@ -460,6 +462,13 @@ func (m *UpdateReleaseRequest) GetForce() bool {
return false return false
} }
func (m *UpdateReleaseRequest) GetDescription() string {
if m != nil {
return m.Description
}
return ""
}
// UpdateReleaseResponse is the response to an update request. // UpdateReleaseResponse is the response to an update request.
type UpdateReleaseResponse struct { type UpdateReleaseResponse struct {
Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
@ -495,6 +504,8 @@ type RollbackReleaseRequest struct {
Wait bool `protobuf:"varint,7,opt,name=wait" json:"wait,omitempty"` Wait bool `protobuf:"varint,7,opt,name=wait" json:"wait,omitempty"`
// Force resource update through delete/recreate if needed. // Force resource update through delete/recreate if needed.
Force bool `protobuf:"varint,8,opt,name=force" json:"force,omitempty"` Force bool `protobuf:"varint,8,opt,name=force" json:"force,omitempty"`
// Description, if set, will set the description for the rollback
Description string `protobuf:"bytes,9,opt,name=description" json:"description,omitempty"`
} }
func (m *RollbackReleaseRequest) Reset() { *m = RollbackReleaseRequest{} } func (m *RollbackReleaseRequest) Reset() { *m = RollbackReleaseRequest{} }
@ -558,6 +569,13 @@ func (m *RollbackReleaseRequest) GetForce() bool {
return false return false
} }
func (m *RollbackReleaseRequest) GetDescription() string {
if m != nil {
return m.Description
}
return ""
}
// RollbackReleaseResponse is the response to an update request. // RollbackReleaseResponse is the response to an update request.
type RollbackReleaseResponse struct { type RollbackReleaseResponse struct {
Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
@ -601,6 +619,8 @@ type InstallReleaseRequest struct {
// before marking the release as successful. It will wait for as long as timeout // before marking the release as successful. It will wait for as long as timeout
Wait bool `protobuf:"varint,9,opt,name=wait" json:"wait,omitempty"` Wait bool `protobuf:"varint,9,opt,name=wait" json:"wait,omitempty"`
DisableCrdHook bool `protobuf:"varint,10,opt,name=disable_crd_hook,json=disableCrdHook" json:"disable_crd_hook,omitempty"` DisableCrdHook bool `protobuf:"varint,10,opt,name=disable_crd_hook,json=disableCrdHook" json:"disable_crd_hook,omitempty"`
// Description, if set, will set the description for the installed release
Description string `protobuf:"bytes,11,opt,name=description" json:"description,omitempty"`
} }
func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} } func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} }
@ -678,6 +698,13 @@ func (m *InstallReleaseRequest) GetDisableCrdHook() bool {
return false return false
} }
func (m *InstallReleaseRequest) GetDescription() string {
if m != nil {
return m.Description
}
return ""
}
// InstallReleaseResponse is the response from a release installation. // InstallReleaseResponse is the response from a release installation.
type InstallReleaseResponse struct { type InstallReleaseResponse struct {
Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` Release *hapi_release5.Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
@ -705,6 +732,8 @@ type UninstallReleaseRequest struct {
Purge bool `protobuf:"varint,3,opt,name=purge" json:"purge,omitempty"` Purge bool `protobuf:"varint,3,opt,name=purge" json:"purge,omitempty"`
// timeout specifies the max amount of time any kubernetes client command can run. // timeout specifies the max amount of time any kubernetes client command can run.
Timeout int64 `protobuf:"varint,4,opt,name=timeout" json:"timeout,omitempty"` Timeout int64 `protobuf:"varint,4,opt,name=timeout" json:"timeout,omitempty"`
// Description, if set, will set the description for the uninnstalled release
Description string `protobuf:"bytes,5,opt,name=description" json:"description,omitempty"`
} }
func (m *UninstallReleaseRequest) Reset() { *m = UninstallReleaseRequest{} } func (m *UninstallReleaseRequest) Reset() { *m = UninstallReleaseRequest{} }
@ -740,6 +769,13 @@ func (m *UninstallReleaseRequest) GetTimeout() int64 {
return 0 return 0
} }
func (m *UninstallReleaseRequest) GetDescription() string {
if m != nil {
return m.Description
}
return ""
}
// UninstallReleaseResponse represents a successful response to an uninstall request. // UninstallReleaseResponse represents a successful response to an uninstall request.
type UninstallReleaseResponse struct { type UninstallReleaseResponse struct {
// Release is the release that was marked deleted. // Release is the release that was marked deleted.
@ -1376,83 +1412,85 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("hapi/services/tiller.proto", fileDescriptor0) } func init() { proto.RegisterFile("hapi/services/tiller.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 1235 bytes of a gzipped FileDescriptorProto // 1267 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdd, 0x6e, 0xe3, 0xc4, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xed, 0x6e, 0xe3, 0x44,
0x17, 0xaf, 0xf3, 0x9d, 0x93, 0x6e, 0xfe, 0xd9, 0x69, 0xda, 0xba, 0xfe, 0x2f, 0xa8, 0x18, 0xc1, 0x17, 0x6e, 0xe2, 0x7c, 0x9e, 0x74, 0xf3, 0x66, 0x67, 0xb3, 0xad, 0xeb, 0x77, 0x41, 0xc1, 0x08,
0x66, 0x17, 0x36, 0x85, 0xc0, 0x0d, 0x12, 0x42, 0xea, 0x66, 0xa3, 0xb6, 0x50, 0xba, 0x92, 0xb3, 0x36, 0xbb, 0xb0, 0x29, 0x04, 0xfe, 0x20, 0x21, 0xa4, 0x6e, 0x36, 0x6a, 0x0b, 0xa5, 0x2b, 0x39,
0x5d, 0x24, 0x04, 0x44, 0x6e, 0x32, 0x69, 0xcd, 0x3a, 0x76, 0xf0, 0x8c, 0xcb, 0xf6, 0x96, 0x3b, 0xdb, 0x45, 0x42, 0x40, 0xe4, 0x26, 0x93, 0xd6, 0xac, 0x63, 0x07, 0xcf, 0xb8, 0x6c, 0x2f, 0x00,
0xde, 0x8a, 0x77, 0xe0, 0x92, 0x4b, 0x78, 0x10, 0x34, 0x5f, 0xae, 0x27, 0xb5, 0x5b, 0xd3, 0x9b, 0x24, 0xee, 0x83, 0x0b, 0xe1, 0x3e, 0xb8, 0x0e, 0xfe, 0x23, 0xcf, 0x87, 0xeb, 0x71, 0xec, 0xd4,
0x78, 0x66, 0xce, 0xf7, 0xef, 0x9c, 0x39, 0x73, 0x02, 0xd6, 0x85, 0xbb, 0xf4, 0xf6, 0x08, 0x8e, 0xf4, 0x4f, 0xe3, 0x99, 0x73, 0xe6, 0x7c, 0x3c, 0xcf, 0x9c, 0x33, 0xa7, 0x60, 0x5c, 0xda, 0x2b,
0x2e, 0xbd, 0x29, 0x26, 0x7b, 0xd4, 0xf3, 0x7d, 0x1c, 0xf5, 0x97, 0x51, 0x48, 0x43, 0xd4, 0x65, 0x67, 0x9f, 0xe0, 0xe0, 0xca, 0x99, 0x61, 0xb2, 0x4f, 0x1d, 0xd7, 0xc5, 0xc1, 0x60, 0x15, 0xf8,
0xb4, 0xbe, 0xa2, 0xf5, 0x05, 0xcd, 0xda, 0xe2, 0x12, 0xd3, 0x0b, 0x37, 0xa2, 0xe2, 0x57, 0x70, 0xd4, 0x47, 0xdd, 0x48, 0x36, 0x90, 0xb2, 0x01, 0x97, 0x19, 0x3b, 0xec, 0xc4, 0xec, 0xd2, 0x0e,
0x5b, 0xdb, 0xe9, 0xf3, 0x30, 0x98, 0x7b, 0xe7, 0x92, 0x20, 0x4c, 0x44, 0xd8, 0xc7, 0x2e, 0xc1, 0x28, 0xff, 0xcb, 0xb5, 0x8d, 0xdd, 0xe4, 0xbe, 0xef, 0x2d, 0x9c, 0x0b, 0x21, 0xe0, 0x2e, 0x02,
0xea, 0xab, 0x09, 0x29, 0x9a, 0x17, 0xcc, 0x43, 0x49, 0xf8, 0xbf, 0x46, 0xa0, 0x98, 0xd0, 0x49, 0xec, 0x62, 0x9b, 0x60, 0xf9, 0xab, 0x1c, 0x92, 0x32, 0xc7, 0x5b, 0xf8, 0x42, 0xf0, 0x7f, 0x45,
0x14, 0x07, 0x92, 0xb8, 0xa3, 0x11, 0x09, 0x75, 0x69, 0x4c, 0x34, 0x63, 0x97, 0x38, 0x22, 0x5e, 0x40, 0x31, 0xa1, 0xd3, 0x20, 0xf4, 0x84, 0x70, 0x4f, 0x11, 0x12, 0x6a, 0xd3, 0x90, 0x28, 0xce,
0x18, 0xa8, 0xaf, 0xa0, 0xd9, 0x7f, 0x94, 0x60, 0xe3, 0xd8, 0x23, 0xd4, 0x11, 0x82, 0xc4, 0xc1, 0xae, 0x70, 0x40, 0x1c, 0xdf, 0x93, 0xbf, 0x5c, 0x66, 0xfe, 0x55, 0x86, 0x07, 0x27, 0x0e, 0xa1,
0xbf, 0xc4, 0x98, 0x50, 0xd4, 0x85, 0xaa, 0xef, 0x2d, 0x3c, 0x6a, 0x1a, 0xbb, 0x46, 0xaf, 0xec, 0x16, 0x3f, 0x48, 0x2c, 0xfc, 0x4b, 0x88, 0x09, 0x45, 0x5d, 0xa8, 0xba, 0xce, 0xd2, 0xa1, 0x7a,
0x88, 0x0d, 0xda, 0x82, 0x5a, 0x38, 0x9f, 0x13, 0x4c, 0xcd, 0xd2, 0xae, 0xd1, 0x6b, 0x3a, 0x72, 0xa9, 0x57, 0xea, 0x6b, 0x16, 0x5f, 0xa0, 0x1d, 0xa8, 0xf9, 0x8b, 0x05, 0xc1, 0x54, 0x2f, 0xf7,
0x87, 0xbe, 0x82, 0x3a, 0x09, 0x23, 0x3a, 0x39, 0xbb, 0x32, 0xcb, 0xbb, 0x46, 0xaf, 0x3d, 0xf8, 0x4a, 0xfd, 0xa6, 0x25, 0x56, 0xe8, 0x2b, 0xa8, 0x13, 0x3f, 0xa0, 0xd3, 0xf3, 0x6b, 0x5d, 0xeb,
0xa0, 0x9f, 0x85, 0x53, 0x9f, 0x59, 0x1a, 0x87, 0x11, 0xed, 0xb3, 0x9f, 0xe7, 0x57, 0x4e, 0x8d, 0x95, 0xfa, 0xed, 0xe1, 0x07, 0x83, 0x2c, 0x9c, 0x06, 0x91, 0xa7, 0x89, 0x1f, 0xd0, 0x41, 0xf4,
0xf0, 0x2f, 0xd3, 0x3b, 0xf7, 0x7c, 0x8a, 0x23, 0xb3, 0x22, 0xf4, 0x8a, 0x1d, 0x3a, 0x00, 0xe0, 0xe7, 0xf9, 0xb5, 0x55, 0x23, 0xec, 0x37, 0xb2, 0xbb, 0x70, 0x5c, 0x8a, 0x03, 0xbd, 0xc2, 0xed,
0x7a, 0xc3, 0x68, 0x86, 0x23, 0xb3, 0xca, 0x55, 0xf7, 0x0a, 0xa8, 0x7e, 0xc9, 0xf8, 0x9d, 0x26, 0xf2, 0x15, 0x3a, 0x04, 0x60, 0x76, 0xfd, 0x60, 0x8e, 0x03, 0xbd, 0xca, 0x4c, 0xf7, 0x0b, 0x98,
0x51, 0x4b, 0xf4, 0x25, 0xac, 0x0b, 0x48, 0x26, 0xd3, 0x70, 0x86, 0x89, 0x59, 0xdb, 0x2d, 0xf7, 0x7e, 0x19, 0xe9, 0x5b, 0x4d, 0x22, 0x3f, 0xd1, 0x97, 0xb0, 0xcd, 0x21, 0x99, 0xce, 0xfc, 0x39,
0xda, 0x83, 0x1d, 0xa1, 0x4a, 0xc1, 0x3f, 0x16, 0xa0, 0x0d, 0xc3, 0x19, 0x76, 0x5a, 0x82, 0x9d, 0x26, 0x7a, 0xad, 0xa7, 0xf5, 0xdb, 0xc3, 0x3d, 0x6e, 0x4a, 0xc2, 0x3f, 0xe1, 0xa0, 0x8d, 0xfc,
0xad, 0x09, 0x7a, 0x04, 0xcd, 0xc0, 0x5d, 0x60, 0xb2, 0x74, 0xa7, 0xd8, 0xac, 0x73, 0x0f, 0xaf, 0x39, 0xb6, 0x5a, 0x5c, 0x3d, 0xfa, 0x26, 0xe8, 0x11, 0x34, 0x3d, 0x7b, 0x89, 0xc9, 0xca, 0x9e,
0x0f, 0xec, 0x9f, 0xa0, 0xa1, 0x8c, 0xdb, 0x03, 0xa8, 0x89, 0xd0, 0x50, 0x0b, 0xea, 0xa7, 0x27, 0x61, 0xbd, 0xce, 0x22, 0xbc, 0xd9, 0x30, 0x7f, 0x82, 0x86, 0x74, 0x6e, 0x0e, 0xa1, 0xc6, 0x53,
0xdf, 0x9c, 0xbc, 0xfc, 0xee, 0xa4, 0xb3, 0x86, 0x1a, 0x50, 0x39, 0xd9, 0xff, 0x76, 0xd4, 0x31, 0x43, 0x2d, 0xa8, 0x9f, 0x9d, 0x7e, 0x73, 0xfa, 0xf2, 0xbb, 0xd3, 0xce, 0x16, 0x6a, 0x40, 0xe5,
0xd0, 0x43, 0x78, 0x70, 0xbc, 0x3f, 0x7e, 0x35, 0x71, 0x46, 0xc7, 0xa3, 0xfd, 0xf1, 0xe8, 0x45, 0xf4, 0xe0, 0xdb, 0x71, 0xa7, 0x84, 0xee, 0xc3, 0xbd, 0x93, 0x83, 0xc9, 0xab, 0xa9, 0x35, 0x3e,
0xa7, 0x64, 0xbf, 0x0b, 0xcd, 0xc4, 0x67, 0x54, 0x87, 0xf2, 0xfe, 0x78, 0x28, 0x44, 0x5e, 0x8c, 0x19, 0x1f, 0x4c, 0xc6, 0x2f, 0x3a, 0x65, 0xf3, 0x5d, 0x68, 0xc6, 0x31, 0xa3, 0x3a, 0x68, 0x07,
0xc6, 0xc3, 0x8e, 0x61, 0xff, 0x6e, 0x40, 0x57, 0x4f, 0x11, 0x59, 0x86, 0x01, 0xc1, 0x2c, 0x47, 0x93, 0x11, 0x3f, 0xf2, 0x62, 0x3c, 0x19, 0x75, 0x4a, 0xe6, 0x1f, 0x25, 0xe8, 0xaa, 0x14, 0x91,
0xd3, 0x30, 0x0e, 0x92, 0x1c, 0xf1, 0x0d, 0x42, 0x50, 0x09, 0xf0, 0x5b, 0x95, 0x21, 0xbe, 0x66, 0x95, 0xef, 0x11, 0x1c, 0x71, 0x34, 0xf3, 0x43, 0x2f, 0xe6, 0x88, 0x2d, 0x10, 0x82, 0x8a, 0x87,
0x9c, 0x34, 0xa4, 0xae, 0xcf, 0xb3, 0x53, 0x76, 0xc4, 0x06, 0x7d, 0x0a, 0x0d, 0x19, 0x3a, 0x31, 0xdf, 0x4a, 0x86, 0xd8, 0x77, 0xa4, 0x49, 0x7d, 0x6a, 0xbb, 0x8c, 0x1d, 0xcd, 0xe2, 0x0b, 0xf4,
0x2b, 0xbb, 0xe5, 0x5e, 0x6b, 0xb0, 0xa9, 0x03, 0x22, 0x2d, 0x3a, 0x09, 0x9b, 0x7d, 0x00, 0xdb, 0x29, 0x34, 0x44, 0xea, 0x44, 0xaf, 0xf4, 0xb4, 0x7e, 0x6b, 0xf8, 0x50, 0x05, 0x44, 0x78, 0xb4,
0x07, 0x58, 0x79, 0x22, 0xf0, 0x52, 0x15, 0xc3, 0xec, 0xba, 0x0b, 0xcc, 0x9d, 0x61, 0x76, 0xdd, 0x62, 0x35, 0xf3, 0x10, 0x76, 0x0f, 0xb1, 0x8c, 0x84, 0xe3, 0x25, 0x6f, 0x4c, 0xe4, 0xd7, 0x5e,
0x05, 0x46, 0x26, 0xd4, 0x65, 0xb9, 0x71, 0x77, 0xaa, 0x8e, 0xda, 0xda, 0x14, 0xcc, 0x9b, 0x8a, 0x62, 0x16, 0x4c, 0xe4, 0xd7, 0x5e, 0x62, 0xa4, 0x43, 0x5d, 0x5c, 0x37, 0x16, 0x4e, 0xd5, 0x92,
0x64, 0x5c, 0x59, 0x9a, 0x3e, 0x84, 0x0a, 0xbb, 0x09, 0x5c, 0x4d, 0x6b, 0x80, 0x74, 0x3f, 0x8f, 0x4b, 0x93, 0x82, 0xbe, 0x6e, 0x48, 0xe4, 0x95, 0x65, 0xe9, 0x43, 0xa8, 0x44, 0x95, 0xc0, 0xcc,
0x82, 0x79, 0xe8, 0x70, 0xba, 0x9e, 0xaa, 0xf2, 0x6a, 0xaa, 0x0e, 0xd3, 0x56, 0x87, 0x61, 0x40, 0xb4, 0x86, 0x48, 0x8d, 0xf3, 0xd8, 0x5b, 0xf8, 0x16, 0x93, 0xab, 0x54, 0x69, 0x69, 0xaa, 0x8e,
0x71, 0x40, 0xef, 0xe7, 0xff, 0x31, 0xec, 0x64, 0x68, 0x92, 0x01, 0xec, 0x41, 0x5d, 0xba, 0xc6, 0x92, 0x5e, 0x47, 0xbe, 0x47, 0xb1, 0x47, 0xef, 0x16, 0xff, 0x09, 0xec, 0x65, 0x58, 0x12, 0x09,
0xb5, 0xe5, 0xe2, 0xaa, 0xb8, 0xec, 0xbf, 0x4b, 0xd0, 0x3d, 0x5d, 0xce, 0x5c, 0x8a, 0x15, 0xe9, 0xec, 0x43, 0x5d, 0x84, 0xc6, 0xac, 0xe5, 0xe2, 0x2a, 0xb5, 0xcc, 0xdf, 0x34, 0xe8, 0x9e, 0xad,
0x16, 0xa7, 0x1e, 0x43, 0x95, 0x77, 0x14, 0x89, 0xc5, 0x43, 0xa1, 0x5b, 0xb4, 0x9d, 0x21, 0xfb, 0xe6, 0x36, 0xc5, 0x52, 0xb4, 0x21, 0xa8, 0xc7, 0x50, 0x65, 0x1d, 0x45, 0x60, 0x71, 0x9f, 0xdb,
0x75, 0x04, 0x1d, 0x3d, 0x85, 0xda, 0xa5, 0xeb, 0xc7, 0x98, 0x70, 0x20, 0x12, 0xd4, 0x24, 0x27, 0xe6, 0x6d, 0x67, 0x14, 0xfd, 0xb5, 0xb8, 0x1c, 0x3d, 0x85, 0xda, 0x95, 0xed, 0x86, 0x98, 0x30,
0x6f, 0x47, 0x8e, 0xe4, 0x40, 0xdb, 0x50, 0x9f, 0x45, 0x57, 0xac, 0x9f, 0xf0, 0x2b, 0xd8, 0x70, 0x20, 0x62, 0xd4, 0x84, 0x26, 0x6b, 0x47, 0x96, 0xd0, 0x40, 0xbb, 0x50, 0x9f, 0x07, 0xd7, 0x51,
0x6a, 0xb3, 0xe8, 0xca, 0x89, 0x03, 0xf4, 0x3e, 0x3c, 0x98, 0x79, 0xc4, 0x3d, 0xf3, 0xf1, 0xe4, 0x3f, 0x61, 0x25, 0xd8, 0xb0, 0x6a, 0xf3, 0xe0, 0xda, 0x0a, 0x3d, 0xf4, 0x3e, 0xdc, 0x9b, 0x3b,
0x22, 0x0c, 0xdf, 0x10, 0x7e, 0x0b, 0x1b, 0xce, 0xba, 0x3c, 0x3c, 0x64, 0x67, 0xc8, 0x62, 0x95, 0xc4, 0x3e, 0x77, 0xf1, 0xf4, 0xd2, 0xf7, 0xdf, 0x10, 0x56, 0x85, 0x0d, 0x6b, 0x5b, 0x6c, 0x1e,
0x34, 0x8d, 0xb0, 0x4b, 0xb1, 0x59, 0xe3, 0xf4, 0x64, 0xcf, 0x30, 0xa4, 0xde, 0x02, 0x87, 0x31, 0x45, 0x7b, 0xc8, 0x88, 0x6e, 0xd2, 0x2c, 0xc0, 0x36, 0xc5, 0x7a, 0x8d, 0xc9, 0xe3, 0x75, 0x84,
0xe5, 0x57, 0xa7, 0xec, 0xa8, 0x2d, 0x7a, 0x0f, 0xd6, 0x23, 0x4c, 0x30, 0x9d, 0x48, 0x2f, 0x1b, 0x21, 0x75, 0x96, 0xd8, 0x0f, 0x29, 0x2b, 0x1d, 0xcd, 0x92, 0x4b, 0xf4, 0x1e, 0x6c, 0x07, 0x98,
0x5c, 0xb2, 0xc5, 0xcf, 0x5e, 0x0b, 0xb7, 0x10, 0x54, 0x7e, 0x75, 0x3d, 0x6a, 0x36, 0x39, 0x89, 0x60, 0x3a, 0x15, 0x51, 0x36, 0xd8, 0xc9, 0x16, 0xdb, 0x7b, 0xcd, 0xc3, 0x42, 0x50, 0xf9, 0xd5,
0xaf, 0x85, 0x58, 0x4c, 0xb0, 0x12, 0x03, 0x25, 0x16, 0x13, 0x2c, 0xc5, 0xba, 0x50, 0x9d, 0x87, 0x76, 0xa8, 0xde, 0x64, 0x22, 0xf6, 0xcd, 0x8f, 0x85, 0x04, 0xcb, 0x63, 0x20, 0x8f, 0x85, 0x04,
0xd1, 0x14, 0x9b, 0x2d, 0x4e, 0x13, 0x1b, 0xfb, 0x10, 0x36, 0x57, 0x40, 0xbe, 0x6f, 0xbe, 0xfe, 0x8b, 0x63, 0x5d, 0xa8, 0x2e, 0xfc, 0x60, 0x86, 0xf5, 0x16, 0x93, 0xf1, 0x05, 0xea, 0x41, 0x6b,
0x31, 0x60, 0xcb, 0x09, 0x7d, 0xff, 0xcc, 0x9d, 0xbe, 0x29, 0x90, 0xb1, 0x14, 0xb8, 0xa5, 0xdb, 0x8e, 0xc9, 0x2c, 0x70, 0x56, 0x34, 0x62, 0x74, 0x9b, 0x61, 0x9a, 0xdc, 0x32, 0x8f, 0xe0, 0x61,
0xc1, 0x2d, 0x67, 0x80, 0x9b, 0x2a, 0xc2, 0x8a, 0x56, 0x84, 0x1a, 0xec, 0xd5, 0x7c, 0xd8, 0x6b, 0x8a, 0x86, 0xbb, 0x32, 0xfa, 0x7b, 0x19, 0x76, 0x2c, 0xdf, 0x75, 0xcf, 0xed, 0xd9, 0x9b, 0x02,
0x3a, 0xec, 0x0a, 0xd3, 0x7a, 0x0a, 0xd3, 0x04, 0xb0, 0x46, 0x1a, 0xb0, 0xaf, 0x61, 0xfb, 0x46, 0x9c, 0x26, 0xe0, 0x2f, 0x6f, 0x86, 0x5f, 0xcb, 0x80, 0x3f, 0x71, 0x4d, 0x2b, 0xca, 0x35, 0x55,
0x94, 0xf7, 0x85, 0xec, 0xcf, 0x12, 0x6c, 0x1e, 0x05, 0x84, 0xba, 0xbe, 0xbf, 0x82, 0x58, 0x52, 0x88, 0xa9, 0xe6, 0x13, 0x53, 0x53, 0x89, 0x91, 0xa8, 0xd7, 0x13, 0xa8, 0xc7, 0x90, 0x36, 0x36,
0xcf, 0x46, 0xe1, 0x7a, 0x2e, 0xfd, 0x97, 0x7a, 0x2e, 0x6b, 0x90, 0xab, 0xfc, 0x54, 0x52, 0xf9, 0x40, 0xda, 0x5c, 0x87, 0xf4, 0x6b, 0xd8, 0x5d, 0xc3, 0xe1, 0xae, 0xa0, 0xfe, 0x53, 0x86, 0x87,
0x29, 0x54, 0xe3, 0x5a, 0x67, 0xa9, 0xad, 0x74, 0x16, 0xf4, 0x0e, 0x80, 0x28, 0x4a, 0xae, 0x5c, 0xc7, 0x1e, 0xa1, 0xb6, 0xeb, 0xa6, 0x30, 0x8d, 0x6b, 0xa2, 0x54, 0xb8, 0x26, 0xca, 0xff, 0xa5,
0x40, 0xdb, 0xe4, 0x27, 0x27, 0xb2, 0x91, 0xa8, 0x6c, 0x34, 0xb2, 0xb3, 0x91, 0xae, 0xf0, 0x1e, 0x26, 0x34, 0x85, 0x14, 0xc9, 0x60, 0x25, 0xc1, 0x60, 0xa1, 0x3a, 0x51, 0xba, 0x53, 0x2d, 0xd5,
0x74, 0x94, 0x3f, 0xd3, 0x68, 0xc6, 0x7d, 0x92, 0x55, 0xde, 0x96, 0xe7, 0xc3, 0x68, 0xc6, 0xbc, 0x9d, 0xd0, 0x3b, 0x00, 0xfc, 0x62, 0x33, 0xe3, 0x1c, 0xfc, 0x26, 0xdb, 0x39, 0x15, 0xcd, 0x48,
0xb2, 0x8f, 0x60, 0x6b, 0x15, 0xd4, 0xfb, 0x26, 0xe8, 0x37, 0x03, 0xb6, 0x4f, 0x03, 0x2f, 0x33, 0xf2, 0xd5, 0xc8, 0xe6, 0x2b, 0x59, 0x25, 0x7d, 0xe8, 0xc8, 0x78, 0x66, 0xc1, 0x9c, 0xc5, 0x24,
0x45, 0x59, 0x45, 0x7d, 0x03, 0xb4, 0x52, 0x06, 0x68, 0x5d, 0xa8, 0x2e, 0xe3, 0xe8, 0x1c, 0xcb, 0x2a, 0xa5, 0x2d, 0xf6, 0x47, 0xc1, 0x3c, 0x8a, 0x2a, 0xcd, 0x61, 0x6b, 0x9d, 0xc3, 0x63, 0xd8,
0x24, 0x88, 0x4d, 0x1a, 0x8d, 0x8a, 0x86, 0x86, 0x3d, 0x01, 0xf3, 0xa6, 0x0f, 0xf7, 0x8c, 0x88, 0x49, 0xc3, 0x7e, 0x57, 0x0a, 0xff, 0x2c, 0xc1, 0xee, 0x99, 0xe7, 0x64, 0x92, 0x98, 0x55, 0x18,
0x79, 0x9d, 0xbc, 0x19, 0x4d, 0xf1, 0x3e, 0xd8, 0x1b, 0xf0, 0xf0, 0x00, 0xd3, 0xd7, 0xe2, 0x02, 0x6b, 0xb0, 0x96, 0x33, 0x60, 0xed, 0x42, 0x75, 0x15, 0x06, 0x17, 0x58, 0xd0, 0xc4, 0x17, 0x49,
0xc9, 0xf0, 0xec, 0x11, 0xa0, 0xf4, 0xe1, 0xb5, 0x3d, 0x79, 0xa4, 0xdb, 0x53, 0x03, 0x94, 0xe2, 0xbc, 0x2a, 0x2a, 0x5e, 0xa9, 0x8c, 0xab, 0xeb, 0x19, 0x4f, 0x41, 0x5f, 0x8f, 0xf2, 0x8e, 0x39,
0x57, 0x5c, 0xf6, 0x17, 0x5c, 0xf7, 0xa1, 0x47, 0x68, 0x18, 0x5d, 0xdd, 0x06, 0x5d, 0x07, 0xca, 0x47, 0x79, 0xc5, 0x6f, 0x57, 0x93, 0xbf, 0x53, 0xe6, 0x03, 0xb8, 0x7f, 0x88, 0xe9, 0x6b, 0x5e,
0x0b, 0xf7, 0xad, 0x7c, 0x52, 0xd8, 0xd2, 0x3e, 0xe0, 0x1e, 0x24, 0xa2, 0xd2, 0x83, 0xf4, 0x03, 0xa6, 0x02, 0x00, 0x73, 0x0c, 0x28, 0xb9, 0x79, 0xe3, 0x4f, 0x6c, 0xa9, 0xfe, 0xe4, 0x20, 0x27,
0x6d, 0x14, 0x7b, 0xa0, 0x7f, 0x00, 0xf4, 0x0a, 0x27, 0xb3, 0xc2, 0x1d, 0x6f, 0x9b, 0x4a, 0x42, 0xf5, 0xa5, 0x96, 0xf9, 0x05, 0xb3, 0x7d, 0xe4, 0x10, 0xea, 0x07, 0xd7, 0x9b, 0xc0, 0xed, 0x80,
0x49, 0x2f, 0x49, 0x13, 0xea, 0x53, 0x1f, 0xbb, 0x41, 0xbc, 0x94, 0x69, 0x53, 0x5b, 0xfb, 0x47, 0xb6, 0xb4, 0xdf, 0x8a, 0xa7, 0x2d, 0xfa, 0x34, 0x0f, 0x59, 0x04, 0xf1, 0x51, 0x11, 0x41, 0x72,
0xd8, 0xd0, 0xb4, 0x4b, 0x3f, 0x59, 0x3c, 0xe4, 0x5c, 0x6a, 0x67, 0x4b, 0xf4, 0x39, 0xd4, 0xc4, 0x50, 0x28, 0x15, 0x1b, 0x14, 0x7e, 0x00, 0xf4, 0x0a, 0xc7, 0x33, 0xcb, 0x2d, 0x6f, 0xac, 0xa4,
0x00, 0xc5, 0x75, 0xb7, 0x07, 0x8f, 0x74, 0xbf, 0xb9, 0x92, 0x38, 0x90, 0x13, 0x97, 0x23, 0x79, 0xa9, 0xac, 0xd2, 0xa4, 0x43, 0x7d, 0xe6, 0x62, 0xdb, 0x0b, 0x57, 0x82, 0x58, 0xb9, 0x34, 0x7f,
0x07, 0x7f, 0x35, 0xa0, 0xad, 0x46, 0x02, 0x31, 0xde, 0x21, 0x0f, 0xd6, 0xd3, 0xb3, 0x0f, 0x7a, 0x84, 0x07, 0x8a, 0x75, 0x11, 0x67, 0x94, 0x0f, 0xb9, 0x10, 0xd6, 0xa3, 0x4f, 0xf4, 0x39, 0xd4,
0x92, 0x3f, 0xfd, 0xad, 0x8c, 0xb0, 0xd6, 0xd3, 0x22, 0xac, 0x22, 0x02, 0x7b, 0xed, 0x13, 0x03, 0xf8, 0x20, 0xc7, 0x6c, 0xb7, 0x87, 0x8f, 0xd4, 0xb8, 0x99, 0x91, 0xd0, 0x13, 0x93, 0x9f, 0x25,
0x11, 0xe8, 0xac, 0x8e, 0x24, 0xe8, 0x59, 0xb6, 0x8e, 0x9c, 0x19, 0xc8, 0xea, 0x17, 0x65, 0x57, 0x74, 0x87, 0x7f, 0x37, 0xa0, 0x2d, 0x47, 0x13, 0x3e, 0x66, 0x22, 0x07, 0xb6, 0x93, 0x33, 0x18,
0x66, 0xd1, 0x25, 0xaf, 0x19, 0x7d, 0x8e, 0x40, 0x77, 0xaa, 0xd1, 0x47, 0x17, 0x6b, 0xaf, 0x30, 0x7a, 0x92, 0x3f, 0x85, 0xa6, 0x46, 0x69, 0xe3, 0x69, 0x11, 0x55, 0x9e, 0x81, 0xb9, 0xf5, 0x49,
0x7f, 0x62, 0xf7, 0x67, 0x78, 0xa0, 0xbd, 0x85, 0x28, 0x07, 0xad, 0xac, 0xa9, 0xc4, 0xfa, 0xa8, 0x09, 0x11, 0xe8, 0xa4, 0x47, 0x23, 0xf4, 0x2c, 0xdb, 0x46, 0xce, 0x2c, 0x66, 0x0c, 0x8a, 0xaa,
0x10, 0x6f, 0x62, 0x6b, 0x01, 0x6d, 0xbd, 0x49, 0xa1, 0x1c, 0x05, 0x99, 0xef, 0x83, 0xf5, 0x71, 0x4b, 0xb7, 0xe8, 0x8a, 0xdd, 0x19, 0x75, 0x9e, 0x41, 0xb7, 0x9a, 0x51, 0x47, 0x28, 0x63, 0xbf,
0x31, 0xe6, 0xc4, 0x1c, 0x81, 0xce, 0x6a, 0x0f, 0xc9, 0xcb, 0x63, 0x4e, 0xbf, 0xcb, 0xcb, 0x63, 0xb0, 0x7e, 0xec, 0xf7, 0x67, 0xb8, 0xa7, 0xbc, 0xb8, 0x28, 0x07, 0xad, 0xac, 0xe9, 0xc8, 0xf8,
0x5e, 0x6b, 0xb2, 0xd7, 0x90, 0x0b, 0x70, 0xdd, 0x42, 0xd0, 0xe3, 0xdc, 0x84, 0xe8, 0x9d, 0xc7, 0xa8, 0x90, 0x6e, 0xec, 0x6b, 0x09, 0x6d, 0xb5, 0x8d, 0xa1, 0x1c, 0x03, 0x99, 0x6f, 0x8c, 0xf1,
0xea, 0xdd, 0xcd, 0x98, 0x98, 0x58, 0xc2, 0xff, 0x56, 0x5e, 0x63, 0x94, 0x03, 0x4d, 0xf6, 0x68, 0x71, 0x31, 0xe5, 0xd8, 0x1d, 0x81, 0x4e, 0xba, 0x87, 0xe4, 0xf1, 0x98, 0xd3, 0x11, 0xf3, 0x78,
0x62, 0x3d, 0x2b, 0xc8, 0xbd, 0x12, 0x94, 0xec, 0x4a, 0xb7, 0x04, 0xa5, 0xb7, 0xbc, 0x5b, 0x82, 0xcc, 0x6b, 0x4d, 0xe6, 0x16, 0xb2, 0x01, 0x6e, 0x5a, 0x08, 0x7a, 0x9c, 0x4b, 0x88, 0xda, 0x79,
0x5a, 0x69, 0x70, 0xf6, 0x1a, 0xf2, 0xa0, 0xed, 0xc4, 0x81, 0x34, 0xcd, 0xda, 0x02, 0xca, 0x91, 0x8c, 0xfe, 0xed, 0x8a, 0xb1, 0x8b, 0x15, 0xfc, 0x2f, 0xf5, 0xa2, 0xa3, 0x1c, 0x68, 0xb2, 0x07,
0xbe, 0xd9, 0xd5, 0xac, 0x27, 0x05, 0x38, 0xaf, 0xef, 0xf7, 0x73, 0xf8, 0xbe, 0xa1, 0x58, 0xcf, 0x20, 0xe3, 0x59, 0x41, 0xed, 0x54, 0x52, 0xa2, 0x2b, 0x6d, 0x48, 0x4a, 0x6d, 0x79, 0x1b, 0x92,
0x6a, 0xfc, 0xdf, 0xef, 0x67, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x5d, 0xc3, 0xd5, 0x55, 0xeb, 0x4a, 0x35, 0x38, 0x73, 0x0b, 0x39, 0xd0, 0xb6, 0x42, 0x4f, 0xb8, 0x8e, 0xda, 0x02, 0xca, 0x39,
0x0f, 0x00, 0x00, 0xbd, 0xde, 0xd5, 0x8c, 0x27, 0x05, 0x34, 0x6f, 0xea, 0xfb, 0x39, 0x7c, 0xdf, 0x90, 0xaa, 0xe7,
0x35, 0xf6, 0x5f, 0xf8, 0x67, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x9d, 0x73, 0x4f, 0x4d, 0x73,
0x10, 0x00, 0x00,
} }

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save