From 8ea2d1bc9b4ce2814afa2e864cfb5232dde05d43 Mon Sep 17 00:00:00 2001 From: Yuvi Panda Date: Wed, 16 Nov 2016 20:39:01 -0800 Subject: [PATCH 01/39] Remove double explanation of why MariaDB is in the list --- docs/using_helm.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/using_helm.md b/docs/using_helm.md index 3ff197940..aababc6e3 100644 --- a/docs/using_helm.md +++ b/docs/using_helm.md @@ -63,9 +63,7 @@ stable/mysql 0.1.0 Chart for MySQL stable/mariadb 0.5.1 Chart for MariaDB ``` -Now you will only see the results that match your filter. MySQL is -listed, of course, but so is MariaDB. Why? Because its full description -relates it to MySQL: +Now you will only see the results that match your filter. Why is `mariadb` in the list? Because its package description relates it to From dce6b647aaa53b1e7cd866d49445207bff4e2b87 Mon Sep 17 00:00:00 2001 From: Fabian Ruff Date: Sat, 19 Nov 2016 00:31:18 +0100 Subject: [PATCH 02/39] Bump sprig, adds sha256sum template function --- glide.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.lock b/glide.lock index e5dd9bd7a..c6ee4ade8 100644 --- a/glide.lock +++ b/glide.lock @@ -264,7 +264,7 @@ imports: - name: github.com/Masterminds/semver version: 808ed7761c233af2de3f9729a041d68c62527f3a - name: github.com/Masterminds/sprig - version: 8f797f5b23118d8fe846c4296b0ad55044201b14 + version: 3fb136ad254dd34998b95f8d523b09a0dafa31b5 - name: github.com/mattn/go-runewidth version: d6bea18f789704b5f83375793155289da36a3c7f - name: github.com/matttproud/golang_protobuf_extensions From 335b3806a520e779c0603f79290a35d75a54e1ee Mon Sep 17 00:00:00 2001 From: Fabian Ruff Date: Sat, 19 Nov 2016 00:32:14 +0100 Subject: [PATCH 03/39] Add docs for rolling deployments on config change --- docs/charts_tips_and_tricks.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/charts_tips_and_tricks.md b/docs/charts_tips_and_tricks.md index 2b1e975e1..e97b560ce 100644 --- a/docs/charts_tips_and_tricks.md +++ b/docs/charts_tips_and_tricks.md @@ -61,6 +61,29 @@ Because YAML ascribes significance to indentation levels and whitespace, this is one great way to include snippets of code, but handle indentation in a relevant context. +## Automatically Roll Deployments When ConfigMaps or Secrets change + +Often times configmaps or secrets are injected as configuration +files in containers. +Depending on the application a restart may be required should those +be updated with a subsequent `helm upgrade`, but if the +deployment spec itself didn't change the application keeps running +with the old configuration resulting in an inconsistent deployment. + +The `sha256sum` function can be used together with the `include` +function to ensure a deployments template section is updated if another +spec changes: + +``` +kind: Deployment +spec: + template: + metadata: + annotations: + checksum/config: {{ include "mychart/templates/configmap.yaml" . | sha256sum }} +[...] +``` + ## Using "Partials" and Template Includes Sometimes you want to create some reusable parts in your chart, whether From 98ff1b87973a570d44bbdb38948f14f62f51b763 Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Tue, 22 Nov 2016 17:01:01 -0800 Subject: [PATCH 04/39] chore(*): remove glide hacks that are no longer required --- glide.lock | 120 ++++++----------------------------------------------- glide.yaml | 7 +--- 2 files changed, 13 insertions(+), 114 deletions(-) diff --git a/glide.lock b/glide.lock index e5dd9bd7a..ead5a1050 100644 --- a/glide.lock +++ b/glide.lock @@ -1,8 +1,11 @@ -hash: e04a956fc7be01bd1a2450cdc0000ed25394da383f0c7a7e057a9377bd832c1e -updated: 2016-10-13T12:28:13.380298639-07:00 +hash: 99054419731f37edfc9fca9ae35d473635e865f1e1c9a7633ec36963dfa25c2a +updated: 2016-11-22T16:38:51.234855217-08:00 imports: -- name: bitbucket.org/ww/goautoneg - version: 75cd24fc2f2c2a2088577d12123ddee5f54e0675 +- name: cloud.google.com/go + version: 3b1ae45394a234c385be014e9a488f2bb6eef821 + subpackages: + - compute/metadata + - internal - name: github.com/aokoli/goutils version: 9c37978a95bd5c709a15883b6242714ea6709e64 - name: github.com/asaskevich/govalidator @@ -11,67 +14,8 @@ imports: version: 70b2c90b260171e829f1ebd7c17f600c11858dbe subpackages: - winterm -- name: github.com/beorn7/perks - version: 3ac7bf7a47d159a033b107610db8a1b6575507a4 - subpackages: - - quantile - name: github.com/blang/semver version: 31b736133b98f26d5e078ec9eb591666edfd091f -- name: github.com/coreos/etcd - version: 9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0 - subpackages: - - alarm - - auth - - auth/authpb - - client - - clientv3 - - compactor - - discovery - - error - - etcdserver - - etcdserver/api - - etcdserver/api/v2http - - etcdserver/api/v2http/httptypes - - etcdserver/api/v3rpc - - etcdserver/api/v3rpc/rpctypes - - etcdserver/auth - - etcdserver/etcdserverpb - - etcdserver/membership - - etcdserver/stats - - integration - - lease - - lease/leasehttp - - lease/leasepb - - mvcc - - mvcc/backend - - mvcc/mvccpb - - pkg/adt - - pkg/contention - - pkg/crc - - pkg/fileutil - - pkg/httputil - - pkg/idutil - - pkg/ioutil - - pkg/logutil - - pkg/netutil - - pkg/pathutil - - pkg/pbutil - - pkg/runtime - - pkg/schedule - - pkg/testutil - - pkg/tlsutil - - pkg/transport - - pkg/types - - pkg/wait - - raft - - raft/raftpb - - rafthttp - - snap - - snap/snappb - - store - - version - - wal - - wal/walpb - name: github.com/coreos/go-oidc version: 5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b subpackages: @@ -192,12 +136,11 @@ imports: - name: github.com/golang/protobuf version: df1d3ca07d2d07bba352d5b73c4313b4e2a6203e subpackages: - - jsonpb - proto - ptypes/any - ptypes/timestamp - name: github.com/google/cadvisor - version: 0cdf4912793fac9990de3790c273342ec31817fb + version: a726d13de8cb32860e73d72a78dc8e0124267709 subpackages: - api - cache/memory @@ -247,12 +190,6 @@ imports: subpackages: - util/strutil - util/wordwrap -- name: github.com/grpc-ecosystem/grpc-gateway - version: f52d055dc48aec25854ed7d31862f78913cf17d1 - subpackages: - - runtime - - runtime/internal - - utilities - name: github.com/imdario/mergo version: 6633656539c1639d9d78127b7d47c622b5d7b6dc - name: github.com/inconshreveable/mousetrap @@ -267,27 +204,8 @@ imports: version: 8f797f5b23118d8fe846c4296b0ad55044201b14 - name: github.com/mattn/go-runewidth version: d6bea18f789704b5f83375793155289da36a3c7f -- name: github.com/matttproud/golang_protobuf_extensions - version: fc2b8d3a73c4867e51861bbdd5ae3c1f0869dd6a - subpackages: - - pbutil - name: github.com/pborman/uuid version: ca53cad383cad2479bbba7f7a1a05797ec1386e4 -- name: github.com/prometheus/client_golang - version: e51041b3fa41cece0dca035740ba6411905be473 - subpackages: - - prometheus -- name: github.com/prometheus/client_model - version: fa8ad6fec33561be4280a8f0514318c79d7f6cb6 - subpackages: - - go -- name: github.com/prometheus/common - version: ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650 - subpackages: - - expfmt - - model -- name: github.com/prometheus/procfs - version: 454a56f35412459b5e684fd5ec0f9211b94f002a - name: github.com/satori/go.uuid version: 879c5887cd475cd7864858769793b2ceb0d44feb - name: github.com/Sirupsen/logrus @@ -314,6 +232,7 @@ imports: - openpgp/errors - openpgp/packet - openpgp/s2k + - ssh/terminal - name: golang.org/x/net version: fb93926129b8ec0056f2f458b1f519654814edf0 subpackages: @@ -325,14 +244,14 @@ imports: - trace - websocket - name: golang.org/x/oauth2 - version: b5adcc2dcdf009d0391547edc6ecbaff889f5bb9 + version: 3c3a985cb79f52a3190fbc056984415ca6763d01 subpackages: - google - internal - jws - jwt - name: google.golang.org/appengine - version: 12d5545dc1cfa6047a286d5e853841b6471f4c19 + version: 4f7eeb5305a4ba1966344836ba4af9996b7b4e05 subpackages: - internal - internal/app_identity @@ -343,13 +262,6 @@ imports: - internal/remote_api - internal/urlfetch - urlfetch -- name: google.golang.org/cloud - version: eb47ba841d53d93506cfbfbc03927daf9cc48f88 - repo: https://code.googlesource.com/gocloud - vcs: git - subpackages: - - compute/metadata - - internal - name: google.golang.org/grpc version: 0032a855ba5c8a3c8e0d71c2deef354b70af1584 subpackages: @@ -434,7 +346,7 @@ imports: - 1.4/tools/metrics - 1.4/transport - name: k8s.io/kubernetes - version: fc3dab7de68c15de3421896dd051c2f127fb64ab + version: fd8fac83034df346529c6e11aabceea2db48d663 subpackages: - federation/apis/federation - federation/apis/federation/install @@ -547,7 +459,6 @@ imports: - pkg/kubelet/types - pkg/labels - pkg/master/ports - - pkg/registry/generic - pkg/registry/thirdpartyresourcedata - pkg/runtime - pkg/runtime/serializer @@ -560,15 +471,8 @@ imports: - pkg/security/podsecuritypolicy/util - pkg/selection - pkg/storage - - pkg/storage/etcd - - pkg/storage/etcd/metrics - - pkg/storage/etcd/util - - pkg/storage/etcd3 - - pkg/storage/storagebackend - - pkg/storage/storagebackend/factory - pkg/types - pkg/util - - pkg/util/cache - pkg/util/certificates - pkg/util/clock - pkg/util/config diff --git a/glide.yaml b/glide.yaml index 8d30c72b2..6125587e0 100644 --- a/glide.yaml +++ b/glide.yaml @@ -5,8 +5,6 @@ import: subpackages: - context - package: github.com/spf13/cobra -- package: github.com/spf13/pflag - version: 367864438f1b1a3c7db4da06a2f55b144e6784e0 - package: github.com/Masterminds/sprig version: ^2.6 - package: github.com/ghodss/yaml @@ -20,7 +18,7 @@ import: - ptypes/any - ptypes/timestamp - package: google.golang.org/grpc - version: v1.0.1-GA + version: 1.0.3 - package: k8s.io/kubernetes version: ~1.4.1 subpackages: @@ -48,9 +46,6 @@ import: - package: github.com/gosuri/uitable - package: github.com/asaskevich/govalidator version: ^4.0.0 -- package: google.golang.org/cloud - vcs: git - repo: https://code.googlesource.com/gocloud - package: golang.org/x/crypto subpackages: - openpgp From 6a1aab7fc83660601800e91f9c982832101684d6 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Mon, 21 Nov 2016 19:06:03 -0700 Subject: [PATCH 05/39] fix(helm): improve --set parser This replaces the old set parser with a brand new one. This also changes the internal algorithm from duplicating YAML to merging YAML, which might solve a problem one user reported in chat, but which was never captured in an issue. Closes #1540 Closes #1556 --- cmd/helm/install.go | 103 ++----------- cmd/helm/install_test.go | 66 -------- cmd/helm/strvals/doc.go | 32 ++++ cmd/helm/strvals/parser.go | 258 ++++++++++++++++++++++++++++++++ cmd/helm/strvals/parser_test.go | 232 ++++++++++++++++++++++++++++ cmd/helm/upgrade.go | 27 ++-- docs/using_helm.md | 51 +++++++ 7 files changed, 595 insertions(+), 174 deletions(-) create mode 100644 cmd/helm/strvals/doc.go create mode 100644 cmd/helm/strvals/parser.go create mode 100644 cmd/helm/strvals/parser_test.go diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 169e8a805..d0c919285 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -24,7 +24,6 @@ import ( "io/ioutil" "os" "path/filepath" - "strconv" "strings" "text/template" @@ -35,6 +34,7 @@ import ( "k8s.io/helm/cmd/helm/downloader" "k8s.io/helm/cmd/helm/helmpath" + "k8s.io/helm/cmd/helm/strvals" "k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/kube" "k8s.io/helm/pkg/proto/hapi/release" @@ -95,7 +95,7 @@ type installCmd struct { keyring string out io.Writer client helm.Interface - values *values + values string nameTemplate string version string } @@ -104,7 +104,6 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command { inst := &installCmd{ out: out, client: c, - values: new(values), } cmd := &cobra.Command{ @@ -133,7 +132,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command { f.BoolVar(&inst.dryRun, "dry-run", false, "simulate an install") f.BoolVar(&inst.disableHooks, "no-hooks", false, "prevent hooks from running during install") f.BoolVar(&inst.replace, "replace", false, "re-use the given name, even if that name is already used. This is unsafe in production") - f.Var(inst.values, "set", "set values on the command line. Separate values with commas: key1=val1,key2=val2") + f.StringVar(&inst.values, "set", "", "set values on the command line. Separate values with commas: key1=val1,key2=val2") f.StringVar(&inst.nameTemplate, "name-template", "", "specify template used to name the release") f.BoolVar(&inst.verify, "verify", false, "verify the package before installing it") f.StringVar(&inst.keyring, "keyring", defaultKeyring(), "location of public keys used for verification") @@ -199,7 +198,7 @@ func (i *installCmd) run() error { } func (i *installCmd) vals() ([]byte, error) { - var buffer bytes.Buffer + base := map[string]interface{}{} // User specified a values file via -f/--values if i.valuesFile != "" { @@ -207,24 +206,17 @@ func (i *installCmd) vals() ([]byte, error) { if err != nil { return []byte{}, err } - buffer.Write(bytes) - // Force a new line. An extra won't matter, but a missing one can - // break things. https://github.com/kubernetes/helm/issues/1430 - buffer.WriteRune('\n') + if err := yaml.Unmarshal(bytes, &base); err != nil { + return []byte{}, fmt.Errorf("failed to parse %s: %s", i.valuesFile, err) + } } - // User specified value pairs via --set - // These override any values in the specified file - if len(i.values.pairs) > 0 { - bytes, err := i.values.yaml() - if err != nil { - return []byte{}, err - } - buffer.Write(bytes) + if err := strvals.ParseInto(i.values, base); err != nil { + return []byte{}, fmt.Errorf("failed parsing --set data: %s", err) } - return buffer.Bytes(), nil + return yaml.Marshal(base) } // printRelease prints info about a release if the flagDebug is true. @@ -243,81 +235,6 @@ func (i *installCmd) printRelease(rel *release.Release) { } } -// values represents the command-line value pairs -type values struct { - pairs map[string]interface{} -} - -func (v *values) yaml() ([]byte, error) { - return yaml.Marshal(v.pairs) -} - -func (v *values) String() string { - out, _ := v.yaml() - return string(out) -} - -func (v *values) Type() string { - // Added to pflags.Value interface, but not documented there. - return "struct" -} - -func (v *values) Set(data string) error { - v.pairs = map[string]interface{}{} - - items := strings.Split(data, ",") - for _, item := range items { - n, val := splitPair(item) - names := strings.Split(n, ".") - ln := len(names) - current := &v.pairs - for i := 0; i < ln; i++ { - if i+1 == ln { - // We're at the last element. Set it. - (*current)[names[i]] = val - } else { - // - if e, ok := (*current)[names[i]]; !ok { - m := map[string]interface{}{} - (*current)[names[i]] = m - current = &m - } else if m, ok := e.(map[string]interface{}); ok { - current = &m - } - } - } - } - return nil -} - -func typedVal(val string) interface{} { - if strings.EqualFold(val, "true") { - return true - } - - if strings.EqualFold(val, "false") { - return false - } - - if iv, err := strconv.ParseInt(val, 10, 64); err == nil { - return iv - } - - if fv, err := strconv.ParseFloat(val, 64); err == nil { - return fv - } - - return val -} - -func splitPair(item string) (name string, value interface{}) { - pair := strings.SplitN(item, "=", 2) - if len(pair) == 1 { - return pair[0], true - } - return pair[0], typedVal(pair[1]) -} - // locateChartPath looks for a chart directory in known places, and returns either the full path or an error. // // This does not ensure that the chart is well-formed; only that the requested filename exists. diff --git a/cmd/helm/install_test.go b/cmd/helm/install_test.go index 76da76ea8..e2e5e1e8b 100644 --- a/cmd/helm/install_test.go +++ b/cmd/helm/install_test.go @@ -17,7 +17,6 @@ limitations under the License. package main import ( - "fmt" "io" "regexp" "strings" @@ -99,71 +98,6 @@ func TestInstall(t *testing.T) { }) } -func TestValues(t *testing.T) { - args := "sailor=sinbad,good,port.source=baghdad,port.destination=basrah,success=True" - vobj := new(values) - vobj.Set(args) - - if vobj.Type() != "struct" { - t.Fatalf("Expected Type to be struct, got %s", vobj.Type()) - } - - vals := vobj.pairs - if fmt.Sprint(vals["good"]) != "true" { - t.Errorf("Expected good to be true. Got %v", vals["good"]) - } - - if !vals["success"].(bool) { - t.Errorf("Expected boolean true. Got %T, %v", vals["success"], vals["success"]) - } - - port := vals["port"].(map[string]interface{}) - - if fmt.Sprint(port["source"]) != "baghdad" { - t.Errorf("Expected source to be baghdad. Got %s", port["source"]) - } - if fmt.Sprint(port["destination"]) != "basrah" { - t.Errorf("Expected source to be baghdad. Got %s", port["source"]) - } - - y := `good: true -port: - destination: basrah - source: baghdad -sailor: sinbad -success: true -` - out, err := vobj.yaml() - if err != nil { - t.Fatal(err) - } - if string(out) != y { - t.Errorf("Expected YAML to be \n%s\nGot\n%s\n", y, out) - } - - if vobj.String() != y { - t.Errorf("Expected String() to be \n%s\nGot\n%s\n", y, out) - } - - // Combined case, overriding a property - vals["sailor"] = "pisti" - updatedYAML := `good: true -port: - destination: basrah - source: baghdad -sailor: pisti -success: true -` - newOut, err := vobj.yaml() - if err != nil { - t.Fatal(err) - } - if string(newOut) != updatedYAML { - t.Errorf("Expected YAML to be \n%s\nGot\n%s\n", updatedYAML, newOut) - } - -} - type nameTemplateTestCase struct { tpl string expected string diff --git a/cmd/helm/strvals/doc.go b/cmd/helm/strvals/doc.go new file mode 100644 index 000000000..d2b859e67 --- /dev/null +++ b/cmd/helm/strvals/doc.go @@ -0,0 +1,32 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/*Package strvals provides tools for working with strval lines. + +Helm supports a compressed format for YAML settings which we call strvals. +The format is roughly like this: + + name=value,topname.subname=value + +The above is equivalent to the YAML document + + name: value + topname: + subname: value + +This package provides a parser and utilities for converting the strvals format +to other formats. +*/ +package strvals diff --git a/cmd/helm/strvals/parser.go b/cmd/helm/strvals/parser.go new file mode 100644 index 000000000..e63efa3e9 --- /dev/null +++ b/cmd/helm/strvals/parser.go @@ -0,0 +1,258 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package strvals + +import ( + "bytes" + "errors" + "fmt" + "io" + "strconv" + "strings" + + "github.com/ghodss/yaml" +) + +// ToYAML takes a string of arguments and converts to a YAML document. +func ToYAML(s string) (string, error) { + m, err := Parse(s) + if err != nil { + return "", err + } + d, err := yaml.Marshal(m) + return string(d), err +} + +// Parse parses a set line. +// +// A set line is of the form name1=value1,name2=value2 +func Parse(s string) (map[string]interface{}, error) { + vals := map[string]interface{}{} + scanner := bytes.NewBufferString(s) + t := newParser(scanner, vals) + err := t.parse() + return vals, err +} + +//ParseInto parses a strvals line and merges the result into dest. +// +// If the strval string has a key that exists in dest, it overwrites the +// dest version. +func ParseInto(s string, dest map[string]interface{}) error { + scanner := bytes.NewBufferString(s) + t := newParser(scanner, dest) + return t.parse() +} + +// parser is a simple parser that takes a strvals line and parses it into a +// map representation. +type parser struct { + sc *bytes.Buffer + data map[string]interface{} +} + +func newParser(sc *bytes.Buffer, data map[string]interface{}) *parser { + return &parser{sc: sc, data: data} +} + +func (t *parser) parse() error { + for { + err := t.key(t.data) + if err == nil { + continue + } + if err == io.EOF { + return nil + } + return err + } +} + +func runeSet(r []rune) map[rune]bool { + s := make(map[rune]bool, len(r)) + for _, rr := range r { + s[rr] = true + } + return s +} + +func (t *parser) key(data map[string]interface{}) error { + stop := runeSet([]rune{'=', ',', '.'}) + for { + switch k, last, err := runesUntil(t.sc, stop); { + case err != nil: + if len(k) == 0 { + return err + } + return fmt.Errorf("key %q has no value", string(k)) + //set(data, string(k), "") + //return err + case last == '=': + //End of key. Consume =, Get value. + // FIXME: Get value list first + vl, e := t.valList() + switch e { + case nil: + set(data, string(k), vl) + return nil + case io.EOF: + set(data, string(k), "") + return e + case ErrNotList: + v, e := t.val() + set(data, string(k), typedVal(v)) + return e + default: + return e + } + + case last == ',': + // No value given. Set the value to empty string. Return error. + set(data, string(k), "") + return fmt.Errorf("key %q has no value (cannot end with ,)", string(k)) + case last == '.': + // First, create or find the target map. + inner := map[string]interface{}{} + if _, ok := data[string(k)]; ok { + inner = data[string(k)].(map[string]interface{}) + } + + // Recurse + e := t.key(inner) + if len(inner) == 0 { + return fmt.Errorf("key map %q has no value", string(k)) + } + set(data, string(k), inner) + return e + } + } +} + +func set(data map[string]interface{}, key string, val interface{}) { + // If key is empty, don't set it. + if len(key) == 0 { + return + } + data[key] = val +} + +func (t *parser) val() ([]rune, error) { + v := []rune{} + stop := runeSet([]rune{','}) + v, _, err := runesUntil(t.sc, stop) + return v, err +} + +var ErrNotList = errors.New("not a list") + +func (t *parser) valList() ([]interface{}, error) { + + r, _, e := t.sc.ReadRune() + if e != nil { + return []interface{}{}, e + } + + if r != '{' { + t.sc.UnreadRune() + return []interface{}{}, ErrNotList + } + + list := []interface{}{} + stop := runeSet([]rune{',', '}'}) + for { + switch v, last, err := runesUntil(t.sc, stop); { + case err != nil: + if err == io.EOF { + err = errors.New("list must terminate with '}'") + } + return list, err + case last == '}': + // If this is followed by ',', consume it. + if r, _, e := t.sc.ReadRune(); e == nil && r != ',' { + t.sc.UnreadRune() + } + list = append(list, typedVal(v)) + return list, nil + case last == ',': + list = append(list, typedVal(v)) + } + } +} + +func runesUntil(in *bytes.Buffer, stop map[rune]bool) ([]rune, rune, error) { + v := []rune{} + for { + switch r, _, e := in.ReadRune(); { + case e != nil: + return v, r, e + case inMap(r, stop): + return v, r, nil + case r == '\\': + next, _, e := in.ReadRune() + if e != nil { + return v, next, e + } + v = append(v, next) + default: + v = append(v, r) + } + } +} + +func inMap(k rune, m map[rune]bool) bool { + _, ok := m[k] + return ok +} + +func (t *parser) listVal() []rune { + v := []rune{} + for { + switch r, _, e := t.sc.ReadRune(); { + case e != nil: + // End of input or error with reader stops value parsing. + return v + case r == '\\': + //Escape char. Consume next and append. + next, _, e := t.sc.ReadRune() + if e != nil { + return v + } + v = append(v, next) + case r == ',': + //End of key. Consume ',' and return. + return v + default: + v = append(v, r) + } + } +} + +func typedVal(v []rune) interface{} { + val := string(v) + if strings.EqualFold(val, "true") { + return true + } + + if strings.EqualFold(val, "false") { + return false + } + + if iv, err := strconv.ParseInt(val, 10, 64); err == nil { + return iv + } + + return val +} diff --git a/cmd/helm/strvals/parser_test.go b/cmd/helm/strvals/parser_test.go new file mode 100644 index 000000000..cd3ae1884 --- /dev/null +++ b/cmd/helm/strvals/parser_test.go @@ -0,0 +1,232 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package strvals + +import ( + "testing" + + "github.com/ghodss/yaml" +) + +func TestParseSet(t *testing.T) { + tests := []struct { + str string + expect map[string]interface{} + err bool + }{ + { + "name1=value1", + map[string]interface{}{"name1": "value1"}, + false, + }, + { + "name1=value1,name2=value2", + map[string]interface{}{"name1": "value1", "name2": "value2"}, + false, + }, + { + "name1=value1,name2=value2,", + map[string]interface{}{"name1": "value1", "name2": "value2"}, + false, + }, + { + str: "name1=value1,,,,name2=value2,", + err: true, + }, + { + str: "name1=,name2=value2", + expect: map[string]interface{}{"name1": "", "name2": "value2"}, + }, + { + str: "name1,name2=", + err: true, + }, + { + str: "name1,name2=value2", + err: true, + }, + { + str: "name1,name2=value2\\", + err: true, + }, + { + str: "name1,name2", + err: true, + }, + { + "name1=one\\,two,name2=three\\,four", + map[string]interface{}{"name1": "one,two", "name2": "three,four"}, + false, + }, + { + "name1=one\\=two,name2=three\\=four", + map[string]interface{}{"name1": "one=two", "name2": "three=four"}, + false, + }, + { + "name1=one two three,name2=three two one", + map[string]interface{}{"name1": "one two three", "name2": "three two one"}, + false, + }, + { + "outer.inner=value", + map[string]interface{}{"outer": map[string]interface{}{"inner": "value"}}, + false, + }, + { + "outer.middle.inner=value", + map[string]interface{}{"outer": map[string]interface{}{"middle": map[string]interface{}{"inner": "value"}}}, + false, + }, + { + "outer.inner1=value,outer.inner2=value2", + map[string]interface{}{"outer": map[string]interface{}{"inner1": "value", "inner2": "value2"}}, + false, + }, + { + "outer.inner1=value,outer.middle.inner=value", + map[string]interface{}{ + "outer": map[string]interface{}{ + "inner1": "value", + "middle": map[string]interface{}{ + "inner": "value", + }, + }, + }, + false, + }, + { + str: "name1.name2", + err: true, + }, + { + str: "name1.name2,name1.name3", + err: true, + }, + { + str: "name1.name2=", + expect: map[string]interface{}{"name1": map[string]interface{}{"name2": ""}}, + }, + { + str: "name1.=name2", + err: true, + }, + { + str: "name1.,name2", + err: true, + }, + { + "name1={value1,value2}", + map[string]interface{}{"name1": []string{"value1", "value2"}}, + false, + }, + { + "name1={value1,value2},name2={value1,value2}", + map[string]interface{}{ + "name1": []string{"value1", "value2"}, + "name2": []string{"value1", "value2"}, + }, + false, + }, + { + "name1={1021,902}", + map[string]interface{}{"name1": []int{1021, 902}}, + false, + }, + { + "name1.name2={value1,value2}", + map[string]interface{}{"name1": map[string]interface{}{"name2": []string{"value1", "value2"}}}, + false, + }, + { + str: "name1={1021,902", + err: true, + }, + } + + for _, tt := range tests { + got, err := Parse(tt.str) + if err != nil { + if tt.err { + continue + } + t.Fatalf("%s: %s", tt.str, err) + } + if tt.err { + t.Errorf("%s: Expected error. Got nil", tt.str) + } + + y1, err := yaml.Marshal(tt.expect) + if err != nil { + t.Fatal(err) + } + y2, err := yaml.Marshal(got) + if err != nil { + t.Fatalf("Error serializing parsed value: %s", err) + } + + if string(y1) != string(y2) { + t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.str, y1, y2) + } + } +} + +func TestParseInto(t *testing.T) { + got := map[string]interface{}{ + "outer": map[string]interface{}{ + "inner1": "overwrite", + "inner2": "value2", + }, + } + input := "outer.inner1=value1,outer.inner3=value3" + expect := map[string]interface{}{ + "outer": map[string]interface{}{ + "inner1": "value1", + "inner2": "value2", + "inner3": "value3", + }, + } + + if err := ParseInto(input, got); err != nil { + t.Fatal(err) + } + + y1, err := yaml.Marshal(expect) + if err != nil { + t.Fatal(err) + } + y2, err := yaml.Marshal(got) + if err != nil { + t.Fatalf("Error serializing parsed value: %s", err) + } + + if string(y1) != string(y2) { + t.Errorf("%s: Expected:\n%s\nGot:\n%s", input, y1, y2) + } +} + +func TestToYAML(t *testing.T) { + // The TestParse does the hard part. We just verify that YAML formatting is + // happening. + o, err := ToYAML("name=value") + if err != nil { + t.Fatal(err) + } + expect := "name: value\n" + if o != expect { + t.Errorf("Expected %q, got %q", expect, o) + } +} diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 3d92a0cf4..076b57ca5 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -17,14 +17,15 @@ limitations under the License. package main import ( - "bytes" "fmt" "io" "io/ioutil" "strings" + "github.com/ghodss/yaml" "github.com/spf13/cobra" + "k8s.io/helm/cmd/helm/strvals" "k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/storage/driver" ) @@ -49,7 +50,7 @@ type upgradeCmd struct { dryRun bool disableHooks bool valuesFile string - values *values + values string verify bool keyring string install bool @@ -62,7 +63,6 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command { upgrade := &upgradeCmd{ out: out, client: client, - values: new(values), } cmd := &cobra.Command{ @@ -86,7 +86,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command { f := cmd.Flags() f.StringVarP(&upgrade.valuesFile, "values", "f", "", "path to a values YAML file") f.BoolVar(&upgrade.dryRun, "dry-run", false, "simulate an upgrade") - f.Var(upgrade.values, "set", "set values on the command line. Separate values with commas: key1=val1,key2=val2") + f.StringVar(&upgrade.values, "set", "", "set values on the command line. Separate values with commas: key1=val1,key2=val2") f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks") f.BoolVar(&upgrade.verify, "verify", false, "verify the provenance of the chart before upgrading") f.StringVar(&upgrade.keyring, "keyring", defaultKeyring(), "path to the keyring that contains public singing keys") @@ -154,7 +154,7 @@ func (u *upgradeCmd) run() error { } func (u *upgradeCmd) vals() ([]byte, error) { - var buffer bytes.Buffer + base := map[string]interface{}{} // User specified a values file via -f/--values if u.valuesFile != "" { @@ -162,18 +162,15 @@ func (u *upgradeCmd) vals() ([]byte, error) { if err != nil { return []byte{}, err } - buffer.Write(bytes) - } - // User specified value pairs via --set - // These override any values in the specified file - if len(u.values.pairs) > 0 { - bytes, err := u.values.yaml() - if err != nil { - return []byte{}, err + if err := yaml.Unmarshal(bytes, base); err != nil { + return []byte{}, fmt.Errorf("failed to parse %s: %s", u.valuesFile, err) } - buffer.Write(bytes) } - return buffer.Bytes(), nil + if err := strvals.ParseInto(u.values, base); err != nil { + return []byte{}, fmt.Errorf("failed parsing --set data: %s", err) + } + + return yaml.Marshal(base) } diff --git a/docs/using_helm.md b/docs/using_helm.md index 3ff197940..fb4fc6a27 100644 --- a/docs/using_helm.md +++ b/docs/using_helm.md @@ -224,6 +224,57 @@ $ helm install -f config.yaml stable/mariadb The above will set the default MariaDB user to `user0`, but accept all the rest of the defaults for that chart. +There are two ways to pass configuration data during install: + +- `--values` (or `-f`): Specifiy a YAML file with overrides. +- `--set`: Specify overrides on the command line. + +If both are used, `--set` values are merged into `--values` with higher precedence. + +#### The Format and Limitations of `--set` + +The `--set` option takes zero or more name/value pairs. At its simplest, it is +used like this: `--set name=value`. The YAML equivalent of that is: + +```yaml +name: value +``` + +Multiple values are separated by `,` characters. So `--set a=b,c=d` becomes: + +```yaml +a: b +c: d +``` + +More complex expressions are supported. For example, `--set outer.inner=value` is +translated into this: +```yaml +outer: + inner: value +``` + +Lists can be expressed by enclosing values in `{` and `}`. For example, +`--set name={a, b, c}` translates to: + +```yaml +name: + - a + - b + - c +``` + +Sometimes you need to use special characters in your `--set` lines. You can use +a backslash to escape the characters; `--set name=value1\,value2` will become: + +```yaml +name: "value1,value2" +``` + +The `--set` syntax is not as expressive as YAML, especially when it comes to +collections. And there is currently no method for expressing things such as "set +the third item in a list to...". + ### More Installation Methods The `helm install` command can install from several sources: From 51ecadaeaf16af8279dc76a31956cac6a7671e60 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Tue, 29 Nov 2016 11:42:37 -0500 Subject: [PATCH 06/39] fix(semver): range handling includes prerelease when it should not A bug in the semver package caused prereleases to be included in version ranges by default. Prereleases, per the spec, are not expected to be API compatible with the releases themselves. The semver package now ignores prereleases when evaluating constraints when the constraint does not contain a prerelease. If the constraint contains a prerelease they are evaluated. --- glide.lock | 6 +++--- glide.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/glide.lock b/glide.lock index ead5a1050..e777b53a7 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 99054419731f37edfc9fca9ae35d473635e865f1e1c9a7633ec36963dfa25c2a -updated: 2016-11-22T16:38:51.234855217-08:00 +hash: 89695daf5f2de706b79fdd8e8b095f9514f418c0fbcf80d7fdca4c208d114d19 +updated: 2016-11-29T11:37:40.998261206-05:00 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -199,7 +199,7 @@ imports: - name: github.com/juju/ratelimit version: 77ed1c8a01217656d2080ad51981f6e99adaa177 - name: github.com/Masterminds/semver - version: 808ed7761c233af2de3f9729a041d68c62527f3a + version: 52edfc04e184ecf0962489d167b511b27aeebd61 - name: github.com/Masterminds/sprig version: 8f797f5b23118d8fe846c4296b0ad55044201b14 - name: github.com/mattn/go-runewidth diff --git a/glide.yaml b/glide.yaml index 6125587e0..ab2871485 100644 --- a/glide.yaml +++ b/glide.yaml @@ -9,7 +9,7 @@ import: version: ^2.6 - package: github.com/ghodss/yaml - package: github.com/Masterminds/semver - version: 1.1.0 + version: ~1.2.1 - package: github.com/technosophos/moniker - package: github.com/golang/protobuf version: df1d3ca07d2d07bba352d5b73c4313b4e2a6203e From fad755e7ae926fcdf0b05ea6b150e39eb44020d0 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Mon, 21 Nov 2016 11:40:46 -0700 Subject: [PATCH 07/39] feat(helm): add plugin system backend This adds a backend for a plugin system. Closes #1572 --- README.md | 1 + cmd/helm/helm.go | 10 +- cmd/helm/helm_test.go | 2 +- cmd/helm/helmpath/helmhome.go | 5 + cmd/helm/init.go | 2 +- cmd/helm/plugins.go | 180 ++++++++++++++++++ cmd/helm/plugins_test.go | 125 ++++++++++++ cmd/helm/testdata/helmhome/plugins/args.sh | 2 + cmd/helm/testdata/helmhome/plugins/args.yaml | 4 + cmd/helm/testdata/helmhome/plugins/echo.yaml | 4 + cmd/helm/testdata/helmhome/plugins/env.yaml | 4 + cmd/helm/testdata/helmhome/plugins/fullenv.sh | 10 + .../testdata/helmhome/plugins/fullenv.yaml | 4 + docs/plugins.md | 176 +++++++++++++++++ pkg/plugin/plugin.go | 135 +++++++++++++ pkg/plugin/plugin_test.go | 117 ++++++++++++ pkg/plugin/testdata/plugdir/echo/plugin.yaml | 6 + pkg/plugin/testdata/plugdir/hello/hello.sh | 13 ++ pkg/plugin/testdata/plugdir/hello/plugin.yaml | 8 + 19 files changed, 804 insertions(+), 4 deletions(-) create mode 100644 cmd/helm/plugins.go create mode 100644 cmd/helm/plugins_test.go create mode 100755 cmd/helm/testdata/helmhome/plugins/args.sh create mode 100644 cmd/helm/testdata/helmhome/plugins/args.yaml create mode 100644 cmd/helm/testdata/helmhome/plugins/echo.yaml create mode 100644 cmd/helm/testdata/helmhome/plugins/env.yaml create mode 100755 cmd/helm/testdata/helmhome/plugins/fullenv.sh create mode 100644 cmd/helm/testdata/helmhome/plugins/fullenv.yaml create mode 100644 docs/plugins.md create mode 100644 pkg/plugin/plugin.go create mode 100644 pkg/plugin/plugin_test.go create mode 100644 pkg/plugin/testdata/plugdir/echo/plugin.yaml create mode 100755 pkg/plugin/testdata/plugdir/hello/hello.sh create mode 100644 pkg/plugin/testdata/plugdir/hello/plugin.yaml diff --git a/README.md b/README.md index 337a59a9e..40aea5545 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ including installing pre-releases. - [Kubernetes Distribution Notes](docs/kubernetes_distros.md) - [Frequently Asked Questions](docs/install_faq.md) - [Using Helm](docs/using_helm.md) + - [Plugins](docs/plugins.md) - [Developing Charts](docs/charts.md) - [Chart Lifecycle Hooks](docs/charts_hooks.md) - [Chart Tips and Tricks](docs/charts_tips_and_tricks.md) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index d9b169f00..59f88f6fb 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -31,6 +31,7 @@ import ( "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/helm/cmd/helm/helmpath" "k8s.io/helm/pkg/kube" ) @@ -91,7 +92,7 @@ func newRootCmd(out io.Writer) *cobra.Command { p.StringVar(&helmHome, "home", home, "location of your Helm config. Overrides $HELM_HOME") p.StringVar(&tillerHost, "host", thost, "address of tiller. Overrides $HELM_HOST") p.StringVar(&kubeContext, "kube-context", "", "name of the kubeconfig context to use") - p.BoolVarP(&flagDebug, "debug", "", false, "enable verbose output") + p.BoolVar(&flagDebug, "debug", false, "enable verbose output") // Tell gRPC not to log to console. grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags)) @@ -124,6 +125,10 @@ func newRootCmd(out io.Writer) *cobra.Command { // Deprecated rup, ) + + // Find and add plugins + loadPlugins(cmd, helmpath.Home(homePath()), out) + return cmd } @@ -141,7 +146,7 @@ func setupConnection(c *cobra.Command, args []string) error { return err } - tillerHost = fmt.Sprintf(":%d", tunnel.Local) + tillerHost = fmt.Sprintf("localhost:%d", tunnel.Local) if flagDebug { fmt.Printf("Created tunnel using local port: '%d'\n", tunnel.Local) } @@ -151,6 +156,7 @@ func setupConnection(c *cobra.Command, args []string) error { if flagDebug { fmt.Printf("SERVER: %q\n", tillerHost) } + // Plugin support. return nil } diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go index ac03e178a..682709f2d 100644 --- a/cmd/helm/helm_test.go +++ b/cmd/helm/helm_test.go @@ -241,7 +241,7 @@ func tempHelmHome(t *testing.T) (string, error) { // // t is used only for logging. func ensureTestHome(home helmpath.Home, t *testing.T) error { - configDirectories := []string{home.String(), home.Repository(), home.Cache(), home.LocalRepository(), home.Starters()} + configDirectories := []string{home.String(), home.Repository(), home.Cache(), home.LocalRepository(), home.Plugins(), home.Starters()} for _, p := range configDirectories { if fi, err := os.Stat(p); err != nil { if err := os.MkdirAll(p, 0755); err != nil { diff --git a/cmd/helm/helmpath/helmhome.go b/cmd/helm/helmpath/helmhome.go index 9289c9d45..03f65c6bb 100644 --- a/cmd/helm/helmpath/helmhome.go +++ b/cmd/helm/helmpath/helmhome.go @@ -67,3 +67,8 @@ func (h Home) LocalRepository(paths ...string) string { frag := append([]string{string(h), "repository/local"}, paths...) return filepath.Join(frag...) } + +// Plugins returns the path to the plugins directory. +func (h Home) Plugins() string { + return filepath.Join(string(h), "plugins") +} diff --git a/cmd/helm/init.go b/cmd/helm/init.go index 8bce43384..d3e60f629 100644 --- a/cmd/helm/init.go +++ b/cmd/helm/init.go @@ -143,7 +143,7 @@ func (i *initCmd) run() error { // // If $HELM_HOME does not exist, this function will create it. func ensureHome(home helmpath.Home, out io.Writer) error { - configDirectories := []string{home.String(), home.Repository(), home.Cache(), home.LocalRepository(), home.Starters()} + configDirectories := []string{home.String(), home.Repository(), home.Cache(), home.LocalRepository(), home.Plugins(), home.Starters()} for _, p := range configDirectories { if fi, err := os.Stat(p); err != nil { fmt.Fprintf(out, "Creating %s \n", p) diff --git a/cmd/helm/plugins.go b/cmd/helm/plugins.go new file mode 100644 index 000000000..a9a4383f5 --- /dev/null +++ b/cmd/helm/plugins.go @@ -0,0 +1,180 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "fmt" + "io" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/spf13/cobra" + + "k8s.io/helm/cmd/helm/helmpath" + "k8s.io/helm/pkg/plugin" +) + +const pluginEnvVar = "HELM_PLUGIN" + +// loadPlugins loads plugins into the command list. +// +// This follows a different pattern than the other commands because it has +// to inspect its environment and then add commands to the base command +// as it finds them. +func loadPlugins(baseCmd *cobra.Command, home helmpath.Home, out io.Writer) { + plugdirs := os.Getenv(pluginEnvVar) + if plugdirs == "" { + plugdirs = home.Plugins() + } + + found, err := findPlugins(plugdirs) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to load plugins: %s", err) + return + } + + // Now we create commands for all of these. + for _, plug := range found { + plug := plug + md := plug.Metadata + if md.Usage == "" { + md.Usage = fmt.Sprintf("the %q plugin", md.Name) + } + + c := &cobra.Command{ + Use: md.Name, + Short: md.Usage, + Long: md.Description, + RunE: func(cmd *cobra.Command, args []string) error { + + k, u := manuallyProcessArgs(args) + if err := cmd.ParseFlags(k); err != nil { + return err + } + + // Call setupEnv before PrepareCommand because + // PrepareCommand uses os.ExpandEnv and expects the + // setupEnv vars. + setupEnv(md.Name, plug.Dir, plugdirs, home) + main, argv := plug.PrepareCommand(u) + + prog := exec.Command(main, argv...) + prog.Env = os.Environ() + prog.Stdout = out + prog.Stderr = os.Stderr + if err := prog.Run(); err != nil { + eerr := err.(*exec.ExitError) + os.Stderr.Write(eerr.Stderr) + return fmt.Errorf("plugin %q exited with error", md.Name) + } + return nil + }, + // This passes all the flags to the subcommand. + DisableFlagParsing: true, + } + + if md.UseTunnel { + c.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { + // Parse the parent flag, but not the local flags. + k, _ := manuallyProcessArgs(args) + if err := c.Parent().ParseFlags(k); err != nil { + return err + } + return setupConnection(cmd, args) + } + } + + // TODO: Make sure a command with this name does not already exist. + baseCmd.AddCommand(c) + } +} + +// manuallyProcessArgs processes an arg array, removing special args. +// +// Returns two sets of args: known and unknown (in that order) +func manuallyProcessArgs(args []string) ([]string, []string) { + known := []string{} + unknown := []string{} + kvargs := []string{"--host", "--kube-context", "--home"} + knownArg := func(a string) bool { + for _, pre := range kvargs { + if strings.HasPrefix(a, pre+"=") { + return true + } + } + return false + } + for i := 0; i < len(args); i++ { + switch a := args[i]; a { + case "--debug": + known = append(known, a) + case "--host", "--kube-context", "--home": + known = append(known, a, args[i+1]) + i++ + default: + if knownArg(a) { + known = append(known, a) + continue + } + unknown = append(unknown, a) + } + } + return known, unknown +} + +// findPlugins returns a list of YAML files that describe plugins. +func findPlugins(plugdirs string) ([]*plugin.Plugin, error) { + found := []*plugin.Plugin{} + // Let's get all UNIXy and allow path separators + for _, p := range filepath.SplitList(plugdirs) { + matches, err := plugin.LoadAll(p) + if err != nil { + return matches, err + } + found = append(found, matches...) + } + return found, nil +} + +// setupEnv prepares os.Env for plugins. It operates on os.Env because +// the plugin subsystem itself needs access to the environment variables +// created here. +func setupEnv(shortname, base, plugdirs string, home helmpath.Home) { + // Set extra env vars: + for key, val := range map[string]string{ + "HELM_PLUGIN_NAME": shortname, + "HELM_PLUGIN_DIR": base, + "HELM_BIN": os.Args[0], + + // Set vars that may not have been set, and save client the + // trouble of re-parsing. + pluginEnvVar: plugdirs, + homeEnvVar: home.String(), + + // Set vars that convey common information. + "HELM_PATH_REPOSITORY": home.Repository(), + "HELM_PATH_REPOSITORY_FILE": home.RepositoryFile(), + "HELM_PATH_CACHE": home.Cache(), + "HELM_PATH_LOCAL_REPOSITORY": home.LocalRepository(), + //"HELM_PATH_STARTER": home.Starter(), + + "TILLER_HOST": tillerHost, + } { + os.Setenv(key, val) + } +} diff --git a/cmd/helm/plugins_test.go b/cmd/helm/plugins_test.go new file mode 100644 index 000000000..77828ea3b --- /dev/null +++ b/cmd/helm/plugins_test.go @@ -0,0 +1,125 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "bytes" + "os" + "strings" + "testing" + + "k8s.io/helm/cmd/helm/helmpath" + + "github.com/spf13/cobra" +) + +func TestManuallyProcessArgs(t *testing.T) { + input := []string{ + "--debug", + "--foo", + "bar", + "--host", + "example.com", + "--kube-context", + "test1", + "--home=/tmp", + "command", + } + + expectKnown := []string{ + "--debug", "--host", "example.com", "--kube-context", "test1", "--home=/tmp", + } + + expectUnknown := []string{ + "--foo", "bar", "command", + } + + known, unknown := manuallyProcessArgs(input) + + for i, k := range known { + if k != expectKnown[i] { + t.Errorf("expected known flag %d to be %q, got %q", i, expectKnown[i], k) + } + } + for i, k := range unknown { + if k != expectUnknown[i] { + t.Errorf("expected unknown flag %d to be %q, got %q", i, expectUnknown[i], k) + } + } + +} + +func TestLoadPlugins(t *testing.T) { + // Set helm home to point to testdata + old := helmHome + helmHome = "testdata/helmhome" + defer func() { + helmHome = old + }() + hh := helmpath.Home(homePath()) + + out := bytes.NewBuffer(nil) + cmd := &cobra.Command{} + loadPlugins(cmd, hh, out) + + envs := strings.Join([]string{ + "fullenv", + "fullenv.yaml", + hh.Plugins(), + hh.String(), + hh.Repository(), + hh.RepositoryFile(), + hh.Cache(), + hh.LocalRepository(), + os.Args[0], + }, "\n") + + // Test that the YAML file was correctly converted to a command. + tests := []struct { + use string + short string + long string + expect string + args []string + }{ + {"args", "echo args", "This echos args", "-a -b -c\n", []string{"-a", "-b", "-c"}}, + {"echo", "echo stuff", "This echos stuff", "hello\n", []string{}}, + {"env", "env stuff", "show the env", hh.String() + "\n", []string{}}, + {"fullenv", "show env vars", "show all env vars", envs + "\n", []string{}}, + } + + plugins := cmd.Commands() + for i := 0; i < len(plugins); i++ { + out.Reset() + tt := tests[i] + pp := plugins[i] + if pp.Use != tt.use { + t.Errorf("%d: Expected Use=%q, got %q", i, tt.use, pp.Use) + } + if pp.Short != tt.short { + t.Errorf("%d: Expected Use=%q, got %q", i, tt.short, pp.Short) + } + if pp.Long != tt.long { + t.Errorf("%d: Expected Use=%q, got %q", i, tt.long, pp.Long) + } + if err := pp.RunE(pp, tt.args); err != nil { + t.Errorf("Error running %s: %s", tt.use, err) + } + if out.String() != tt.expect { + t.Errorf("Expected %s to output:\n%s\ngot\n%s", tt.use, tt.expect, out.String()) + } + } +} diff --git a/cmd/helm/testdata/helmhome/plugins/args.sh b/cmd/helm/testdata/helmhome/plugins/args.sh new file mode 100755 index 000000000..678b4eff5 --- /dev/null +++ b/cmd/helm/testdata/helmhome/plugins/args.sh @@ -0,0 +1,2 @@ +#!/bin/bash +echo $* diff --git a/cmd/helm/testdata/helmhome/plugins/args.yaml b/cmd/helm/testdata/helmhome/plugins/args.yaml new file mode 100644 index 000000000..dbea13673 --- /dev/null +++ b/cmd/helm/testdata/helmhome/plugins/args.yaml @@ -0,0 +1,4 @@ +name: args +usage: "echo args" +description: "This echos args" +command: "$HELM_HOME/plugins/args.sh" diff --git a/cmd/helm/testdata/helmhome/plugins/echo.yaml b/cmd/helm/testdata/helmhome/plugins/echo.yaml new file mode 100644 index 000000000..7b9362a08 --- /dev/null +++ b/cmd/helm/testdata/helmhome/plugins/echo.yaml @@ -0,0 +1,4 @@ +name: echo +usage: "echo stuff" +description: "This echos stuff" +command: "echo hello" diff --git a/cmd/helm/testdata/helmhome/plugins/env.yaml b/cmd/helm/testdata/helmhome/plugins/env.yaml new file mode 100644 index 000000000..c8ae40350 --- /dev/null +++ b/cmd/helm/testdata/helmhome/plugins/env.yaml @@ -0,0 +1,4 @@ +name: env +usage: "env stuff" +description: "show the env" +command: "echo $HELM_HOME" diff --git a/cmd/helm/testdata/helmhome/plugins/fullenv.sh b/cmd/helm/testdata/helmhome/plugins/fullenv.sh new file mode 100755 index 000000000..e72047333 --- /dev/null +++ b/cmd/helm/testdata/helmhome/plugins/fullenv.sh @@ -0,0 +1,10 @@ +#!/bin/sh +echo $HELM_PLUGIN_SHORTNAME +echo $HELM_PLUGIN_NAME +echo $HELM_PLUGIN +echo $HELM_HOME +echo $HELM_PATH_REPOSITORY +echo $HELM_PATH_REPOSITORY_FILE +echo $HELM_PATH_CACHE +echo $HELM_PATH_LOCAL_REPOSITORY +echo $HELM_BIN diff --git a/cmd/helm/testdata/helmhome/plugins/fullenv.yaml b/cmd/helm/testdata/helmhome/plugins/fullenv.yaml new file mode 100644 index 000000000..a6f4c5a4e --- /dev/null +++ b/cmd/helm/testdata/helmhome/plugins/fullenv.yaml @@ -0,0 +1,4 @@ +name: fullenv +usage: "show env vars" +description: "show all env vars" +command: "$HELM_HOME/plugins/fullenv.sh" diff --git a/docs/plugins.md b/docs/plugins.md new file mode 100644 index 000000000..d8aae6bea --- /dev/null +++ b/docs/plugins.md @@ -0,0 +1,176 @@ +# The Helm Plugins Guide + +Helm 2.1.0 introduced the concept of a client-side Helm _plugin_. A plugin is a +tool that can be accessed through the `helm` CLI, but which is not part of the +built-in Helm codebase. + +This guide explains how to use and create plugins. + +## An Overview + +Helm plugins are add-on tools that integrate seemlessly with Helm. They provide +a way to extend the core feature set of Helm, but without requiring every new +feature to be written in Go and added to the core tool. + +Helm plugins have the following features: + +- They can be added and removed from a Helm installation without impacting the + core Helm tool. +- They can be written in any programming language. +- They integrate with Helm, and will show up in `helm help` and other places. + +Helm plugins live in `$(helm home)/plugins`. + +The Helm plugin model is partially modeled on Git's plugin model. To that end, +you may sometimes hear `helm` referred to as the _porcelain_ layer, with +plugins being the _plumbing_. This is a shorthand way of suggesting that +Helm provides the user experience and top level processing logic, while the +plugins do the "detail work" of performing a desired action. + +## Installing a Plugin + +A Helm plugin management system is in the works. But in the short term, plugins +are installed by copying the plugin directory into `$(helm home)/plugins`. + +```console +$ cp -a myplugin/ $(helm home)/plugins/ +``` + +If you have a plugin tar distribution, simply untar the plugin into the +`$(helm home)/plugins` directory. + +## Building Plugins + +In many ways, a plugin is similar to a chart. Each plugin has a top-level +directory, and then a `plugin.yaml` file. + +``` +$(helm home)/plugins/ + |- keybase/ + | + |- plugin.yaml + |- keybase.sh + +``` + +In the example above, the `keybase` plugin is contained inside of a directory +named `keybase`. It has two files: `plugin.yaml` (required) and an executable +script, `keybase.sh` (optional). + +The core of a plugin is a simple YAML file named `plugin.yaml`. +Here is a plugin YAML for a plugin that adds support for Keybase operations: + +``` +name: "keybase" +version: "0.1.0" +usage: "Integreate Keybase.io tools with Helm" +description: |- + This plugin provides Keybase services to Helm. +ignoreFlags: false +useTunnel: false +command: "$HELM_PLUGIN_DIR/keybase.sh" +``` + +The `name` is the name of the plugin. When Helm executes it plugin, this is the +name it will use (e.g. `helm NAME` will invoke this plugin). + +_`name` should match the directory name._ In our example above, that means the +plugin with `name: keybase` should be contained in a directory named `keybase`. + +Restrictions on `name`: + +- `name` cannot duplicate one of the existing `helm` top-level commands. +- `name` must be restricted to the characters ASCII a-z, A-Z, 0-9, `_` and `-`. + +`version` is the SemVer 2 version of the plugin. +`usage` and `description` are both used to generate the help text of a command. + +The `ignoreFlags` switch tells Helm to _not_ pass flags to the plugin. So if a +plugin is called with `helm myplugin --foo` and `ignoreFlags: true`, then `--foo` +is silently discarded. + +The `useTunnel` switch indicates that the plugin needs a tunnel to Tiller. This +should be set to `true` _anytime a plugin talks to Tiller_. It will cause Helm +to open a tunnel, and then set `$TILLER_HOST` to the right local address for that +tunnel. But don't worry: if Helm detects that a tunnel is not necessary because +Tiller is running locally, it will not create the tunnel. + +Finally, and most importantly, `command` is the command that this plugin will +execute when it is called. Environment variables are interpolated before the plugin +is executed. The pattern above illustrates the preferred way to indicate where +the plugin program lives. + +There are some strategies for working with plugin commands: + +- If a plugin includes an executable, the executable for a `command:` should be + packaged in the plugin directory. +- The `command:` line will have any environment variables expanded before + execution. `$HELM_PLUGIN_DIR` will point to the plugin directory. +- The command itself is not executed in a shell. So you can't oneline a shell script. +- Helm injects lots of configuration into environment variables. Take a look at + the environment to see what information is available. +- Helm makes no assumptions about the language of the plugin. You can write it + in whatever you prefer. +- Commands are responsible for implementing specific help text for `-h` and `--help`. + Helm will use `usage` and `description` for `helm help` and `helm help myplugin`, + but will not handle `helm myplugin --help`. + +## Environment Variables + +When Helm executes a plugin, it passes the outer environment to the plugin, and +also injects some additional environment variables. + +Variables like `KUBECONFIG` are set for the plugin if they are set in the +outer environment. + +The following variables are guaranteed to be set: + +- `HELM_PLUGIN`: The path to the plugins directory +- `HELM_PLUGIN_NAME`: The name of the plugin, as invoked by `helm`. So + `helm myplug` will have the short name `myplug`. +- `HELM_PLUGIN_DIR`: The directory that contains the plugin. +- `HELM_BIN`: The path to the `helm` command (as executed by the user). +- `HELM_HOME`: The path to the Helm home. +- `HELM_PATH_*`: Paths to important Helm files and directories are stored in + environment variables prefixed by `HELM_PATH`. +- `TILLER_HOST`: The `domain:port` to Tiller. If a tunnel is created, this + will point to the local endpoint for the tunnel. Otherwise, it will point + to `$HELM_HOST`, `--host`, or the default host (according to Helm's rules of + precedence). + +While `HELM_HOST` _may_ be set, there is no guarantee that it will point to the +correct Tiller instance. This is done to allow plugin developer to access +`HELM_HOST` in its raw state when the plugin itself needs to manually configure +a connection. + +## A Note on `useTunnel` + +If a plugin specifies `useTunnel: true`, Helm will do the following (in order): + +1. Parse global flags and the environment +2. Create the tunnel +3. Set `TILLER_HOST` +4. Execute the plugin +5. Close the tunnel + +The tunnel is removed as soon as the `command` returns. So, for example, a +command cannot background a process and assume that that process will be able +to use the tunnel. + +## A Note on Flag Parsing + +When executing a plugin, Helm will parse global flags for its own use, but pass +all flags to the plugin. + +Plugins MUST NOT produce an error for the following flags: + +- `--debug` +- `--home` +- `--host` +- `--kube-context` +- `-h` +- `--help` + +Plugins _should_ display help text and then exit for `-h` and `--help`. In all +other cases, plugins may simply ignore the flags. + diff --git a/pkg/plugin/plugin.go b/pkg/plugin/plugin.go new file mode 100644 index 000000000..bc8cbb732 --- /dev/null +++ b/pkg/plugin/plugin.go @@ -0,0 +1,135 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package plugin + +import ( + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/ghodss/yaml" +) + +// PluginFileName is the name of a plugin file. +const PluginFileName = "plugin.yaml" + +// Metadata describes a plugin. +// +// This is the plugin equivalent of a chart.Metadata. +type Metadata struct { + // Name is the name of the plugin + Name string `json:"name"` + + // Version is a SemVer 2 version of the plugin. + Version string `json:"version"` + + // Usage is the single-line usage text shown in help + Usage string `json:"usage"` + + // Description is a long description shown in places like `helm help` + Description string `json:"description"` + + // Command is the command, as a single string. + // + // The command will be passed through environment expansion, so env vars can + // be present in this command. Unless IgnoreFlags is set, this will + // also merge the flags passed from Helm. + // + // Note that command is not executed in a shell. To do so, we suggest + // pointing the command to a shell script. + Command string `json:"command"` + + // IgnoreFlags ignores any flags passed in from Helm + // + // For example, if the plugin is invoked as `helm --debug myplugin`, if this + // is false, `--debug` will be appended to `--command`. If this is true, + // the `--debug` flag will be discarded. + IgnoreFlags bool `json:"ignoreFlags"` + + // UseTunnel indicates that this command needs a tunnel. + // Setting this will cause a number of side effects, such as the + // automatic setting of HELM_HOST. + UseTunnel bool `json:"useTunnel"` +} + +// Plugin represents a plugin. +type Plugin struct { + // Metadata is a parsed representation of a plugin.yaml + Metadata *Metadata + // Dir is the string path to the directory that holds the plugin. + Dir string +} + +// PrepareCommand takes a Plugin.Command and prepares it for execution. +// +// It merges extraArgs into any arguments supplied in the plugin. It +// returns the name of the command and an args array. +// +// The result is suitable to pass to exec.Command. +func (p *Plugin) PrepareCommand(extraArgs []string) (string, []string) { + parts := strings.Split(os.ExpandEnv(p.Metadata.Command), " ") + main := parts[0] + baseArgs := []string{} + if len(parts) > 1 { + baseArgs = parts[1:] + } + if !p.Metadata.IgnoreFlags { + baseArgs = append(baseArgs, extraArgs...) + } + return main, baseArgs +} + +// LoadDir loads a plugin from the given directory. +func LoadDir(dirname string) (*Plugin, error) { + data, err := ioutil.ReadFile(filepath.Join(dirname, PluginFileName)) + if err != nil { + return nil, err + } + + plug := &Plugin{Dir: dirname} + if err := yaml.Unmarshal(data, &plug.Metadata); err != nil { + return nil, err + } + return plug, nil +} + +// LoadAll loads all plugins found beneath the base directory. +// +// This scans only one directory level. +func LoadAll(basedir string) ([]*Plugin, error) { + plugins := []*Plugin{} + // We want basedir/*/plugin.yaml + scanpath := filepath.Join(basedir, "*", PluginFileName) + matches, err := filepath.Glob(scanpath) + if err != nil { + return plugins, err + } + + if matches == nil { + return plugins, nil + } + + for _, yaml := range matches { + dir := filepath.Dir(yaml) + p, err := LoadDir(dir) + if err != nil { + return plugins, err + } + plugins = append(plugins, p) + } + return plugins, nil +} diff --git a/pkg/plugin/plugin_test.go b/pkg/plugin/plugin_test.go new file mode 100644 index 000000000..aa976546a --- /dev/null +++ b/pkg/plugin/plugin_test.go @@ -0,0 +1,117 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package plugin + +import ( + "reflect" + "testing" +) + +func TestPrepareCommand(t *testing.T) { + p := &Plugin{ + Dir: "/tmp", // Unused + Metadata: &Metadata{ + Name: "test", + Command: "echo -n foo", + }, + } + argv := []string{"--debug", "--foo", "bar"} + + cmd, args := p.PrepareCommand(argv) + if cmd != "echo" { + t.Errorf("Expected echo, got %q", cmd) + } + + if l := len(args); l != 5 { + t.Errorf("expected 5 args, got %d", l) + } + + expect := []string{"-n", "foo", "--debug", "--foo", "bar"} + for i := 0; i < len(args); i++ { + if expect[i] != args[i] { + t.Errorf("Expected arg=%q, got %q", expect[i], args[i]) + } + } + + // Test with IgnoreFlags. This should omit --debug, --foo, bar + p.Metadata.IgnoreFlags = true + cmd, args = p.PrepareCommand(argv) + if cmd != "echo" { + t.Errorf("Expected echo, got %q", cmd) + } + if l := len(args); l != 2 { + t.Errorf("expected 2 args, got %d", l) + } + expect = []string{"-n", "foo"} + for i := 0; i < len(args); i++ { + if expect[i] != args[i] { + t.Errorf("Expected arg=%q, got %q", expect[i], args[i]) + } + } +} + +func TestLoadDir(t *testing.T) { + dirname := "testdata/plugdir/hello" + plug, err := LoadDir(dirname) + if err != nil { + t.Fatalf("error loading Hello plugin: %s", err) + } + + if plug.Dir != dirname { + t.Errorf("Expected dir %q, got %q", dirname, plug.Dir) + } + + expect := Metadata{ + Name: "hello", + Version: "0.1.0", + Usage: "usage", + Description: "description", + Command: "$HELM_PLUGIN_SELF/hello.sh", + UseTunnel: true, + IgnoreFlags: true, + } + + if reflect.DeepEqual(expect, plug.Metadata) { + t.Errorf("Expected name %v, got %v", expect, plug.Metadata) + } +} + +func TestLoadAll(t *testing.T) { + + // Verify that empty dir loads: + if plugs, err := LoadAll("testdata"); err != nil { + t.Fatalf("error loading dir with no plugins: %s", err) + } else if len(plugs) > 0 { + t.Fatalf("expected empty dir to have 0 plugins") + } + + basedir := "testdata/plugdir" + plugs, err := LoadAll(basedir) + if err != nil { + t.Fatalf("Could not load %q: %s", basedir, err) + } + + if l := len(plugs); l != 2 { + t.Fatalf("expected 2 plugins, found %d", l) + } + + if plugs[0].Metadata.Name != "echo" { + t.Errorf("Expected first plugin to be echo, got %q", plugs[0].Metadata.Name) + } + if plugs[1].Metadata.Name != "hello" { + t.Errorf("Expected second plugin to be hello, got %q", plugs[1].Metadata.Name) + } +} diff --git a/pkg/plugin/testdata/plugdir/echo/plugin.yaml b/pkg/plugin/testdata/plugdir/echo/plugin.yaml new file mode 100644 index 000000000..da6f656eb --- /dev/null +++ b/pkg/plugin/testdata/plugdir/echo/plugin.yaml @@ -0,0 +1,6 @@ +name: "echo" +version: "1.2.3" +usage: "echo something" +description: |- + This is a testing fixture. +command: "echo Hello" diff --git a/pkg/plugin/testdata/plugdir/hello/hello.sh b/pkg/plugin/testdata/plugdir/hello/hello.sh new file mode 100755 index 000000000..db7c0f54d --- /dev/null +++ b/pkg/plugin/testdata/plugdir/hello/hello.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +echo "Hello from a Helm plugin" + +echo "PARAMS" +echo $* + +echo "ENVIRONMENT" +echo $TILLER_HOST +echo $HELM_HOME + +$HELM_BIN --host $TILLER_HOST ls --all + diff --git a/pkg/plugin/testdata/plugdir/hello/plugin.yaml b/pkg/plugin/testdata/plugdir/hello/plugin.yaml new file mode 100644 index 000000000..6415e6fa0 --- /dev/null +++ b/pkg/plugin/testdata/plugdir/hello/plugin.yaml @@ -0,0 +1,8 @@ +name: "hello" +version: "0.1.0" +usage: "usage" +description: |- + description +command: "$HELM_PLUGIN_SELF/helm-hello" +useTunnel: true +ignoreFlags: true From 702b6fb53bbbbf797faeef654825e2b9d837b577 Mon Sep 17 00:00:00 2001 From: Serge Catudal Date: Tue, 29 Nov 2016 15:41:20 -0500 Subject: [PATCH 08/39] fix(helm): fix windows support with port forward connection in setupConnection This fixes the port forward connection using helm on windows by assigning explicitely 'localhost' to 'TillerHost' in 'setupConnection'. Otherwise, the connection between the helm client with the Tiller server deployed on Kubernetes will not work. --- cmd/helm/helm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index d9b169f00..b0979f62f 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -141,7 +141,7 @@ func setupConnection(c *cobra.Command, args []string) error { return err } - tillerHost = fmt.Sprintf(":%d", tunnel.Local) + tillerHost = fmt.Sprintf("localhost:%d", tunnel.Local) if flagDebug { fmt.Printf("Created tunnel using local port: '%d'\n", tunnel.Local) } From 02a1cf382c20f59a9f34cc549e8d6cbb5cfc2f98 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Tue, 29 Nov 2016 14:07:24 -0700 Subject: [PATCH 09/39] fix(tiller): validate names before performing operations There were several places where an invalid name could be interpreted into a wild-card by Kubernetes. That allows Bad Things. This fix requires names to match the Kubernetes pattern for naming. Closes #1594 --- pkg/tiller/release_server.go | 22 +++++++++++++++++----- pkg/tiller/release_server_test.go | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index a1a17fd02..abf8a30ff 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -70,6 +70,17 @@ var ( // ListDefaultLimit is the default limit for number of items returned in a list. var ListDefaultLimit int64 = 512 +// ValidName is a regular expression for names. +// +// According to the Kubernetes help text, the regular expression it uses is: +// +// (([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])? +// +// We modified that. First, we added start and end delimiters. Second, we changed +// the final ? to + to require that the pattern match at least once. This modification +// prevents an empty string from matching. +var ValidName = regexp.MustCompile("^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])+$") + // ReleaseServer implements the server-side gRPC endpoint for the HAPI services. type ReleaseServer struct { env *environment.Environment @@ -211,7 +222,7 @@ func (s *ReleaseServer) GetReleaseStatus(c ctx.Context, req *services.GetRelease return nil, errIncompatibleVersion } - if req.Name == "" { + if !ValidName.MatchString(req.Name) { return nil, errMissingRelease } @@ -267,9 +278,10 @@ func (s *ReleaseServer) GetReleaseContent(c ctx.Context, req *services.GetReleas return nil, errIncompatibleVersion } - if req.Name == "" { + if !ValidName.MatchString(req.Name) { return nil, errMissingRelease } + if req.Version <= 0 { rel, err := s.env.Releases.Deployed(req.Name) return &services.GetReleaseContentResponse{Release: rel}, err @@ -355,7 +367,7 @@ func (s *ReleaseServer) reuseValues(req *services.UpdateReleaseRequest, current // prepareUpdate builds an updated release for an update operation. func (s *ReleaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*release.Release, *release.Release, error) { - if req.Name == "" { + if !ValidName.MatchString(req.Name) { return nil, nil, errMissingRelease } @@ -486,7 +498,7 @@ func (s *ReleaseServer) performKubeUpdate(currentRelease, targetRelease *release // the previous release's configuration func (s *ReleaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*release.Release, *release.Release, error) { switch { - case req.Name == "": + case !ValidName.MatchString(req.Name): return nil, nil, errMissingRelease case req.Version < 0: return nil, nil, errInvalidRevision @@ -905,7 +917,7 @@ func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallR return nil, errIncompatibleVersion } - if req.Name == "" { + if !ValidName.MatchString(req.Name) { log.Printf("uninstall: Release not found: %s", req.Name) return nil, errMissingRelease } diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index 5e5e118b9..6b8a7f754 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -144,6 +144,28 @@ func upgradeReleaseVersion(rel *release.Release) *release.Release { } } +func TestValidName(t *testing.T) { + for name, valid := range map[string]bool{ + "nina pinta santa-maria": false, + "nina-pinta-santa-maria": true, + "-nina": false, + "pinta-": false, + "santa-maria": true, + "niña": false, + "...": false, + "pinta...": false, + "santa...maria": true, + "": false, + " ": false, + ".nina.": false, + "nina.pinta": true, + } { + if valid != ValidName.MatchString(name) { + t.Errorf("Expected %q to be %t", name, valid) + } + } +} + func TestGetVersionSet(t *testing.T) { rs := rsFixture() vs, err := rs.getVersionSet() From aca9f86df62f6ff13fdade755ece70d25bdfe079 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Mon, 31 Oct 2016 17:11:31 -0600 Subject: [PATCH 10/39] feat(helm): add command to generate documentation This adds a hidden 'helm doc' command that generates documentation out of the Helm help text. Currently it can create: - man pages for HELM(1) - Markdown documentation - bash autocompletions Those are the three built-ins for Cobra. The command is hidden so that it doesn't show up to the regular user, since this is really a specialized task. It has the advantage of making it trivially easy to install man pages and bash completion at installation time. --- Makefile | 7 + cmd/helm/docs.go | 80 ++ cmd/helm/helm.go | 4 + docs/developers.md | 13 + docs/helm/helm.md | 62 ++ docs/helm/helm_create.md | 49 + docs/helm/helm_delete.md | 40 + docs/helm/helm_dependency.md | 58 ++ docs/helm/helm_dependency_build.md | 42 + docs/helm/helm_dependency_list.md | 34 + docs/helm/helm_dependency_update.md | 41 + docs/helm/helm_fetch.md | 50 + docs/helm/helm_get.md | 46 + docs/helm/helm_get_hooks.md | 36 + docs/helm/helm_get_manifest.md | 38 + docs/helm/helm_get_values.md | 35 + docs/helm/helm_history.md | 46 + docs/helm/helm_home.md | 29 + docs/helm/helm_init.md | 54 ++ docs/helm/helm_inspect.md | 41 + docs/helm/helm_inspect_chart.md | 37 + docs/helm/helm_inspect_values.md | 37 + docs/helm/helm_install.md | 84 ++ docs/helm/helm_lint.md | 39 + docs/helm/helm_list.md | 65 ++ docs/helm/helm_package.md | 44 + docs/helm/helm_repo.md | 33 + docs/helm/helm_repo_add.md | 32 + docs/helm/helm_repo_index.md | 42 + docs/helm/helm_repo_list.md | 26 + docs/helm/helm_repo_remove.md | 26 + docs/helm/helm_repo_update.md | 32 + docs/helm/helm_rollback.md | 36 + docs/helm/helm_search.md | 38 + docs/helm/helm_serve.md | 39 + docs/helm/helm_status.md | 34 + docs/helm/helm_upgrade.md | 51 + docs/helm/helm_verify.md | 41 + docs/helm/helm_version.md | 49 + docs/man/man1/helm.1 | 79 ++ docs/man/man1/helm_create.1 | 76 ++ docs/man/man1/helm_delete.1 | 65 ++ docs/man/man1/helm_dependency.1 | 90 ++ docs/man/man1/helm_dependency_build.1 | 65 ++ docs/man/man1/helm_dependency_list.1 | 54 ++ docs/man/man1/helm_dependency_update.1 | 64 ++ docs/man/man1/helm_fetch.1 | 86 ++ docs/man/man1/helm_get.1 | 65 ++ docs/man/man1/helm_get_hooks.1 | 55 ++ docs/man/man1/helm_get_manifest.1 | 57 ++ docs/man/man1/helm_get_values.1 | 56 ++ docs/man/man1/helm_history.1 | 73 ++ docs/man/man1/helm_home.1 | 47 + docs/man/man1/helm_init.1 | 85 ++ docs/man/man1/helm_inspect.1 | 64 ++ docs/man/man1/helm_inspect_chart.1 | 61 ++ docs/man/man1/helm_inspect_values.1 | 61 ++ docs/man/man1/helm_install.1 | 167 ++++ docs/man/man1/helm_lint.1 | 58 ++ docs/man/man1/helm_list.1 | 119 +++ docs/man/man1/helm_package.1 | 73 ++ docs/man/man1/helm_repo.1 | 51 + docs/man/man1/helm_repo_add.1 | 52 + docs/man/man1/helm_repo_index.1 | 65 ++ docs/man/man1/helm_repo_list.1 | 46 + docs/man/man1/helm_repo_remove.1 | 46 + docs/man/man1/helm_repo_update.1 | 51 + docs/man/man1/helm_rollback.1 | 57 ++ docs/man/man1/helm_search.1 | 60 ++ docs/man/man1/helm_serve.1 | 61 ++ docs/man/man1/helm_status.1 | 52 + docs/man/man1/helm_upgrade.1 | 102 ++ docs/man/man1/helm_verify.1 | 61 ++ docs/man/man1/helm_version.1 | 75 ++ glide.lock | 16 +- pkg/tiller/release_server_test.go | 1 + scripts/completions.bash | 1200 ++++++++++++++++++++++++ 77 files changed, 5203 insertions(+), 3 deletions(-) create mode 100644 cmd/helm/docs.go create mode 100644 docs/helm/helm.md create mode 100644 docs/helm/helm_create.md create mode 100644 docs/helm/helm_delete.md create mode 100644 docs/helm/helm_dependency.md create mode 100644 docs/helm/helm_dependency_build.md create mode 100644 docs/helm/helm_dependency_list.md create mode 100644 docs/helm/helm_dependency_update.md create mode 100644 docs/helm/helm_fetch.md create mode 100644 docs/helm/helm_get.md create mode 100644 docs/helm/helm_get_hooks.md create mode 100644 docs/helm/helm_get_manifest.md create mode 100644 docs/helm/helm_get_values.md create mode 100644 docs/helm/helm_history.md create mode 100644 docs/helm/helm_home.md create mode 100644 docs/helm/helm_init.md create mode 100644 docs/helm/helm_inspect.md create mode 100644 docs/helm/helm_inspect_chart.md create mode 100644 docs/helm/helm_inspect_values.md create mode 100644 docs/helm/helm_install.md create mode 100644 docs/helm/helm_lint.md create mode 100644 docs/helm/helm_list.md create mode 100644 docs/helm/helm_package.md create mode 100644 docs/helm/helm_repo.md create mode 100644 docs/helm/helm_repo_add.md create mode 100644 docs/helm/helm_repo_index.md create mode 100644 docs/helm/helm_repo_list.md create mode 100644 docs/helm/helm_repo_remove.md create mode 100644 docs/helm/helm_repo_update.md create mode 100644 docs/helm/helm_rollback.md create mode 100644 docs/helm/helm_search.md create mode 100644 docs/helm/helm_serve.md create mode 100644 docs/helm/helm_status.md create mode 100644 docs/helm/helm_upgrade.md create mode 100644 docs/helm/helm_verify.md create mode 100644 docs/helm/helm_version.md create mode 100644 docs/man/man1/helm.1 create mode 100644 docs/man/man1/helm_create.1 create mode 100644 docs/man/man1/helm_delete.1 create mode 100644 docs/man/man1/helm_dependency.1 create mode 100644 docs/man/man1/helm_dependency_build.1 create mode 100644 docs/man/man1/helm_dependency_list.1 create mode 100644 docs/man/man1/helm_dependency_update.1 create mode 100644 docs/man/man1/helm_fetch.1 create mode 100644 docs/man/man1/helm_get.1 create mode 100644 docs/man/man1/helm_get_hooks.1 create mode 100644 docs/man/man1/helm_get_manifest.1 create mode 100644 docs/man/man1/helm_get_values.1 create mode 100644 docs/man/man1/helm_history.1 create mode 100644 docs/man/man1/helm_home.1 create mode 100644 docs/man/man1/helm_init.1 create mode 100644 docs/man/man1/helm_inspect.1 create mode 100644 docs/man/man1/helm_inspect_chart.1 create mode 100644 docs/man/man1/helm_inspect_values.1 create mode 100644 docs/man/man1/helm_install.1 create mode 100644 docs/man/man1/helm_lint.1 create mode 100644 docs/man/man1/helm_list.1 create mode 100644 docs/man/man1/helm_package.1 create mode 100644 docs/man/man1/helm_repo.1 create mode 100644 docs/man/man1/helm_repo_add.1 create mode 100644 docs/man/man1/helm_repo_index.1 create mode 100644 docs/man/man1/helm_repo_list.1 create mode 100644 docs/man/man1/helm_repo_remove.1 create mode 100644 docs/man/man1/helm_repo_update.1 create mode 100644 docs/man/man1/helm_rollback.1 create mode 100644 docs/man/man1/helm_search.1 create mode 100644 docs/man/man1/helm_serve.1 create mode 100644 docs/man/man1/helm_status.1 create mode 100644 docs/man/man1/helm_upgrade.1 create mode 100644 docs/man/man1/helm_verify.1 create mode 100644 docs/man/man1/helm_version.1 create mode 100644 scripts/completions.bash diff --git a/Makefile b/Makefile index a4b04490c..d311e35d2 100644 --- a/Makefile +++ b/Makefile @@ -84,6 +84,13 @@ test-style: protoc: $(MAKE) -C _proto/ all +.PHONY: docs +docs: build + @mkdir -p docs/helm docs/man/man1 + bin/helm docs --dir ./docs/helm + bin/helm docs --dir ./docs/man/man1 --type man + bin/helm docs --dir ./scripts --type bash + .PHONY: clean clean: @rm -rf $(BINDIR) ./rootfs/tiller ./_dist diff --git a/cmd/helm/docs.go b/cmd/helm/docs.go new file mode 100644 index 000000000..3b1d22005 --- /dev/null +++ b/cmd/helm/docs.go @@ -0,0 +1,80 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "fmt" + "io" + "path/filepath" + + "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" +) + +const docsDesc = ` +Generate documentation files for Helm. + +This command can generate documentation for Helm in the following formats: + +- Markdown +- Man pages + +It can also generate bash autocompletions. + + $ helm docs markdown -dir mydocs/ +` + +type docsCmd struct { + out io.Writer + dest string + docTypeString string + topCmd *cobra.Command +} + +func newDocsCmd(out io.Writer, topCmd *cobra.Command) *cobra.Command { + dc := &docsCmd{out: out, topCmd: topCmd} + + cmd := &cobra.Command{ + Use: "docs", + Short: "Generate documentation as markdown or man pages", + Long: docsDesc, + Hidden: true, + RunE: func(cmd *cobra.Command, args []string) error { + dc.run() + return nil + }, + } + + f := cmd.Flags() + f.StringVar(&dc.dest, "dir", "./", "directory to which documentation is written") + f.StringVar(&dc.docTypeString, "type", "markdown", "the type of documentation to generate (markdown, man, bash)") + + return cmd +} + +func (d *docsCmd) run() error { + switch d.docTypeString { + case "markdown", "mdown", "md": + return doc.GenMarkdownTree(d.topCmd, d.dest) + case "man": + manHdr := &doc.GenManHeader{Title: "HELM", Section: "1"} + return doc.GenManTree(d.topCmd, manHdr, d.dest) + case "bash": + return d.topCmd.GenBashCompletionFile(filepath.Join(d.dest, "completions.bash")) + default: + return fmt.Errorf("unknown doc type %q. Try 'markdown' or 'man'", d.docTypeString) + } +} diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index b0979f62f..1ca2f9665 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -121,6 +121,10 @@ func newRootCmd(out io.Writer) *cobra.Command { newUpgradeCmd(nil, out), newVerifyCmd(out), newVersionCmd(nil, out), + + // Hidden documentation generator command: 'helm docs' + newDocsCmd(out, cmd), + // Deprecated rup, ) diff --git a/docs/developers.md b/docs/developers.md index 4ae16a10d..58a0dbe30 100644 --- a/docs/developers.md +++ b/docs/developers.md @@ -32,6 +32,19 @@ To run Helm and Tiller locally, you can run `bin/helm` or `bin/tiller`. - Tiller must have access to a Kubernetes cluster. It learns about the cluster by examining the Kube config files that `kubectl` uses. +### Man pages + +Man pages and Markdown documentation are already pre-built in `docs/`. You may +regenerate documentation using `make docs`. + +To expose the Helm man pages to your `man` client, you can put the files in your +`$MANPATH`: + +``` +$ export MANPATH=$GOPATH/src/k8s.io/helm/docs/man:$MANPATH +$ man helm +``` + ## gRPC and Protobuf Helm and Tiller communicate using gRPC. To get started with gRPC, you will need to... diff --git a/docs/helm/helm.md b/docs/helm/helm.md new file mode 100644 index 000000000..b0b947d1a --- /dev/null +++ b/docs/helm/helm.md @@ -0,0 +1,62 @@ +## helm + +The Helm package manager for Kubernetes. + +### Synopsis + + +The Kubernetes package manager + +To begin working with Helm, run the 'helm init' command: + + $ helm init + +This will install Tiller to your running Kubernetes cluster. +It will also set up any necessary local configuration. + +Common actions from this point include: + +- helm search: search for charts +- helm fetch: download a chart to your local directory to view +- helm install: upload the chart to Kubernetes +- helm list: list releases of charts + +Environment: + $HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm + $HELM_HOST set an alternative Tiller host. The format is host:port + $KUBECONFIG set an alternate Kubernetes configuration file (default "~/.kube/config") + + +### Options + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm create](helm_create.md) - create a new chart with the given name +* [helm delete](helm_delete.md) - given a release name, delete the release from Kubernetes +* [helm dependency](helm_dependency.md) - manage a chart's dependencies +* [helm fetch](helm_fetch.md) - download a chart from a repository and (optionally) unpack it in local directory +* [helm get](helm_get.md) - download a named release +* [helm history](helm_history.md) - fetch release history +* [helm home](helm_home.md) - displays the location of HELM_HOME +* [helm init](helm_init.md) - initialize Helm on both client and server +* [helm inspect](helm_inspect.md) - inspect a chart +* [helm install](helm_install.md) - install a chart archive +* [helm lint](helm_lint.md) - examines a chart for possible issues +* [helm list](helm_list.md) - list releases +* [helm package](helm_package.md) - package a chart directory into a chart archive +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories +* [helm rollback](helm_rollback.md) - roll back a release to a previous revision +* [helm search](helm_search.md) - search for a keyword in charts +* [helm serve](helm_serve.md) - start a local http web server +* [helm status](helm_status.md) - displays the status of the named release +* [helm upgrade](helm_upgrade.md) - upgrade a release +* [helm verify](helm_verify.md) - verify that a chart at the given path has been signed and is valid +* [helm version](helm_version.md) - print the client/server version information + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_create.md b/docs/helm/helm_create.md new file mode 100644 index 000000000..89dccd584 --- /dev/null +++ b/docs/helm/helm_create.md @@ -0,0 +1,49 @@ +## helm create + +create a new chart with the given name + +### Synopsis + + + +This command creates a chart directory along with the common files and +directories used in a chart. + +For example, 'helm create foo' will create a directory structure that looks +something like this: + + foo/ + | + |- .helmignore # Contains patterns to ignore when packaging Helm charts. + | + |- Chart.yaml # Information about your chart + | + |- values.yaml # The default values for your templates + | + |- charts/ # Charts that this chart depends on + | + |- templates/ # The template files + +'helm create' takes a path for an argument. If directories in the given path +do not exist, Helm will attempt to create them as it goes. If the given +destination exists and there are files in that directory, conflicting files +will be overwritten, but other files will be left alone. + + +``` +helm create NAME +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_delete.md b/docs/helm/helm_delete.md new file mode 100644 index 000000000..2a94af0fd --- /dev/null +++ b/docs/helm/helm_delete.md @@ -0,0 +1,40 @@ +## helm delete + +given a release name, delete the release from Kubernetes + +### Synopsis + + + +This command takes a release name, and then deletes the release from Kubernetes. +It removes all of the resources associated with the last release of the chart. + +Use the '--dry-run' flag to see which releases will be deleted without actually +deleting them. + + +``` +helm delete [flags] RELEASE_NAME [...] +``` + +### Options + +``` + --dry-run simulate a delete + --no-hooks prevent hooks from running during deletion + --purge remove the release from the store and make its name free for later use +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_dependency.md b/docs/helm/helm_dependency.md new file mode 100644 index 000000000..af7f7ea00 --- /dev/null +++ b/docs/helm/helm_dependency.md @@ -0,0 +1,58 @@ +## helm dependency + +manage a chart's dependencies + +### Synopsis + + + +Manage the dependencies of a chart. + +Helm charts store their dependencies in 'charts/'. For chart developers, it is +often easier to manage a single dependency file ('requirements.yaml') +which declares all dependencies. + +The dependency commands operate on that file, making it easy to synchronize +between the desired dependencies and the actual dependencies stored in the +'charts/' directory. + +A 'requirements.yaml' file is a YAML file in which developers can declare chart +dependencies, along with the location of the chart and the desired version. +For example, this requirements file declares two dependencies: + + # requirements.yaml + dependencies: + - name: nginx + version: "1.2.3" + repository: "https://example.com/charts" + - name: memcached + version: "3.2.1" + repository: "https://another.example.com/charts" + +The 'name' should be the name of a chart, where that name must match the name +in that chart's 'Chart.yaml' file. + +The 'version' field should contain a semantic version or version range. + +The 'repository' URL should point to a Chart Repository. Helm expects that by +appending '/index.yaml' to the URL, it should be able to retrieve the chart +repository's index. Note: 'repository' cannot be a repository alias. It must be +a URL. + + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm dependency build](helm_dependency_build.md) - rebuild the charts/ directory based on the requirements.lock file +* [helm dependency list](helm_dependency_list.md) - list the dependencies for the given chart +* [helm dependency update](helm_dependency_update.md) - update charts/ based on the contents of requirements.yaml + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_dependency_build.md b/docs/helm/helm_dependency_build.md new file mode 100644 index 000000000..f073770c0 --- /dev/null +++ b/docs/helm/helm_dependency_build.md @@ -0,0 +1,42 @@ +## helm dependency build + +rebuild the charts/ directory based on the requirements.lock file + +### Synopsis + + + +Build out the charts/ directory from the requirements.lock file. + +Build is used to reconstruct a chart's dependencies to the state specified in +the lock file. This will not re-negotiate dependencies, as 'helm dependency update' +does. + +If no lock file is found, 'helm dependency build' will mirror the behavior +of 'helm dependency update'. + + +``` +helm dependency build [flags] CHART +``` + +### Options + +``` + --keyring string keyring containing public keys (default "/Users/mattbutcher/.gnupg/pubring.gpg") + --verify verify the packages against signatures +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm dependency](helm_dependency.md) - manage a chart's dependencies + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_dependency_list.md b/docs/helm/helm_dependency_list.md new file mode 100644 index 000000000..66b1799bc --- /dev/null +++ b/docs/helm/helm_dependency_list.md @@ -0,0 +1,34 @@ +## helm dependency list + +list the dependencies for the given chart + +### Synopsis + + + +List all of the dependencies declared in a chart. + +This can take chart archives and chart directories as input. It will not alter +the contents of a chart. + +This will produce an error if the chart cannot be loaded. It will emit a warning +if it cannot find a requirements.yaml. + + +``` +helm dependency list [flags] CHART +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm dependency](helm_dependency.md) - manage a chart's dependencies + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_dependency_update.md b/docs/helm/helm_dependency_update.md new file mode 100644 index 000000000..64a9c822e --- /dev/null +++ b/docs/helm/helm_dependency_update.md @@ -0,0 +1,41 @@ +## helm dependency update + +update charts/ based on the contents of requirements.yaml + +### Synopsis + + + +Update the on-disk dependencies to mirror the requirements.yaml file. + +This command verifies that the required charts, as expressed in 'requirements.yaml', +are present in 'charts/' and are at an acceptable version. + +On successful update, this will generate a lock file that can be used to +rebuild the requirements to an exact version. + + +``` +helm dependency update [flags] CHART +``` + +### Options + +``` + --keyring string keyring containing public keys (default "/Users/mattbutcher/.gnupg/pubring.gpg") + --verify verify the packages against signatures +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm dependency](helm_dependency.md) - manage a chart's dependencies + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_fetch.md b/docs/helm/helm_fetch.md new file mode 100644 index 000000000..c954d8dfe --- /dev/null +++ b/docs/helm/helm_fetch.md @@ -0,0 +1,50 @@ +## helm fetch + +download a chart from a repository and (optionally) unpack it in local directory + +### Synopsis + + + +Retrieve a package from a package repository, and download it locally. + +This is useful for fetching packages to inspect, modify, or repackage. It can +also be used to perform cryptographic verification of a chart without installing +the chart. + +There are options for unpacking the chart after download. This will create a +directory for the chart and uncomparess into that directory. + +If the --verify flag is specified, the requested chart MUST have a provenance +file, and MUST pass the verification process. Failure in any part of this will +result in an error, and the chart will not be saved locally. + + +``` +helm fetch [flags] [chart URL | repo/chartname] [...] +``` + +### Options + +``` + -d, --destination string location to write the chart. If this and tardir are specified, tardir is appended to this (default ".") + --keyring string keyring containing public keys (default "/Users/mattbutcher/.gnupg/pubring.gpg") + --untar if set to true, will untar the chart after downloading it + --untardir string if untar is specified, this flag specifies the name of the directory into which the chart is expanded (default ".") + --verify verify the package against its signature + --version string specific version of a chart. Without this, the latest version is fetched +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_get.md b/docs/helm/helm_get.md new file mode 100644 index 000000000..e879cac7e --- /dev/null +++ b/docs/helm/helm_get.md @@ -0,0 +1,46 @@ +## helm get + +download a named release + +### Synopsis + + + +This command shows the details of a named release. + +It can be used to get extended information about the release, including: + + - The values used to generate the release + - The chart used to generate the release + - The generated manifest file + +By default, this prints a human readable collection of information about the +chart, the supplied values, and the generated manifest file. + + +``` +helm get [flags] RELEASE_NAME +``` + +### Options + +``` + --revision value get the named release with revision +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm get hooks](helm_get_hooks.md) - download all hooks for a named release +* [helm get manifest](helm_get_manifest.md) - download the manifest for a named release +* [helm get values](helm_get_values.md) - download the values file for a named release + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_get_hooks.md b/docs/helm/helm_get_hooks.md new file mode 100644 index 000000000..a37002e05 --- /dev/null +++ b/docs/helm/helm_get_hooks.md @@ -0,0 +1,36 @@ +## helm get hooks + +download all hooks for a named release + +### Synopsis + + + +This command downloads hooks for a given release. + +Hooks are formatted in YAML and separated by the YAML '---\n' separator. + + +``` +helm get hooks [flags] RELEASE_NAME +``` + +### Options + +``` + --revision value get the named release with revision +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm get](helm_get.md) - download a named release + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_get_manifest.md b/docs/helm/helm_get_manifest.md new file mode 100644 index 000000000..cd8505c6b --- /dev/null +++ b/docs/helm/helm_get_manifest.md @@ -0,0 +1,38 @@ +## helm get manifest + +download the manifest for a named release + +### Synopsis + + + +This command fetches the generated manifest for a given release. + +A manifest is a YAML-encoded representation of the Kubernetes resources that +were generated from this release's chart(s). If a chart is dependent on other +charts, those resources will also be included in the manifest. + + +``` +helm get manifest [flags] RELEASE_NAME +``` + +### Options + +``` + --revision value get the named release with revision +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm get](helm_get.md) - download a named release + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_get_values.md b/docs/helm/helm_get_values.md new file mode 100644 index 000000000..53d1f6591 --- /dev/null +++ b/docs/helm/helm_get_values.md @@ -0,0 +1,35 @@ +## helm get values + +download the values file for a named release + +### Synopsis + + + +This command downloads a values file for a given release. + + +``` +helm get values [flags] RELEASE_NAME +``` + +### Options + +``` + -a, --all dump all (computed) values + --revision value get the named release with revision +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm get](helm_get.md) - download a named release + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_history.md b/docs/helm/helm_history.md new file mode 100644 index 000000000..d067398fa --- /dev/null +++ b/docs/helm/helm_history.md @@ -0,0 +1,46 @@ +## helm history + +fetch release history + +### Synopsis + + + +History prints historical revisions for a given release. + +A default maximum of 256 revisions will be returned. Setting '--max' +configures the maximum length of the revision list returned. + +The historical release set is printed as a formatted table, e.g: + + $ helm history angry-bird --max=4 + REVISION UPDATED STATUS CHART + 1 Mon Oct 3 10:15:13 2016 SUPERSEDED alpine-0.1.0 + 2 Mon Oct 3 10:15:13 2016 SUPERSEDED alpine-0.1.0 + 3 Mon Oct 3 10:15:13 2016 SUPERSEDED alpine-0.1.0 + 4 Mon Oct 3 10:15:13 2016 DEPLOYED alpine-0.1.0 + + +``` +helm history [flags] RELEASE_NAME +``` + +### Options + +``` + --max value maximum number of revision to include in history (default 256) +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_home.md b/docs/helm/helm_home.md new file mode 100644 index 000000000..b2b58b5c8 --- /dev/null +++ b/docs/helm/helm_home.md @@ -0,0 +1,29 @@ +## helm home + +displays the location of HELM_HOME + +### Synopsis + + + +This command displays the location of HELM_HOME. This is where +any helm configuration files live. + + +``` +helm home +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_init.md b/docs/helm/helm_init.md new file mode 100644 index 000000000..4a38f934b --- /dev/null +++ b/docs/helm/helm_init.md @@ -0,0 +1,54 @@ +## helm init + +initialize Helm on both client and server + +### Synopsis + + + +This command installs Tiller (the helm server side component) onto your +Kubernetes Cluster and sets up local configuration in $HELM_HOME (default ~/.helm/) + +As with the rest of the Helm commands, 'helm init' discovers Kubernetes clusters +by reading $KUBECONFIG (default '~/.kube/config') and using the default context. + +To set up just a local environment, use '--client-only'. That will configure +$HELM_HOME, but not attempt to connect to a remote cluster and install the Tiller +deployment. + +When installing Tiller, 'helm init' will attempt to install the latest released +version. You can specify an alternative image with '--tiller-image'. For those +frequently working on the latest code, the flag '--canary-image' will install +the latest pre-release version of Tiller (e.g. the HEAD commit in the GitHub +repository on the master branch). + +To dump a manifest containing the Tiller deployment YAML, combine the +'--dry-run' and '--debug' flags. + + +``` +helm init +``` + +### Options + +``` + --canary-image use the canary tiller image + -c, --client-only if set does not install tiller + --dry-run do not install local or remote + -i, --tiller-image string override tiller image +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_inspect.md b/docs/helm/helm_inspect.md new file mode 100644 index 000000000..3a4798dc4 --- /dev/null +++ b/docs/helm/helm_inspect.md @@ -0,0 +1,41 @@ +## helm inspect + +inspect a chart + +### Synopsis + + + +This command inspects a chart and displays information. It takes a chart reference +('stable/drupal'), a full path to a directory or packaged chart, or a URL. + +Inspect prints the contents of the Chart.yaml file and the values.yaml file. + + +``` +helm inspect [CHART] +``` + +### Options + +``` + --keyring string path to the keyring containing public verification keys (default "/Users/mattbutcher/.gnupg/pubring.gpg") + --verify verify the provenance data for this chart + --version string version of the chart. By default, the newest chart is shown +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm inspect chart](helm_inspect_chart.md) - shows inspect chart +* [helm inspect values](helm_inspect_values.md) - shows inspect values + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_inspect_chart.md b/docs/helm/helm_inspect_chart.md new file mode 100644 index 000000000..f49fa254f --- /dev/null +++ b/docs/helm/helm_inspect_chart.md @@ -0,0 +1,37 @@ +## helm inspect chart + +shows inspect chart + +### Synopsis + + + +This command inspects a chart (directory, file, or URL) and displays the contents +of the Charts.yaml file + + +``` +helm inspect chart [CHART] +``` + +### Options + +``` + --keyring string path to the keyring containing public verification keys (default "/Users/mattbutcher/.gnupg/pubring.gpg") + --verify verify the provenance data for this chart + --version string version of the chart. By default, the newest chart is shown +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm inspect](helm_inspect.md) - inspect a chart + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_inspect_values.md b/docs/helm/helm_inspect_values.md new file mode 100644 index 000000000..3fa7b4ed2 --- /dev/null +++ b/docs/helm/helm_inspect_values.md @@ -0,0 +1,37 @@ +## helm inspect values + +shows inspect values + +### Synopsis + + + +This command inspects a chart (directory, file, or URL) and displays the contents +of the values.yaml file + + +``` +helm inspect values [CHART] +``` + +### Options + +``` + --keyring string path to the keyring containing public verification keys (default "/Users/mattbutcher/.gnupg/pubring.gpg") + --verify verify the provenance data for this chart + --version string version of the chart. By default, the newest chart is shown +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm inspect](helm_inspect.md) - inspect a chart + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_install.md b/docs/helm/helm_install.md new file mode 100644 index 000000000..280d287da --- /dev/null +++ b/docs/helm/helm_install.md @@ -0,0 +1,84 @@ +## helm install + +install a chart archive + +### Synopsis + + + +This command installs a chart archive. + +The install argument must be either a relative path to a chart directory or the +name of a chart in the current working directory. + +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. + + $ helm install -f myvalues.yaml ./redis + +or + + $ helm install --set name=prod ./redis + +To check the generated manifests of a release without installing the chart, +the '--debug' and '--dry-run' flags can be combined. This will still require a +round-trip to the Tiller server. + +If --verify is set, the chart MUST have a provenance file, and the provenenace +fall MUST pass all verification steps. + +There are four different ways you can express the chart you want to install: + +1. By chart reference: helm install stable/mariadb +2. By path to a packaged chart: helm install ./nginx-1.2.3.tgz +3. By path to an unpacked chart directory: helm install ./nginx +4. By absolute URL: helm install https://example.com/charts/nginx-1.2.3.tgz + +CHART REFERENCES + +A chart reference is a convenient way of reference a chart in a chart repository. + +When you use a chart reference ('stable/mariadb'), Helm will look in the local +configuration for a chart repository named 'stable', and will then look for a +chart in that repository whose name is 'mariadb'. It will install the latest +version of that chart unless you also supply a version number with the +'--version' flag. + +To see the list of chart repositories, use 'helm repo list'. To search for +charts in a repository, use 'helm search'. + + +``` +helm install [CHART] +``` + +### Options + +``` + --dry-run simulate an install + --keyring string location of public keys used for verification (default "/Users/mattbutcher/.gnupg/pubring.gpg") + -n, --name string release name. If unspecified, it will autogenerate one for you + --name-template string specify template used to name the release + --namespace string namespace to install the release into + --no-hooks prevent hooks from running during install + --replace re-use the given name, even if that name is already used. This is unsafe in production + --set value set values on the command line. Separate values with commas: key1=val1,key2=val2 (default null +) + -f, --values string specify values in a YAML file + --verify verify the package before installing it + --version string specify the exact chart version to install. If this is not specified, the latest version is installed +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_lint.md b/docs/helm/helm_lint.md new file mode 100644 index 000000000..0de9e53fc --- /dev/null +++ b/docs/helm/helm_lint.md @@ -0,0 +1,39 @@ +## helm lint + +examines a chart for possible issues + +### Synopsis + + + +This command takes a path to a chart and runs a series of tests to verify that +the chart is well-formed. + +If the linter encounters things that will cause the chart to fail installation, +it will emit [ERROR] messages. If it encounters issues that break with convention +or recommendation, it will emit [WARNING] messages. + + +``` +helm lint [flags] PATH +``` + +### Options + +``` + --strict fail on lint warnings +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_list.md b/docs/helm/helm_list.md new file mode 100644 index 000000000..d063b59c9 --- /dev/null +++ b/docs/helm/helm_list.md @@ -0,0 +1,65 @@ +## helm list + +list releases + +### Synopsis + + + +This command lists all of the releases. + +By default, it lists only releases that are deployed or failed. Flags like +'--delete' and '--all' will alter this behavior. Such flags can be combined: +'--deleted --failed'. + +By default, items are sorted alphabetically. Use the '-d' flag to sort by +release date. + +If an argument is provided, it will be treated as a filter. Filters are +regular expressions (Perl compatible) that are applied to the list of releases. +Only items that match the filter will be returned. + + $ helm list 'ara[a-z]+' + NAME UPDATED CHART + maudlin-arachnid Mon May 9 16:07:08 2016 alpine-0.1.0 + +If no results are found, 'helm list' will exit 0, but with no output (or in +the case of no '-q' flag, only headers). + +By default, up to 256 items may be returned. To limit this, use the '--max' flag. +Setting '--max' to 0 will not return all results. Rather, it will return the +server's default, which may be much higher than 256. Pairing the '--max' +flag with the '--offset' flag allows you to page through results. + + +``` +helm list [flags] [FILTER] +``` + +### Options + +``` + --all show all releases, not just the ones marked DEPLOYED + -d, --date sort by release date + --deleted show deleted releases + --deployed show deployed releases. If no other is specified, this will be automatically enabled + --failed show failed releases + -m, --max int maximum number of releases to fetch (default 256) + -o, --offset string next release name in the list, used to offset from start value + -r, --reverse reverse the sort order + -q, --short output short (quiet) listing format +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_package.md b/docs/helm/helm_package.md new file mode 100644 index 000000000..b0aec6293 --- /dev/null +++ b/docs/helm/helm_package.md @@ -0,0 +1,44 @@ +## helm package + +package a chart directory into a chart archive + +### Synopsis + + + +This command packages a chart into a versioned chart archive file. If a path +is given, this will look at that path for a chart (which must contain a +Chart.yaml file) and then package that directory. + +If no path is given, this will look in the present working directory for a +Chart.yaml file, and (if found) build the current directory into a chart. + +Versioned chart archives are used by Helm package repositories. + + +``` +helm package [flags] [CHART_PATH] [...] +``` + +### Options + +``` + --key string name of the key to use when signing. Used if --sign is true + --keyring string location of a public keyring (default "/Users/mattbutcher/.gnupg/pubring.gpg") + --save save packaged chart to local chart repository (default true) + --sign use a PGP private key to sign this package +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_repo.md b/docs/helm/helm_repo.md new file mode 100644 index 000000000..11c2fe876 --- /dev/null +++ b/docs/helm/helm_repo.md @@ -0,0 +1,33 @@ +## helm repo + +add, list, remove, update, and index chart repositories + +### Synopsis + + + +This command consists of multiple subcommands to interact with chart repositories. + +It can be used to add, remove, list, and index chart repositories. +Example usage: + $ helm repo add [NAME] [REPO_URL] + + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm repo add](helm_repo_add.md) - add a chart repository +* [helm repo index](helm_repo_index.md) - generate an index file given a directory containing packaged charts +* [helm repo list](helm_repo_list.md) - list chart repositories +* [helm repo remove](helm_repo_remove.md) - remove a chart repository +* [helm repo update](helm_repo_update.md) - update information on available charts in the chart repositories + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_repo_add.md b/docs/helm/helm_repo_add.md new file mode 100644 index 000000000..3c72658f9 --- /dev/null +++ b/docs/helm/helm_repo_add.md @@ -0,0 +1,32 @@ +## helm repo add + +add a chart repository + +### Synopsis + + +add a chart repository + +``` +helm repo add [flags] [NAME] [URL] +``` + +### Options + +``` + --no-update raise error if repo is already registered +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_repo_index.md b/docs/helm/helm_repo_index.md new file mode 100644 index 000000000..b5ea598b9 --- /dev/null +++ b/docs/helm/helm_repo_index.md @@ -0,0 +1,42 @@ +## helm repo index + +generate an index file given a directory containing packaged charts + +### Synopsis + + + +Read the current directory and generate an index file based on the charts found. + +This tool is used for creating an 'index.yaml' file for a chart repository. To +set an absolute URL to the charts, use '--url' flag. + +To merge the generated index with an existing index file, use the '--merge' +flag. In this case, the charts found in the current directory will be merged +into the existing index, with local charts taking priority over existing charts. + + +``` +helm repo index [flags] [DIR] +``` + +### Options + +``` + --merge string merge the generated index into the given index + --url string url of chart repository +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_repo_list.md b/docs/helm/helm_repo_list.md new file mode 100644 index 000000000..4d1215375 --- /dev/null +++ b/docs/helm/helm_repo_list.md @@ -0,0 +1,26 @@ +## helm repo list + +list chart repositories + +### Synopsis + + +list chart repositories + +``` +helm repo list [flags] +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_repo_remove.md b/docs/helm/helm_repo_remove.md new file mode 100644 index 000000000..5902cb509 --- /dev/null +++ b/docs/helm/helm_repo_remove.md @@ -0,0 +1,26 @@ +## helm repo remove + +remove a chart repository + +### Synopsis + + +remove a chart repository + +``` +helm repo remove [flags] [NAME] +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_repo_update.md b/docs/helm/helm_repo_update.md new file mode 100644 index 000000000..a6fbcdf40 --- /dev/null +++ b/docs/helm/helm_repo_update.md @@ -0,0 +1,32 @@ +## helm repo update + +update information on available charts in the chart repositories + +### Synopsis + + + +Update gets the latest information about charts from the respective chart repositories. +Information is cached locally, where it is used by commands like 'helm search'. + +'helm update' is the deprecated form of 'helm repo update'. It will be removed in +future releases. + + +``` +helm repo update +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_rollback.md b/docs/helm/helm_rollback.md new file mode 100644 index 000000000..852db4fe9 --- /dev/null +++ b/docs/helm/helm_rollback.md @@ -0,0 +1,36 @@ +## helm rollback + +roll back a release to a previous revision + +### Synopsis + + + +This command rolls back a release to the previous revision. +The argument of the rollback command is the name of a release. + + +``` +helm rollback [RELEASE] +``` + +### Options + +``` + --dry-run simulate a rollback + --no-hooks prevent hooks from running during rollback +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_search.md b/docs/helm/helm_search.md new file mode 100644 index 000000000..ad89b2abd --- /dev/null +++ b/docs/helm/helm_search.md @@ -0,0 +1,38 @@ +## helm search + +search for a keyword in charts + +### Synopsis + + + +Search reads through all of the repositories configured on the system, and +looks for matches. + +Repositories are managed with 'helm repo' commands. + + +``` +helm search [keyword] +``` + +### Options + +``` + -r, --regexp use regular expressions for searching + -l, --versions show the long listing, with each version of each chart on its own line +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_serve.md b/docs/helm/helm_serve.md new file mode 100644 index 000000000..f81aeed3c --- /dev/null +++ b/docs/helm/helm_serve.md @@ -0,0 +1,39 @@ +## helm serve + +start a local http web server + +### Synopsis + + + +This command starts a local chart repository server that serves charts from a local directory. + +The new server will provide HTTP access to a repository. By default, it will +scan all of the charts in '$HELM_HOME/repository/local' and serve those over +the a local IPv4 TCP port (default '127.0.0.1:8879'). + + +``` +helm serve +``` + +### Options + +``` + --address string address to listen on (default "127.0.0.1:8879") + --repo-path string local directory path from which to serve charts (default "/Users/mattbutcher/Code/helm_home/repository/local") +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_status.md b/docs/helm/helm_status.md new file mode 100644 index 000000000..197bc6e2d --- /dev/null +++ b/docs/helm/helm_status.md @@ -0,0 +1,34 @@ +## helm status + +displays the status of the named release + +### Synopsis + + + +This command shows the status of a named release. + + +``` +helm status [flags] RELEASE_NAME +``` + +### Options + +``` + --revision value if set, display the status of the named release with revision +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_upgrade.md b/docs/helm/helm_upgrade.md new file mode 100644 index 000000000..174855724 --- /dev/null +++ b/docs/helm/helm_upgrade.md @@ -0,0 +1,51 @@ +## helm upgrade + +upgrade a release + +### Synopsis + + + +This command upgrades a release to a new version of a chart. + +The upgrade arguments must be a release and chart. The chart +argument can be either: a chart reference('stable/mariadb'), a path to a chart directory, +a packaged chart, or a fully qualified URL. For chart references, the latest +version will be specified unless the '--version' flag is set. + +To override values in a chart, use either the '--values' flag and pass in a file +or use the '--set' flag and pass configuration from the command line. + + +``` +helm upgrade [RELEASE] [CHART] +``` + +### Options + +``` + --disable-hooks disable pre/post upgrade hooks + --dry-run simulate an upgrade + -i, --install if a release by this name doesn't already exist, run an install + --keyring string path to the keyring that contains public singing keys (default "/Users/mattbutcher/.gnupg/pubring.gpg") + --namespace string namespace to install the release into (only used if --install is set) (default "default") + --set value set values on the command line. Separate values with commas: key1=val1,key2=val2 (default null +) + -f, --values string path to a values YAML file + --verify verify the provenance of the chart before upgrading + --version string specify the exact chart version to use. If this is not specified, the latest version is used +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_verify.md b/docs/helm/helm_verify.md new file mode 100644 index 000000000..388db234b --- /dev/null +++ b/docs/helm/helm_verify.md @@ -0,0 +1,41 @@ +## helm verify + +verify that a chart at the given path has been signed and is valid + +### Synopsis + + + +Verify that the given chart has a valid provenance file. + +Provenance files provide crytographic verification that a chart has not been +tampered with, and was packaged by a trusted provider. + +This command can be used to verify a local chart. Several other commands provide +'--verify' flags that run the same validation. To generate a signed package, use +the 'helm package --sign' command. + + +``` +helm verify [flags] PATH +``` + +### Options + +``` + --keyring string keyring containing public keys (default "/Users/mattbutcher/.gnupg/pubring.gpg") +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/helm/helm_version.md b/docs/helm/helm_version.md new file mode 100644 index 000000000..124bf8816 --- /dev/null +++ b/docs/helm/helm_version.md @@ -0,0 +1,49 @@ +## helm version + +print the client/server version information + +### Synopsis + + + +Show the client and server versions for Helm and tiller. + +This will print a representation of the client and server versions of Helm and +Tiller. The output will look something like this: + +Client: &version.Version{SemVer:"v2.0.0-beta.1", GitCommit:"ff52399e51bb880526e9cd0ed8386f6433b74da1", GitTreeState:"dirty"} +Server: &version.Version{SemVer:"v2.0.0-beta.1", GitCommit:"b0c113dfb9f612a9add796549da66c0d294508a3", GitTreeState:"clean"} + +- SemVer is the semantic version of the release. +- GitCommit is the SHA for the commit that this version was built from. +- GitTreeState is "clean" if there are no local code changes when this binary was + built, and "dirty" if the binary was built from locally modified code. + +To print just the client version, use '--client'. To print just the server version, +use '--server'. + + +``` +helm version +``` + +### Options + +``` + -c, --client if set, show the client version + -s, --server if set, show the server version +``` + +### Options inherited from parent commands + +``` + --debug enable verbose output + --home string location of your Helm config. Overrides $HELM_HOME (default "/Users/mattbutcher/Code/helm_home") + --host string address of tiller. Overrides $HELM_HOST + --kube-context string name of the kubeconfig context to use +``` + +### SEE ALSO +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 1-Nov-2016 diff --git a/docs/man/man1/helm.1 b/docs/man/man1/helm.1 new file mode 100644 index 000000000..e307fe6c2 --- /dev/null +++ b/docs/man/man1/helm.1 @@ -0,0 +1,79 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm \- The Helm package manager for Kubernetes. + + +.SH SYNOPSIS +.PP +\fBhelm\fP + + +.SH DESCRIPTION +.PP +The Kubernetes package manager + +.PP +To begin working with Helm, run the 'helm init' command: + +.PP +.RS + +.nf +$ helm init + +.fi +.RE + +.PP +This will install Tiller to your running Kubernetes cluster. +It will also set up any necessary local configuration. + +.PP +Common actions from this point include: +.IP \(bu 2 +helm search: search for charts +.IP \(bu 2 +helm fetch: download a chart to your local directory to view +.IP \(bu 2 +helm install: upload the chart to Kubernetes +.IP \(bu 2 +helm list: list releases of charts + +.PP +Environment: + $HELM\_HOME set an alternative location for Helm files. By default, these are stored in \~/.helm + $HELM\_HOST set an alternative Tiller host. The format is host:port + $KUBECONFIG set an alternate Kubernetes configuration file (default "\~/.kube/config") + + +.SH OPTIONS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-create(1)\fP, \fBhelm\-delete(1)\fP, \fBhelm\-dependency(1)\fP, \fBhelm\-fetch(1)\fP, \fBhelm\-get(1)\fP, \fBhelm\-history(1)\fP, \fBhelm\-home(1)\fP, \fBhelm\-init(1)\fP, \fBhelm\-inspect(1)\fP, \fBhelm\-install(1)\fP, \fBhelm\-lint(1)\fP, \fBhelm\-list(1)\fP, \fBhelm\-package(1)\fP, \fBhelm\-repo(1)\fP, \fBhelm\-rollback(1)\fP, \fBhelm\-search(1)\fP, \fBhelm\-serve(1)\fP, \fBhelm\-status(1)\fP, \fBhelm\-upgrade(1)\fP, \fBhelm\-verify(1)\fP, \fBhelm\-version(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_create.1 b/docs/man/man1/helm_create.1 new file mode 100644 index 000000000..3e2a4ca0d --- /dev/null +++ b/docs/man/man1/helm_create.1 @@ -0,0 +1,76 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-create \- create a new chart with the given name + + +.SH SYNOPSIS +.PP +\fBhelm create NAME\fP + + +.SH DESCRIPTION +.PP +This command creates a chart directory along with the common files and +directories used in a chart. + +.PP +For example, 'helm create foo' will create a directory structure that looks +something like this: + +.PP +.RS + +.nf +foo/ + | + |\- .helmignore # Contains patterns to ignore when packaging Helm charts. + | + |\- Chart.yaml # Information about your chart + | + |\- values.yaml # The default values for your templates + | + |\- charts/ # Charts that this chart depends on + | + |\- templates/ # The template files + +.fi +.RE + +.PP +\&'helm create' takes a path for an argument. If directories in the given path +do not exist, Helm will attempt to create them as it goes. If the given +destination exists and there are files in that directory, conflicting files +will be overwritten, but other files will be left alone. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_delete.1 b/docs/man/man1/helm_delete.1 new file mode 100644 index 000000000..5c1f24415 --- /dev/null +++ b/docs/man/man1/helm_delete.1 @@ -0,0 +1,65 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-delete \- given a release name, delete the release from Kubernetes + + +.SH SYNOPSIS +.PP +\fBhelm delete [flags] RELEASE\_NAME [...]\fP + + +.SH DESCRIPTION +.PP +This command takes a release name, and then deletes the release from Kubernetes. +It removes all of the resources associated with the last release of the chart. + +.PP +Use the '\-\-dry\-run' flag to see which releases will be deleted without actually +deleting them. + + +.SH OPTIONS +.PP +\fB\-\-dry\-run\fP[=false] + simulate a delete + +.PP +\fB\-\-no\-hooks\fP[=false] + prevent hooks from running during deletion + +.PP +\fB\-\-purge\fP[=false] + remove the release from the store and make its name free for later use + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_dependency.1 b/docs/man/man1/helm_dependency.1 new file mode 100644 index 000000000..6c82476bc --- /dev/null +++ b/docs/man/man1/helm_dependency.1 @@ -0,0 +1,90 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-dependency \- manage a chart's dependencies + + +.SH SYNOPSIS +.PP +\fBhelm dependency update|build|list\fP + + +.SH DESCRIPTION +.PP +Manage the dependencies of a chart. + +.PP +Helm charts store their dependencies in 'charts/'. For chart developers, it is +often easier to manage a single dependency file ('requirements.yaml') +which declares all dependencies. + +.PP +The dependency commands operate on that file, making it easy to synchronize +between the desired dependencies and the actual dependencies stored in the +'charts/' directory. + +.PP +A 'requirements.yaml' file is a YAML file in which developers can declare chart +dependencies, along with the location of the chart and the desired version. +For example, this requirements file declares two dependencies: + +.PP +.RS + +.nf +# requirements.yaml +dependencies: + \- name: nginx + version: "1.2.3" + repository: "https://example.com/charts" + \- name: memcached + version: "3.2.1" + repository: "https://another.example.com/charts" + +.fi +.RE + +.PP +The 'name' should be the name of a chart, where that name must match the name +in that chart's 'Chart.yaml' file. + +.PP +The 'version' field should contain a semantic version or version range. + +.PP +The 'repository' URL should point to a Chart Repository. Helm expects that by +appending '/index.yaml' to the URL, it should be able to retrieve the chart +repository's index. Note: 'repository' cannot be a repository alias. It must be +a URL. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP, \fBhelm\-dependency\-build(1)\fP, \fBhelm\-dependency\-list(1)\fP, \fBhelm\-dependency\-update(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_dependency_build.1 b/docs/man/man1/helm_dependency_build.1 new file mode 100644 index 000000000..3a56d8152 --- /dev/null +++ b/docs/man/man1/helm_dependency_build.1 @@ -0,0 +1,65 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-dependency\-build \- rebuild the charts/ directory based on the requirements.lock file + + +.SH SYNOPSIS +.PP +\fBhelm dependency build [flags] CHART\fP + + +.SH DESCRIPTION +.PP +Build out the charts/ directory from the requirements.lock file. + +.PP +Build is used to reconstruct a chart's dependencies to the state specified in +the lock file. This will not re\-negotiate dependencies, as 'helm dependency update' +does. + +.PP +If no lock file is found, 'helm dependency build' will mirror the behavior +of 'helm dependency update'. + + +.SH OPTIONS +.PP +\fB\-\-keyring\fP="/Users/mattbutcher/.gnupg/pubring.gpg" + keyring containing public keys + +.PP +\fB\-\-verify\fP[=false] + verify the packages against signatures + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-dependency(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_dependency_list.1 b/docs/man/man1/helm_dependency_list.1 new file mode 100644 index 000000000..2ac77bade --- /dev/null +++ b/docs/man/man1/helm_dependency_list.1 @@ -0,0 +1,54 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-dependency\-list \- list the dependencies for the given chart + + +.SH SYNOPSIS +.PP +\fBhelm dependency list [flags] CHART\fP + + +.SH DESCRIPTION +.PP +List all of the dependencies declared in a chart. + +.PP +This can take chart archives and chart directories as input. It will not alter +the contents of a chart. + +.PP +This will produce an error if the chart cannot be loaded. It will emit a warning +if it cannot find a requirements.yaml. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-dependency(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_dependency_update.1 b/docs/man/man1/helm_dependency_update.1 new file mode 100644 index 000000000..75147a783 --- /dev/null +++ b/docs/man/man1/helm_dependency_update.1 @@ -0,0 +1,64 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-dependency\-update \- update charts/ based on the contents of requirements.yaml + + +.SH SYNOPSIS +.PP +\fBhelm dependency update [flags] CHART\fP + + +.SH DESCRIPTION +.PP +Update the on\-disk dependencies to mirror the requirements.yaml file. + +.PP +This command verifies that the required charts, as expressed in 'requirements.yaml', +are present in 'charts/' and are at an acceptable version. + +.PP +On successful update, this will generate a lock file that can be used to +rebuild the requirements to an exact version. + + +.SH OPTIONS +.PP +\fB\-\-keyring\fP="/Users/mattbutcher/.gnupg/pubring.gpg" + keyring containing public keys + +.PP +\fB\-\-verify\fP[=false] + verify the packages against signatures + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-dependency(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_fetch.1 b/docs/man/man1/helm_fetch.1 new file mode 100644 index 000000000..37bdd1ce5 --- /dev/null +++ b/docs/man/man1/helm_fetch.1 @@ -0,0 +1,86 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-fetch \- download a chart from a repository and (optionally) unpack it in local directory + + +.SH SYNOPSIS +.PP +\fBhelm fetch [flags] [chart URL | repo/chartname] [...]\fP + + +.SH DESCRIPTION +.PP +Retrieve a package from a package repository, and download it locally. + +.PP +This is useful for fetching packages to inspect, modify, or repackage. It can +also be used to perform cryptographic verification of a chart without installing +the chart. + +.PP +There are options for unpacking the chart after download. This will create a +directory for the chart and uncomparess into that directory. + +.PP +If the \-\-verify flag is specified, the requested chart MUST have a provenance +file, and MUST pass the verification process. Failure in any part of this will +result in an error, and the chart will not be saved locally. + + +.SH OPTIONS +.PP +\fB\-d\fP, \fB\-\-destination\fP="." + location to write the chart. If this and tardir are specified, tardir is appended to this + +.PP +\fB\-\-keyring\fP="/Users/mattbutcher/.gnupg/pubring.gpg" + keyring containing public keys + +.PP +\fB\-\-untar\fP[=false] + if set to true, will untar the chart after downloading it + +.PP +\fB\-\-untardir\fP="." + if untar is specified, this flag specifies the name of the directory into which the chart is expanded + +.PP +\fB\-\-verify\fP[=false] + verify the package against its signature + +.PP +\fB\-\-version\fP="" + specific version of a chart. Without this, the latest version is fetched + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_get.1 b/docs/man/man1/helm_get.1 new file mode 100644 index 000000000..86fbc4a81 --- /dev/null +++ b/docs/man/man1/helm_get.1 @@ -0,0 +1,65 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-get \- download a named release + + +.SH SYNOPSIS +.PP +\fBhelm get [flags] RELEASE\_NAME\fP + + +.SH DESCRIPTION +.PP +This command shows the details of a named release. + +.PP +It can be used to get extended information about the release, including: +.IP \(bu 2 +The values used to generate the release +.IP \(bu 2 +The chart used to generate the release +.IP \(bu 2 +The generated manifest file + +.PP +By default, this prints a human readable collection of information about the +chart, the supplied values, and the generated manifest file. + + +.SH OPTIONS +.PP +\fB\-\-revision\fP=0 + get the named release with revision + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP, \fBhelm\-get\-hooks(1)\fP, \fBhelm\-get\-manifest(1)\fP, \fBhelm\-get\-values(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_get_hooks.1 b/docs/man/man1/helm_get_hooks.1 new file mode 100644 index 000000000..eaffa9520 --- /dev/null +++ b/docs/man/man1/helm_get_hooks.1 @@ -0,0 +1,55 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-get\-hooks \- download all hooks for a named release + + +.SH SYNOPSIS +.PP +\fBhelm get hooks [flags] RELEASE\_NAME\fP + + +.SH DESCRIPTION +.PP +This command downloads hooks for a given release. + +.PP +Hooks are formatted in YAML and separated by the YAML '\-\-\-\\n' separator. + + +.SH OPTIONS +.PP +\fB\-\-revision\fP=0 + get the named release with revision + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-get(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_get_manifest.1 b/docs/man/man1/helm_get_manifest.1 new file mode 100644 index 000000000..894b3bbba --- /dev/null +++ b/docs/man/man1/helm_get_manifest.1 @@ -0,0 +1,57 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-get\-manifest \- download the manifest for a named release + + +.SH SYNOPSIS +.PP +\fBhelm get manifest [flags] RELEASE\_NAME\fP + + +.SH DESCRIPTION +.PP +This command fetches the generated manifest for a given release. + +.PP +A manifest is a YAML\-encoded representation of the Kubernetes resources that +were generated from this release's chart(s). If a chart is dependent on other +charts, those resources will also be included in the manifest. + + +.SH OPTIONS +.PP +\fB\-\-revision\fP=0 + get the named release with revision + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-get(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_get_values.1 b/docs/man/man1/helm_get_values.1 new file mode 100644 index 000000000..ff1536525 --- /dev/null +++ b/docs/man/man1/helm_get_values.1 @@ -0,0 +1,56 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-get\-values \- download the values file for a named release + + +.SH SYNOPSIS +.PP +\fBhelm get values [flags] RELEASE\_NAME\fP + + +.SH DESCRIPTION +.PP +This command downloads a values file for a given release. + + +.SH OPTIONS +.PP +\fB\-a\fP, \fB\-\-all\fP[=false] + dump all (computed) values + +.PP +\fB\-\-revision\fP=0 + get the named release with revision + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-get(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_history.1 b/docs/man/man1/helm_history.1 new file mode 100644 index 000000000..93ae649a8 --- /dev/null +++ b/docs/man/man1/helm_history.1 @@ -0,0 +1,73 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-history \- fetch release history + + +.SH SYNOPSIS +.PP +\fBhelm history [flags] RELEASE\_NAME\fP + + +.SH DESCRIPTION +.PP +History prints historical revisions for a given release. + +.PP +A default maximum of 256 revisions will be returned. Setting '\-\-max' +configures the maximum length of the revision list returned. + +.PP +The historical release set is printed as a formatted table, e.g: + +.PP +.RS + +.nf +$ helm history angry\-bird \-\-max=4 +REVISION UPDATED STATUS CHART +1 Mon Oct 3 10:15:13 2016 SUPERSEDED alpine\-0.1.0 +2 Mon Oct 3 10:15:13 2016 SUPERSEDED alpine\-0.1.0 +3 Mon Oct 3 10:15:13 2016 SUPERSEDED alpine\-0.1.0 +4 Mon Oct 3 10:15:13 2016 DEPLOYED alpine\-0.1.0 + +.fi +.RE + + +.SH OPTIONS +.PP +\fB\-\-max\fP=256 + maximum number of revision to include in history + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_home.1 b/docs/man/man1/helm_home.1 new file mode 100644 index 000000000..c6be2c047 --- /dev/null +++ b/docs/man/man1/helm_home.1 @@ -0,0 +1,47 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-home \- displays the location of HELM\_HOME + + +.SH SYNOPSIS +.PP +\fBhelm home\fP + + +.SH DESCRIPTION +.PP +This command displays the location of HELM\_HOME. This is where +any helm configuration files live. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_init.1 b/docs/man/man1/helm_init.1 new file mode 100644 index 000000000..3fa525942 --- /dev/null +++ b/docs/man/man1/helm_init.1 @@ -0,0 +1,85 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-init \- initialize Helm on both client and server + + +.SH SYNOPSIS +.PP +\fBhelm init\fP + + +.SH DESCRIPTION +.PP +This command installs Tiller (the helm server side component) onto your +Kubernetes Cluster and sets up local configuration in $HELM\_HOME (default \~/.helm/) + +.PP +As with the rest of the Helm commands, 'helm init' discovers Kubernetes clusters +by reading $KUBECONFIG (default '\~/.kube/config') and using the default context. + +.PP +To set up just a local environment, use '\-\-client\-only'. That will configure +$HELM\_HOME, but not attempt to connect to a remote cluster and install the Tiller +deployment. + +.PP +When installing Tiller, 'helm init' will attempt to install the latest released +version. You can specify an alternative image with '\-\-tiller\-image'. For those +frequently working on the latest code, the flag '\-\-canary\-image' will install +the latest pre\-release version of Tiller (e.g. the HEAD commit in the GitHub +repository on the master branch). + +.PP +To dump a manifest containing the Tiller deployment YAML, combine the +'\-\-dry\-run' and '\-\-debug' flags. + + +.SH OPTIONS +.PP +\fB\-\-canary\-image\fP[=false] + use the canary tiller image + +.PP +\fB\-c\fP, \fB\-\-client\-only\fP[=false] + if set does not install tiller + +.PP +\fB\-\-dry\-run\fP[=false] + do not install local or remote + +.PP +\fB\-i\fP, \fB\-\-tiller\-image\fP="" + override tiller image + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_inspect.1 b/docs/man/man1/helm_inspect.1 new file mode 100644 index 000000000..5e446e875 --- /dev/null +++ b/docs/man/man1/helm_inspect.1 @@ -0,0 +1,64 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-inspect \- inspect a chart + + +.SH SYNOPSIS +.PP +\fBhelm inspect [CHART]\fP + + +.SH DESCRIPTION +.PP +This command inspects a chart and displays information. It takes a chart reference +('stable/drupal'), a full path to a directory or packaged chart, or a URL. + +.PP +Inspect prints the contents of the Chart.yaml file and the values.yaml file. + + +.SH OPTIONS +.PP +\fB\-\-keyring\fP="/Users/mattbutcher/.gnupg/pubring.gpg" + path to the keyring containing public verification keys + +.PP +\fB\-\-verify\fP[=false] + verify the provenance data for this chart + +.PP +\fB\-\-version\fP="" + version of the chart. By default, the newest chart is shown + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP, \fBhelm\-inspect\-chart(1)\fP, \fBhelm\-inspect\-values(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_inspect_chart.1 b/docs/man/man1/helm_inspect_chart.1 new file mode 100644 index 000000000..5f0685f00 --- /dev/null +++ b/docs/man/man1/helm_inspect_chart.1 @@ -0,0 +1,61 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-inspect\-chart \- shows inspect chart + + +.SH SYNOPSIS +.PP +\fBhelm inspect chart [CHART]\fP + + +.SH DESCRIPTION +.PP +This command inspects a chart (directory, file, or URL) and displays the contents +of the Charts.yaml file + + +.SH OPTIONS +.PP +\fB\-\-keyring\fP="/Users/mattbutcher/.gnupg/pubring.gpg" + path to the keyring containing public verification keys + +.PP +\fB\-\-verify\fP[=false] + verify the provenance data for this chart + +.PP +\fB\-\-version\fP="" + version of the chart. By default, the newest chart is shown + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-inspect(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_inspect_values.1 b/docs/man/man1/helm_inspect_values.1 new file mode 100644 index 000000000..4f8570c6f --- /dev/null +++ b/docs/man/man1/helm_inspect_values.1 @@ -0,0 +1,61 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-inspect\-values \- shows inspect values + + +.SH SYNOPSIS +.PP +\fBhelm inspect values [CHART]\fP + + +.SH DESCRIPTION +.PP +This command inspects a chart (directory, file, or URL) and displays the contents +of the values.yaml file + + +.SH OPTIONS +.PP +\fB\-\-keyring\fP="/Users/mattbutcher/.gnupg/pubring.gpg" + path to the keyring containing public verification keys + +.PP +\fB\-\-verify\fP[=false] + verify the provenance data for this chart + +.PP +\fB\-\-version\fP="" + version of the chart. By default, the newest chart is shown + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-inspect(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_install.1 b/docs/man/man1/helm_install.1 new file mode 100644 index 000000000..10b1fa82f --- /dev/null +++ b/docs/man/man1/helm_install.1 @@ -0,0 +1,167 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-install \- install a chart archive + + +.SH SYNOPSIS +.PP +\fBhelm install [CHART]\fP + + +.SH DESCRIPTION +.PP +This command installs a chart archive. + +.PP +The install argument must be either a relative path to a chart directory or the +name of a chart in the current working directory. + +.PP +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. + +.PP +.RS + +.nf +$ helm install \-f myvalues.yaml ./redis + +.fi +.RE + +.PP +or + +.PP +.RS + +.nf +$ helm install \-\-set name=prod ./redis + +.fi +.RE + +.PP +To check the generated manifests of a release without installing the chart, +the '\-\-debug' and '\-\-dry\-run' flags can be combined. This will still require a +round\-trip to the Tiller server. + +.PP +If \-\-verify is set, the chart MUST have a provenance file, and the provenenace +fall MUST pass all verification steps. + +.PP +There are four different ways you can express the chart you want to install: +.IP " 1." 5 +By chart reference: helm install stable/mariadb +.IP " 2." 5 +By path to a packaged chart: helm install ./nginx\-1.2.3.tgz +.IP " 3." 5 +By path to an unpacked chart directory: helm install ./nginx +.IP " 4." 5 +By absolute URL: helm install +\[la]https://example.com/charts/nginx-1.2.3.tgz\[ra] + +.PP +CHART REFERENCES + +.PP +A chart reference is a convenient way of reference a chart in a chart repository. + +.PP +When you use a chart reference ('stable/mariadb'), Helm will look in the local +configuration for a chart repository named 'stable', and will then look for a +chart in that repository whose name is 'mariadb'. It will install the latest +version of that chart unless you also supply a version number with the +'\-\-version' flag. + +.PP +To see the list of chart repositories, use 'helm repo list'. To search for +charts in a repository, use 'helm search'. + + +.SH OPTIONS +.PP +\fB\-\-dry\-run\fP[=false] + simulate an install + +.PP +\fB\-\-keyring\fP="/Users/mattbutcher/.gnupg/pubring.gpg" + location of public keys used for verification + +.PP +\fB\-n\fP, \fB\-\-name\fP="" + release name. If unspecified, it will autogenerate one for you + +.PP +\fB\-\-name\-template\fP="" + specify template used to name the release + +.PP +\fB\-\-namespace\fP="" + namespace to install the release into + +.PP +\fB\-\-no\-hooks\fP[=false] + prevent hooks from running during install + +.PP +\fB\-\-replace\fP[=false] + re\-use the given name, even if that name is already used. This is unsafe in production + +.PP +\fB\-\-set\fP=null + +.PP +.RS + +.nf +set values on the command line. Separate values with commas: key1=val1,key2=val2 + +.fi +.RE + +.PP +\fB\-f\fP, \fB\-\-values\fP="" + specify values in a YAML file + +.PP +\fB\-\-verify\fP[=false] + verify the package before installing it + +.PP +\fB\-\-version\fP="" + specify the exact chart version to install. If this is not specified, the latest version is installed + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_lint.1 b/docs/man/man1/helm_lint.1 new file mode 100644 index 000000000..7e8107e6a --- /dev/null +++ b/docs/man/man1/helm_lint.1 @@ -0,0 +1,58 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-lint \- examines a chart for possible issues + + +.SH SYNOPSIS +.PP +\fBhelm lint [flags] PATH\fP + + +.SH DESCRIPTION +.PP +This command takes a path to a chart and runs a series of tests to verify that +the chart is well\-formed. + +.PP +If the linter encounters things that will cause the chart to fail installation, +it will emit [ERROR] messages. If it encounters issues that break with convention +or recommendation, it will emit [WARNING] messages. + + +.SH OPTIONS +.PP +\fB\-\-strict\fP[=false] + fail on lint warnings + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_list.1 b/docs/man/man1/helm_list.1 new file mode 100644 index 000000000..4a76687de --- /dev/null +++ b/docs/man/man1/helm_list.1 @@ -0,0 +1,119 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-list \- list releases + + +.SH SYNOPSIS +.PP +\fBhelm list [flags] [FILTER]\fP + + +.SH DESCRIPTION +.PP +This command lists all of the releases. + +.PP +By default, it lists only releases that are deployed or failed. Flags like +'\-\-delete' and '\-\-all' will alter this behavior. Such flags can be combined: +'\-\-deleted \-\-failed'. + +.PP +By default, items are sorted alphabetically. Use the '\-d' flag to sort by +release date. + +.PP +If an argument is provided, it will be treated as a filter. Filters are +regular expressions (Perl compatible) that are applied to the list of releases. +Only items that match the filter will be returned. + +.PP +.RS + +.nf +$ helm list 'ara[a\-z]+' +NAME UPDATED CHART +maudlin\-arachnid Mon May 9 16:07:08 2016 alpine\-0.1.0 + +.fi +.RE + +.PP +If no results are found, 'helm list' will exit 0, but with no output (or in +the case of no '\-q' flag, only headers). + +.PP +By default, up to 256 items may be returned. To limit this, use the '\-\-max' flag. +Setting '\-\-max' to 0 will not return all results. Rather, it will return the +server's default, which may be much higher than 256. Pairing the '\-\-max' +flag with the '\-\-offset' flag allows you to page through results. + + +.SH OPTIONS +.PP +\fB\-\-all\fP[=false] + show all releases, not just the ones marked DEPLOYED + +.PP +\fB\-d\fP, \fB\-\-date\fP[=false] + sort by release date + +.PP +\fB\-\-deleted\fP[=false] + show deleted releases + +.PP +\fB\-\-deployed\fP[=false] + show deployed releases. If no other is specified, this will be automatically enabled + +.PP +\fB\-\-failed\fP[=false] + show failed releases + +.PP +\fB\-m\fP, \fB\-\-max\fP=256 + maximum number of releases to fetch + +.PP +\fB\-o\fP, \fB\-\-offset\fP="" + next release name in the list, used to offset from start value + +.PP +\fB\-r\fP, \fB\-\-reverse\fP[=false] + reverse the sort order + +.PP +\fB\-q\fP, \fB\-\-short\fP[=false] + output short (quiet) listing format + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_package.1 b/docs/man/man1/helm_package.1 new file mode 100644 index 000000000..f15a9ce1a --- /dev/null +++ b/docs/man/man1/helm_package.1 @@ -0,0 +1,73 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-package \- package a chart directory into a chart archive + + +.SH SYNOPSIS +.PP +\fBhelm package [flags] [CHART\_PATH] [...]\fP + + +.SH DESCRIPTION +.PP +This command packages a chart into a versioned chart archive file. If a path +is given, this will look at that path for a chart (which must contain a +Chart.yaml file) and then package that directory. + +.PP +If no path is given, this will look in the present working directory for a +Chart.yaml file, and (if found) build the current directory into a chart. + +.PP +Versioned chart archives are used by Helm package repositories. + + +.SH OPTIONS +.PP +\fB\-\-key\fP="" + name of the key to use when signing. Used if \-\-sign is true + +.PP +\fB\-\-keyring\fP="/Users/mattbutcher/.gnupg/pubring.gpg" + location of a public keyring + +.PP +\fB\-\-save\fP[=true] + save packaged chart to local chart repository + +.PP +\fB\-\-sign\fP[=false] + use a PGP private key to sign this package + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_repo.1 b/docs/man/man1/helm_repo.1 new file mode 100644 index 000000000..106eb04e8 --- /dev/null +++ b/docs/man/man1/helm_repo.1 @@ -0,0 +1,51 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-repo \- add, list, remove, update, and index chart repositories + + +.SH SYNOPSIS +.PP +\fBhelm repo [FLAGS] add|remove|list|index|update [ARGS]\fP + + +.SH DESCRIPTION +.PP +This command consists of multiple subcommands to interact with chart repositories. + +.PP +It can be used to add, remove, list, and index chart repositories. +Example usage: + $ helm repo add [NAME] [REPO\_URL] + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP, \fBhelm\-repo\-add(1)\fP, \fBhelm\-repo\-index(1)\fP, \fBhelm\-repo\-list(1)\fP, \fBhelm\-repo\-remove(1)\fP, \fBhelm\-repo\-update(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_repo_add.1 b/docs/man/man1/helm_repo_add.1 new file mode 100644 index 000000000..745f2e9b7 --- /dev/null +++ b/docs/man/man1/helm_repo_add.1 @@ -0,0 +1,52 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-repo\-add \- add a chart repository + + +.SH SYNOPSIS +.PP +\fBhelm repo add [flags] [NAME] [URL]\fP + + +.SH DESCRIPTION +.PP +add a chart repository + + +.SH OPTIONS +.PP +\fB\-\-no\-update\fP[=false] + raise error if repo is already registered + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-repo(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_repo_index.1 b/docs/man/man1/helm_repo_index.1 new file mode 100644 index 000000000..47d41e02c --- /dev/null +++ b/docs/man/man1/helm_repo_index.1 @@ -0,0 +1,65 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-repo\-index \- generate an index file given a directory containing packaged charts + + +.SH SYNOPSIS +.PP +\fBhelm repo index [flags] [DIR]\fP + + +.SH DESCRIPTION +.PP +Read the current directory and generate an index file based on the charts found. + +.PP +This tool is used for creating an 'index.yaml' file for a chart repository. To +set an absolute URL to the charts, use '\-\-url' flag. + +.PP +To merge the generated index with an existing index file, use the '\-\-merge' +flag. In this case, the charts found in the current directory will be merged +into the existing index, with local charts taking priority over existing charts. + + +.SH OPTIONS +.PP +\fB\-\-merge\fP="" + merge the generated index into the given index + +.PP +\fB\-\-url\fP="" + url of chart repository + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-repo(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_repo_list.1 b/docs/man/man1/helm_repo_list.1 new file mode 100644 index 000000000..4621cea3e --- /dev/null +++ b/docs/man/man1/helm_repo_list.1 @@ -0,0 +1,46 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-repo\-list \- list chart repositories + + +.SH SYNOPSIS +.PP +\fBhelm repo list [flags]\fP + + +.SH DESCRIPTION +.PP +list chart repositories + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-repo(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_repo_remove.1 b/docs/man/man1/helm_repo_remove.1 new file mode 100644 index 000000000..4221a0ab0 --- /dev/null +++ b/docs/man/man1/helm_repo_remove.1 @@ -0,0 +1,46 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-repo\-remove \- remove a chart repository + + +.SH SYNOPSIS +.PP +\fBhelm repo remove [flags] [NAME]\fP + + +.SH DESCRIPTION +.PP +remove a chart repository + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-repo(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_repo_update.1 b/docs/man/man1/helm_repo_update.1 new file mode 100644 index 000000000..3c4d65e16 --- /dev/null +++ b/docs/man/man1/helm_repo_update.1 @@ -0,0 +1,51 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-repo\-update \- update information on available charts in the chart repositories + + +.SH SYNOPSIS +.PP +\fBhelm repo update\fP + + +.SH DESCRIPTION +.PP +Update gets the latest information about charts from the respective chart repositories. +Information is cached locally, where it is used by commands like 'helm search'. + +.PP +\&'helm update' is the deprecated form of 'helm repo update'. It will be removed in +future releases. + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm\-repo(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_rollback.1 b/docs/man/man1/helm_rollback.1 new file mode 100644 index 000000000..ead1a8c32 --- /dev/null +++ b/docs/man/man1/helm_rollback.1 @@ -0,0 +1,57 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-rollback \- roll back a release to a previous revision + + +.SH SYNOPSIS +.PP +\fBhelm rollback [RELEASE]\fP + + +.SH DESCRIPTION +.PP +This command rolls back a release to the previous revision. +The argument of the rollback command is the name of a release. + + +.SH OPTIONS +.PP +\fB\-\-dry\-run\fP[=false] + simulate a rollback + +.PP +\fB\-\-no\-hooks\fP[=false] + prevent hooks from running during rollback + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_search.1 b/docs/man/man1/helm_search.1 new file mode 100644 index 000000000..eeadce86b --- /dev/null +++ b/docs/man/man1/helm_search.1 @@ -0,0 +1,60 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-search \- search for a keyword in charts + + +.SH SYNOPSIS +.PP +\fBhelm search [keyword]\fP + + +.SH DESCRIPTION +.PP +Search reads through all of the repositories configured on the system, and +looks for matches. + +.PP +Repositories are managed with 'helm repo' commands. + + +.SH OPTIONS +.PP +\fB\-r\fP, \fB\-\-regexp\fP[=false] + use regular expressions for searching + +.PP +\fB\-l\fP, \fB\-\-versions\fP[=false] + show the long listing, with each version of each chart on its own line + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_serve.1 b/docs/man/man1/helm_serve.1 new file mode 100644 index 000000000..802feb571 --- /dev/null +++ b/docs/man/man1/helm_serve.1 @@ -0,0 +1,61 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-serve \- start a local http web server + + +.SH SYNOPSIS +.PP +\fBhelm serve\fP + + +.SH DESCRIPTION +.PP +This command starts a local chart repository server that serves charts from a local directory. + +.PP +The new server will provide HTTP access to a repository. By default, it will +scan all of the charts in '$HELM\_HOME/repository/local' and serve those over +the a local IPv4 TCP port (default '127.0.0.1:8879'). + + +.SH OPTIONS +.PP +\fB\-\-address\fP="127.0.0.1:8879" + address to listen on + +.PP +\fB\-\-repo\-path\fP="/Users/mattbutcher/Code/helm\_home/repository/local" + local directory path from which to serve charts + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_status.1 b/docs/man/man1/helm_status.1 new file mode 100644 index 000000000..f6e90b290 --- /dev/null +++ b/docs/man/man1/helm_status.1 @@ -0,0 +1,52 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-status \- displays the status of the named release + + +.SH SYNOPSIS +.PP +\fBhelm status [flags] RELEASE\_NAME\fP + + +.SH DESCRIPTION +.PP +This command shows the status of a named release. + + +.SH OPTIONS +.PP +\fB\-\-revision\fP=0 + if set, display the status of the named release with revision + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_upgrade.1 b/docs/man/man1/helm_upgrade.1 new file mode 100644 index 000000000..e50bf7fc5 --- /dev/null +++ b/docs/man/man1/helm_upgrade.1 @@ -0,0 +1,102 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-upgrade \- upgrade a release + + +.SH SYNOPSIS +.PP +\fBhelm upgrade [RELEASE] [CHART]\fP + + +.SH DESCRIPTION +.PP +This command upgrades a release to a new version of a chart. + +.PP +The upgrade arguments must be a release and chart. The chart +argument can be either: a chart reference('stable/mariadb'), a path to a chart directory, +a packaged chart, or a fully qualified URL. For chart references, the latest +version will be specified unless the '\-\-version' flag is set. + +.PP +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. + + +.SH OPTIONS +.PP +\fB\-\-disable\-hooks\fP[=false] + disable pre/post upgrade hooks + +.PP +\fB\-\-dry\-run\fP[=false] + simulate an upgrade + +.PP +\fB\-i\fP, \fB\-\-install\fP[=false] + if a release by this name doesn't already exist, run an install + +.PP +\fB\-\-keyring\fP="/Users/mattbutcher/.gnupg/pubring.gpg" + path to the keyring that contains public singing keys + +.PP +\fB\-\-namespace\fP="default" + namespace to install the release into (only used if \-\-install is set) + +.PP +\fB\-\-set\fP=null + +.PP +.RS + +.nf +set values on the command line. Separate values with commas: key1=val1,key2=val2 + +.fi +.RE + +.PP +\fB\-f\fP, \fB\-\-values\fP="" + path to a values YAML file + +.PP +\fB\-\-verify\fP[=false] + verify the provenance of the chart before upgrading + +.PP +\fB\-\-version\fP="" + specify the exact chart version to use. If this is not specified, the latest version is used + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_verify.1 b/docs/man/man1/helm_verify.1 new file mode 100644 index 000000000..b421fc7ac --- /dev/null +++ b/docs/man/man1/helm_verify.1 @@ -0,0 +1,61 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-verify \- verify that a chart at the given path has been signed and is valid + + +.SH SYNOPSIS +.PP +\fBhelm verify [flags] PATH\fP + + +.SH DESCRIPTION +.PP +Verify that the given chart has a valid provenance file. + +.PP +Provenance files provide crytographic verification that a chart has not been +tampered with, and was packaged by a trusted provider. + +.PP +This command can be used to verify a local chart. Several other commands provide +'\-\-verify' flags that run the same validation. To generate a signed package, use +the 'helm package \-\-sign' command. + + +.SH OPTIONS +.PP +\fB\-\-keyring\fP="/Users/mattbutcher/.gnupg/pubring.gpg" + keyring containing public keys + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/docs/man/man1/helm_version.1 b/docs/man/man1/helm_version.1 new file mode 100644 index 000000000..c5e5c9c78 --- /dev/null +++ b/docs/man/man1/helm_version.1 @@ -0,0 +1,75 @@ +.TH "HELM" "1" "Nov 2016" "Auto generated by spf13/cobra" "" +.nh +.ad l + + +.SH NAME +.PP +helm\-version \- print the client/server version information + + +.SH SYNOPSIS +.PP +\fBhelm version\fP + + +.SH DESCRIPTION +.PP +Show the client and server versions for Helm and tiller. + +.PP +This will print a representation of the client and server versions of Helm and +Tiller. The output will look something like this: + +.PP +Client: \&version.Version{SemVer:"v2.0.0\-beta.1", GitCommit:"ff52399e51bb880526e9cd0ed8386f6433b74da1", GitTreeState:"dirty"} +Server: \&version.Version{SemVer:"v2.0.0\-beta.1", GitCommit:"b0c113dfb9f612a9add796549da66c0d294508a3", GitTreeState:"clean"} +.IP \(bu 2 +SemVer is the semantic version of the release. +.IP \(bu 2 +GitCommit is the SHA for the commit that this version was built from. +.IP \(bu 2 +GitTreeState is "clean" if there are no local code changes when this binary was +built, and "dirty" if the binary was built from locally modified code. + +.PP +To print just the client version, use '\-\-client'. To print just the server version, +use '\-\-server'. + + +.SH OPTIONS +.PP +\fB\-c\fP, \fB\-\-client\fP[=false] + if set, show the client version + +.PP +\fB\-s\fP, \fB\-\-server\fP[=false] + if set, show the server version + + +.SH OPTIONS INHERITED FROM PARENT COMMANDS +.PP +\fB\-\-debug\fP[=false] + enable verbose output + +.PP +\fB\-\-home\fP="/Users/mattbutcher/Code/helm\_home" + location of your Helm config. Overrides $HELM\_HOME + +.PP +\fB\-\-host\fP="" + address of tiller. Overrides $HELM\_HOST + +.PP +\fB\-\-kube\-context\fP="" + name of the kubeconfig context to use + + +.SH SEE ALSO +.PP +\fBhelm(1)\fP + + +.SH HISTORY +.PP +1\-Nov\-2016 Auto generated by spf13/cobra diff --git a/glide.lock b/glide.lock index 55a83c7b7..d7b9736d1 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ hash: 89695daf5f2de706b79fdd8e8b095f9514f418c0fbcf80d7fdca4c208d114d19 -updated: 2016-11-29T11:37:40.998261206-05:00 +updated: 2016-11-29T14:56:31.55726541-07:00 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -41,6 +41,10 @@ imports: - health - httputil - timeutil +- name: github.com/cpuguy83/go-md2man + version: a65d4d2de4d5f7c74868dfa9b202a3c8be315aaa + subpackages: + - md2man - name: github.com/davecgh/go-spew version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d subpackages: @@ -201,17 +205,23 @@ imports: - name: github.com/Masterminds/semver version: 52edfc04e184ecf0962489d167b511b27aeebd61 - name: github.com/Masterminds/sprig - version: 3fb136ad254dd34998b95f8d523b09a0dafa31b5 + version: 8f797f5b23118d8fe846c4296b0ad55044201b14 - name: github.com/mattn/go-runewidth version: d6bea18f789704b5f83375793155289da36a3c7f - name: github.com/pborman/uuid version: ca53cad383cad2479bbba7f7a1a05797ec1386e4 +- name: github.com/russross/blackfriday + version: 300106c228d52c8941d4b3de6054a6062a86dda3 - name: github.com/satori/go.uuid version: 879c5887cd475cd7864858769793b2ceb0d44feb +- name: github.com/shurcooL/sanitized_anchor_name + version: 10ef21a441db47d8b13ebcc5fd2310f636973c77 - name: github.com/Sirupsen/logrus version: 51fe59aca108dc5680109e7b2051cbdcfa5a253c - name: github.com/spf13/cobra version: 6a8bd97bdb1fc0d08a83459940498ea49d3e8c93 + subpackages: + - doc - name: github.com/spf13/pflag version: 367864438f1b1a3c7db4da06a2f55b144e6784e0 - name: github.com/technosophos/moniker @@ -263,7 +273,7 @@ imports: - internal/urlfetch - urlfetch - name: google.golang.org/grpc - version: 0032a855ba5c8a3c8e0d71c2deef354b70af1584 + version: b7f1379d3cbbbeb2ca3405852012e237aa05459e subpackages: - codes - credentials diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go index 5e5e118b9..74c4b4942 100644 --- a/pkg/tiller/release_server_test.go +++ b/pkg/tiller/release_server_test.go @@ -1302,3 +1302,4 @@ func (l *mockListServer) SendMsg(v interface{}) error { return nil } func (l *mockListServer) RecvMsg(v interface{}) error { return nil } func (l *mockListServer) SendHeader(m metadata.MD) error { return nil } func (l *mockListServer) SetTrailer(m metadata.MD) {} +func (l *mockListServer) SetHeader(m metadata.MD) error { return nil } diff --git a/scripts/completions.bash b/scripts/completions.bash new file mode 100644 index 000000000..d307b3300 --- /dev/null +++ b/scripts/completions.bash @@ -0,0 +1,1200 @@ +# bash completion for helm -*- shell-script -*- + +__debug() +{ + if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then + echo "$*" >> "${BASH_COMP_DEBUG_FILE}" + fi +} + +# Homebrew on Macs have version 1.3 of bash-completion which doesn't include +# _init_completion. This is a very minimal version of that function. +__my_init_completion() +{ + COMPREPLY=() + _get_comp_words_by_ref "$@" cur prev words cword +} + +__index_of_word() +{ + local w word=$1 + shift + index=0 + for w in "$@"; do + [[ $w = "$word" ]] && return + index=$((index+1)) + done + index=-1 +} + +__contains_word() +{ + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done + return 1 +} + +__handle_reply() +{ + __debug "${FUNCNAME[0]}" + case $cur in + -*) + if [[ $(type -t compopt) = "builtin" ]]; then + compopt -o nospace + fi + local allflags + if [ ${#must_have_one_flag[@]} -ne 0 ]; then + allflags=("${must_have_one_flag[@]}") + else + allflags=("${flags[*]} ${two_word_flags[*]}") + fi + COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") ) + if [[ $(type -t compopt) = "builtin" ]]; then + [[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace + fi + + # complete after --flag=abc + if [[ $cur == *=* ]]; then + if [[ $(type -t compopt) = "builtin" ]]; then + compopt +o nospace + fi + + local index flag + flag="${cur%%=*}" + __index_of_word "${flag}" "${flags_with_completion[@]}" + if [[ ${index} -ge 0 ]]; then + COMPREPLY=() + PREFIX="" + cur="${cur#*=}" + ${flags_completion[${index}]} + if [ -n "${ZSH_VERSION}" ]; then + # zfs completion needs --flag= prefix + eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )" + fi + fi + fi + return 0; + ;; + esac + + # check if we are handling a flag with special work handling + local index + __index_of_word "${prev}" "${flags_with_completion[@]}" + if [[ ${index} -ge 0 ]]; then + ${flags_completion[${index}]} + return + fi + + # we are parsing a flag and don't have a special handler, no completion + if [[ ${cur} != "${words[cword]}" ]]; then + return + fi + + local completions + completions=("${commands[@]}") + if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then + completions=("${must_have_one_noun[@]}") + fi + if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then + completions+=("${must_have_one_flag[@]}") + fi + COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") ) + + if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then + COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") ) + fi + + if [[ ${#COMPREPLY[@]} -eq 0 ]]; then + declare -F __custom_func >/dev/null && __custom_func + fi + + __ltrim_colon_completions "$cur" +} + +# The arguments should be in the form "ext1|ext2|extn" +__handle_filename_extension_flag() +{ + local ext="$1" + _filedir "@(${ext})" +} + +__handle_subdirs_in_dir_flag() +{ + local dir="$1" + pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 +} + +__handle_flag() +{ + __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" + + # if a command required a flag, and we found it, unset must_have_one_flag() + local flagname=${words[c]} + local flagvalue + # if the word contained an = + if [[ ${words[c]} == *"="* ]]; then + flagvalue=${flagname#*=} # take in as flagvalue after the = + flagname=${flagname%%=*} # strip everything after the = + flagname="${flagname}=" # but put the = back + fi + __debug "${FUNCNAME[0]}: looking for ${flagname}" + if __contains_word "${flagname}" "${must_have_one_flag[@]}"; then + must_have_one_flag=() + fi + + # if you set a flag which only applies to this command, don't show subcommands + if __contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then + commands=() + fi + + # keep flag value with flagname as flaghash + if [ -n "${flagvalue}" ] ; then + flaghash[${flagname}]=${flagvalue} + elif [ -n "${words[ $((c+1)) ]}" ] ; then + flaghash[${flagname}]=${words[ $((c+1)) ]} + else + flaghash[${flagname}]="true" # pad "true" for bool flag + fi + + # skip the argument to a two word flag + if __contains_word "${words[c]}" "${two_word_flags[@]}"; then + c=$((c+1)) + # if we are looking for a flags value, don't show commands + if [[ $c -eq $cword ]]; then + commands=() + fi + fi + + c=$((c+1)) + +} + +__handle_noun() +{ + __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" + + if __contains_word "${words[c]}" "${must_have_one_noun[@]}"; then + must_have_one_noun=() + elif __contains_word "${words[c]}" "${noun_aliases[@]}"; then + must_have_one_noun=() + fi + + nouns+=("${words[c]}") + c=$((c+1)) +} + +__handle_command() +{ + __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" + + local next_command + if [[ -n ${last_command} ]]; then + next_command="_${last_command}_${words[c]//:/__}" + else + if [[ $c -eq 0 ]]; then + next_command="_$(basename "${words[c]//:/__}")" + else + next_command="_${words[c]//:/__}" + fi + fi + c=$((c+1)) + __debug "${FUNCNAME[0]}: looking for ${next_command}" + declare -F $next_command >/dev/null && $next_command +} + +__handle_word() +{ + if [[ $c -ge $cword ]]; then + __handle_reply + return + fi + __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}" + if [[ "${words[c]}" == -* ]]; then + __handle_flag + elif __contains_word "${words[c]}" "${commands[@]}"; then + __handle_command + elif [[ $c -eq 0 ]] && __contains_word "$(basename "${words[c]}")" "${commands[@]}"; then + __handle_command + else + __handle_noun + fi + __handle_word +} + +_helm_create() +{ + last_command="helm_create" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_delete() +{ + last_command="helm_delete" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--dry-run") + local_nonpersistent_flags+=("--dry-run") + flags+=("--no-hooks") + local_nonpersistent_flags+=("--no-hooks") + flags+=("--purge") + local_nonpersistent_flags+=("--purge") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_dependency_build() +{ + last_command="helm_dependency_build" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--keyring=") + local_nonpersistent_flags+=("--keyring=") + flags+=("--verify") + local_nonpersistent_flags+=("--verify") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_dependency_list() +{ + last_command="helm_dependency_list" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_dependency_update() +{ + last_command="helm_dependency_update" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--keyring=") + local_nonpersistent_flags+=("--keyring=") + flags+=("--verify") + local_nonpersistent_flags+=("--verify") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_dependency() +{ + last_command="helm_dependency" + commands=() + commands+=("build") + commands+=("list") + commands+=("update") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_fetch() +{ + last_command="helm_fetch" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--destination=") + two_word_flags+=("-d") + local_nonpersistent_flags+=("--destination=") + flags+=("--keyring=") + local_nonpersistent_flags+=("--keyring=") + flags+=("--untar") + local_nonpersistent_flags+=("--untar") + flags+=("--untardir=") + local_nonpersistent_flags+=("--untardir=") + flags+=("--verify") + local_nonpersistent_flags+=("--verify") + flags+=("--version=") + local_nonpersistent_flags+=("--version=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_get_hooks() +{ + last_command="helm_get_hooks" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--revision=") + local_nonpersistent_flags+=("--revision=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_get_manifest() +{ + last_command="helm_get_manifest" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--revision=") + local_nonpersistent_flags+=("--revision=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_get_values() +{ + last_command="helm_get_values" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--all") + flags+=("-a") + local_nonpersistent_flags+=("--all") + flags+=("--revision=") + local_nonpersistent_flags+=("--revision=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_get() +{ + last_command="helm_get" + commands=() + commands+=("hooks") + commands+=("manifest") + commands+=("values") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--revision=") + local_nonpersistent_flags+=("--revision=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_history() +{ + last_command="helm_history" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--max=") + local_nonpersistent_flags+=("--max=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_home() +{ + last_command="helm_home" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_init() +{ + last_command="helm_init" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--canary-image") + local_nonpersistent_flags+=("--canary-image") + flags+=("--client-only") + flags+=("-c") + local_nonpersistent_flags+=("--client-only") + flags+=("--dry-run") + local_nonpersistent_flags+=("--dry-run") + flags+=("--tiller-image=") + two_word_flags+=("-i") + local_nonpersistent_flags+=("--tiller-image=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_inspect_chart() +{ + last_command="helm_inspect_chart" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--keyring=") + local_nonpersistent_flags+=("--keyring=") + flags+=("--verify") + local_nonpersistent_flags+=("--verify") + flags+=("--version=") + local_nonpersistent_flags+=("--version=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_inspect_values() +{ + last_command="helm_inspect_values" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--keyring=") + local_nonpersistent_flags+=("--keyring=") + flags+=("--verify") + local_nonpersistent_flags+=("--verify") + flags+=("--version=") + local_nonpersistent_flags+=("--version=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_inspect() +{ + last_command="helm_inspect" + commands=() + commands+=("chart") + commands+=("values") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--keyring=") + local_nonpersistent_flags+=("--keyring=") + flags+=("--verify") + local_nonpersistent_flags+=("--verify") + flags+=("--version=") + local_nonpersistent_flags+=("--version=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_install() +{ + last_command="helm_install" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--dry-run") + local_nonpersistent_flags+=("--dry-run") + flags+=("--keyring=") + local_nonpersistent_flags+=("--keyring=") + flags+=("--name=") + two_word_flags+=("-n") + local_nonpersistent_flags+=("--name=") + flags+=("--name-template=") + local_nonpersistent_flags+=("--name-template=") + flags+=("--namespace=") + local_nonpersistent_flags+=("--namespace=") + flags+=("--no-hooks") + local_nonpersistent_flags+=("--no-hooks") + flags+=("--replace") + local_nonpersistent_flags+=("--replace") + flags+=("--set=") + local_nonpersistent_flags+=("--set=") + flags+=("--values=") + two_word_flags+=("-f") + local_nonpersistent_flags+=("--values=") + flags+=("--verify") + local_nonpersistent_flags+=("--verify") + flags+=("--version=") + local_nonpersistent_flags+=("--version=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_lint() +{ + last_command="helm_lint" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--strict") + local_nonpersistent_flags+=("--strict") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_list() +{ + last_command="helm_list" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--all") + local_nonpersistent_flags+=("--all") + flags+=("--date") + flags+=("-d") + local_nonpersistent_flags+=("--date") + flags+=("--deleted") + local_nonpersistent_flags+=("--deleted") + flags+=("--deployed") + local_nonpersistent_flags+=("--deployed") + flags+=("--failed") + local_nonpersistent_flags+=("--failed") + flags+=("--max=") + two_word_flags+=("-m") + local_nonpersistent_flags+=("--max=") + flags+=("--offset=") + two_word_flags+=("-o") + local_nonpersistent_flags+=("--offset=") + flags+=("--reverse") + flags+=("-r") + local_nonpersistent_flags+=("--reverse") + flags+=("--short") + flags+=("-q") + local_nonpersistent_flags+=("--short") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_package() +{ + last_command="helm_package" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--key=") + local_nonpersistent_flags+=("--key=") + flags+=("--keyring=") + local_nonpersistent_flags+=("--keyring=") + flags+=("--save") + local_nonpersistent_flags+=("--save") + flags+=("--sign") + local_nonpersistent_flags+=("--sign") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_repo_add() +{ + last_command="helm_repo_add" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--no-update") + local_nonpersistent_flags+=("--no-update") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_repo_index() +{ + last_command="helm_repo_index" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--merge=") + local_nonpersistent_flags+=("--merge=") + flags+=("--url=") + local_nonpersistent_flags+=("--url=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_repo_list() +{ + last_command="helm_repo_list" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_repo_remove() +{ + last_command="helm_repo_remove" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_repo_update() +{ + last_command="helm_repo_update" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_repo() +{ + last_command="helm_repo" + commands=() + commands+=("add") + commands+=("index") + commands+=("list") + commands+=("remove") + commands+=("update") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_rollback() +{ + last_command="helm_rollback" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--dry-run") + local_nonpersistent_flags+=("--dry-run") + flags+=("--no-hooks") + local_nonpersistent_flags+=("--no-hooks") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_search() +{ + last_command="helm_search" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--regexp") + flags+=("-r") + local_nonpersistent_flags+=("--regexp") + flags+=("--versions") + flags+=("-l") + local_nonpersistent_flags+=("--versions") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_serve() +{ + last_command="helm_serve" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--address=") + local_nonpersistent_flags+=("--address=") + flags+=("--repo-path=") + local_nonpersistent_flags+=("--repo-path=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_status() +{ + last_command="helm_status" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--revision=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_upgrade() +{ + last_command="helm_upgrade" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--disable-hooks") + local_nonpersistent_flags+=("--disable-hooks") + flags+=("--dry-run") + local_nonpersistent_flags+=("--dry-run") + flags+=("--install") + flags+=("-i") + local_nonpersistent_flags+=("--install") + flags+=("--keyring=") + local_nonpersistent_flags+=("--keyring=") + flags+=("--namespace=") + local_nonpersistent_flags+=("--namespace=") + flags+=("--set=") + local_nonpersistent_flags+=("--set=") + flags+=("--values=") + two_word_flags+=("-f") + local_nonpersistent_flags+=("--values=") + flags+=("--verify") + local_nonpersistent_flags+=("--verify") + flags+=("--version=") + local_nonpersistent_flags+=("--version=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_verify() +{ + last_command="helm_verify" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--keyring=") + local_nonpersistent_flags+=("--keyring=") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm_version() +{ + last_command="helm_version" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--client") + flags+=("-c") + local_nonpersistent_flags+=("--client") + flags+=("--server") + flags+=("-s") + local_nonpersistent_flags+=("--server") + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +_helm() +{ + last_command="helm" + commands=() + commands+=("create") + commands+=("delete") + commands+=("dependency") + commands+=("fetch") + commands+=("get") + commands+=("history") + commands+=("home") + commands+=("init") + commands+=("inspect") + commands+=("install") + commands+=("lint") + commands+=("list") + commands+=("package") + commands+=("repo") + commands+=("rollback") + commands+=("search") + commands+=("serve") + commands+=("status") + commands+=("upgrade") + commands+=("verify") + commands+=("version") + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--debug") + flags+=("--home=") + flags+=("--host=") + flags+=("--kube-context=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + +__start_helm() +{ + local cur prev words cword + declare -A flaghash 2>/dev/null || : + if declare -F _init_completion >/dev/null 2>&1; then + _init_completion -s || return + else + __my_init_completion -n "=" || return + fi + + local c=0 + local flags=() + local two_word_flags=() + local local_nonpersistent_flags=() + local flags_with_completion=() + local flags_completion=() + local commands=("helm") + local must_have_one_flag=() + local must_have_one_noun=() + local last_command + local nouns=() + + __handle_word +} + +if [[ $(type -t compopt) = "builtin" ]]; then + complete -o default -F __start_helm helm +else + complete -o default -o nospace -F __start_helm helm +fi + +# ex: ts=4 sw=4 et filetype=sh From 5f3d255ecd1f9d7bdd33310e217e67cec9e54914 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Tue, 29 Nov 2016 16:58:55 -0700 Subject: [PATCH 11/39] fix(helm): pass the no-hooks flag during upgrade Helm upgrades were not passing the no-hooks value to the server. Closes #1590 --- cmd/helm/upgrade.go | 7 ++++++- pkg/helm/client.go | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 076b57ca5..d55a8013f 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -135,7 +135,12 @@ func (u *upgradeCmd) run() error { return err } - _, err = u.client.UpdateRelease(u.release, chartPath, helm.UpdateValueOverrides(rawVals), helm.UpgradeDryRun(u.dryRun), helm.UpgradeDisableHooks(u.disableHooks)) + _, err = u.client.UpdateRelease( + u.release, + chartPath, + helm.UpdateValueOverrides(rawVals), + helm.UpgradeDryRun(u.dryRun), + helm.UpgradeDisableHooks(u.disableHooks)) if err != nil { return fmt.Errorf("UPGRADE FAILED: %v", prettyError(err)) } diff --git a/pkg/helm/client.go b/pkg/helm/client.go index a39b8c170..5ae781328 100644 --- a/pkg/helm/client.go +++ b/pkg/helm/client.go @@ -132,6 +132,7 @@ func (h *Client) UpdateRelease(rlsName string, chstr string, opts ...UpdateOptio req.Chart = chart req.DryRun = h.opts.dryRun req.Name = rlsName + req.DisableHooks = h.opts.disableHooks ctx := NewContext() if h.opts.before != nil { From 2c326895b7d5c451ffec24403bc19132fd981031 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Tue, 29 Nov 2016 17:15:12 -0700 Subject: [PATCH 12/39] fix(helm): fix doc string for ErrNotList This just moves a var declaration to the top of a file and then properly documents it. --- cmd/helm/strvals/parser.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/helm/strvals/parser.go b/cmd/helm/strvals/parser.go index e63efa3e9..c4f35e11d 100644 --- a/cmd/helm/strvals/parser.go +++ b/cmd/helm/strvals/parser.go @@ -26,6 +26,9 @@ import ( "github.com/ghodss/yaml" ) +// ErrNotList indicates that a non-list was treated as a list. +var ErrNotList = errors.New("not a list") + // ToYAML takes a string of arguments and converts to a YAML document. func ToYAML(s string) (string, error) { m, err := Parse(s) @@ -156,8 +159,6 @@ func (t *parser) val() ([]rune, error) { return v, err } -var ErrNotList = errors.New("not a list") - func (t *parser) valList() ([]interface{}, error) { r, _, e := t.sc.ReadRune() From 6b25f85dee2a5ae12a634e91d8fe6e1b40b816fe Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Tue, 29 Nov 2016 17:28:59 -0700 Subject: [PATCH 13/39] fix(Makefile): build windows amd64 binaries This adds back support for Windows now that it has been tested by the community. Closes #1596 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d311e35d2..d5d53f30e 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ DOCKER_REGISTRY ?= gcr.io IMAGE_PREFIX ?= kubernetes-helm SHORT_NAME ?= tiller -TARGETS = darwin/amd64 linux/amd64 linux/386 +TARGETS = darwin/amd64 linux/amd64 linux/386 windows/amd64 DIST_DIRS = find * -type d -exec # go option From a59604f40a87887942d90d754d1ebc7b6ed77b44 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Wed, 30 Nov 2016 10:26:33 -0700 Subject: [PATCH 14/39] fix(helm): improve URL comparison logic Normalize URLs before comparing them. This deviates slightly from the URL spec, but in order to accomodate the predominant use pattern for Helm. Specifically, './', '../', and '/' are all "interpreted" to be filepath-like. Closes #1588 --- cmd/helm/downloader/manager.go | 9 +++++++++ cmd/helm/downloader/manager_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/cmd/helm/downloader/manager.go b/cmd/helm/downloader/manager.go index db3d3c4f0..f7bd08657 100644 --- a/cmd/helm/downloader/manager.go +++ b/cmd/helm/downloader/manager.go @@ -313,6 +313,8 @@ func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) { func urlsAreEqual(a, b string) bool { au, err := url.Parse(a) if err != nil { + a = filepath.Clean(a) + b = filepath.Clean(b) // If urls are paths, return true only if they are an exact match return a == b } @@ -320,6 +322,13 @@ func urlsAreEqual(a, b string) bool { if err != nil { return false } + + for _, u := range []*url.URL{au, bu} { + if u.Path == "" { + u.Path = "/" + } + u.Path = filepath.Clean(u.Path) + } return au.String() == bu.String() } diff --git a/cmd/helm/downloader/manager_test.go b/cmd/helm/downloader/manager_test.go index 7224ccc41..7cfcca4ed 100644 --- a/cmd/helm/downloader/manager_test.go +++ b/cmd/helm/downloader/manager_test.go @@ -135,3 +135,27 @@ func TestGetRepoNames(t *testing.T) { } } } + +func TestUrlsAreEqual(t *testing.T) { + for _, tt := range []struct { + a, b string + match bool + }{ + {"http://example.com", "http://example.com", true}, + {"http://example.com", "http://another.example.com", false}, + {"https://example.com", "https://example.com", true}, + {"http://example.com/", "http://example.com", true}, + {"https://example.com", "http://example.com", false}, + {"http://example.com/foo", "http://example.com/foo/", true}, + {"http://example.com/foo//", "http://example.com/foo/", true}, + {"http://example.com/./foo/", "http://example.com/foo/", true}, + {"http://example.com/bar/../foo/", "http://example.com/foo/", true}, + {"/foo", "/foo", true}, + {"/foo", "/foo/", true}, + {"/foo/.", "/foo/", true}, + } { + if tt.match != urlsAreEqual(tt.a, tt.b) { + t.Errorf("Expected %q==%q to be %t", tt.a, tt.b, tt.match) + } + } +} From ba7910082a52b60d66d6ac82fbc4a8405639c0da Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Wed, 30 Nov 2016 11:37:59 -0700 Subject: [PATCH 15/39] fix(helm): add no-hooks to upgrade Mark disable-hooks as deprecated. Closes #1575 --- cmd/helm/upgrade.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index d55a8013f..950c48c71 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -87,13 +87,16 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command { f.StringVarP(&upgrade.valuesFile, "values", "f", "", "path to a values YAML file") f.BoolVar(&upgrade.dryRun, "dry-run", false, "simulate an upgrade") f.StringVar(&upgrade.values, "set", "", "set values on the command line. Separate values with commas: key1=val1,key2=val2") - f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade 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.verify, "verify", false, "verify the provenance of the chart before upgrading") f.StringVar(&upgrade.keyring, "keyring", defaultKeyring(), "path to the keyring that contains public singing keys") f.BoolVarP(&upgrade.install, "install", "i", false, "if a release by this name doesn't already exist, run an install") f.StringVar(&upgrade.namespace, "namespace", "default", "namespace to install the release into (only used if --install is set)") f.StringVar(&upgrade.version, "version", "", "specify the exact chart version to use. If this is not specified, the latest version is used") + f.MarkDeprecated("disable-hooks", "use --no-hooks instead") + return cmd } From 18248e553034905713d39e22b5f35cb8c88335bc Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Tue, 29 Nov 2016 17:55:05 -0700 Subject: [PATCH 16/39] feat(helm): add 'helm fetch --prov' to fetch prov info Previously, there was no way to get provenance data unless you were verifying it. This allows `fetch` to get the provenance data, but not perform any verification. Adding this will allow external plugins to perform verification against other sources, like Keybase. --- cmd/helm/downloader/chart_downloader.go | 17 +++++--- cmd/helm/downloader/chart_downloader_test.go | 44 ++++++++++++++++++++ cmd/helm/fetch.go | 8 +++- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/cmd/helm/downloader/chart_downloader.go b/cmd/helm/downloader/chart_downloader.go index 84def6cd0..350ccb6c0 100644 --- a/cmd/helm/downloader/chart_downloader.go +++ b/cmd/helm/downloader/chart_downloader.go @@ -44,6 +44,10 @@ const ( // VerifyAlways will always attempt a verification, and will fail if the // verification fails. VerifyAlways + // VerifyLater will fetch verification data, but not do any verification. + // This is to accommodate the case where another step of the process will + // perform verification. + VerifyLater ) // ChartDownloader handles downloading a chart. @@ -65,6 +69,7 @@ type ChartDownloader struct { // If Verify is set to VerifyNever, the verification will be nil. // If Verify is set to VerifyIfPossible, this will return a verification (or nil on failure), and print a warning on failure. // If Verify is set to VerifyAlways, this will return a verification or an error if the verification fails. +// If Verify is set to VerifyLater, this will download the prov file (if it exists), but not verify it. // // For VerifyNever and VerifyIfPossible, the Verification may be empty. // @@ -104,11 +109,13 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven return destfile, nil, err } - ver, err = VerifyChart(destfile, c.Keyring) - if err != nil { - // Fail always in this case, since it means the verification step - // failed. - return destfile, ver, err + if c.Verify != VerifyLater { + ver, err = VerifyChart(destfile, c.Keyring) + if err != nil { + // Fail always in this case, since it means the verification step + // failed. + return destfile, ver, err + } } } return destfile, ver, nil diff --git a/cmd/helm/downloader/chart_downloader_test.go b/cmd/helm/downloader/chart_downloader_test.go index d2cf191f9..0d9144fda 100644 --- a/cmd/helm/downloader/chart_downloader_test.go +++ b/cmd/helm/downloader/chart_downloader_test.go @@ -153,3 +153,47 @@ func TestDownloadTo(t *testing.T) { return } } + +func TestDownloadTo_VerifyLater(t *testing.T) { + hh, err := ioutil.TempDir("", "helm-downloadto-") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(hh) + + dest := filepath.Join(hh, "dest") + os.MkdirAll(dest, 0755) + + // Set up a fake repo + srv := repotest.NewServer(hh) + defer srv.Stop() + if _, err := srv.CopyCharts("testdata/*.tgz*"); err != nil { + t.Error(err) + return + } + + c := ChartDownloader{ + HelmHome: helmpath.Home("testdata/helmhome"), + Out: os.Stderr, + Verify: VerifyLater, + } + cname := "/signtest-0.1.0.tgz" + where, _, err := c.DownloadTo(srv.URL()+cname, "", dest) + if err != nil { + t.Error(err) + return + } + + if expect := filepath.Join(dest, cname); where != expect { + t.Errorf("Expected download to %s, got %s", expect, where) + } + + if _, err := os.Stat(filepath.Join(dest, cname)); err != nil { + t.Error(err) + return + } + if _, err := os.Stat(filepath.Join(dest, cname+".prov")); err != nil { + t.Error(err) + return + } +} diff --git a/cmd/helm/fetch.go b/cmd/helm/fetch.go index c67b4714a..cd729e64c 100644 --- a/cmd/helm/fetch.go +++ b/cmd/helm/fetch.go @@ -51,8 +51,9 @@ type fetchCmd struct { destdir string version string - verify bool - keyring string + verify bool + verifyLater bool + keyring string out io.Writer } @@ -82,6 +83,7 @@ func newFetchCmd(out io.Writer) *cobra.Command { f.BoolVar(&fch.untar, "untar", false, "if set to true, will untar the chart after downloading it") f.StringVar(&fch.untardir, "untardir", ".", "if untar is specified, this flag specifies the name of the directory into which the chart is expanded") f.BoolVar(&fch.verify, "verify", false, "verify the package against its signature") + f.BoolVar(&fch.verifyLater, "prov", false, "fetch the provenance file, but don't perform verification") f.StringVar(&fch.version, "version", "", "specific version of a chart. Without this, the latest version is fetched") f.StringVar(&fch.keyring, "keyring", defaultKeyring(), "keyring containing public keys") f.StringVarP(&fch.destdir, "destination", "d", ".", "location to write the chart. If this and tardir are specified, tardir is appended to this") @@ -100,6 +102,8 @@ func (f *fetchCmd) run() error { if f.verify { c.Verify = downloader.VerifyAlways + } else if f.verifyLater { + c.Verify = downloader.VerifyLater } // If untar is set, we fetch to a tempdir, then untar and copy after From c340c04e210cabef7b89867444a1f67da7fa235b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Armesto?= Date: Wed, 30 Nov 2016 23:00:57 +0100 Subject: [PATCH 17/39] Remove trailing slash (if any) from repo url --- cmd/helm/repo_add.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/helm/repo_add.go b/cmd/helm/repo_add.go index 414e962fa..d36b48488 100644 --- a/cmd/helm/repo_add.go +++ b/cmd/helm/repo_add.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "path/filepath" + "strings" "github.com/spf13/cobra" @@ -95,7 +96,7 @@ func insertRepoLine(name, url string, home helmpath.Home) error { } f.Add(&repo.Entry{ Name: name, - URL: url, + URL: strings.TrimSuffix(url, "/"), Cache: filepath.Base(cif), }) return f.WriteFile(home.RepositoryFile(), 0644) From 4bc0f816767a31710a8e69d81c06d1be173f96f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Armesto?= Date: Wed, 30 Nov 2016 23:14:11 +0100 Subject: [PATCH 18/39] Remove trailing slash when comparing dependency url with repo url --- cmd/helm/downloader/manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/downloader/manager.go b/cmd/helm/downloader/manager.go index db3d3c4f0..6ef4804b4 100644 --- a/cmd/helm/downloader/manager.go +++ b/cmd/helm/downloader/manager.go @@ -226,7 +226,7 @@ func (m *Manager) hasAllRepos(deps []*chartutil.Dependency) error { found = true } else { for _, repo := range repos { - if urlsAreEqual(repo.URL, dd.Repository) { + if urlsAreEqual(repo.URL, strings.TrimSuffix(dd.Repository, "/")) { found = true } } From dcc2bc598a74f4ed8a2c81dd6696cf4fd5510832 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Wed, 30 Nov 2016 16:57:04 -0700 Subject: [PATCH 19/39] fix(helm): handle errors when plugin command is not found If a 'command:' is not found for a plugin, it will not result in an ExitError, but in a PathError. This prevents that condition from panicing. Closes #1609 --- cmd/helm/plugins.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cmd/helm/plugins.go b/cmd/helm/plugins.go index a9a4383f5..d0f317a4b 100644 --- a/cmd/helm/plugins.go +++ b/cmd/helm/plugins.go @@ -78,9 +78,11 @@ func loadPlugins(baseCmd *cobra.Command, home helmpath.Home, out io.Writer) { prog.Stdout = out prog.Stderr = os.Stderr if err := prog.Run(); err != nil { - eerr := err.(*exec.ExitError) - os.Stderr.Write(eerr.Stderr) - return fmt.Errorf("plugin %q exited with error", md.Name) + if eerr, ok := err.(*exec.ExitError); ok { + os.Stderr.Write(eerr.Stderr) + return fmt.Errorf("plugin %q exited with error", md.Name) + } + return err } return nil }, From 6050a4bcfe66a6eaa13c3da33740f12a61b1fb4c Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Wed, 30 Nov 2016 20:14:31 -0800 Subject: [PATCH 20/39] fix(helm): add missing line ending on list output --- cmd/helm/list.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/helm/list.go b/cmd/helm/list.go index dba2dfde6..3168c4c08 100644 --- a/cmd/helm/list.go +++ b/cmd/helm/list.go @@ -142,8 +142,8 @@ func (l *listCmd) run() error { return nil } - if res.Next != "" { - fmt.Fprintf(l.out, "\tnext: %s", res.Next) + if res.Next != "" && !l.short { + fmt.Fprintf(l.out, "\tnext: %s\n", res.Next) } rels := res.Releases From 803475c82463795fc1c6f4388c021285f14d1cbe Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Wed, 30 Nov 2016 20:22:59 -0800 Subject: [PATCH 21/39] fix(*): misc linter issues --- cmd/helm/package.go | 4 ++-- cmd/helm/strvals/parser.go | 4 +--- pkg/kube/client.go | 2 +- pkg/kube/tunnel.go | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cmd/helm/package.go b/cmd/helm/package.go index f9cf4cdbc..d59d5cba9 100644 --- a/cmd/helm/package.go +++ b/cmd/helm/package.go @@ -166,7 +166,7 @@ func (p *packageCmd) clearsign(filename string) error { // promptUser implements provenance.PassphraseFetcher func promptUser(name string) ([]byte, error) { fmt.Printf("Password for key %q > ", name) - pw, err := terminal.ReadPassword(int(syscall.Stdin)) + pw, err := terminal.ReadPassword(syscall.Stdin) fmt.Println() - return []byte(pw), err + return pw, err } diff --git a/cmd/helm/strvals/parser.go b/cmd/helm/strvals/parser.go index c4f35e11d..c4859ad39 100644 --- a/cmd/helm/strvals/parser.go +++ b/cmd/helm/strvals/parser.go @@ -153,14 +153,12 @@ func set(data map[string]interface{}, key string, val interface{}) { } func (t *parser) val() ([]rune, error) { - v := []rune{} stop := runeSet([]rune{','}) v, _, err := runesUntil(t.sc, stop) return v, err } func (t *parser) valList() ([]interface{}, error) { - r, _, e := t.sc.ReadRune() if e != nil { return []interface{}{}, e @@ -193,7 +191,7 @@ func (t *parser) valList() ([]interface{}, error) { } } -func runesUntil(in *bytes.Buffer, stop map[rune]bool) ([]rune, rune, error) { +func runesUntil(in io.RuneReader, stop map[rune]bool) ([]rune, rune, error) { v := []rune{} for { switch r, _, e := in.ReadRune(); { diff --git a/pkg/kube/client.go b/pkg/kube/client.go index d74a1d030..e76ed5180 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -443,7 +443,7 @@ func getCurrentObject(target *resource.Info, infos []*resource.Info) (runtime.Ob if found, ok := findMatchingInfo(target, infos); ok { return found.Mapping.ConvertToVersion(found.Object, found.Mapping.GroupVersionKind.GroupVersion()) } - return nil, fmt.Errorf("No resource with the name %s found.", target.Name) + return nil, fmt.Errorf("no resource with the name %s found", target.Name) } // isMatchingInfo returns true if infos match on Name and Kind. diff --git a/pkg/kube/tunnel.go b/pkg/kube/tunnel.go index 622f2682e..a93c0384b 100644 --- a/pkg/kube/tunnel.go +++ b/pkg/kube/tunnel.go @@ -96,7 +96,7 @@ func (t *Tunnel) ForwardPort() error { select { case err = <-errChan: - return fmt.Errorf("Error forwarding ports: %v\n", err) + return fmt.Errorf("forwarding ports: %v", err) case <-pf.Ready: return nil } From aa4732089f49834d988827839fb034e71b476e07 Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Wed, 30 Nov 2016 22:14:15 -0800 Subject: [PATCH 22/39] chore(*): bump go1.7.3 --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index 5e214f34b..33120b0d6 100644 --- a/circle.yml +++ b/circle.yml @@ -3,7 +3,7 @@ machine: - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0 environment: - GOVERSION: "1.7.1" + GOVERSION: "1.7.3" GOPATH: "${HOME}/.go_workspace" WORKDIR: "${GOPATH}/src/k8s.io/helm" PROJECT_NAME: "kubernetes-helm" From e8eed3cc3eddb45398d6fb41a5931805af63e185 Mon Sep 17 00:00:00 2001 From: Rollulus Date: Thu, 1 Dec 2016 13:42:53 +0100 Subject: [PATCH 23/39] fix(helm): write yaml with non-exec permission --- pkg/chartutil/chartfile.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/chartutil/chartfile.go b/pkg/chartutil/chartfile.go index 27b8364df..ea40f5706 100644 --- a/pkg/chartutil/chartfile.go +++ b/pkg/chartutil/chartfile.go @@ -56,5 +56,5 @@ func SaveChartfile(filename string, cf *chart.Metadata) error { if err != nil { return err } - return ioutil.WriteFile(filename, out, 0755) + return ioutil.WriteFile(filename, out, 0644) } From 2de1728f058adde13a3df3d0975c468924227665 Mon Sep 17 00:00:00 2001 From: Andrew Stuart Date: Thu, 1 Dec 2016 09:09:46 -0700 Subject: [PATCH 24/39] feat(helm): Add Files.Glob method to permit file organization --- docs/chart_template_guide/accessing_files.md | 38 +++++++++++++++++++ glide.lock | 14 ++++++- glide.yaml | 2 + pkg/chartutil/files.go | 30 ++++++++++++++- pkg/chartutil/files_test.go | 39 ++++++++++++++------ 5 files changed, 108 insertions(+), 15 deletions(-) diff --git a/docs/chart_template_guide/accessing_files.md b/docs/chart_template_guide/accessing_files.md index e68ee22c9..5e276cb0b 100644 --- a/docs/chart_template_guide/accessing_files.md +++ b/docs/chart_template_guide/accessing_files.md @@ -9,6 +9,8 @@ Helm provides access to files through the `.Files` object. Before we get going w - Files in `templates/` cannot be accessed. - Charts to not preserve UNIX mode information, so file-level permissions will have no impact on the availability of a file when it comes to the `.Files` object. +## Basic example + With those caveats behind, let's write a template that reads three files into our ConfigMap. To get started, we will add three files to the chart, putting all three directly inside of the `mychart/` directory. `config1.toml`: @@ -65,6 +67,42 @@ data: message = Goodbye from config 3 ``` +As your chart grows, you may find you have a greater need to organize your +files more, and so we provide a `Files.Glob(pattern string)` method to assist +in extracting certain files however you need. + +For example, imagine the directory structure: + +``` +foo/: + foo.txt foo.yaml + +bar/: + bar.go bar.conf baz.yaml +``` + +## Glob patterns + +You have multiple options with Globs: + + +```yaml +{{ range $path := .Files.Glob "**.yaml" }} +{{ $path }}: | +{{ .Files.Get $path }} +{{ end }} +``` + +Or + +```yaml +{{ range $path, $bytes := .Files.Glob "foo/*" }} +{{ $path }}: '{{ b64enc $bytes }}' +{{ end }} +``` + +## Secrets + When working with a Secret resource, you can import a file and have the template base-64 encode it for you: ```yaml diff --git a/glide.lock b/glide.lock index d7b9736d1..837873285 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 89695daf5f2de706b79fdd8e8b095f9514f418c0fbcf80d7fdca4c208d114d19 -updated: 2016-11-29T14:56:31.55726541-07:00 +hash: 707ac6d1785d0029397f2f9a3b0bc45f7d8ce819f14f6c246967b0a404627a2c +updated: 2016-12-01T09:07:51.289370422-07:00 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -103,6 +103,16 @@ imports: version: 465937c80b3c07a7c7ad20cc934898646a91c1de - name: github.com/ghodss/yaml version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee +- name: github.com/gobwas/glob + version: 0354991b92587e2742549d3036f3b5bae5ab03f2 + subpackages: + - compiler + - match + - syntax + - syntax/ast + - syntax/lexer + - util/runes + - util/strings - name: github.com/gogo/protobuf version: e18d7aa8f8c624c915db340349aad4c49b10d173 subpackages: diff --git a/glide.yaml b/glide.yaml index ab2871485..487a3279a 100644 --- a/glide.yaml +++ b/glide.yaml @@ -49,3 +49,5 @@ import: - package: golang.org/x/crypto subpackages: - openpgp +- package: github.com/gobwas/glob + version: ^0.2.1 diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go index 89120a42f..3747776ba 100644 --- a/pkg/chartutil/files.go +++ b/pkg/chartutil/files.go @@ -16,6 +16,7 @@ limitations under the License. package chartutil import ( + "github.com/gobwas/glob" "github.com/golang/protobuf/ptypes/any" ) @@ -26,8 +27,10 @@ type Files map[string][]byte // Given an []*any.Any (the format for files in a chart.Chart), extract a map of files. func NewFiles(from []*any.Any) Files { files := map[string][]byte{} - for _, f := range from { - files[f.TypeUrl] = f.Value + if from != nil { + for _, f := range from { + files[f.TypeUrl] = f.Value + } } return files } @@ -56,3 +59,26 @@ func (f Files) GetBytes(name string) []byte { func (f Files) Get(name string) string { return string(f.GetBytes(name)) } + +// Glob takes a glob pattern and returns another files object only containing +// matched files. +// +// This is designed to be called from a template. +// {{ range $name, $content := .Files.Glob("foo/**") }} +// {{ $name }}: | +// {{ .Files.Get($name) | indent 4 }}{{ end }} +func (f Files) Glob(pattern string) Files { + g, err := glob.Compile(pattern, '/') + if err != nil { + g, _ = glob.Compile("**") + } + + nf := NewFiles(nil) + for name, contents := range f { + if g.Match(name) { + nf[name] = contents + } + } + + return nf +} diff --git a/pkg/chartutil/files_test.go b/pkg/chartutil/files_test.go index 5e162f19d..268ac1abd 100644 --- a/pkg/chartutil/files_test.go +++ b/pkg/chartutil/files_test.go @@ -21,23 +21,25 @@ import ( "github.com/golang/protobuf/ptypes/any" ) -func TestNewFiles(t *testing.T) { - - cases := []struct { - path, data string - }{ - {"ship/captain.txt", "The Captain"}, - {"ship/stowaway.txt", "Legatt"}, - {"story/name.txt", "The Secret Sharer"}, - {"story/author.txt", "Joseph Conrad"}, - } +var cases = []struct { + path, data string +}{ + {"ship/captain.txt", "The Captain"}, + {"ship/stowaway.txt", "Legatt"}, + {"story/name.txt", "The Secret Sharer"}, + {"story/author.txt", "Joseph Conrad"}, +} +func getTestFiles() []*any.Any { a := []*any.Any{} for _, c := range cases { a = append(a, &any.Any{TypeUrl: c.path, Value: []byte(c.data)}) } + return a +} - files := NewFiles(a) +func TestNewFiles(t *testing.T) { + files := NewFiles(getTestFiles()) if len(files) != len(cases) { t.Errorf("Expected len() = %d, got %d", len(cases), len(files)) } @@ -51,3 +53,18 @@ func TestNewFiles(t *testing.T) { } } } + +func TestFileGlob(t *testing.T) { + f := NewFiles(getTestFiles()) + + matched := f.Glob("story/**") + + if len(matched) != 2 { + t.Errorf("Expected two files in glob story/**, got %d", len(matched)) + } + + m, expect := matched.Get("story/author.txt"), "Joseph Conrad" + if m != expect { + t.Errorf("Wrong globbed file content. Expected %s, got %s", expect, m) + } +} From d07e5cdfb6fad29532974867282177e0c58fa1cf Mon Sep 17 00:00:00 2001 From: Andrew Stuart Date: Thu, 1 Dec 2016 11:02:51 -0700 Subject: [PATCH 25/39] Correct docs heading location --- docs/chart_template_guide/accessing_files.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/chart_template_guide/accessing_files.md b/docs/chart_template_guide/accessing_files.md index 5e276cb0b..8d380edd6 100644 --- a/docs/chart_template_guide/accessing_files.md +++ b/docs/chart_template_guide/accessing_files.md @@ -67,6 +67,8 @@ data: message = Goodbye from config 3 ``` +## Glob patterns + As your chart grows, you may find you have a greater need to organize your files more, and so we provide a `Files.Glob(pattern string)` method to assist in extracting certain files however you need. @@ -81,8 +83,6 @@ bar/: bar.go bar.conf baz.yaml ``` -## Glob patterns - You have multiple options with Globs: From c311b085d5ed554862ffe9ca894c53529ec543b1 Mon Sep 17 00:00:00 2001 From: Andrew Stuart Date: Thu, 1 Dec 2016 11:06:50 -0700 Subject: [PATCH 26/39] Improve language of glob explanation --- docs/chart_template_guide/accessing_files.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chart_template_guide/accessing_files.md b/docs/chart_template_guide/accessing_files.md index 8d380edd6..e14417fde 100644 --- a/docs/chart_template_guide/accessing_files.md +++ b/docs/chart_template_guide/accessing_files.md @@ -71,7 +71,7 @@ data: As your chart grows, you may find you have a greater need to organize your files more, and so we provide a `Files.Glob(pattern string)` method to assist -in extracting certain files however you need. +in extracting certain files with all the flexibility of [glob patterns](//godoc.org/github.com/gobwas/glob). For example, imagine the directory structure: From ec020a9e40ac34090590d73f59884223d2276792 Mon Sep 17 00:00:00 2001 From: Andrew Stuart Date: Thu, 1 Dec 2016 11:07:08 -0700 Subject: [PATCH 27/39] Improve formatting of godoc --- pkg/chartutil/files.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go index 3747776ba..ba07e5ebb 100644 --- a/pkg/chartutil/files.go +++ b/pkg/chartutil/files.go @@ -64,6 +64,7 @@ func (f Files) Get(name string) string { // matched files. // // This is designed to be called from a template. +// // {{ range $name, $content := .Files.Glob("foo/**") }} // {{ $name }}: | // {{ .Files.Get($name) | indent 4 }}{{ end }} From 052cfe164000cca9d37dc2a02386c0976cbb8995 Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Thu, 1 Dec 2016 10:37:40 -0800 Subject: [PATCH 28/39] fix(ci): do not push canary image on release --- scripts/ci/deploy.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/ci/deploy.sh b/scripts/ci/deploy.sh index edb69d239..6f8199a18 100755 --- a/scripts/ci/deploy.sh +++ b/scripts/ci/deploy.sh @@ -40,10 +40,7 @@ echo "Building the tiller image" make docker-build VERSION="${VERSION}" echo "Pushing image to gcr.io" -if [[ "${VERSION}" != "canary" ]]; then - docker push "gcr.io/kubernetes-helm/tiller:${VERSION}" -fi -docker push gcr.io/kubernetes-helm/tiller:canary +docker push "gcr.io/kubernetes-helm/tiller:${VERSION}" echo "Building helm binaries" make build-cross From a9f3de84e1a83aa0e0f250256e86e61ca9179d49 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Thu, 1 Dec 2016 12:50:41 -0700 Subject: [PATCH 29/39] fix(hel): fix plugin format on tests Test plugins were in the original format. Updated to current format and fixed the tests to stop silently ignoring the broken test. --- cmd/helm/plugins_test.go | 7 ++++++- cmd/helm/testdata/helmhome/plugins/{ => args}/args.sh | 0 .../helmhome/plugins/{args.yaml => args/plugin.yaml} | 2 +- .../helmhome/plugins/{echo.yaml => echo/plugin.yaml} | 0 .../helmhome/plugins/{env.yaml => env/plugin.yaml} | 0 .../testdata/helmhome/plugins/{ => fullenv}/fullenv.sh | 2 +- .../helmhome/plugins/{fullenv.yaml => fullenv/plugin.yaml} | 2 +- 7 files changed, 9 insertions(+), 4 deletions(-) rename cmd/helm/testdata/helmhome/plugins/{ => args}/args.sh (100%) rename cmd/helm/testdata/helmhome/plugins/{args.yaml => args/plugin.yaml} (61%) rename cmd/helm/testdata/helmhome/plugins/{echo.yaml => echo/plugin.yaml} (100%) rename cmd/helm/testdata/helmhome/plugins/{env.yaml => env/plugin.yaml} (100%) rename cmd/helm/testdata/helmhome/plugins/{ => fullenv}/fullenv.sh (87%) rename cmd/helm/testdata/helmhome/plugins/{fullenv.yaml => fullenv/plugin.yaml} (63%) diff --git a/cmd/helm/plugins_test.go b/cmd/helm/plugins_test.go index 77828ea3b..55c36c2f6 100644 --- a/cmd/helm/plugins_test.go +++ b/cmd/helm/plugins_test.go @@ -77,7 +77,7 @@ func TestLoadPlugins(t *testing.T) { envs := strings.Join([]string{ "fullenv", - "fullenv.yaml", + hh.Plugins() + "/fullenv", hh.Plugins(), hh.String(), hh.Repository(), @@ -102,6 +102,11 @@ func TestLoadPlugins(t *testing.T) { } plugins := cmd.Commands() + + if len(plugins) != len(tests) { + t.Fatalf("Expected %d plugins, got %d", len(tests), len(plugins)) + } + for i := 0; i < len(plugins); i++ { out.Reset() tt := tests[i] diff --git a/cmd/helm/testdata/helmhome/plugins/args.sh b/cmd/helm/testdata/helmhome/plugins/args/args.sh similarity index 100% rename from cmd/helm/testdata/helmhome/plugins/args.sh rename to cmd/helm/testdata/helmhome/plugins/args/args.sh diff --git a/cmd/helm/testdata/helmhome/plugins/args.yaml b/cmd/helm/testdata/helmhome/plugins/args/plugin.yaml similarity index 61% rename from cmd/helm/testdata/helmhome/plugins/args.yaml rename to cmd/helm/testdata/helmhome/plugins/args/plugin.yaml index dbea13673..21e28a7c2 100644 --- a/cmd/helm/testdata/helmhome/plugins/args.yaml +++ b/cmd/helm/testdata/helmhome/plugins/args/plugin.yaml @@ -1,4 +1,4 @@ name: args usage: "echo args" description: "This echos args" -command: "$HELM_HOME/plugins/args.sh" +command: "$HELM_PLUGIN_DIR/args.sh" diff --git a/cmd/helm/testdata/helmhome/plugins/echo.yaml b/cmd/helm/testdata/helmhome/plugins/echo/plugin.yaml similarity index 100% rename from cmd/helm/testdata/helmhome/plugins/echo.yaml rename to cmd/helm/testdata/helmhome/plugins/echo/plugin.yaml diff --git a/cmd/helm/testdata/helmhome/plugins/env.yaml b/cmd/helm/testdata/helmhome/plugins/env/plugin.yaml similarity index 100% rename from cmd/helm/testdata/helmhome/plugins/env.yaml rename to cmd/helm/testdata/helmhome/plugins/env/plugin.yaml diff --git a/cmd/helm/testdata/helmhome/plugins/fullenv.sh b/cmd/helm/testdata/helmhome/plugins/fullenv/fullenv.sh similarity index 87% rename from cmd/helm/testdata/helmhome/plugins/fullenv.sh rename to cmd/helm/testdata/helmhome/plugins/fullenv/fullenv.sh index e72047333..518f492e9 100755 --- a/cmd/helm/testdata/helmhome/plugins/fullenv.sh +++ b/cmd/helm/testdata/helmhome/plugins/fullenv/fullenv.sh @@ -1,6 +1,6 @@ #!/bin/sh -echo $HELM_PLUGIN_SHORTNAME echo $HELM_PLUGIN_NAME +echo $HELM_PLUGIN_DIR echo $HELM_PLUGIN echo $HELM_HOME echo $HELM_PATH_REPOSITORY diff --git a/cmd/helm/testdata/helmhome/plugins/fullenv.yaml b/cmd/helm/testdata/helmhome/plugins/fullenv/plugin.yaml similarity index 63% rename from cmd/helm/testdata/helmhome/plugins/fullenv.yaml rename to cmd/helm/testdata/helmhome/plugins/fullenv/plugin.yaml index a6f4c5a4e..63f2f12db 100644 --- a/cmd/helm/testdata/helmhome/plugins/fullenv.yaml +++ b/cmd/helm/testdata/helmhome/plugins/fullenv/plugin.yaml @@ -1,4 +1,4 @@ name: fullenv usage: "show env vars" description: "show all env vars" -command: "$HELM_HOME/plugins/fullenv.sh" +command: "$HELM_PLUGIN_DIR/fullenv.sh" From a5d818dc4af65fc1660ce10ae3db43328694b53f Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Thu, 1 Dec 2016 16:28:59 -0700 Subject: [PATCH 30/39] fi(helm): add more tests for plugins This adds tests for setupEnv, and also updates some documentation to mirror the current state of plugins. --- cmd/helm/plugins.go | 6 +++++- cmd/helm/plugins_test.go | 34 ++++++++++++++++++++++++++++++++++ docs/plugins.md | 19 ++++++++----------- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/cmd/helm/plugins.go b/cmd/helm/plugins.go index d0f317a4b..af3848379 100644 --- a/cmd/helm/plugins.go +++ b/cmd/helm/plugins.go @@ -173,10 +173,14 @@ func setupEnv(shortname, base, plugdirs string, home helmpath.Home) { "HELM_PATH_REPOSITORY_FILE": home.RepositoryFile(), "HELM_PATH_CACHE": home.Cache(), "HELM_PATH_LOCAL_REPOSITORY": home.LocalRepository(), - //"HELM_PATH_STARTER": home.Starter(), + "HELM_PATH_STARTER": home.Starters(), "TILLER_HOST": tillerHost, } { os.Setenv(key, val) } + + if flagDebug { + os.Setenv("HELM_DEBUG", "1") + } } diff --git a/cmd/helm/plugins_test.go b/cmd/helm/plugins_test.go index 77828ea3b..cd6cc8f71 100644 --- a/cmd/helm/plugins_test.go +++ b/cmd/helm/plugins_test.go @@ -18,6 +18,7 @@ package main import ( "bytes" "os" + "path/filepath" "strings" "testing" @@ -123,3 +124,36 @@ func TestLoadPlugins(t *testing.T) { } } } + +func TestSetupEnv(t *testing.T) { + name := "pequod" + hh := helmpath.Home("testdata/helmhome") + base := filepath.Join(hh.Plugins(), name) + plugdirs := hh.Plugins() + flagDebug = true + defer func() { + flagDebug = false + }() + + setupEnv(name, base, plugdirs, hh) + for _, tt := range []struct { + name string + expect string + }{ + {"HELM_PLUGIN_NAME", name}, + {"HELM_PLUGIN_DIR", base}, + {"HELM_PLUGIN", hh.Plugins()}, + {"HELM_DEBUG", "1"}, + {"HELM_HOME", hh.String()}, + {"HELM_PATH_REPOSITORY", hh.Repository()}, + {"HELM_PATH_REPOSITORY_FILE", hh.RepositoryFile()}, + {"HELM_PATH_CACHE", hh.Cache()}, + {"HELM_PATH_LOCAL_REPOSITORY", hh.LocalRepository()}, + {"HELM_PATH_STARTER", hh.Starters()}, + {"TILLER_HOST", tillerHost}, + } { + if got := os.Getenv(tt.name); got != tt.expect { + t.Errorf("Expected $%s=%q, got %q", tt.name, tt.expect, got) + } + } +} diff --git a/docs/plugins.md b/docs/plugins.md index d8aae6bea..3bb7a043e 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -159,18 +159,15 @@ to use the tunnel. ## A Note on Flag Parsing -When executing a plugin, Helm will parse global flags for its own use, but pass -all flags to the plugin. +When executing a plugin, Helm will parse global flags for its own use. Some of +these flags are _not_ passed on to the plugin. -Plugins MUST NOT produce an error for the following flags: - -- `--debug` -- `--home` -- `--host` -- `--kube-context` -- `-h` -- `--help` +- `--debug`: If this is specified, `$HELM_DEBUG` is set to `1` +- `--home`: This is converted to `$HELM_HOME` +- `--host`: This is convereted to `$HELM_HOST` +- `--kube-context`: This is simply dropped. If your plugin uses `useTunnel`, this + is used to set up the tunnel for you. Plugins _should_ display help text and then exit for `-h` and `--help`. In all -other cases, plugins may simply ignore the flags. +other cases, plugins may use flags as appropriate. From f9b37957d99f487574dd54a9b255b481882d957b Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Thu, 1 Dec 2016 16:46:17 -0700 Subject: [PATCH 31/39] fix(helm): fix prompt error on Windows build This backs out an earlier change that removed an int type assertion. --- cmd/helm/package.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/package.go b/cmd/helm/package.go index d59d5cba9..92e217202 100644 --- a/cmd/helm/package.go +++ b/cmd/helm/package.go @@ -166,7 +166,7 @@ func (p *packageCmd) clearsign(filename string) error { // promptUser implements provenance.PassphraseFetcher func promptUser(name string) ([]byte, error) { fmt.Printf("Password for key %q > ", name) - pw, err := terminal.ReadPassword(syscall.Stdin) + pw, err := terminal.ReadPassword(int(syscall.Stdin)) fmt.Println() return pw, err } From d39c26c3599744ef476ec3a68f5b09d3cf717c8f Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Thu, 1 Dec 2016 17:35:31 -0700 Subject: [PATCH 32/39] feat(tiller): update sprig to 2.7.0 This adds shasum, int, and float64 functions, and fixes quote escaping for 'quote'. Closes #1524 --- glide.lock | 6 +++--- glide.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/glide.lock b/glide.lock index 837873285..0f309e1c6 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 707ac6d1785d0029397f2f9a3b0bc45f7d8ce819f14f6c246967b0a404627a2c -updated: 2016-12-01T09:07:51.289370422-07:00 +hash: 8ae84a3225f6cc31f91cc42dc8cf816792a989838254964cdcaaa57c75c37cdc +updated: 2016-12-01T17:35:05.940550036-07:00 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -215,7 +215,7 @@ imports: - name: github.com/Masterminds/semver version: 52edfc04e184ecf0962489d167b511b27aeebd61 - name: github.com/Masterminds/sprig - version: 8f797f5b23118d8fe846c4296b0ad55044201b14 + version: 1e60e4ce482a1e2c7b9c9be667535ef152e04300 - name: github.com/mattn/go-runewidth version: d6bea18f789704b5f83375793155289da36a3c7f - name: github.com/pborman/uuid diff --git a/glide.yaml b/glide.yaml index 487a3279a..f3e3a4b3e 100644 --- a/glide.yaml +++ b/glide.yaml @@ -6,7 +6,7 @@ import: - context - package: github.com/spf13/cobra - package: github.com/Masterminds/sprig - version: ^2.6 + version: ^2.7 - package: github.com/ghodss/yaml - package: github.com/Masterminds/semver version: ~1.2.1 From 7cec48c8e1d05a4acd34cd0e765bd5089e6a77e8 Mon Sep 17 00:00:00 2001 From: Morten Lied Johansen Date: Fri, 2 Dec 2016 12:24:03 +0100 Subject: [PATCH 33/39] Increase column width when listing releases --- cmd/helm/list.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/list.go b/cmd/helm/list.go index 3168c4c08..928fc0ab4 100644 --- a/cmd/helm/list.go +++ b/cmd/helm/list.go @@ -194,7 +194,7 @@ func (l *listCmd) statusCodes() []release.Status_Code { func formatList(rels []*release.Release) string { table := uitable.New() - table.MaxColWidth = 30 + table.MaxColWidth = 60 table.AddRow("NAME", "REVISION", "UPDATED", "STATUS", "CHART") for _, r := range rels { c := fmt.Sprintf("%s-%s", r.Chart.Metadata.Name, r.Chart.Metadata.Version) From a5d96c27040218d09155d7c713df3e4586cae804 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Fri, 2 Dec 2016 17:14:07 -0700 Subject: [PATCH 34/39] fix(tiller): fix spurious "no release found" errors. There are some places where releases are only located if they are in the state DEPLOYED. That particular logic was incorrectly used for upgrades. That caused #1566. While fixing that issue, I found that this was also the root cause of #1587 (though because it was off by one). I added a generic method to get the last release, regardless of its status. This allows some behaviors that previously failed: - 'helm upgrade' can now be performed on a DELETED release - 'helm rollback' can now be performed on a DELETED release even if there is only one revision of that release history. Closes #1566 Closes #1587 --- pkg/storage/storage.go | 13 +++++++++++++ pkg/storage/storage_test.go | 32 ++++++++++++++++++++++++++++++++ pkg/tiller/release_server.go | 23 +++++------------------ 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index 25ab6dae4..88fcd255f 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -139,6 +139,19 @@ func (s *Storage) History(name string) ([]*rspb.Release, error) { return l, nil } +func (s *Storage) Last(name string) (*rspb.Release, error) { + h, err := s.History(name) + if err != nil { + return nil, err + } + if len(h) == 0 { + return nil, fmt.Errorf("no revision for release %q", name) + } + + relutil.Reverse(h, relutil.SortByRevision) + return h[0], nil +} + // makeKey concatenates a release name and version into // a string with format ```#v```. // This key is used to uniquely identify storage objects. diff --git a/pkg/storage/storage_test.go b/pkg/storage/storage_test.go index 5935b4e88..141a019fa 100644 --- a/pkg/storage/storage_test.go +++ b/pkg/storage/storage_test.go @@ -217,6 +217,38 @@ func TestStorageHistory(t *testing.T) { } } +func TestStorageLast(t *testing.T) { + storage := Init(driver.NewMemory()) + + const name = "angry-bird" + + // setup storage with test releases + setup := func() { + // release records + rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease() + rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_SUPERSEDED}.ToRelease() + rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_SUPERSEDED}.ToRelease() + rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_FAILED}.ToRelease() + + // create the release records in the storage + assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)") + assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)") + assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)") + assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)") + } + + setup() + + h, err := storage.Last(name) + if err != nil { + t.Fatalf("Failed to query for release history (%q): %s\n", name, err) + } + + if h.Version != 4 { + t.Errorf("Expected revision 4, got %d", h.Version) + } +} + type ReleaseTestData struct { Name string Version int32 diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index abf8a30ff..64fc9da6f 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -229,17 +229,11 @@ func (s *ReleaseServer) GetReleaseStatus(c ctx.Context, req *services.GetRelease var rel *release.Release if req.Version <= 0 { - h, err := s.env.Releases.History(req.Name) + var err error + rel, err = s.env.Releases.Last(req.Name) if err != nil { - return nil, fmt.Errorf("getting deployed release '%s': %s", req.Name, err) - } - if len(h) < 1 { - return nil, errMissingRelease + return nil, fmt.Errorf("getting deployed release %q: %s", req.Name, err) } - - relutil.Reverse(h, relutil.SortByRevision) - rel = h[0] - } else { var err error if rel, err = s.env.Releases.Get(req.Name, req.Version); err != nil { @@ -376,7 +370,7 @@ func (s *ReleaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*rele } // finds the non-deleted release with the given name - currentRelease, err := s.env.Releases.Deployed(req.Name) + currentRelease, err := s.env.Releases.Last(req.Name) if err != nil { return nil, nil, err } @@ -504,17 +498,10 @@ func (s *ReleaseServer) prepareRollback(req *services.RollbackReleaseRequest) (* return nil, nil, errInvalidRevision } - // finds the non-deleted release with the given name - h, err := s.env.Releases.History(req.Name) + crls, err := s.env.Releases.Last(req.Name) if err != nil { return nil, nil, err } - if len(h) <= 1 { - return nil, nil, errors.New("no revision to rollback") - } - - relutil.SortByRevision(h) - crls := h[len(h)-1] rbv := req.Version if req.Version == 0 { From cba094f352303724447dff618fe7ac07925ff069 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Fri, 2 Dec 2016 17:39:05 -0700 Subject: [PATCH 35/39] fix(helm): fix broken --values flag This fixes the 'helm upgrade --values', which I broke when fixing '--set'. Closes #1631 --- cmd/helm/upgrade.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go index 950c48c71..4d42c1d36 100644 --- a/cmd/helm/upgrade.go +++ b/cmd/helm/upgrade.go @@ -171,7 +171,7 @@ func (u *upgradeCmd) vals() ([]byte, error) { return []byte{}, err } - if err := yaml.Unmarshal(bytes, base); err != nil { + if err := yaml.Unmarshal(bytes, &base); err != nil { return []byte{}, fmt.Errorf("failed to parse %s: %s", u.valuesFile, err) } } From 58dcef86c8b74ae7f847b7da81928e595f3cb231 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Sat, 3 Dec 2016 09:00:14 -0700 Subject: [PATCH 36/39] fix(helm): give different error if key is not private Previously, a "not found" error was returned if a key exists, but is not a private key. Updated the error to better indicate the case. --- pkg/provenance/sign.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/provenance/sign.go b/pkg/provenance/sign.go index 480932648..ecd6612a3 100644 --- a/pkg/provenance/sign.go +++ b/pkg/provenance/sign.go @@ -168,8 +168,10 @@ type PassphraseFetcher func(name string) ([]byte, error) // // If the key is successfully unlocked, it will return nil. func (s *Signatory) DecryptKey(fn PassphraseFetcher) error { - if s.Entity == nil || s.Entity.PrivateKey == nil { + if s.Entity == nil { return errors.New("private key not found") + } else if s.Entity.PrivateKey == nil { + return errors.New("provided key is not a private key") } // Nothing else to do if key is not encrypted. @@ -200,8 +202,10 @@ func (s *Signatory) DecryptKey(fn PassphraseFetcher) error { // The Signatory must have a valid Entity.PrivateKey for this to work. If it does // not, an error will be returned. func (s *Signatory) ClearSign(chartpath string) (string, error) { - if s.Entity == nil || s.Entity.PrivateKey == nil { + if s.Entity == nil { return "", errors.New("private key not found") + } else if s.Entity.PrivateKey == nil { + return "", errors.New("provided key is not a private key") } if fi, err := os.Stat(chartpath); err != nil { From c38fb120bf16fb8e6303bf1832aac85fae8389d4 Mon Sep 17 00:00:00 2001 From: John Hofman Date: Mon, 5 Dec 2016 10:01:25 +0100 Subject: [PATCH 37/39] fix(helm): add trimSuffix to helper functions --- docs/examples/nginx/templates/_helpers.tpl | 4 ++-- pkg/chartutil/create.go | 4 ++-- pkg/lint/rules/testdata/albatross/templates/_helpers.tpl | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/nginx/templates/_helpers.tpl b/docs/examples/nginx/templates/_helpers.tpl index 200aee93a..11d18431d 100644 --- a/docs/examples/nginx/templates/_helpers.tpl +++ b/docs/examples/nginx/templates/_helpers.tpl @@ -2,7 +2,7 @@ {{/* Expand the name of the chart. */}} -{{define "name"}}{{default "nginx" .Values.nameOverride | trunc 24 }}{{end}} +{{define "name"}}{{default "nginx" .Values.nameOverride | trunc 24 | trimSuffix "-" }}{{end}} {{/* Create a default fully qualified app name. @@ -12,5 +12,5 @@ We truncate at 24 chars because some Kubernetes name fields are limited to this */}} {{define "fullname"}} {{- $name := default "nginx" .Values.nameOverride -}} -{{printf "%s-%s" .Release.Name $name | trunc 24 -}} +{{printf "%s-%s" .Release.Name $name | trunc 24 | trimSuffix "-" -}} {{end}} diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index 406e93de2..f4f83cc75 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -162,7 +162,7 @@ const defaultHelpers = `{{/* vim: set filetype=mustache: */}} Expand the name of the chart. */}} {{- define "name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 24 -}} +{{- default .Chart.Name .Values.nameOverride | trunc 24 | trimSuffix "-" -}} {{- end -}} {{/* @@ -171,7 +171,7 @@ We truncate at 24 chars because some Kubernetes name fields are limited to this */}} {{- define "fullname" -}} {{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s" .Release.Name $name | trunc 24 -}} +{{- printf "%s-%s" .Release.Name $name | trunc 24 | trimSuffix "-" -}} {{- end -}} ` diff --git a/pkg/lint/rules/testdata/albatross/templates/_helpers.tpl b/pkg/lint/rules/testdata/albatross/templates/_helpers.tpl index 200aee93a..11d18431d 100644 --- a/pkg/lint/rules/testdata/albatross/templates/_helpers.tpl +++ b/pkg/lint/rules/testdata/albatross/templates/_helpers.tpl @@ -2,7 +2,7 @@ {{/* Expand the name of the chart. */}} -{{define "name"}}{{default "nginx" .Values.nameOverride | trunc 24 }}{{end}} +{{define "name"}}{{default "nginx" .Values.nameOverride | trunc 24 | trimSuffix "-" }}{{end}} {{/* Create a default fully qualified app name. @@ -12,5 +12,5 @@ We truncate at 24 chars because some Kubernetes name fields are limited to this */}} {{define "fullname"}} {{- $name := default "nginx" .Values.nameOverride -}} -{{printf "%s-%s" .Release.Name $name | trunc 24 -}} +{{printf "%s-%s" .Release.Name $name | trunc 24 | trimSuffix "-" -}} {{end}} From f3b205c6ef75cc3de2a0144511c4bb156570d816 Mon Sep 17 00:00:00 2001 From: Rodrigue Cloutier Date: Fri, 2 Dec 2016 08:15:36 -0500 Subject: [PATCH 38/39] fix(*): fixed tests for Windows --- .gitignore | 2 ++ cmd/helm/helmpath/helmhome_test.go | 37 -------------------- cmd/helm/helmpath/helmhome_unix_test.go | 40 ++++++++++++++++++++++ cmd/helm/helmpath/helmhome_windows_test.go | 37 ++++++++++++++++++++ cmd/helm/inspect_test.go | 6 ++-- cmd/helm/plugins_test.go | 16 ++++++--- cmd/helm/search/search.go | 6 ++-- cmd/helm/verify_test.go | 16 +++++++-- pkg/chartutil/load.go | 4 +++ pkg/tiller/release_server.go | 5 +-- 10 files changed, 118 insertions(+), 51 deletions(-) delete mode 100644 cmd/helm/helmpath/helmhome_test.go create mode 100755 cmd/helm/helmpath/helmhome_unix_test.go create mode 100755 cmd/helm/helmpath/helmhome_windows_test.go mode change 100644 => 100755 cmd/helm/inspect_test.go mode change 100644 => 100755 cmd/helm/plugins_test.go mode change 100644 => 100755 cmd/helm/search/search.go mode change 100644 => 100755 cmd/helm/verify_test.go mode change 100644 => 100755 pkg/chartutil/load.go mode change 100644 => 100755 pkg/tiller/release_server.go diff --git a/.gitignore b/.gitignore index 4613d316a..3d7644671 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ .DS_Store .coverage/ .vimrc +.vscode/ _dist/ _proto/*.pb.go bin/ rootfs/tiller vendor/ +*.exe diff --git a/cmd/helm/helmpath/helmhome_test.go b/cmd/helm/helmpath/helmhome_test.go deleted file mode 100644 index d7254f60d..000000000 --- a/cmd/helm/helmpath/helmhome_test.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package helmpath - -import ( - "testing" -) - -func TestHelmHome(t *testing.T) { - hh := Home("/r") - isEq := func(t *testing.T, a, b string) { - if a != b { - t.Errorf("Expected %q, got %q", a, b) - } - } - - isEq(t, hh.String(), "/r") - isEq(t, hh.Repository(), "/r/repository") - isEq(t, hh.RepositoryFile(), "/r/repository/repositories.yaml") - isEq(t, hh.LocalRepository(), "/r/repository/local") - isEq(t, hh.Cache(), "/r/repository/cache") - isEq(t, hh.CacheIndex("t"), "/r/repository/cache/t-index.yaml") - isEq(t, hh.Starters(), "/r/starters") -} diff --git a/cmd/helm/helmpath/helmhome_unix_test.go b/cmd/helm/helmpath/helmhome_unix_test.go new file mode 100755 index 000000000..cca303d29 --- /dev/null +++ b/cmd/helm/helmpath/helmhome_unix_test.go @@ -0,0 +1,40 @@ +// Copyright 2016 The Kubernetes Authors All rights reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris +// +build !windows + +package helmpath + +import ( + "runtime" + "testing" +) + +func TestHelmHome(t *testing.T) { + hh := Home("/r") + isEq := func(t *testing.T, a, b string) { + if a != b { + t.Error(runtime.GOOS) + t.Errorf("Expected %q, got %q", a, b) + } + } + + isEq(t, hh.String(), "/r") + isEq(t, hh.Repository(), "/r/repository") + isEq(t, hh.RepositoryFile(), "/r/repository/repositories.yaml") + isEq(t, hh.LocalRepository(), "/r/repository/local") + isEq(t, hh.Cache(), "/r/repository/cache") + isEq(t, hh.CacheIndex("t"), "/r/repository/cache/t-index.yaml") + isEq(t, hh.Starters(), "/r/starters") +} diff --git a/cmd/helm/helmpath/helmhome_windows_test.go b/cmd/helm/helmpath/helmhome_windows_test.go new file mode 100755 index 000000000..11b2e9686 --- /dev/null +++ b/cmd/helm/helmpath/helmhome_windows_test.go @@ -0,0 +1,37 @@ +// Copyright 2016 The Kubernetes Authors All rights reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build windows + +package helmpath + +import ( + "testing" +) + +func TestHelmHome(t *testing.T) { + hh := Home("r:\\") + isEq := func(t *testing.T, a, b string) { + if a != b { + t.Errorf("Expected %q, got %q", b, a) + } + } + + isEq(t, hh.String(), "r:\\") + isEq(t, hh.Repository(), "r:\\repository") + isEq(t, hh.RepositoryFile(), "r:\\repository\\repositories.yaml") + isEq(t, hh.LocalRepository(), "r:\\repository\\local") + isEq(t, hh.Cache(), "r:\\repository\\cache") + isEq(t, hh.CacheIndex("t"), "r:\\repository\\cache\\t-index.yaml") + isEq(t, hh.Starters(), "r:\\starters") +} diff --git a/cmd/helm/inspect_test.go b/cmd/helm/inspect_test.go old mode 100644 new mode 100755 index bbd9c6199..b34b793f6 --- a/cmd/helm/inspect_test.go +++ b/cmd/helm/inspect_test.go @@ -49,14 +49,14 @@ func TestInspect(t *testing.T) { } expect := []string{ - strings.TrimSpace(string(cdata)), - strings.TrimSpace(string(data)), + strings.Replace(strings.TrimSpace(string(cdata)), "\r", "", -1), + strings.Replace(strings.TrimSpace(string(data)), "\r", "", -1), } // Problem: ghodss/yaml doesn't marshal into struct order. To solve, we // have to carefully craft the Chart.yaml to match. for i, got := range parts { - got = strings.TrimSpace(got) + got = strings.Replace(strings.TrimSpace(got), "\r", "", -1) if got != expect[i] { t.Errorf("Expected\n%q\nGot\n%q\n", expect[i], got) } diff --git a/cmd/helm/plugins_test.go b/cmd/helm/plugins_test.go old mode 100644 new mode 100755 index 622969048..471f2370f --- a/cmd/helm/plugins_test.go +++ b/cmd/helm/plugins_test.go @@ -19,6 +19,7 @@ import ( "bytes" "os" "path/filepath" + "runtime" "strings" "testing" @@ -121,11 +122,16 @@ func TestLoadPlugins(t *testing.T) { if pp.Long != tt.long { t.Errorf("%d: Expected Use=%q, got %q", i, tt.long, pp.Long) } - if err := pp.RunE(pp, tt.args); err != nil { - t.Errorf("Error running %s: %s", tt.use, err) - } - if out.String() != tt.expect { - t.Errorf("Expected %s to output:\n%s\ngot\n%s", tt.use, tt.expect, out.String()) + + // Currently, plugins assume a Linux subsystem. Skip the execution + // tests until this is fixed + if runtime.GOOS != "windows" { + if err := pp.RunE(pp, tt.args); err != nil { + t.Errorf("Error running %s: %s", tt.use, err) + } + if out.String() != tt.expect { + t.Errorf("Expected %s to output:\n%s\ngot\n%s", tt.use, tt.expect, out.String()) + } } } } diff --git a/cmd/helm/search/search.go b/cmd/helm/search/search.go old mode 100644 new mode 100755 index bc4a8eaf1..4d394e0f5 --- a/cmd/helm/search/search.go +++ b/cmd/helm/search/search.go @@ -24,7 +24,7 @@ package search import ( "errors" - "path/filepath" + "path" "regexp" "sort" "strings" @@ -70,7 +70,9 @@ func (i *Index) AddRepo(rname string, ind *repo.IndexFile, all bool) { // By convention, an index file is supposed to have the newest at the // 0 slot, so our best bet is to grab the 0 entry and build the index // entry off of that. - fname := filepath.Join(rname, name) + // Note: Do not use filePath.Join since on Windows it will return \ + // which results in a repo name that cannot be understood. + fname := path.Join(rname, name) if !all { i.lines[fname] = indstr(rname, ref[0]) i.charts[fname] = ref[0] diff --git a/cmd/helm/verify_test.go b/cmd/helm/verify_test.go old mode 100644 new mode 100755 index 425f1a28b..fa248e67b --- a/cmd/helm/verify_test.go +++ b/cmd/helm/verify_test.go @@ -17,10 +17,22 @@ package main import ( "bytes" + "fmt" + "runtime" "testing" ) func TestVerifyCmd(t *testing.T) { + + stat_exe := "stat" + stat_path_msg := "no such file or directory" + stat_file_msg := stat_path_msg + if runtime.GOOS == "windows" { + stat_exe = "GetFileAttributesEx" + stat_path_msg = "The system cannot find the path specified." + stat_file_msg = "The system cannot find the file specified." + } + tests := []struct { name string args []string @@ -36,7 +48,7 @@ func TestVerifyCmd(t *testing.T) { { name: "verify requires that chart exists", args: []string{"no/such/file"}, - expect: "stat no/such/file: no such file or directory", + expect: fmt.Sprintf("%s no/such/file: %s", stat_exe, stat_path_msg), err: true, }, { @@ -48,7 +60,7 @@ func TestVerifyCmd(t *testing.T) { { name: "verify requires that chart has prov file", args: []string{"testdata/testcharts/compressedchart-0.1.0.tgz"}, - expect: "could not load provenance file testdata/testcharts/compressedchart-0.1.0.tgz.prov: stat testdata/testcharts/compressedchart-0.1.0.tgz.prov: no such file or directory", + expect: fmt.Sprintf("could not load provenance file testdata/testcharts/compressedchart-0.1.0.tgz.prov: %s testdata/testcharts/compressedchart-0.1.0.tgz.prov: %s", stat_exe, stat_file_msg), err: true, }, { diff --git a/pkg/chartutil/load.go b/pkg/chartutil/load.go old mode 100644 new mode 100755 index 9a01bdad4..87ee8820c --- a/pkg/chartutil/load.go +++ b/pkg/chartutil/load.go @@ -229,6 +229,10 @@ func LoadDir(dir string) (*chart.Chart, error) { err = filepath.Walk(topdir, func(name string, fi os.FileInfo, err error) error { n := strings.TrimPrefix(name, topdir) + + // Normalize to / since it will also work on Windows + n = filepath.ToSlash(n) + if err != nil { return err } diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go old mode 100644 new mode 100755 index abf8a30ff..35abcb15b --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -21,7 +21,7 @@ import ( "errors" "fmt" "log" - "path/filepath" + "path" "regexp" "strings" @@ -735,7 +735,8 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values for k, v := range files { if strings.HasSuffix(k, notesFileSuffix) { // Only apply the notes if it belongs to the parent chart - if k == filepath.Join(ch.Metadata.Name, "templates", notesFileSuffix) { + // Note: Do not use filePath.Join since it creates a path with \ which is not expected + if k == path.Join(ch.Metadata.Name, "templates", notesFileSuffix) { notes = v } delete(files, k) From 1f01bf51e7d9686a5047010f942b794dc8f42617 Mon Sep 17 00:00:00 2001 From: Adam Reese Date: Mon, 5 Dec 2016 08:47:58 -0800 Subject: [PATCH 39/39] fix(tiller): increase the max message size for grpc Increases the default message size from 4MB to 10MB. --- cmd/tiller/tiller.go | 3 +-- pkg/tiller/release_server.go | 12 ++++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/cmd/tiller/tiller.go b/cmd/tiller/tiller.go index 70672a85d..188eddfec 100644 --- a/cmd/tiller/tiller.go +++ b/cmd/tiller/tiller.go @@ -24,7 +24,6 @@ import ( "os" "github.com/spf13/cobra" - "google.golang.org/grpc" "k8s.io/helm/pkg/proto/hapi/services" "k8s.io/helm/pkg/storage" @@ -41,7 +40,7 @@ const ( // rootServer is the root gRPC server. // // Each gRPC service registers itself to this server during init(). -var rootServer = grpc.NewServer() +var rootServer = tiller.NewServer() // env is the default environment. // diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go index abf8a30ff..2762db3b5 100644 --- a/pkg/tiller/release_server.go +++ b/pkg/tiller/release_server.go @@ -25,6 +25,7 @@ import ( "regexp" "strings" + "google.golang.org/grpc" "google.golang.org/grpc/metadata" "github.com/technosophos/moniker" @@ -81,6 +82,17 @@ var ListDefaultLimit int64 = 512 // prevents an empty string from matching. var ValidName = regexp.MustCompile("^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])+$") +// maxMsgSize use 10MB as the default message size limit. +// grpc library default is 4MB +var maxMsgSize = 1024 * 1024 * 10 + +// NewServer creates a new grpc server. +func NewServer() *grpc.Server { + return grpc.NewServer( + grpc.MaxMsgSize(maxMsgSize), + ) +} + // ReleaseServer implements the server-side gRPC endpoint for the HAPI services. type ReleaseServer struct { env *environment.Environment