ref(cmd): consistent naming of cmd variables

pull/4027/head
Adam Reese 7 years ago
parent c30637b8a1
commit 57e288a88d
No known key found for this signature in database
GPG Key ID: 06F35E60A7A18DD6

@ -37,16 +37,11 @@ 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
.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
@ -54,37 +49,40 @@ destination exists and there are files in that directory, conflicting files
will be overwritten, but other files will be left alone.
`
type createCmd struct {
home helmpath.Home
type createOptions struct {
starter string // --starter
// args
name string
starter string
home helmpath.Home
}
func newCreateCmd(out io.Writer) *cobra.Command {
cc := &createCmd{}
o := &createOptions{}
cmd := &cobra.Command{
Use: "create NAME",
Short: "create a new chart with the given name",
Long: createDesc,
RunE: func(cmd *cobra.Command, args []string) error {
cc.home = settings.Home
o.home = settings.Home
if len(args) == 0 {
return errors.New("the name of the new chart is required")
}
cc.name = args[0]
return cc.run(out)
o.name = args[0]
return o.run(out)
},
}
cmd.Flags().StringVarP(&cc.starter, "starter", "p", "", "the named Helm starter scaffold")
cmd.Flags().StringVarP(&o.starter, "starter", "p", "", "the named Helm starter scaffold")
return cmd
}
func (c *createCmd) run(out io.Writer) error {
fmt.Fprintf(out, "Creating %s\n", c.name)
func (o *createOptions) run(out io.Writer) error {
fmt.Fprintf(out, "Creating %s\n", o.name)
chartname := filepath.Base(c.name)
chartname := filepath.Base(o.name)
cfile := &chart.Metadata{
Name: chartname,
Description: "A Helm chart for Kubernetes",
@ -93,12 +91,12 @@ func (c *createCmd) run(out io.Writer) error {
APIVersion: chartutil.APIVersionv1,
}
if c.starter != "" {
if o.starter != "" {
// Create from the starter
lstarter := filepath.Join(c.home.Starters(), c.starter)
return chartutil.CreateFrom(cfile, filepath.Dir(c.name), lstarter)
lstarter := filepath.Join(o.home.Starters(), o.starter)
return chartutil.CreateFrom(cfile, filepath.Dir(o.name), lstarter)
}
_, err := chartutil.Create(cfile, filepath.Dir(c.name))
_, err := chartutil.Create(cfile, filepath.Dir(o.name))
return err
}

@ -34,18 +34,20 @@ Use the '--dry-run' flag to see which releases will be deleted without actually
deleting them.
`
type deleteCmd struct {
type deleteOptions struct {
disableHooks bool // --no-hooks
dryRun bool // --dry-run
purge bool // --purge
timeout int64 // --timeout
// args
name string
dryRun bool
disableHooks bool
purge bool
timeout int64
client helm.Interface
}
func newDeleteCmd(c helm.Interface, out io.Writer) *cobra.Command {
del := &deleteCmd{client: c}
o := &deleteOptions{client: c}
cmd := &cobra.Command{
Use: "delete [flags] RELEASE_NAME [...]",
@ -57,37 +59,37 @@ func newDeleteCmd(c helm.Interface, out io.Writer) *cobra.Command {
if len(args) == 0 {
return errors.New("command 'delete' requires a release name")
}
del.client = ensureHelmClient(del.client, false)
o.client = ensureHelmClient(o.client, false)
for i := 0; i < len(args); i++ {
del.name = args[i]
if err := del.run(out); err != nil {
o.name = args[i]
if err := o.run(out); err != nil {
return err
}
fmt.Fprintf(out, "release \"%s\" deleted\n", del.name)
fmt.Fprintf(out, "release \"%s\" deleted\n", o.name)
}
return nil
},
}
f := cmd.Flags()
f.BoolVar(&del.dryRun, "dry-run", false, "simulate a delete")
f.BoolVar(&del.disableHooks, "no-hooks", false, "prevent hooks from running during deletion")
f.BoolVar(&del.purge, "purge", false, "remove the release from the store and make its name free for later use")
f.Int64Var(&del.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&o.dryRun, "dry-run", false, "simulate a delete")
f.BoolVar(&o.disableHooks, "no-hooks", false, "prevent hooks from running during deletion")
f.BoolVar(&o.purge, "purge", false, "remove the release from the store and make its name free for later use")
f.Int64Var(&o.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
return cmd
}
func (d *deleteCmd) run(out io.Writer) error {
func (o *deleteOptions) run(out io.Writer) error {
opts := []helm.DeleteOption{
helm.DeleteDryRun(d.dryRun),
helm.DeleteDisableHooks(d.disableHooks),
helm.DeletePurge(d.purge),
helm.DeleteTimeout(d.timeout),
helm.DeleteDryRun(o.dryRun),
helm.DeleteDisableHooks(o.disableHooks),
helm.DeletePurge(o.purge),
helm.DeleteTimeout(o.timeout),
}
res, err := d.client.DeleteRelease(d.name, opts...)
res, err := o.client.DeleteRelease(o.name, opts...)
if res != nil && res.Info != "" {
fmt.Fprintln(out, res.Info)
}

@ -102,12 +102,14 @@ func newDependencyCmd(out io.Writer) *cobra.Command {
return cmd
}
type dependencyListCmd struct {
type dependencyLisOptions struct {
chartpath string
}
func newDependencyListCmd(out io.Writer) *cobra.Command {
dlc := &dependencyListCmd{}
o := &dependencyLisOptions{
chartpath: ".",
}
cmd := &cobra.Command{
Use: "list [flags] CHART",
@ -115,20 +117,17 @@ func newDependencyListCmd(out io.Writer) *cobra.Command {
Short: "list the dependencies for the given chart",
Long: dependencyListDesc,
RunE: func(cmd *cobra.Command, args []string) error {
cp := "."
if len(args) > 0 {
cp = args[0]
o.chartpath = filepath.Clean(args[0])
}
dlc.chartpath = filepath.Clean(cp)
return dlc.run()
return o.run(out)
},
}
return cmd
}
func (l *dependencyListCmd) run(out io.Writer) error {
c, err := chartutil.Load(l.chartpath)
func (o *dependencyLisOptions) run(out io.Writer) error {
c, err := chartutil.Load(o.chartpath)
if err != nil {
return err
}
@ -136,21 +135,21 @@ func (l *dependencyListCmd) run(out io.Writer) error {
r, err := chartutil.LoadRequirements(c)
if err != nil {
if err == chartutil.ErrRequirementsNotFound {
fmt.Fprintf(out, "WARNING: no requirements at %s/charts\n", l.chartpath)
fmt.Fprintf(out, "WARNING: no requirements at %s/charts\n", o.chartpath)
return nil
}
return err
}
l.printRequirements(out, r)
o.printRequirements(out, r)
fmt.Fprintln(out)
l.printMissing(out, r)
o.printMissing(out, r)
return nil
}
func (l *dependencyListCmd) dependencyStatus(dep *chartutil.Dependency) string {
func (o *dependencyLisOptions) dependencyStatus(dep *chartutil.Dependency) string {
filename := fmt.Sprintf("%s-%s.tgz", dep.Name, "*")
archives, err := filepath.Glob(filepath.Join(l.chartpath, "charts", filename))
archives, err := filepath.Glob(filepath.Join(o.chartpath, "charts", filename))
if err != nil {
return "bad pattern"
} else if len(archives) > 1 {
@ -186,7 +185,7 @@ func (l *dependencyListCmd) dependencyStatus(dep *chartutil.Dependency) string {
}
}
folder := filepath.Join(l.chartpath, "charts", dep.Name)
folder := filepath.Join(o.chartpath, "charts", dep.Name)
if fi, err := os.Stat(folder); err != nil {
return "missing"
} else if !fi.IsDir() {
@ -223,19 +222,19 @@ func (l *dependencyListCmd) dependencyStatus(dep *chartutil.Dependency) string {
}
// printRequirements prints all of the requirements in the yaml file.
func (l *dependencyListCmd) printRequirements(out io.Writer, reqs *chartutil.Requirements) {
func (o *dependencyLisOptions) printRequirements(out io.Writer, reqs *chartutil.Requirements) {
table := uitable.New()
table.MaxColWidth = 80
table.AddRow("NAME", "VERSION", "REPOSITORY", "STATUS")
for _, row := range reqs.Dependencies {
table.AddRow(row.Name, row.Version, row.Repository, l.dependencyStatus(row))
table.AddRow(row.Name, row.Version, row.Repository, o.dependencyStatus(row))
}
fmt.Fprintln(out, table)
}
// printMissing prints warnings about charts that are present on disk, but are not in the requirements.
func (l *dependencyListCmd) printMissing(out io.Writer, reqs *chartutil.Requirements) {
folder := filepath.Join(l.chartpath, "charts/*")
func (o *dependencyLisOptions) printMissing(out io.Writer, reqs *chartutil.Requirements) {
folder := filepath.Join(o.chartpath, "charts/*")
files, err := filepath.Glob(folder)
if err != nil {
fmt.Fprintln(out, err)

@ -36,47 +36,50 @@ If no lock file is found, 'helm dependency build' will mirror the behavior
of 'helm dependency update'.
`
type dependencyBuildCmd struct {
type dependencyBuildOptions struct {
keyring string // --keyring
verify bool // --verify
// args
chartpath string
verify bool
keyring string
helmhome helmpath.Home
}
func newDependencyBuildCmd(out io.Writer) *cobra.Command {
dbc := &dependencyBuildCmd{}
o := &dependencyBuildOptions{
chartpath: ".",
}
cmd := &cobra.Command{
Use: "build [flags] CHART",
Short: "rebuild the charts/ directory based on the requirements.lock file",
Long: dependencyBuildDesc,
RunE: func(cmd *cobra.Command, args []string) error {
dbc.helmhome = settings.Home
dbc.chartpath = "."
o.helmhome = settings.Home
if len(args) > 0 {
dbc.chartpath = args[0]
o.chartpath = args[0]
}
return dbc.run(out)
return o.run(out)
},
}
f := cmd.Flags()
f.BoolVar(&dbc.verify, "verify", false, "verify the packages against signatures")
f.StringVar(&dbc.keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.BoolVar(&o.verify, "verify", false, "verify the packages against signatures")
f.StringVar(&o.keyring, "keyring", defaultKeyring(), "keyring containing public keys")
return cmd
}
func (d *dependencyBuildCmd) run(out io.Writer) error {
func (o *dependencyBuildOptions) run(out io.Writer) error {
man := &downloader.Manager{
Out: out,
ChartPath: d.chartpath,
HelmHome: d.helmhome,
Keyring: d.keyring,
ChartPath: o.chartpath,
HelmHome: o.helmhome,
Keyring: o.keyring,
Getters: getter.All(settings),
}
if d.verify {
if o.verify {
man.Verify = downloader.VerifyIfPossible
}

@ -41,18 +41,23 @@ reason, an update command will not remove charts unless they are (a) present
in the requirements.yaml file, but (b) at the wrong version.
`
// dependencyUpdateCmd describes a 'helm dependency update'
type dependencyUpdateCmd struct {
// dependencyUpdateOptions describes a 'helm dependency update'
type dependencyUpdateOptions struct {
keyring string // --keyring
skipRefresh bool // --skip-refresh
verify bool // --verify
// args
chartpath string
helmhome helmpath.Home
verify bool
keyring string
skipRefresh bool
}
// newDependencyUpdateCmd creates a new dependency update command.
func newDependencyUpdateCmd(out io.Writer) *cobra.Command {
duc := &dependencyUpdateCmd{}
o := &dependencyUpdateOptions{
chartpath: ".",
}
cmd := &cobra.Command{
Use: "update [flags] CHART",
@ -60,42 +65,33 @@ func newDependencyUpdateCmd(out io.Writer) *cobra.Command {
Short: "update charts/ based on the contents of requirements.yaml",
Long: dependencyUpDesc,
RunE: func(cmd *cobra.Command, args []string) error {
cp := "."
if len(args) > 0 {
cp = args[0]
o.chartpath = filepath.Clean(args[0])
}
var err error
duc.chartpath, err = filepath.Abs(cp)
if err != nil {
return err
}
duc.helmhome = settings.Home
return duc.run(out)
o.helmhome = settings.Home
return o.run(out)
},
}
f := cmd.Flags()
f.BoolVar(&duc.verify, "verify", false, "verify the packages against signatures")
f.StringVar(&duc.keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.BoolVar(&duc.skipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
f.BoolVar(&o.verify, "verify", false, "verify the packages against signatures")
f.StringVar(&o.keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.BoolVar(&o.skipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
return cmd
}
// run runs the full dependency update process.
func (d *dependencyUpdateCmd) run(out io.Writer) error {
func (o *dependencyUpdateOptions) run(out io.Writer) error {
man := &downloader.Manager{
Out: out,
ChartPath: d.chartpath,
HelmHome: d.helmhome,
Keyring: d.keyring,
SkipUpdate: d.skipRefresh,
ChartPath: o.chartpath,
HelmHome: o.helmhome,
Keyring: o.keyring,
SkipUpdate: o.skipRefresh,
Getters: getter.All(settings),
}
if d.verify {
if o.verify {
man.Verify = downloader.VerifyAlways
}
if settings.Debug {

@ -190,11 +190,11 @@ func TestDependencyUpdateCmd_DontDeleteOldChartsOnError(t *testing.T) {
}
out := bytes.NewBuffer(nil)
duc := &dependencyUpdateCmd{}
duc.helmhome = helmpath.Home(hh)
duc.chartpath = hh.Path(chartname)
o := &dependencyUpdateOptions{}
o.helmhome = helmpath.Home(hh)
o.chartpath = hh.Path(chartname)
if err := duc.run(out); err != nil {
if err := o.run(out); err != nil {
output := out.String()
t.Logf("Output: %s", output)
t.Fatal(err)
@ -203,14 +203,14 @@ func TestDependencyUpdateCmd_DontDeleteOldChartsOnError(t *testing.T) {
// Chart repo is down
srv.Stop()
if err := duc.run(out); err == nil {
if err := o.run(out); err == nil {
output := out.String()
t.Logf("Output: %s", output)
t.Fatal("Expected error, got nil")
}
// Make sure charts dir still has dependencies
files, err := ioutil.ReadDir(filepath.Join(duc.chartpath, "charts"))
files, err := ioutil.ReadDir(filepath.Join(o.chartpath, "charts"))
if err != nil {
t.Fatal(err)
}
@ -226,7 +226,7 @@ func TestDependencyUpdateCmd_DontDeleteOldChartsOnError(t *testing.T) {
}
// Make sure tmpcharts is deleted
if _, err := os.Stat(filepath.Join(duc.chartpath, "tmpcharts")); !os.IsNotExist(err) {
if _, err := os.Stat(filepath.Join(o.chartpath, "tmpcharts")); !os.IsNotExist(err) {
t.Fatalf("tmpcharts dir still exists")
}
}

@ -37,15 +37,14 @@ It can also generate bash autocompletions.
$ helm docs markdown -dir mydocs/
`
type docsCmd struct {
out io.Writer
type docsOptions struct {
dest string
docTypeString string
topCmd *cobra.Command
}
func newDocsCmd(out io.Writer) *cobra.Command {
dc := &docsCmd{out: out}
o := &docsOptions{}
cmd := &cobra.Command{
Use: "docs",
@ -53,28 +52,28 @@ func newDocsCmd(out io.Writer) *cobra.Command {
Long: docsDesc,
Hidden: true,
RunE: func(cmd *cobra.Command, args []string) error {
dc.topCmd = cmd.Root()
return dc.run()
o.topCmd = cmd.Root()
return o.run(out)
},
}
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)")
f.StringVar(&o.dest, "dir", "./", "directory to which documentation is written")
f.StringVar(&o.docTypeString, "type", "markdown", "the type of documentation to generate (markdown, man, bash)")
return cmd
}
func (d *docsCmd) run() error {
switch d.docTypeString {
func (o *docsOptions) run(out io.Writer) error {
switch o.docTypeString {
case "markdown", "mdown", "md":
return doc.GenMarkdownTree(d.topCmd, d.dest)
return doc.GenMarkdownTree(o.topCmd, o.dest)
case "man":
manHdr := &doc.GenManHeader{Title: "HELM", Section: "1"}
return doc.GenManTree(d.topCmd, manHdr, d.dest)
return doc.GenManTree(o.topCmd, manHdr, o.dest)
case "bash":
return d.topCmd.GenBashCompletionFile(filepath.Join(d.dest, "completions.bash"))
return o.topCmd.GenBashCompletionFile(filepath.Join(o.dest, "completions.bash"))
default:
return fmt.Errorf("unknown doc type %q. Try 'markdown' or 'man'", d.docTypeString)
return fmt.Errorf("unknown doc type %q. Try 'markdown' or 'man'", o.docTypeString)
}
}

@ -46,29 +46,27 @@ 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.
`
type fetchCmd struct {
untar bool
untardir string
chartRef string
destdir string
version string
repoURL string
username string
password string
verify bool
verifyLater bool
keyring string
type fetchOptions struct {
caFile string // --ca-file
certFile string // --cert-file
destdir string // --destination
devel bool // --devel
keyFile string // --key-file
keyring string // --keyring
password string // --password
repoURL string // --repo
untar bool // --untar
untardir string // --untardir
username string // --username
verify bool // --verify
verifyLater bool // --prov
version string // --version
certFile string
keyFile string
caFile string
devel bool
chartRef string
}
func newFetchCmd(out io.Writer) *cobra.Command {
fch := &fetchCmd{}
o := &fetchOptions{}
cmd := &cobra.Command{
Use: "fetch [flags] [chart URL | repo/chartname] [...]",
@ -79,14 +77,14 @@ func newFetchCmd(out io.Writer) *cobra.Command {
return fmt.Errorf("need at least one argument, url or repo/name of the chart")
}
if fch.version == "" && fch.devel {
if o.version == "" && o.devel {
debug("setting version to >0.0.0-0")
fch.version = ">0.0.0-0"
o.version = ">0.0.0-0"
}
for i := 0; i < len(args); i++ {
fch.chartRef = args[i]
if err := fch.run(out); err != nil {
o.chartRef = args[i]
if err := o.run(out); err != nil {
return err
}
}
@ -95,45 +93,45 @@ func newFetchCmd(out io.Writer) *cobra.Command {
}
f := cmd.Flags()
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")
f.StringVar(&fch.repoURL, "repo", "", "chart repository url where to locate the requested chart")
f.StringVar(&fch.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&fch.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&fch.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&fch.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
f.StringVar(&fch.username, "username", "", "chart repository username")
f.StringVar(&fch.password, "password", "", "chart repository password")
f.BoolVar(&o.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
f.BoolVar(&o.untar, "untar", false, "if set to true, will untar the chart after downloading it")
f.BoolVar(&o.verify, "verify", false, "verify the package against its signature")
f.BoolVar(&o.verifyLater, "prov", false, "fetch the provenance file, but don't perform verification")
f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.StringVar(&o.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&o.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&o.keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.StringVar(&o.password, "password", "", "chart repository password")
f.StringVar(&o.repoURL, "repo", "", "chart repository url where to locate the requested chart")
f.StringVar(&o.untardir, "untardir", ".", "if untar is specified, this flag specifies the name of the directory into which the chart is expanded")
f.StringVar(&o.username, "username", "", "chart repository username")
f.StringVar(&o.version, "version", "", "specific version of a chart. Without this, the latest version is fetched")
f.StringVarP(&o.destdir, "destination", "d", ".", "location to write the chart. If this and tardir are specified, tardir is appended to this")
return cmd
}
func (f *fetchCmd) run(out io.Writer) error {
func (o *fetchOptions) run(out io.Writer) error {
c := downloader.ChartDownloader{
HelmHome: settings.Home,
Out: out,
Keyring: f.keyring,
Keyring: o.keyring,
Verify: downloader.VerifyNever,
Getters: getter.All(settings),
Username: f.username,
Password: f.password,
Username: o.username,
Password: o.password,
}
if f.verify {
if o.verify {
c.Verify = downloader.VerifyAlways
} else if f.verifyLater {
} else if o.verifyLater {
c.Verify = downloader.VerifyLater
}
// If untar is set, we fetch to a tempdir, then untar and copy after
// verification.
dest := f.destdir
if f.untar {
dest := o.destdir
if o.untar {
var err error
dest, err = ioutil.TempDir("", "helm-")
if err != nil {
@ -142,28 +140,28 @@ func (f *fetchCmd) run(out io.Writer) error {
defer os.RemoveAll(dest)
}
if f.repoURL != "" {
chartURL, err := repo.FindChartInAuthRepoURL(f.repoURL, f.username, f.password, f.chartRef, f.version, f.certFile, f.keyFile, f.caFile, getter.All(settings))
if o.repoURL != "" {
chartURL, err := repo.FindChartInAuthRepoURL(o.repoURL, o.username, o.password, o.chartRef, o.version, o.certFile, o.keyFile, o.caFile, getter.All(settings))
if err != nil {
return err
}
f.chartRef = chartURL
o.chartRef = chartURL
}
saved, v, err := c.DownloadTo(f.chartRef, f.version, dest)
saved, v, err := c.DownloadTo(o.chartRef, o.version, dest)
if err != nil {
return err
}
if f.verify {
if o.verify {
fmt.Fprintf(out, "Verification: %v\n", v)
}
// After verification, untar the chart into the requested directory.
if f.untar {
ud := f.untardir
if o.untar {
ud := o.untardir
if !filepath.IsAbs(ud) {
ud = filepath.Join(f.destdir, ud)
ud = filepath.Join(o.destdir, ud)
}
if fi, err := os.Stat(ud); err != nil {
if err := os.MkdirAll(ud, 0755); err != nil {

@ -40,15 +40,16 @@ chart, the supplied values, and the generated manifest file.
var errReleaseRequired = errors.New("release name is required")
type getCmd struct {
type getOptions struct {
version int // --revision
release string
version int
client helm.Interface
}
func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
get := &getCmd{client: client}
o := &getOptions{client: client}
cmd := &cobra.Command{
Use: "get [flags] RELEASE_NAME",
@ -58,13 +59,13 @@ func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
if len(args) == 0 {
return errReleaseRequired
}
get.release = args[0]
get.client = ensureHelmClient(get.client, false)
return get.run(out)
o.release = args[0]
o.client = ensureHelmClient(o.client, false)
return o.run(out)
},
}
cmd.Flags().IntVar(&get.version, "revision", 0, "get the named release with revision")
cmd.Flags().IntVar(&o.version, "revision", 0, "get the named release with revision")
cmd.AddCommand(newGetValuesCmd(client, out))
cmd.AddCommand(newGetManifestCmd(client, out))
@ -73,8 +74,7 @@ func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
return cmd
}
// getCmd is the command that implements 'helm get'
func (g *getCmd) run(out io.Writer) error {
func (g *getOptions) run(out io.Writer) error {
res, err := g.client.ReleaseContent(g.release, g.version)
if err != nil {
return err

@ -31,14 +31,14 @@ This command downloads hooks for a given release.
Hooks are formatted in YAML and separated by the YAML '---\n' separator.
`
type getHooksCmd struct {
type getHooksOptions struct {
release string
client helm.Interface
version int
}
func newGetHooksCmd(client helm.Interface, out io.Writer) *cobra.Command {
ghc := &getHooksCmd{client: client}
o := &getHooksOptions{client: client}
cmd := &cobra.Command{
Use: "hooks [flags] RELEASE_NAME",
@ -48,19 +48,19 @@ func newGetHooksCmd(client helm.Interface, out io.Writer) *cobra.Command {
if len(args) == 0 {
return errReleaseRequired
}
ghc.release = args[0]
ghc.client = ensureHelmClient(ghc.client, false)
return ghc.run(out)
o.release = args[0]
o.client = ensureHelmClient(o.client, false)
return o.run(out)
},
}
cmd.Flags().IntVar(&ghc.version, "revision", 0, "get the named release with revision")
cmd.Flags().IntVar(&o.version, "revision", 0, "get the named release with revision")
return cmd
}
func (g *getHooksCmd) run(out io.Writer) error {
res, err := g.client.ReleaseContent(g.release, g.version)
func (o *getHooksOptions) run(out io.Writer) error {
res, err := o.client.ReleaseContent(o.release, o.version)
if err != nil {
fmt.Fprintln(out, g.release)
fmt.Fprintln(out, o.release)
return err
}

@ -33,14 +33,16 @@ 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.
`
type getManifestCmd struct {
type getManifestOptions struct {
version int // --revision
release string
client helm.Interface
version int
}
func newGetManifestCmd(client helm.Interface, out io.Writer) *cobra.Command {
get := &getManifestCmd{client: client}
o := &getManifestOptions{client: client}
cmd := &cobra.Command{
Use: "manifest [flags] RELEASE_NAME",
@ -50,19 +52,19 @@ func newGetManifestCmd(client helm.Interface, out io.Writer) *cobra.Command {
if len(args) == 0 {
return errReleaseRequired
}
get.release = args[0]
get.client = ensureHelmClient(get.client, false)
return get.run(out)
o.release = args[0]
o.client = ensureHelmClient(o.client, false)
return o.run(out)
},
}
cmd.Flags().IntVar(&get.version, "revision", 0, "get the named release with revision")
cmd.Flags().IntVar(&o.version, "revision", 0, "get the named release with revision")
return cmd
}
// getManifest implements 'helm get manifest'
func (g *getManifestCmd) run(out io.Writer) error {
res, err := g.client.ReleaseContent(g.release, g.version)
func (o *getManifestOptions) run(out io.Writer) error {
res, err := o.client.ReleaseContent(o.release, o.version)
if err != nil {
return err
}

@ -30,15 +30,17 @@ var getValuesHelp = `
This command downloads a values file for a given release.
`
type getValuesCmd struct {
type getValuesOptions struct {
allValues bool // --all
version int // --revision
release string
allValues bool
client helm.Interface
version int
}
func newGetValuesCmd(client helm.Interface, out io.Writer) *cobra.Command {
get := &getValuesCmd{client: client}
o := &getValuesOptions{client: client}
cmd := &cobra.Command{
Use: "values [flags] RELEASE_NAME",
@ -48,26 +50,26 @@ func newGetValuesCmd(client helm.Interface, out io.Writer) *cobra.Command {
if len(args) == 0 {
return errReleaseRequired
}
get.release = args[0]
get.client = ensureHelmClient(get.client, false)
return get.run(out)
o.release = args[0]
o.client = ensureHelmClient(o.client, false)
return o.run(out)
},
}
cmd.Flags().IntVar(&get.version, "revision", 0, "get the named release with revision")
cmd.Flags().BoolVarP(&get.allValues, "all", "a", false, "dump all (computed) values")
cmd.Flags().BoolVarP(&o.allValues, "all", "a", false, "dump all (computed) values")
cmd.Flags().IntVar(&o.version, "revision", 0, "get the named release with revision")
return cmd
}
// getValues implements 'helm get values'
func (g *getValuesCmd) run(out io.Writer) error {
res, err := g.client.ReleaseContent(g.release, g.version)
func (o *getValuesOptions) run(out io.Writer) error {
res, err := o.client.ReleaseContent(o.release, o.version)
if err != nil {
return err
}
// If the user wants all values, compute the values and return.
if g.allValues {
if o.allValues {
cfg, err := chartutil.CoalesceValues(res.Chart, res.Config)
if err != nil {
return err

@ -30,13 +30,13 @@ import (
"k8s.io/client-go/tools/clientcmd"
"k8s.io/helm/pkg/helm"
helm_env "k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/kube"
"k8s.io/helm/pkg/storage/driver"
)
var (
settings helm_env.EnvSettings
settings environment.EnvSettings
config clientcmd.ClientConfig
configOnce sync.Once
)

@ -56,16 +56,18 @@ The historical release set is printed as a formatted table, e.g:
4 Mon Oct 3 10:15:13 2016 deployed alpine-0.1.0 Upgraded successfully
`
type historyCmd struct {
max int
rls string
helmc helm.Interface
colWidth uint
outputFormat string
type historyOptions struct {
colWidth uint // --col-width
max int // --max
outputFormat string // --output
release string
client helm.Interface
}
func newHistoryCmd(c helm.Interface, out io.Writer) *cobra.Command {
his := &historyCmd{helmc: c}
o := &historyOptions{client: c}
cmd := &cobra.Command{
Use: "history [flags] RELEASE_NAME",
@ -76,22 +78,22 @@ func newHistoryCmd(c helm.Interface, out io.Writer) *cobra.Command {
if len(args) == 0 {
return errReleaseRequired
}
his.helmc = ensureHelmClient(his.helmc, false)
his.rls = args[0]
return his.run(out)
o.client = ensureHelmClient(o.client, false)
o.release = args[0]
return o.run(out)
},
}
f := cmd.Flags()
f.IntVar(&his.max, "max", 256, "maximum number of revision to include in history")
f.UintVar(&his.colWidth, "col-width", 60, "specifies the max column width of output")
f.StringVarP(&his.outputFormat, "output", "o", "table", "prints the output in the specified format (json|table|yaml)")
f.IntVar(&o.max, "max", 256, "maximum number of revision to include in history")
f.UintVar(&o.colWidth, "col-width", 60, "specifies the max column width of output")
f.StringVarP(&o.outputFormat, "output", "o", "table", "prints the output in the specified format (json|table|yaml)")
return cmd
}
func (cmd *historyCmd) run(out io.Writer) error {
rels, err := cmd.helmc.ReleaseHistory(cmd.rls, cmd.max)
func (o *historyOptions) run(out io.Writer) error {
rels, err := o.client.ReleaseHistory(o.release, o.max)
if err != nil {
return err
}
@ -104,15 +106,15 @@ func (cmd *historyCmd) run(out io.Writer) error {
var history []byte
var formattingError error
switch cmd.outputFormat {
switch o.outputFormat {
case "yaml":
history, formattingError = yaml.Marshal(releaseHistory)
case "json":
history, formattingError = json.Marshal(releaseHistory)
case "table":
history = formatAsTable(releaseHistory, cmd.colWidth)
history = formatAsTable(releaseHistory, o.colWidth)
default:
return fmt.Errorf("unknown output format %q", cmd.outputFormat)
return fmt.Errorf("unknown output format %q", o.outputFormat)
}
if formattingError != nil {

@ -33,17 +33,20 @@ const initDesc = `
This command sets up local configuration in $HELM_HOME (default ~/.helm/).
`
const stableRepository = "stable"
const (
stableRepository = "stable"
defaultStableRepositoryURL = "https://kubernetes-charts.storage.googleapis.com"
)
var stableRepositoryURL = "https://kubernetes-charts.storage.googleapis.com"
type initOptions struct {
skipRefresh bool // --skip-refresh
stableRepositoryURL string // --stable-repo-url
type initCmd struct {
skipRefresh bool
home helmpath.Home
}
func newInitCmd(out io.Writer) *cobra.Command {
i := &initCmd{}
o := &initOptions{}
cmd := &cobra.Command{
Use: "init",
@ -53,27 +56,27 @@ func newInitCmd(out io.Writer) *cobra.Command {
if len(args) != 0 {
return errors.New("This command does not accept arguments")
}
i.home = settings.Home
return i.run(out)
o.home = settings.Home
return o.run(out)
},
}
f := cmd.Flags()
f.BoolVar(&i.skipRefresh, "skip-refresh", false, "do not refresh (download) the local repository cache")
f.StringVar(&stableRepositoryURL, "stable-repo-url", stableRepositoryURL, "URL for stable repository")
f.BoolVar(&o.skipRefresh, "skip-refresh", false, "do not refresh (download) the local repository cache")
f.StringVar(&o.stableRepositoryURL, "stable-repo-url", defaultStableRepositoryURL, "URL for stable repository")
return cmd
}
// run initializes local config and installs Tiller to Kubernetes cluster.
func (i *initCmd) run(out io.Writer) error {
if err := ensureDirectories(i.home, out); err != nil {
// run initializes local config.
func (o *initOptions) run(out io.Writer) error {
if err := ensureDirectories(o.home, out); err != nil {
return err
}
if err := ensureDefaultRepos(i.home, out, i.skipRefresh); err != nil {
if err := ensureDefaultRepos(o.home, out, o.skipRefresh, o.stableRepositoryURL); err != nil {
return err
}
if err := ensureRepoFileFormat(i.home.RepositoryFile(), out); err != nil {
if err := ensureRepoFileFormat(o.home.RepositoryFile(), out); err != nil {
return err
}
fmt.Fprintf(out, "$HELM_HOME has been configured at %s.\n", settings.Home)
@ -107,12 +110,12 @@ func ensureDirectories(home helmpath.Home, out io.Writer) error {
return nil
}
func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) error {
func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool, url string) error {
repoFile := home.RepositoryFile()
if fi, err := os.Stat(repoFile); err != nil {
fmt.Fprintf(out, "Creating %s \n", repoFile)
f := repo.NewRepoFile()
sr, err := initStableRepo(home.CacheIndex(stableRepository), out, skipRefresh, home)
sr, err := initRepo(url, home.CacheIndex(stableRepository), out, skipRefresh, home)
if err != nil {
return err
}
@ -126,11 +129,11 @@ func ensureDefaultRepos(home helmpath.Home, out io.Writer, skipRefresh bool) err
return nil
}
func initStableRepo(cacheFile string, out io.Writer, skipRefresh bool, home helmpath.Home) (*repo.Entry, error) {
fmt.Fprintf(out, "Adding %s repo with URL: %s \n", stableRepository, stableRepositoryURL)
func initRepo(url, cacheFile string, out io.Writer, skipRefresh bool, home helmpath.Home) (*repo.Entry, error) {
fmt.Fprintf(out, "Adding %s repo with URL: %s \n", stableRepository, url)
c := repo.Entry{
Name: stableRepository,
URL: stableRepositoryURL,
URL: url,
Cache: cacheFile,
}
r, err := repo.NewChartRepository(&c, getter.All(settings))
@ -145,7 +148,7 @@ func initStableRepo(cacheFile string, out io.Writer, skipRefresh bool, home helm
// In this case, the cacheFile is always absolute. So passing empty string
// is safe.
if err := r.DownloadIndexFile(""); err != nil {
return nil, fmt.Errorf("Looks like %q is not a valid chart repository or cannot be reached: %s", stableRepositoryURL, err.Error())
return nil, fmt.Errorf("Looks like %q is not a valid chart repository or cannot be reached: %s", url, err.Error())
}
return &c, nil

@ -38,10 +38,10 @@ func TestEnsureHome(t *testing.T) {
if err := ensureDirectories(hh, b); err != nil {
t.Error(err)
}
if err := ensureDefaultRepos(hh, b, false); err != nil {
if err := ensureDefaultRepos(hh, b, false, defaultStableRepositoryURL); err != nil {
t.Error(err)
}
if err := ensureDefaultRepos(hh, b, true); err != nil {
if err := ensureDefaultRepos(hh, b, true, defaultStableRepositoryURL); err != nil {
t.Error(err)
}
if err := ensureRepoFileFormat(hh.RepositoryFile(), b); err != nil {

@ -50,7 +50,7 @@ This command inspects a chart (directory, file, or URL) and displays the content
of the README file
`
type inspectCmd struct {
type inspectOptions struct {
chartpath string
output string
verify bool
@ -59,7 +59,6 @@ type inspectCmd struct {
repoURL string
username string
password string
certFile string
keyFile string
caFile string
@ -75,7 +74,7 @@ const (
var readmeFileNames = []string{"readme.md", "readme.txt", "readme"}
func newInspectCmd(out io.Writer) *cobra.Command {
insp := &inspectCmd{output: all}
o := &inspectOptions{output: all}
inspectCommand := &cobra.Command{
Use: "inspect [CHART]",
@ -85,13 +84,13 @@ func newInspectCmd(out io.Writer) *cobra.Command {
if err := checkArgsLength(len(args), "chart name"); err != nil {
return err
}
cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring,
insp.certFile, insp.keyFile, insp.caFile)
cp, err := locateChartPath(o.repoURL, o.username, o.password, args[0], o.version, o.verify, o.keyring,
o.certFile, o.keyFile, o.caFile)
if err != nil {
return err
}
insp.chartpath = cp
return insp.run(out)
o.chartpath = cp
return o.run(out)
},
}
@ -100,17 +99,17 @@ func newInspectCmd(out io.Writer) *cobra.Command {
Short: "shows inspect values",
Long: inspectValuesDesc,
RunE: func(cmd *cobra.Command, args []string) error {
insp.output = valuesOnly
o.output = valuesOnly
if err := checkArgsLength(len(args), "chart name"); err != nil {
return err
}
cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring,
insp.certFile, insp.keyFile, insp.caFile)
cp, err := locateChartPath(o.repoURL, o.username, o.password, args[0], o.version, o.verify, o.keyring,
o.certFile, o.keyFile, o.caFile)
if err != nil {
return err
}
insp.chartpath = cp
return insp.run(out)
o.chartpath = cp
return o.run(out)
},
}
@ -119,17 +118,17 @@ func newInspectCmd(out io.Writer) *cobra.Command {
Short: "shows inspect chart",
Long: inspectChartDesc,
RunE: func(cmd *cobra.Command, args []string) error {
insp.output = chartOnly
o.output = chartOnly
if err := checkArgsLength(len(args), "chart name"); err != nil {
return err
}
cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring,
insp.certFile, insp.keyFile, insp.caFile)
cp, err := locateChartPath(o.repoURL, o.username, o.password, args[0], o.version, o.verify, o.keyring,
o.certFile, o.keyFile, o.caFile)
if err != nil {
return err
}
insp.chartpath = cp
return insp.run(out)
o.chartpath = cp
return o.run(out)
},
}
@ -138,17 +137,17 @@ func newInspectCmd(out io.Writer) *cobra.Command {
Short: "shows inspect readme",
Long: readmeChartDesc,
RunE: func(cmd *cobra.Command, args []string) error {
insp.output = readmeOnly
o.output = readmeOnly
if err := checkArgsLength(len(args), "chart name"); err != nil {
return err
}
cp, err := locateChartPath(insp.repoURL, insp.username, insp.password, args[0], insp.version, insp.verify, insp.keyring,
insp.certFile, insp.keyFile, insp.caFile)
cp, err := locateChartPath(o.repoURL, o.username, o.password, args[0], o.version, o.verify, o.keyring,
o.certFile, o.keyFile, o.caFile)
if err != nil {
return err
}
insp.chartpath = cp
return insp.run(out)
o.chartpath = cp
return o.run(out)
},
}
@ -156,56 +155,56 @@ func newInspectCmd(out io.Writer) *cobra.Command {
vflag := "verify"
vdesc := "verify the provenance data for this chart"
for _, subCmd := range cmds {
subCmd.Flags().BoolVar(&insp.verify, vflag, false, vdesc)
subCmd.Flags().BoolVar(&o.verify, vflag, false, vdesc)
}
kflag := "keyring"
kdesc := "path to the keyring containing public verification keys"
kdefault := defaultKeyring()
for _, subCmd := range cmds {
subCmd.Flags().StringVar(&insp.keyring, kflag, kdefault, kdesc)
subCmd.Flags().StringVar(&o.keyring, kflag, kdefault, kdesc)
}
verflag := "version"
verdesc := "version of the chart. By default, the newest chart is shown"
for _, subCmd := range cmds {
subCmd.Flags().StringVar(&insp.version, verflag, "", verdesc)
subCmd.Flags().StringVar(&o.version, verflag, "", verdesc)
}
repoURL := "repo"
repoURLdesc := "chart repository url where to locate the requested chart"
for _, subCmd := range cmds {
subCmd.Flags().StringVar(&insp.repoURL, repoURL, "", repoURLdesc)
subCmd.Flags().StringVar(&o.repoURL, repoURL, "", repoURLdesc)
}
username := "username"
usernamedesc := "chart repository username where to locate the requested chart"
inspectCommand.Flags().StringVar(&insp.username, username, "", usernamedesc)
valuesSubCmd.Flags().StringVar(&insp.username, username, "", usernamedesc)
chartSubCmd.Flags().StringVar(&insp.username, username, "", usernamedesc)
inspectCommand.Flags().StringVar(&o.username, username, "", usernamedesc)
valuesSubCmd.Flags().StringVar(&o.username, username, "", usernamedesc)
chartSubCmd.Flags().StringVar(&o.username, username, "", usernamedesc)
password := "password"
passworddesc := "chart repository password where to locate the requested chart"
inspectCommand.Flags().StringVar(&insp.password, password, "", passworddesc)
valuesSubCmd.Flags().StringVar(&insp.password, password, "", passworddesc)
chartSubCmd.Flags().StringVar(&insp.password, password, "", passworddesc)
inspectCommand.Flags().StringVar(&o.password, password, "", passworddesc)
valuesSubCmd.Flags().StringVar(&o.password, password, "", passworddesc)
chartSubCmd.Flags().StringVar(&o.password, password, "", passworddesc)
certFile := "cert-file"
certFiledesc := "verify certificates of HTTPS-enabled servers using this CA bundle"
for _, subCmd := range cmds {
subCmd.Flags().StringVar(&insp.certFile, certFile, "", certFiledesc)
subCmd.Flags().StringVar(&o.certFile, certFile, "", certFiledesc)
}
keyFile := "key-file"
keyFiledesc := "identify HTTPS client using this SSL key file"
for _, subCmd := range cmds {
subCmd.Flags().StringVar(&insp.keyFile, keyFile, "", keyFiledesc)
subCmd.Flags().StringVar(&o.keyFile, keyFile, "", keyFiledesc)
}
caFile := "ca-file"
caFiledesc := "chart repository url where to locate the requested chart"
for _, subCmd := range cmds {
subCmd.Flags().StringVar(&insp.caFile, caFile, "", caFiledesc)
subCmd.Flags().StringVar(&o.caFile, caFile, "", caFiledesc)
}
for _, subCmd := range cmds[1:] {
@ -215,7 +214,7 @@ func newInspectCmd(out io.Writer) *cobra.Command {
return inspectCommand
}
func (i *inspectCmd) run(out io.Writer) error {
func (i *inspectOptions) run(out io.Writer) error {
chrt, err := chartutil.Load(i.chartpath)
if err != nil {
return err

@ -26,11 +26,11 @@ import (
func TestInspect(t *testing.T) {
b := bytes.NewBuffer(nil)
insp := &inspectCmd{
o := &inspectOptions{
chartpath: "testdata/testcharts/alpine",
output: all,
}
insp.run(b)
o.run(b)
// Load the data from the textfixture directly.
cdata, err := ioutil.ReadFile("testdata/testcharts/alpine/Chart.yaml")
@ -67,11 +67,11 @@ func TestInspect(t *testing.T) {
// Regression tests for missing values. See issue #1024.
b.Reset()
insp = &inspectCmd{
o = &inspectOptions{
chartpath: "testdata/testcharts/novals",
output: "values",
}
insp.run(b)
o.run(b)
if b.Len() != 0 {
t.Errorf("expected empty values buffer, got %q", b.String())
}

@ -104,7 +104,7 @@ To see the list of chart repositories, use 'helm repo list'. To search for
charts in a repository, use 'helm search'.
`
type installCmd struct {
type installOptions struct {
name string // --name
valueFiles valueFiles // --values
dryRun bool // --dry-run
@ -149,7 +149,7 @@ func (v *valueFiles) Set(value string) error {
}
func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
inst := &installCmd{client: c}
o := &installOptions{client: c}
cmd := &cobra.Command{
Use: "install [CHART]",
@ -160,69 +160,69 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
return err
}
debug("Original chart version: %q", inst.version)
if inst.version == "" && inst.devel {
debug("Original chart version: %q", o.version)
if o.version == "" && o.devel {
debug("setting version to >0.0.0-0")
inst.version = ">0.0.0-0"
o.version = ">0.0.0-0"
}
cp, err := locateChartPath(inst.repoURL, inst.username, inst.password, args[0], inst.version, inst.verify, inst.keyring,
inst.certFile, inst.keyFile, inst.caFile)
cp, err := locateChartPath(o.repoURL, o.username, o.password, args[0], o.version, o.verify, o.keyring,
o.certFile, o.keyFile, o.caFile)
if err != nil {
return err
}
inst.chartPath = cp
inst.client = ensureHelmClient(inst.client, false)
return inst.run(out)
o.chartPath = cp
o.client = ensureHelmClient(o.client, false)
return o.run(out)
},
}
f := cmd.Flags()
f.VarP(&inst.valueFiles, "values", "f", "specify values in a YAML file or a URL(can specify multiple)")
f.StringVarP(&inst.name, "name", "", "", "release name. If unspecified, it will autogenerate one for you")
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.StringArrayVar(&inst.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&inst.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringVar(&inst.nameTemplate, "name-template", "", "specify template used to name the release")
f.BoolVar(&inst.verify, "verify", false, "verify the package before installing it")
f.StringVar(&inst.keyring, "keyring", defaultKeyring(), "location of public keys used for verification")
f.StringVar(&inst.version, "version", "", "specify the exact chart version to install. If this is not specified, the latest version is installed")
f.Int64Var(&inst.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&inst.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
f.StringVar(&inst.repoURL, "repo", "", "chart repository url where to locate the requested chart")
f.StringVar(&inst.username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&inst.password, "password", "", "chart repository password where to locate the requested chart")
f.StringVar(&inst.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&inst.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&inst.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&inst.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
f.BoolVar(&inst.depUp, "dep-up", false, "run helm dependency update before installing the chart")
f.VarP(&o.valueFiles, "values", "f", "specify values in a YAML file or a URL(can specify multiple)")
f.StringVarP(&o.name, "name", "", "", "release name. If unspecified, it will autogenerate one for you")
f.BoolVar(&o.dryRun, "dry-run", false, "simulate an install")
f.BoolVar(&o.disableHooks, "no-hooks", false, "prevent hooks from running during install")
f.BoolVar(&o.replace, "replace", false, "re-use the given name, even if that name is already used. This is unsafe in production")
f.StringArrayVar(&o.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&o.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringVar(&o.nameTemplate, "name-template", "", "specify template used to name the release")
f.BoolVar(&o.verify, "verify", false, "verify the package before installing it")
f.StringVar(&o.keyring, "keyring", defaultKeyring(), "location of public keys used for verification")
f.StringVar(&o.version, "version", "", "specify the exact chart version to install. If this is not specified, the latest version is installed")
f.Int64Var(&o.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&o.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
f.StringVar(&o.repoURL, "repo", "", "chart repository url where to locate the requested chart")
f.StringVar(&o.username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&o.password, "password", "", "chart repository password where to locate the requested chart")
f.StringVar(&o.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&o.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&o.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
f.BoolVar(&o.depUp, "dep-up", false, "run helm dependency update before installing the chart")
return cmd
}
func (i *installCmd) run(out io.Writer) error {
debug("CHART PATH: %s\n", i.chartPath)
func (o *installOptions) run(out io.Writer) error {
debug("CHART PATH: %s\n", o.chartPath)
rawVals, err := vals(i.valueFiles, i.values, i.stringValues)
rawVals, err := vals(o.valueFiles, o.values, o.stringValues)
if err != nil {
return err
}
// If template is specified, try to run the template.
if i.nameTemplate != "" {
i.name, err = generateName(i.nameTemplate)
if o.nameTemplate != "" {
o.name, err = generateName(o.nameTemplate)
if err != nil {
return err
}
// Print the final name so the user knows what the final name of the release is.
fmt.Printf("FINAL NAME: %s\n", i.name)
fmt.Printf("FINAL NAME: %s\n", o.name)
}
// Check chart requirements to make sure all dependencies are present in /charts
chartRequested, err := chartutil.Load(i.chartPath)
chartRequested, err := chartutil.Load(o.chartPath)
if err != nil {
return err
}
@ -232,10 +232,10 @@ func (i *installCmd) run(out io.Writer) error {
// As of Helm 2.4.0, this is treated as a stopping condition:
// https://github.com/kubernetes/helm/issues/2209
if err := checkDependencies(chartRequested, req); err != nil {
if i.depUp {
if o.depUp {
man := &downloader.Manager{
Out: out,
ChartPath: i.chartPath,
ChartPath: o.chartPath,
HelmHome: settings.Home,
Keyring: defaultKeyring(),
SkipUpdate: false,
@ -253,16 +253,16 @@ func (i *installCmd) run(out io.Writer) error {
return fmt.Errorf("cannot load requirements: %v", err)
}
rel, err := i.client.InstallReleaseFromChart(
rel, err := o.client.InstallReleaseFromChart(
chartRequested,
getNamespace(),
helm.ValueOverrides(rawVals),
helm.ReleaseName(i.name),
helm.InstallDryRun(i.dryRun),
helm.InstallReuseName(i.replace),
helm.InstallDisableHooks(i.disableHooks),
helm.InstallTimeout(i.timeout),
helm.InstallWait(i.wait))
helm.ReleaseName(o.name),
helm.InstallDryRun(o.dryRun),
helm.InstallReuseName(o.replace),
helm.InstallDisableHooks(o.disableHooks),
helm.InstallTimeout(o.timeout),
helm.InstallWait(o.wait))
if err != nil {
return err
}
@ -270,15 +270,15 @@ func (i *installCmd) run(out io.Writer) error {
if rel == nil {
return nil
}
i.printRelease(out, rel)
o.printRelease(out, rel)
// If this is a dry run, we can't display status.
if i.dryRun {
if o.dryRun {
return nil
}
// Print the status like status command does
status, err := i.client.ReleaseStatus(rel.Name, 0)
status, err := o.client.ReleaseStatus(rel.Name, 0)
if err != nil {
return err
}
@ -359,7 +359,7 @@ func vals(valueFiles valueFiles, values []string, stringValues []string) ([]byte
}
// printRelease prints info about a release if the Debug is true.
func (i *installCmd) printRelease(out io.Writer, rel *release.Release) {
func (o *installOptions) printRelease(out io.Writer, rel *release.Release) {
if rel == nil {
return
}

@ -43,7 +43,7 @@ it will emit [ERROR] messages. If it encounters issues that break with conventio
or recommendation, it will emit [WARNING] messages.
`
type lintCmd struct {
type lintOptions struct {
valueFiles valueFiles
values []string
sValues []string
@ -52,7 +52,7 @@ type lintCmd struct {
}
func newLintCmd(out io.Writer) *cobra.Command {
l := &lintCmd{paths: []string{"."}}
o := &lintOptions{paths: []string{"."}}
cmd := &cobra.Command{
Use: "lint [flags] PATH",
@ -60,40 +60,40 @@ func newLintCmd(out io.Writer) *cobra.Command {
Long: longLintHelp,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
l.paths = args
o.paths = args
}
return l.run(out)
return o.run(out)
},
}
cmd.Flags().VarP(&l.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
cmd.Flags().StringArrayVar(&l.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
cmd.Flags().StringArrayVar(&l.sValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
cmd.Flags().BoolVar(&l.strict, "strict", false, "fail on lint warnings")
cmd.Flags().VarP(&o.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
cmd.Flags().StringArrayVar(&o.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
cmd.Flags().StringArrayVar(&o.sValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
cmd.Flags().BoolVar(&o.strict, "strict", false, "fail on lint warnings")
return cmd
}
var errLintNoChart = errors.New("No chart found for linting (missing Chart.yaml)")
func (l *lintCmd) run(out io.Writer) error {
func (o *lintOptions) run(out io.Writer) error {
var lowestTolerance int
if l.strict {
if o.strict {
lowestTolerance = support.WarningSev
} else {
lowestTolerance = support.ErrorSev
}
// Get the raw values
rvals, err := l.vals()
rvals, err := o.vals()
if err != nil {
return err
}
var total int
var failures int
for _, path := range l.paths {
if linter, err := lintChart(path, rvals, getNamespace(), l.strict); err != nil {
for _, path := range o.paths {
if linter, err := lintChart(path, rvals, getNamespace(), o.strict); err != nil {
fmt.Println("==> Skipping", path)
fmt.Println(err)
if err == errLintNoChart {
@ -167,11 +167,11 @@ func lintChart(path string, vals []byte, namespace string, strict bool) (support
return lint.All(chartPath, vals, namespace, strict), nil
}
func (l *lintCmd) vals() ([]byte, error) {
func (o *lintOptions) vals() ([]byte, error) {
base := map[string]interface{}{}
// User specified a values files via -f/--values
for _, filePath := range l.valueFiles {
for _, filePath := range o.valueFiles {
currentMap := map[string]interface{}{}
bytes, err := ioutil.ReadFile(filePath)
if err != nil {
@ -186,14 +186,14 @@ func (l *lintCmd) vals() ([]byte, error) {
}
// User specified a value via --set
for _, value := range l.values {
for _, value := range o.values {
if err := strvals.ParseInto(value, base); err != nil {
return []byte{}, fmt.Errorf("failed parsing --set data: %s", err)
}
}
// User specified a value via --set-string
for _, value := range l.sValues {
for _, value := range o.sValues {
if err := strvals.ParseIntoString(value, base); err != nil {
return []byte{}, fmt.Errorf("failed parsing --set-string data: %s", err)
}

@ -56,27 +56,31 @@ server's default, which may be much higher than 256. Pairing the '--max'
flag with the '--offset' flag allows you to page through results.
`
type listCmd struct {
type listOptions struct {
// flags
all bool // --all
allNamespaces bool // --all-namespaces
byDate bool // --date
colWidth uint // --col-width
deleted bool // --deleted
deleting bool // --deleting
deployed bool // --deployed
failed bool // --failed
limit int // --max
offset string // --offset
pending bool // --pending
short bool // --short
sortDesc bool // --reverse
superseded bool // --superseded
// args
filter string
short bool
limit int
offset string
byDate bool
sortDesc bool
all bool
deleted bool
deleting bool
deployed bool
failed bool
superseded bool
pending bool
client helm.Interface
colWidth uint
allNamespaces bool
}
func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
list := &listCmd{client: client}
o := &listOptions{client: client}
cmd := &cobra.Command{
Use: "list [flags] [FILTER]",
@ -85,48 +89,49 @@ func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
Aliases: []string{"ls"},
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
list.filter = strings.Join(args, " ")
o.filter = strings.Join(args, " ")
}
list.client = ensureHelmClient(list.client, list.allNamespaces)
return list.run(out)
o.client = ensureHelmClient(o.client, o.allNamespaces)
return o.run(out)
},
}
f := cmd.Flags()
f.BoolVarP(&list.short, "short", "q", false, "output short (quiet) listing format")
f.BoolVarP(&list.byDate, "date", "d", false, "sort by release date")
f.BoolVarP(&list.sortDesc, "reverse", "r", false, "reverse the sort order")
f.IntVarP(&list.limit, "max", "m", 256, "maximum number of releases to fetch")
f.StringVarP(&list.offset, "offset", "o", "", "next release name in the list, used to offset from start value")
f.BoolVarP(&list.all, "all", "a", false, "show all releases, not just the ones marked deployed")
f.BoolVar(&list.deleted, "deleted", false, "show deleted releases")
f.BoolVar(&list.deleting, "deleting", false, "show releases that are currently being deleted")
f.BoolVar(&list.deployed, "deployed", false, "show deployed releases. If no other is specified, this will be automatically enabled")
f.BoolVar(&list.failed, "failed", false, "show failed releases")
f.BoolVar(&list.pending, "pending", false, "show pending releases")
f.UintVar(&list.colWidth, "col-width", 60, "specifies the max column width of output")
f.BoolVar(&list.allNamespaces, "all-namespaces", false, "list releases across all namespaces")
f.BoolVarP(&o.short, "short", "q", false, "output short (quiet) listing format")
f.BoolVarP(&o.byDate, "date", "d", false, "sort by release date")
f.BoolVarP(&o.sortDesc, "reverse", "r", false, "reverse the sort order")
f.IntVarP(&o.limit, "max", "m", 256, "maximum number of releases to fetch")
f.StringVarP(&o.offset, "offset", "o", "", "next release name in the list, used to offset from start value")
f.BoolVarP(&o.all, "all", "a", false, "show all releases, not just the ones marked deployed")
f.BoolVar(&o.deleted, "deleted", false, "show deleted releases")
f.BoolVar(&o.superseded, "superseded", false, "show superseded releases")
f.BoolVar(&o.deleting, "deleting", false, "show releases that are currently being deleted")
f.BoolVar(&o.deployed, "deployed", false, "show deployed releases. If no other is specified, this will be automatically enabled")
f.BoolVar(&o.failed, "failed", false, "show failed releases")
f.BoolVar(&o.pending, "pending", false, "show pending releases")
f.UintVar(&o.colWidth, "col-width", 60, "specifies the max column width of output")
f.BoolVar(&o.allNamespaces, "all-namespaces", false, "list releases across all namespaces")
return cmd
}
func (l *listCmd) run(out io.Writer) error {
func (o *listOptions) run(out io.Writer) error {
sortBy := hapi.SortByName
if l.byDate {
if o.byDate {
sortBy = hapi.SortByLastReleased
}
sortOrder := hapi.SortAsc
if l.sortDesc {
if o.sortDesc {
sortOrder = hapi.SortDesc
}
stats := l.statusCodes()
stats := o.statusCodes()
res, err := l.client.ListReleases(
helm.ReleaseListLimit(l.limit),
helm.ReleaseListOffset(l.offset),
helm.ReleaseListFilter(l.filter),
res, err := o.client.ListReleases(
helm.ReleaseListLimit(o.limit),
helm.ReleaseListOffset(o.offset),
helm.ReleaseListFilter(o.filter),
helm.ReleaseListSort(sortBy),
helm.ReleaseListOrder(sortOrder),
helm.ReleaseListStatuses(stats),
@ -142,13 +147,13 @@ func (l *listCmd) run(out io.Writer) error {
rels := filterList(res)
if l.short {
if o.short {
for _, r := range rels {
fmt.Fprintln(out, r.Name)
}
return nil
}
fmt.Fprintln(out, formatList(rels, l.colWidth))
fmt.Fprintln(out, formatList(rels, o.colWidth))
return nil
}
@ -177,8 +182,8 @@ func filterList(rels []*release.Release) []*release.Release {
}
// statusCodes gets the list of status codes that are to be included in the results.
func (l *listCmd) statusCodes() []release.ReleaseStatus {
if l.all {
func (o *listOptions) statusCodes() []release.ReleaseStatus {
if o.all {
return []release.ReleaseStatus{
release.StatusUnknown,
release.StatusDeployed,
@ -191,22 +196,22 @@ func (l *listCmd) statusCodes() []release.ReleaseStatus {
}
}
status := []release.ReleaseStatus{}
if l.deployed {
if o.deployed {
status = append(status, release.StatusDeployed)
}
if l.deleted {
if o.deleted {
status = append(status, release.StatusDeleted)
}
if l.deleting {
if o.deleting {
status = append(status, release.StatusDeleting)
}
if l.failed {
if o.failed {
status = append(status, release.StatusFailed)
}
if l.superseded {
if o.superseded {
status = append(status, release.StatusSuperseded)
}
if l.pending {
if o.pending {
status = append(status, release.StatusPendingInstall, release.StatusPendingUpgrade, release.StatusPendingRollback)
}

@ -49,45 +49,47 @@ Chart.yaml file, and (if found) build the current directory into a chart.
Versioned chart archives are used by Helm package repositories.
`
type packageCmd struct {
sign bool
type packageOptions struct {
appVersion string // --app-version
dependencyUpdate bool // --dependency-update
destination string // --destination
key string // --key
keyring string // --keyring
sign bool // --sign
stringValues []string // --set-string
valueFiles valueFiles // --values
values []string // --set
version string // --version
// args
path string
valueFiles valueFiles
values []string
stringValues []string
key string
keyring string
version string
appVersion string
destination string
dependencyUpdate bool
home helmpath.Home
}
func newPackageCmd(out io.Writer) *cobra.Command {
pkg := &packageCmd{}
o := &packageOptions{}
cmd := &cobra.Command{
Use: "package [flags] [CHART_PATH] [...]",
Short: "package a chart directory into a chart archive",
Long: packageDesc,
RunE: func(cmd *cobra.Command, args []string) error {
pkg.home = settings.Home
o.home = settings.Home
if len(args) == 0 {
return fmt.Errorf("need at least one argument, the path to the chart")
}
if pkg.sign {
if pkg.key == "" {
if o.sign {
if o.key == "" {
return errors.New("--key is required for signing a package")
}
if pkg.keyring == "" {
if o.keyring == "" {
return errors.New("--keyring is required for signing a package")
}
}
for i := 0; i < len(args); i++ {
pkg.path = args[i]
if err := pkg.run(out); err != nil {
o.path = args[i]
if err := o.run(out); err != nil {
return err
}
}
@ -96,32 +98,32 @@ func newPackageCmd(out io.Writer) *cobra.Command {
}
f := cmd.Flags()
f.VarP(&pkg.valueFiles, "values", "f", "specify values in a YAML file or a URL(can specify multiple)")
f.StringArrayVar(&pkg.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&pkg.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.BoolVar(&pkg.sign, "sign", false, "use a PGP private key to sign this package")
f.StringVar(&pkg.key, "key", "", "name of the key to use when signing. Used if --sign is true")
f.StringVar(&pkg.keyring, "keyring", defaultKeyring(), "location of a public keyring")
f.StringVar(&pkg.version, "version", "", "set the version on the chart to this semver version")
f.StringVar(&pkg.appVersion, "app-version", "", "set the appVersion on the chart to this version")
f.StringVarP(&pkg.destination, "destination", "d", ".", "location to write the chart.")
f.BoolVarP(&pkg.dependencyUpdate, "dependency-update", "u", false, `update dependencies from "requirements.yaml" to dir "charts/" before packaging`)
f.VarP(&o.valueFiles, "values", "f", "specify values in a YAML file or a URL(can specify multiple)")
f.StringArrayVar(&o.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&o.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.BoolVar(&o.sign, "sign", false, "use a PGP private key to sign this package")
f.StringVar(&o.key, "key", "", "name of the key to use when signing. Used if --sign is true")
f.StringVar(&o.keyring, "keyring", defaultKeyring(), "location of a public keyring")
f.StringVar(&o.version, "version", "", "set the version on the chart to this semver version")
f.StringVar(&o.appVersion, "app-version", "", "set the appVersion on the chart to this version")
f.StringVarP(&o.destination, "destination", "d", ".", "location to write the chart.")
f.BoolVarP(&o.dependencyUpdate, "dependency-update", "u", false, `update dependencies from "requirements.yaml" to dir "charts/" before packaging`)
return cmd
}
func (p *packageCmd) run(out io.Writer) error {
path, err := filepath.Abs(p.path)
func (o *packageOptions) run(out io.Writer) error {
path, err := filepath.Abs(o.path)
if err != nil {
return err
}
if p.dependencyUpdate {
if o.dependencyUpdate {
downloadManager := &downloader.Manager{
Out: out,
ChartPath: path,
HelmHome: settings.Home,
Keyring: p.keyring,
Keyring: o.keyring,
Getters: getter.All(settings),
Debug: settings.Debug,
}
@ -136,7 +138,7 @@ func (p *packageCmd) run(out io.Writer) error {
return err
}
overrideVals, err := vals(p.valueFiles, p.values, p.stringValues)
overrideVals, err := vals(o.valueFiles, o.values, o.stringValues)
if err != nil {
return err
}
@ -151,16 +153,16 @@ func (p *packageCmd) run(out io.Writer) error {
ch.Values = newVals
// If version is set, modify the version.
if len(p.version) != 0 {
if err := setVersion(ch, p.version); err != nil {
if len(o.version) != 0 {
if err := setVersion(ch, o.version); err != nil {
return err
}
debug("Setting version to %s", p.version)
debug("Setting version to %s", o.version)
}
if p.appVersion != "" {
ch.Metadata.AppVersion = p.appVersion
debug("Setting appVersion to %s", p.appVersion)
if o.appVersion != "" {
ch.Metadata.AppVersion = o.appVersion
debug("Setting appVersion to %s", o.appVersion)
}
if filepath.Base(path) != ch.Metadata.Name {
@ -178,7 +180,7 @@ func (p *packageCmd) run(out io.Writer) error {
}
var dest string
if p.destination == "." {
if o.destination == "." {
// Save to the current working directory.
dest, err = os.Getwd()
if err != nil {
@ -186,7 +188,7 @@ func (p *packageCmd) run(out io.Writer) error {
}
} else {
// Otherwise save to set destination
dest = p.destination
dest = o.destination
}
name, err := chartutil.Save(ch, dest)
@ -196,8 +198,8 @@ func (p *packageCmd) run(out io.Writer) error {
return fmt.Errorf("Failed to save: %s", err)
}
if p.sign {
err = p.clearsign(name)
if o.sign {
err = o.clearsign(name)
}
return err
@ -214,9 +216,9 @@ func setVersion(ch *chart.Chart, ver string) error {
return nil
}
func (p *packageCmd) clearsign(filename string) error {
func (o *packageOptions) clearsign(filename string) error {
// Load keyring
signer, err := provenance.NewFromKeyring(p.keyring, p.key)
signer, err := provenance.NewFromKeyring(o.keyring, o.key)
if err != nil {
return err
}

@ -26,11 +26,10 @@ import (
"github.com/spf13/cobra"
)
type pluginInstallCmd struct {
type pluginInstallOptions struct {
source string
version string
home helmpath.Home
out io.Writer
}
const pluginInstallDesc = `
@ -41,35 +40,35 @@ Example usage:
`
func newPluginInstallCmd(out io.Writer) *cobra.Command {
pcmd := &pluginInstallCmd{out: out}
o := &pluginInstallOptions{}
cmd := &cobra.Command{
Use: "install [options] <path|url>...",
Short: "install one or more Helm plugins",
Long: pluginInstallDesc,
PreRunE: func(cmd *cobra.Command, args []string) error {
return pcmd.complete(args)
return o.complete(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
return pcmd.run()
return o.run(out)
},
}
cmd.Flags().StringVar(&pcmd.version, "version", "", "specify a version constraint. If this is not specified, the latest version is installed")
cmd.Flags().StringVar(&o.version, "version", "", "specify a version constraint. If this is not specified, the latest version is installed")
return cmd
}
func (pcmd *pluginInstallCmd) complete(args []string) error {
func (o *pluginInstallOptions) complete(args []string) error {
if err := checkArgsLength(len(args), "plugin"); err != nil {
return err
}
pcmd.source = args[0]
pcmd.home = settings.Home
o.source = args[0]
o.home = settings.Home
return nil
}
func (pcmd *pluginInstallCmd) run() error {
func (o *pluginInstallOptions) run(out io.Writer) error {
installer.Debug = settings.Debug
i, err := installer.NewForSource(pcmd.source, pcmd.version, pcmd.home)
i, err := installer.NewForSource(o.source, o.version, o.home)
if err != nil {
return err
}
@ -87,6 +86,6 @@ func (pcmd *pluginInstallCmd) run() error {
return err
}
fmt.Fprintf(pcmd.out, "Installed plugin: %s\n", p.Metadata.Name)
fmt.Fprintf(out, "Installed plugin: %s\n", p.Metadata.Name)
return nil
}

@ -25,24 +25,24 @@ import (
"github.com/spf13/cobra"
)
type pluginListCmd struct {
type pluginListOptions struct {
home helmpath.Home
}
func newPluginListCmd(out io.Writer) *cobra.Command {
pcmd := &pluginListCmd{}
o := &pluginListOptions{}
cmd := &cobra.Command{
Use: "list",
Short: "list installed Helm plugins",
RunE: func(cmd *cobra.Command, args []string) error {
pcmd.home = settings.Home
return pcmd.run(out)
o.home = settings.Home
return o.run(out)
},
}
return cmd
}
func (pcmd *pluginListCmd) run(out io.Writer) error {
func (o *pluginListOptions) run(out io.Writer) error {
debug("pluginDirs: %s", settings.PluginDirs())
plugins, err := findPlugins(settings.PluginDirs())
if err != nil {

@ -28,43 +28,43 @@ import (
"github.com/spf13/cobra"
)
type pluginRemoveCmd struct {
type pluginRemoveOptions struct {
names []string
home helmpath.Home
}
func newPluginRemoveCmd(out io.Writer) *cobra.Command {
pcmd := &pluginRemoveCmd{}
o := &pluginRemoveOptions{}
cmd := &cobra.Command{
Use: "remove <plugin>...",
Short: "remove one or more Helm plugins",
PreRunE: func(cmd *cobra.Command, args []string) error {
return pcmd.complete(args)
return o.complete(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
return pcmd.run(out)
return o.run(out)
},
}
return cmd
}
func (pcmd *pluginRemoveCmd) complete(args []string) error {
func (o *pluginRemoveOptions) complete(args []string) error {
if len(args) == 0 {
return errors.New("please provide plugin name to remove")
}
pcmd.names = args
pcmd.home = settings.Home
o.names = args
o.home = settings.Home
return nil
}
func (pcmd *pluginRemoveCmd) run(out io.Writer) error {
func (o *pluginRemoveOptions) run(out io.Writer) error {
debug("loading installed plugins from %s", settings.PluginDirs())
plugins, err := findPlugins(settings.PluginDirs())
if err != nil {
return err
}
var errorPlugins []string
for _, name := range pcmd.names {
for _, name := range o.names {
if found := findPlugin(plugins, name); found != nil {
if err := removePlugin(found); err != nil {
errorPlugins = append(errorPlugins, fmt.Sprintf("Failed to remove plugin %s, got error (%v)", name, err))

@ -29,36 +29,36 @@ import (
"github.com/spf13/cobra"
)
type pluginUpdateCmd struct {
type pluginUpdateOptions struct {
names []string
home helmpath.Home
}
func newPluginUpdateCmd(out io.Writer) *cobra.Command {
pcmd := &pluginUpdateCmd{}
o := &pluginUpdateOptions{}
cmd := &cobra.Command{
Use: "update <plugin>...",
Short: "update one or more Helm plugins",
PreRunE: func(cmd *cobra.Command, args []string) error {
return pcmd.complete(args)
return o.complete(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
return pcmd.run(out)
return o.run(out)
},
}
return cmd
}
func (pcmd *pluginUpdateCmd) complete(args []string) error {
func (o *pluginUpdateOptions) complete(args []string) error {
if len(args) == 0 {
return errors.New("please provide plugin name to update")
}
pcmd.names = args
pcmd.home = settings.Home
o.names = args
o.home = settings.Home
return nil
}
func (pcmd *pluginUpdateCmd) run(out io.Writer) error {
func (o *pluginUpdateOptions) run(out io.Writer) error {
installer.Debug = settings.Debug
debug("loading installed plugins from %s", settings.PluginDirs())
plugins, err := findPlugins(settings.PluginDirs())
@ -67,9 +67,9 @@ func (pcmd *pluginUpdateCmd) run(out io.Writer) error {
}
var errorPlugins []string
for _, name := range pcmd.names {
for _, name := range o.names {
if found := findPlugin(plugins, name); found != nil {
if err := updatePlugin(found, pcmd.home); err != nil {
if err := updatePlugin(found, o.home); err != nil {
errorPlugins = append(errorPlugins, fmt.Sprintf("Failed to update plugin %s, got error (%v)", name, err))
} else {
fmt.Fprintf(out, "Updated plugin: %s\n", name)

@ -33,7 +33,7 @@ The argument this command takes is the name of a deployed release.
The tests to be run are defined in the chart that was installed.
`
type releaseTestCmd struct {
type releaseTestOptions struct {
name string
client helm.Interface
timeout int64
@ -41,7 +41,7 @@ type releaseTestCmd struct {
}
func newReleaseTestCmd(c helm.Interface, out io.Writer) *cobra.Command {
rlsTest := &releaseTestCmd{client: c}
o := &releaseTestOptions{client: c}
cmd := &cobra.Command{
Use: "test [RELEASE]",
@ -52,24 +52,24 @@ func newReleaseTestCmd(c helm.Interface, out io.Writer) *cobra.Command {
return err
}
rlsTest.name = args[0]
rlsTest.client = ensureHelmClient(rlsTest.client, false)
return rlsTest.run(out)
o.name = args[0]
o.client = ensureHelmClient(o.client, false)
return o.run(out)
},
}
f := cmd.Flags()
f.Int64Var(&rlsTest.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&rlsTest.cleanup, "cleanup", false, "delete test pods upon completion")
f.Int64Var(&o.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&o.cleanup, "cleanup", false, "delete test pods upon completion")
return cmd
}
func (t *releaseTestCmd) run(out io.Writer) (err error) {
c, errc := t.client.RunReleaseTest(
t.name,
helm.ReleaseTestTimeout(t.timeout),
helm.ReleaseTestCleanup(t.cleanup),
func (o *releaseTestOptions) run(out io.Writer) (err error) {
c, errc := o.client.RunReleaseTest(
o.name,
helm.ReleaseTestTimeout(o.timeout),
helm.ReleaseTestCleanup(o.cleanup),
)
testErr := &testErr{}

@ -27,7 +27,7 @@ import (
"k8s.io/helm/pkg/repo"
)
type repoAddCmd struct {
type repoAddOptions struct {
name string
url string
username string
@ -41,7 +41,7 @@ type repoAddCmd struct {
}
func newRepoAddCmd(out io.Writer) *cobra.Command {
add := &repoAddCmd{}
o := &repoAddOptions{}
cmd := &cobra.Command{
Use: "add [flags] [NAME] [URL]",
@ -51,30 +51,30 @@ func newRepoAddCmd(out io.Writer) *cobra.Command {
return err
}
add.name = args[0]
add.url = args[1]
add.home = settings.Home
o.name = args[0]
o.url = args[1]
o.home = settings.Home
return add.run(out)
return o.run(out)
},
}
f := cmd.Flags()
f.StringVar(&add.username, "username", "", "chart repository username")
f.StringVar(&add.password, "password", "", "chart repository password")
f.BoolVar(&add.noupdate, "no-update", false, "raise error if repo is already registered")
f.StringVar(&add.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&add.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&add.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.StringVar(&o.username, "username", "", "chart repository username")
f.StringVar(&o.password, "password", "", "chart repository password")
f.BoolVar(&o.noupdate, "no-update", false, "raise error if repo is already registered")
f.StringVar(&o.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&o.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
return cmd
}
func (a *repoAddCmd) run(out io.Writer) error {
if err := addRepository(a.name, a.url, a.username, a.password, a.home, a.certFile, a.keyFile, a.caFile, a.noupdate); err != nil {
func (o *repoAddOptions) run(out io.Writer) error {
if err := addRepository(o.name, o.url, o.username, o.password, o.home, o.certFile, o.keyFile, o.caFile, o.noupdate); err != nil {
return err
}
fmt.Fprintf(out, "%q has been added to your repositories\n", a.name)
fmt.Fprintf(out, "%q has been added to your repositories\n", o.name)
return nil
}

@ -38,14 +38,14 @@ 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.
`
type repoIndexCmd struct {
type repoIndexOptions struct {
dir string
url string
merge string
}
func newRepoIndexCmd(out io.Writer) *cobra.Command {
index := &repoIndexCmd{}
o := &repoIndexOptions{}
cmd := &cobra.Command{
Use: "index [flags] [DIR]",
@ -56,20 +56,20 @@ func newRepoIndexCmd(out io.Writer) *cobra.Command {
return err
}
index.dir = args[0]
o.dir = args[0]
return index.run(out)
return o.run(out)
},
}
f := cmd.Flags()
f.StringVar(&index.url, "url", "", "url of chart repository")
f.StringVar(&index.merge, "merge", "", "merge the generated index into the given index")
f.StringVar(&o.url, "url", "", "url of chart repository")
f.StringVar(&o.merge, "merge", "", "merge the generated index into the given index")
return cmd
}
func (i *repoIndexCmd) run(out io.Writer) error {
func (i *repoIndexOptions) run(out io.Writer) error {
path, err := filepath.Abs(i.dir)
if err != nil {
return err

@ -28,27 +28,27 @@ import (
"k8s.io/helm/pkg/repo"
)
type repoListCmd struct {
type repoListOptions struct {
home helmpath.Home
}
func newRepoListCmd(out io.Writer) *cobra.Command {
list := &repoListCmd{}
o := &repoListOptions{}
cmd := &cobra.Command{
Use: "list [flags]",
Short: "list chart repositories",
RunE: func(cmd *cobra.Command, args []string) error {
list.home = settings.Home
return list.run(out)
o.home = settings.Home
return o.run(out)
},
}
return cmd
}
func (a *repoListCmd) run(out io.Writer) error {
f, err := repo.LoadRepositoriesFile(a.home.RepositoryFile())
func (o *repoListOptions) run(out io.Writer) error {
f, err := repo.LoadRepositoriesFile(o.home.RepositoryFile())
if err != nil {
return err
}

@ -27,13 +27,13 @@ import (
"k8s.io/helm/pkg/repo"
)
type repoRemoveCmd struct {
type repoRemoveOptions struct {
name string
home helmpath.Home
}
func newRepoRemoveCmd(out io.Writer) *cobra.Command {
remove := &repoRemoveCmd{}
o := &repoRemoveOptions{}
cmd := &cobra.Command{
Use: "remove [flags] [NAME]",
@ -43,17 +43,17 @@ func newRepoRemoveCmd(out io.Writer) *cobra.Command {
if err := checkArgsLength(len(args), "name of chart repository"); err != nil {
return err
}
remove.name = args[0]
remove.home = settings.Home
o.name = args[0]
o.home = settings.Home
return remove.run(out)
return o.run(out)
},
}
return cmd
}
func (r *repoRemoveCmd) run(out io.Writer) error {
func (r *repoRemoveOptions) run(out io.Writer) error {
return removeRepoLine(out, r.name, r.home)
}

@ -39,13 +39,13 @@ future releases.
var errNoRepositories = errors.New("no repositories found. You must add one before updating")
type repoUpdateCmd struct {
type repoUpdateOptions struct {
update func([]*repo.ChartRepository, io.Writer, helmpath.Home)
home helmpath.Home
}
func newRepoUpdateCmd(out io.Writer) *cobra.Command {
u := &repoUpdateCmd{update: updateCharts}
o := &repoUpdateOptions{update: updateCharts}
cmd := &cobra.Command{
Use: "update",
@ -53,15 +53,15 @@ func newRepoUpdateCmd(out io.Writer) *cobra.Command {
Short: "update information of available charts locally from chart repositories",
Long: updateDesc,
RunE: func(cmd *cobra.Command, args []string) error {
u.home = settings.Home
return u.run(out)
o.home = settings.Home
return o.run(out)
},
}
return cmd
}
func (u *repoUpdateCmd) run(out io.Writer) error {
f, err := repo.LoadRepositoriesFile(u.home.RepositoryFile())
func (o *repoUpdateOptions) run(out io.Writer) error {
f, err := repo.LoadRepositoriesFile(o.home.RepositoryFile())
if err != nil {
return err
}
@ -78,7 +78,7 @@ func (u *repoUpdateCmd) run(out io.Writer) error {
repos = append(repos, r)
}
u.update(repos, out, u.home)
o.update(repos, out, o.home)
return nil
}

@ -51,11 +51,11 @@ func TestUpdateCmd(t *testing.T) {
fmt.Fprintln(out, re.Config.Name)
}
}
uc := &repoUpdateCmd{
o := &repoUpdateOptions{
update: updater,
home: helmpath.Home(thome),
}
if err := uc.run(out); err != nil {
if err := o.run(out); err != nil {
t.Fatal(err)
}

@ -34,7 +34,7 @@ second is a revision (version) number. To see revision numbers, run
'helm history RELEASE'.
`
type rollbackCmd struct {
type rollbackOptions struct {
name string
revision int
dryRun bool
@ -47,7 +47,7 @@ type rollbackCmd struct {
}
func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
rollback := &rollbackCmd{client: c}
o := &rollbackOptions{client: c}
cmd := &cobra.Command{
Use: "rollback [flags] [RELEASE] [REVISION]",
@ -58,40 +58,40 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
return err
}
rollback.name = args[0]
o.name = args[0]
v64, err := strconv.ParseInt(args[1], 10, 32)
if err != nil {
return fmt.Errorf("invalid revision number '%q': %s", args[1], err)
}
rollback.revision = int(v64)
rollback.client = ensureHelmClient(rollback.client, false)
return rollback.run(out)
o.revision = int(v64)
o.client = ensureHelmClient(o.client, false)
return o.run(out)
},
}
f := cmd.Flags()
f.BoolVar(&rollback.dryRun, "dry-run", false, "simulate a rollback")
f.BoolVar(&rollback.recreate, "recreate-pods", false, "performs pods restart for the resource if applicable")
f.BoolVar(&rollback.force, "force", false, "force resource update through delete/recreate if needed")
f.BoolVar(&rollback.disableHooks, "no-hooks", false, "prevent hooks from running during rollback")
f.Int64Var(&rollback.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&rollback.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
f.BoolVar(&o.dryRun, "dry-run", false, "simulate a rollback")
f.BoolVar(&o.recreate, "recreate-pods", false, "performs pods restart for the resource if applicable")
f.BoolVar(&o.force, "force", false, "force resource update through delete/recreate if needed")
f.BoolVar(&o.disableHooks, "no-hooks", false, "prevent hooks from running during rollback")
f.Int64Var(&o.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&o.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
return cmd
}
func (r *rollbackCmd) run(out io.Writer) error {
_, err := r.client.RollbackRelease(
r.name,
helm.RollbackDryRun(r.dryRun),
helm.RollbackRecreate(r.recreate),
helm.RollbackForce(r.force),
helm.RollbackDisableHooks(r.disableHooks),
helm.RollbackVersion(r.revision),
helm.RollbackTimeout(r.timeout),
helm.RollbackWait(r.wait))
func (o *rollbackOptions) run(out io.Writer) error {
_, err := o.client.RollbackRelease(
o.name,
helm.RollbackDryRun(o.dryRun),
helm.RollbackRecreate(o.recreate),
helm.RollbackForce(o.force),
helm.RollbackDisableHooks(o.disableHooks),
helm.RollbackVersion(o.revision),
helm.RollbackTimeout(o.timeout),
helm.RollbackWait(o.wait))
if err != nil {
return err
}

@ -40,7 +40,7 @@ Repositories are managed with 'helm repo' commands.
// searchMaxScore suggests that any score higher than this is not considered a match.
const searchMaxScore = 25
type searchCmd struct {
type searchOptions struct {
helmhome helmpath.Home
versions bool
@ -49,28 +49,28 @@ type searchCmd struct {
}
func newSearchCmd(out io.Writer) *cobra.Command {
sc := &searchCmd{}
o := &searchOptions{}
cmd := &cobra.Command{
Use: "search [keyword]",
Short: "search for a keyword in charts",
Long: searchDesc,
RunE: func(cmd *cobra.Command, args []string) error {
sc.helmhome = settings.Home
return sc.run(out, args)
o.helmhome = settings.Home
return o.run(out, args)
},
}
f := cmd.Flags()
f.BoolVarP(&sc.regexp, "regexp", "r", false, "use regular expressions for searching")
f.BoolVarP(&sc.versions, "versions", "l", false, "show the long listing, with each version of each chart on its own line")
f.StringVarP(&sc.version, "version", "v", "", "search using semantic versioning constraints")
f.BoolVarP(&o.regexp, "regexp", "r", false, "use regular expressions for searching")
f.BoolVarP(&o.versions, "versions", "l", false, "show the long listing, with each version of each chart on its own line")
f.StringVarP(&o.version, "version", "v", "", "search using semantic versioning constraints")
return cmd
}
func (s *searchCmd) run(out io.Writer, args []string) error {
index, err := s.buildIndex(out)
func (o *searchOptions) run(out io.Writer, args []string) error {
index, err := o.buildIndex(out)
if err != nil {
return err
}
@ -80,29 +80,29 @@ func (s *searchCmd) run(out io.Writer, args []string) error {
res = index.All()
} else {
q := strings.Join(args, " ")
res, err = index.Search(q, searchMaxScore, s.regexp)
res, err = index.Search(q, searchMaxScore, o.regexp)
if err != nil {
return err
}
}
search.SortScore(res)
data, err := s.applyConstraint(res)
data, err := o.applyConstraint(res)
if err != nil {
return err
}
fmt.Fprintln(out, s.formatSearchResults(data))
fmt.Fprintln(out, o.formatSearchResults(data))
return nil
}
func (s *searchCmd) applyConstraint(res []*search.Result) ([]*search.Result, error) {
if len(s.version) == 0 {
func (o *searchOptions) applyConstraint(res []*search.Result) ([]*search.Result, error) {
if len(o.version) == 0 {
return res, nil
}
constraint, err := semver.NewConstraint(s.version)
constraint, err := semver.NewConstraint(o.version)
if err != nil {
return res, fmt.Errorf("an invalid version/constraint format: %s", err)
}
@ -116,7 +116,7 @@ func (s *searchCmd) applyConstraint(res []*search.Result) ([]*search.Result, err
v, err := semver.NewVersion(r.Chart.Version)
if err != nil || constraint.Check(v) {
data = append(data, r)
if !s.versions {
if !o.versions {
foundNames[r.Name] = true // If user hasn't requested all versions, only show the latest that matches
}
}
@ -125,7 +125,7 @@ func (s *searchCmd) applyConstraint(res []*search.Result) ([]*search.Result, err
return data, nil
}
func (s *searchCmd) formatSearchResults(res []*search.Result) string {
func (o *searchOptions) formatSearchResults(res []*search.Result) string {
if len(res) == 0 {
return "No results found"
}
@ -138,9 +138,9 @@ func (s *searchCmd) formatSearchResults(res []*search.Result) string {
return table.String()
}
func (s *searchCmd) buildIndex(out io.Writer) (*search.Index, error) {
func (o *searchOptions) buildIndex(out io.Writer) (*search.Index, error) {
// Load the repositories.yaml
rf, err := repo.LoadRepositoriesFile(s.helmhome.RepositoryFile())
rf, err := repo.LoadRepositoriesFile(o.helmhome.RepositoryFile())
if err != nil {
return nil, err
}
@ -148,7 +148,7 @@ func (s *searchCmd) buildIndex(out io.Writer) (*search.Index, error) {
i := search.NewIndex()
for _, re := range rf.Repositories {
n := re.Name
f := s.helmhome.CacheIndex(n)
f := o.helmhome.CacheIndex(n)
ind, err := repo.LoadIndexFile(f)
if err != nil {
// TODO should print to stderr
@ -156,7 +156,7 @@ func (s *searchCmd) buildIndex(out io.Writer) (*search.Index, error) {
continue
}
i.AddRepo(n, ind, s.versions || len(s.version) > 0)
i.AddRepo(n, ind, o.versions || len(o.version) > 0)
}
return i, nil
}

@ -44,7 +44,7 @@ The status consists of:
- additional notes provided by the chart
`
type statusCmd struct {
type statusOptions struct {
release string
client helm.Interface
version int
@ -52,7 +52,7 @@ type statusCmd struct {
}
func newStatusCmd(client helm.Interface, out io.Writer) *cobra.Command {
status := &statusCmd{client: client}
o := &statusOptions{client: client}
cmd := &cobra.Command{
Use: "status [flags] RELEASE_NAME",
@ -62,25 +62,25 @@ func newStatusCmd(client helm.Interface, out io.Writer) *cobra.Command {
if len(args) == 0 {
return errReleaseRequired
}
status.release = args[0]
status.client = ensureHelmClient(status.client, false)
return status.run(out)
o.release = args[0]
o.client = ensureHelmClient(o.client, false)
return o.run(out)
},
}
cmd.PersistentFlags().IntVar(&status.version, "revision", 0, "if set, display the status of the named release with revision")
cmd.PersistentFlags().StringVarP(&status.outfmt, "output", "o", "", "output the status in the specified format (json or yaml)")
cmd.PersistentFlags().IntVar(&o.version, "revision", 0, "if set, display the status of the named release with revision")
cmd.PersistentFlags().StringVarP(&o.outfmt, "output", "o", "", "output the status in the specified format (json or yaml)")
return cmd
}
func (s *statusCmd) run(out io.Writer) error {
res, err := s.client.ReleaseStatus(s.release, s.version)
func (o *statusOptions) run(out io.Writer) error {
res, err := o.client.ReleaseStatus(o.release, o.version)
if err != nil {
return err
}
switch s.outfmt {
switch o.outfmt {
case "":
PrintStatus(out, res)
return nil
@ -100,7 +100,7 @@ func (s *statusCmd) run(out io.Writer) error {
return nil
}
return fmt.Errorf("Unknown output format %q", s.outfmt)
return fmt.Errorf("Unknown output format %q", o.outfmt)
}
// PrintStatus prints out the status of a release. Shared because also used by

@ -60,7 +60,7 @@ To render just one template in a chart, use '-x':
$ helm template mychart -x templates/deployment.yaml
`
type templateCmd struct {
type templateOptions struct {
valueFiles valueFiles
chartPath string
values []string
@ -74,7 +74,7 @@ type templateCmd struct {
}
func newTemplateCmd(out io.Writer) *cobra.Command {
t := &templateCmd{}
o := &templateOptions{}
cmd := &cobra.Command{
Use: "template [flags] CHART",
@ -86,39 +86,39 @@ func newTemplateCmd(out io.Writer) *cobra.Command {
}
// verify chart path exists
if _, err := os.Stat(args[0]); err == nil {
if t.chartPath, err = filepath.Abs(args[0]); err != nil {
if o.chartPath, err = filepath.Abs(args[0]); err != nil {
return err
}
} else {
return err
}
return t.run(out)
return o.run(out)
},
}
f := cmd.Flags()
f.BoolVar(&t.showNotes, "notes", false, "show the computed NOTES.txt file as well")
f.StringVarP(&t.releaseName, "name", "", "RELEASE-NAME", "release name")
f.StringArrayVarP(&t.renderFiles, "execute", "x", []string{}, "only execute the given templates")
f.VarP(&t.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
f.StringArrayVar(&t.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&t.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringVar(&t.nameTemplate, "name-template", "", "specify template used to name the release")
f.StringVar(&t.kubeVersion, "kube-version", defaultKubeVersion, "kubernetes version used as Capabilities.KubeVersion.Major/Minor")
f.StringVar(&t.outputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout")
f.BoolVar(&o.showNotes, "notes", false, "show the computed NOTES.txt file as well")
f.StringVarP(&o.releaseName, "name", "", "RELEASE-NAME", "release name")
f.StringArrayVarP(&o.renderFiles, "execute", "x", []string{}, "only execute the given templates")
f.VarP(&o.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
f.StringArrayVar(&o.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&o.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringVar(&o.nameTemplate, "name-template", "", "specify template used to name the release")
f.StringVar(&o.kubeVersion, "kube-version", defaultKubeVersion, "kubernetes version used as Capabilities.KubeVersion.Major/Minor")
f.StringVar(&o.outputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout")
return cmd
}
func (t *templateCmd) run(out io.Writer) error {
func (o *templateOptions) run(out io.Writer) error {
// verify specified templates exist relative to chart
rf := []string{}
var af string
var err error
if len(t.renderFiles) > 0 {
for _, f := range t.renderFiles {
if len(o.renderFiles) > 0 {
for _, f := range o.renderFiles {
if !filepath.IsAbs(f) {
af, err = filepath.Abs(filepath.Join(t.chartPath, f))
af, err = filepath.Abs(filepath.Join(o.chartPath, f))
if err != nil {
return fmt.Errorf("could not resolve template path: %s", err)
}
@ -134,29 +134,29 @@ func (t *templateCmd) run(out io.Writer) error {
}
// verify that output-dir exists if provided
if t.outputDir != "" {
_, err = os.Stat(t.outputDir)
if o.outputDir != "" {
_, err = os.Stat(o.outputDir)
if os.IsNotExist(err) {
return fmt.Errorf("output-dir '%s' does not exist", t.outputDir)
return fmt.Errorf("output-dir '%s' does not exist", o.outputDir)
}
}
// get combined values and create config
config, err := vals(t.valueFiles, t.values, t.stringValues)
config, err := vals(o.valueFiles, o.values, o.stringValues)
if err != nil {
return err
}
// If template is specified, try to run the template.
if t.nameTemplate != "" {
t.releaseName, err = generateName(t.nameTemplate)
if o.nameTemplate != "" {
o.releaseName, err = generateName(o.nameTemplate)
if err != nil {
return err
}
}
// Check chart requirements to make sure all dependencies are present in /charts
c, err := chartutil.Load(t.chartPath)
c, err := chartutil.Load(o.chartPath)
if err != nil {
return err
}
@ -169,7 +169,7 @@ func (t *templateCmd) run(out io.Writer) error {
return fmt.Errorf("cannot load requirements: %v", err)
}
options := chartutil.ReleaseOptions{
Name: t.releaseName,
Name: o.releaseName,
Time: time.Now(),
Namespace: getNamespace(),
}
@ -193,7 +193,7 @@ func (t *templateCmd) run(out io.Writer) error {
}
// kubernetes version
kv, err := semver.NewVersion(t.kubeVersion)
kv, err := semver.NewVersion(o.kubeVersion)
if err != nil {
return fmt.Errorf("could not parse a kubernetes version: %v", err)
}
@ -226,7 +226,7 @@ func (t *templateCmd) run(out io.Writer) error {
// make needle path absolute
d := strings.Split(needle, string(os.PathSeparator))
dd := d[1:]
an := filepath.Join(t.chartPath, strings.Join(dd, string(os.PathSeparator)))
an := filepath.Join(o.chartPath, strings.Join(dd, string(os.PathSeparator)))
for _, h := range haystack {
if h == an {
@ -237,7 +237,7 @@ func (t *templateCmd) run(out io.Writer) error {
}
if settings.Debug {
rel := &release.Release{
Name: t.releaseName,
Name: o.releaseName,
Chart: c,
Config: config,
Version: 1,
@ -247,24 +247,24 @@ func (t *templateCmd) run(out io.Writer) error {
}
for _, m := range tiller.SortByKind(listManifests) {
if len(t.renderFiles) > 0 && !in(m.Name, rf) {
if len(o.renderFiles) > 0 && !in(m.Name, rf) {
continue
}
data := m.Content
b := filepath.Base(m.Name)
if !t.showNotes && b == "NOTES.txt" {
if !o.showNotes && b == "NOTES.txt" {
continue
}
if strings.HasPrefix(b, "_") {
continue
}
if t.outputDir != "" {
if o.outputDir != "" {
// blank template after execution
if whitespaceRegex.MatchString(data) {
continue
}
err = writeToFile(t.outputDir, m.Name, data)
err = writeToFile(o.outputDir, m.Name, data)
if err != nil {
return err
}

@ -53,7 +53,7 @@ set for a key called 'foo', the 'newbar' value would take precedence:
$ helm upgrade --set foo=bar --set foo=newbar redis ./redis
`
type upgradeCmd struct {
type upgradeOptions struct {
release string
chart string
client helm.Interface
@ -83,7 +83,7 @@ type upgradeCmd struct {
}
func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
upgrade := &upgradeCmd{client: client}
o := &upgradeOptions{client: client}
cmd := &cobra.Command{
Use: "upgrade [RELEASE] [CHART]",
@ -94,81 +94,81 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
return err
}
if upgrade.version == "" && upgrade.devel {
if o.version == "" && o.devel {
debug("setting version to >0.0.0-0")
upgrade.version = ">0.0.0-0"
o.version = ">0.0.0-0"
}
upgrade.release = args[0]
upgrade.chart = args[1]
upgrade.client = ensureHelmClient(upgrade.client, false)
o.release = args[0]
o.chart = args[1]
o.client = ensureHelmClient(o.client, false)
return upgrade.run(out)
return o.run(out)
},
}
f := cmd.Flags()
f.VarP(&upgrade.valueFiles, "values", "f", "specify values in a YAML file or a URL(can specify multiple)")
f.BoolVar(&upgrade.dryRun, "dry-run", false, "simulate an upgrade")
f.BoolVar(&upgrade.recreate, "recreate-pods", false, "performs pods restart for the resource if applicable")
f.BoolVar(&upgrade.force, "force", false, "force resource update through delete/recreate if needed")
f.StringArrayVar(&upgrade.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&upgrade.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks. DEPRECATED. Use no-hooks")
f.BoolVar(&upgrade.disableHooks, "no-hooks", false, "disable pre/post upgrade hooks")
f.BoolVar(&upgrade.verify, "verify", false, "verify the provenance of the chart before upgrading")
f.StringVar(&upgrade.keyring, "keyring", defaultKeyring(), "path to the keyring that contains public signing keys")
f.BoolVarP(&upgrade.install, "install", "i", false, "if a release by this name doesn't already exist, run an install")
f.StringVar(&upgrade.version, "version", "", "specify the exact chart version to use. If this is not specified, the latest version is used")
f.Int64Var(&upgrade.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&upgrade.resetValues, "reset-values", false, "when upgrading, reset the values to the ones built into the chart")
f.BoolVar(&upgrade.reuseValues, "reuse-values", false, "when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored.")
f.BoolVar(&upgrade.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
f.StringVar(&upgrade.repoURL, "repo", "", "chart repository url where to locate the requested chart")
f.StringVar(&upgrade.username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&upgrade.password, "password", "", "chart repository password where to locate the requested chart")
f.StringVar(&upgrade.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&upgrade.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&upgrade.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&upgrade.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
f.VarP(&o.valueFiles, "values", "f", "specify values in a YAML file or a URL(can specify multiple)")
f.BoolVar(&o.dryRun, "dry-run", false, "simulate an upgrade")
f.BoolVar(&o.recreate, "recreate-pods", false, "performs pods restart for the resource if applicable")
f.BoolVar(&o.force, "force", false, "force resource update through delete/recreate if needed")
f.StringArrayVar(&o.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&o.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.BoolVar(&o.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks. DEPRECATED. Use no-hooks")
f.BoolVar(&o.disableHooks, "no-hooks", false, "disable pre/post upgrade hooks")
f.BoolVar(&o.verify, "verify", false, "verify the provenance of the chart before upgrading")
f.StringVar(&o.keyring, "keyring", defaultKeyring(), "path to the keyring that contains public signing keys")
f.BoolVarP(&o.install, "install", "i", false, "if a release by this name doesn't already exist, run an install")
f.StringVar(&o.version, "version", "", "specify the exact chart version to use. If this is not specified, the latest version is used")
f.Int64Var(&o.timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)")
f.BoolVar(&o.resetValues, "reset-values", false, "when upgrading, reset the values to the ones built into the chart")
f.BoolVar(&o.reuseValues, "reuse-values", false, "when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored.")
f.BoolVar(&o.wait, "wait", false, "if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout")
f.StringVar(&o.repoURL, "repo", "", "chart repository url where to locate the requested chart")
f.StringVar(&o.username, "username", "", "chart repository username where to locate the requested chart")
f.StringVar(&o.password, "password", "", "chart repository password where to locate the requested chart")
f.StringVar(&o.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
f.StringVar(&o.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
f.BoolVar(&o.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
f.MarkDeprecated("disable-hooks", "use --no-hooks instead")
return cmd
}
func (u *upgradeCmd) run(out io.Writer) error {
chartPath, err := locateChartPath(u.repoURL, u.username, u.password, u.chart, u.version, u.verify, u.keyring, u.certFile, u.keyFile, u.caFile)
func (o *upgradeOptions) run(out io.Writer) error {
chartPath, err := locateChartPath(o.repoURL, o.username, o.password, o.chart, o.version, o.verify, o.keyring, o.certFile, o.keyFile, o.caFile)
if err != nil {
return err
}
if u.install {
if o.install {
// If a release does not exist, install it. If another error occurs during
// the check, ignore the error and continue with the upgrade.
_, err := u.client.ReleaseHistory(u.release, 1)
_, err := o.client.ReleaseHistory(o.release, 1)
if err != nil && strings.Contains(err.Error(), driver.ErrReleaseNotFound(u.release).Error()) {
fmt.Fprintf(out, "Release %q does not exist. Installing it now.\n", u.release)
ic := &installCmd{
if err != nil && strings.Contains(err.Error(), driver.ErrReleaseNotFound(o.release).Error()) {
fmt.Fprintf(out, "Release %q does not exist. Installing it now.\n", o.release)
io := &installOptions{
chartPath: chartPath,
client: u.client,
name: u.release,
valueFiles: u.valueFiles,
dryRun: u.dryRun,
verify: u.verify,
disableHooks: u.disableHooks,
keyring: u.keyring,
values: u.values,
stringValues: u.stringValues,
timeout: u.timeout,
wait: u.wait,
client: o.client,
name: o.release,
valueFiles: o.valueFiles,
dryRun: o.dryRun,
verify: o.verify,
disableHooks: o.disableHooks,
keyring: o.keyring,
values: o.values,
stringValues: o.stringValues,
timeout: o.timeout,
wait: o.wait,
}
return ic.run(out)
return io.run(out)
}
}
rawVals, err := vals(u.valueFiles, u.values, u.stringValues)
rawVals, err := vals(o.valueFiles, o.values, o.stringValues)
if err != nil {
return err
}
@ -186,18 +186,18 @@ func (u *upgradeCmd) run(out io.Writer) error {
return err
}
resp, err := u.client.UpdateRelease(
u.release,
resp, err := o.client.UpdateRelease(
o.release,
chartPath,
helm.UpdateValueOverrides(rawVals),
helm.UpgradeDryRun(u.dryRun),
helm.UpgradeRecreate(u.recreate),
helm.UpgradeForce(u.force),
helm.UpgradeDisableHooks(u.disableHooks),
helm.UpgradeTimeout(u.timeout),
helm.ResetValues(u.resetValues),
helm.ReuseValues(u.reuseValues),
helm.UpgradeWait(u.wait))
helm.UpgradeDryRun(o.dryRun),
helm.UpgradeRecreate(o.recreate),
helm.UpgradeForce(o.force),
helm.UpgradeDisableHooks(o.disableHooks),
helm.UpgradeTimeout(o.timeout),
helm.ResetValues(o.resetValues),
helm.ReuseValues(o.reuseValues),
helm.UpgradeWait(o.wait))
if err != nil {
return fmt.Errorf("UPGRADE FAILED: %v", err)
}
@ -206,10 +206,10 @@ func (u *upgradeCmd) run(out io.Writer) error {
printRelease(out, resp)
}
fmt.Fprintf(out, "Release %q has been upgraded. Happy Helming!\n", u.release)
fmt.Fprintf(out, "Release %q has been upgraded. Happy Helming!\n", o.release)
// Print the status like status command does
status, err := u.client.ReleaseStatus(u.release, 0)
status, err := o.client.ReleaseStatus(o.release, 0)
if err != nil {
return err
}

@ -35,13 +35,13 @@ This command can be used to verify a local chart. Several other commands provide
the 'helm package --sign' command.
`
type verifyCmd struct {
type verifyOptions struct {
keyring string
chartfile string
}
func newVerifyCmd(out io.Writer) *cobra.Command {
vc := &verifyCmd{}
o := &verifyOptions{}
cmd := &cobra.Command{
Use: "verify [flags] PATH",
@ -51,18 +51,18 @@ func newVerifyCmd(out io.Writer) *cobra.Command {
if len(args) == 0 {
return errors.New("a path to a package file is required")
}
vc.chartfile = args[0]
return vc.run(out)
o.chartfile = args[0]
return o.run(out)
},
}
f := cmd.Flags()
f.StringVar(&vc.keyring, "keyring", defaultKeyring(), "keyring containing public keys")
f.StringVar(&o.keyring, "keyring", defaultKeyring(), "keyring containing public keys")
return cmd
}
func (v *verifyCmd) run(out io.Writer) error {
_, err := downloader.VerifyChart(v.chartfile, v.keyring)
func (o *verifyOptions) run(out io.Writer) error {
_, err := downloader.VerifyChart(o.chartfile, o.keyring)
return err
}

@ -40,38 +40,38 @@ version.BuildInfo{Version:"v2.0.0", GitCommit:"ff52399e51bb880526e9cd0ed8386f643
built, and "dirty" if the binary was built from locally modified code.
`
type versionCmd struct {
type versionOptions struct {
short bool
template string
}
func newVersionCmd(out io.Writer) *cobra.Command {
version := &versionCmd{}
o := &versionOptions{}
cmd := &cobra.Command{
Use: "version",
Short: "print the client version information",
Long: versionDesc,
RunE: func(cmd *cobra.Command, args []string) error {
return version.run(out)
return o.run(out)
},
}
f := cmd.Flags()
f.BoolVar(&version.short, "short", false, "print the version number")
f.StringVar(&version.template, "template", "", "template for version string format")
f.BoolVar(&o.short, "short", false, "print the version number")
f.StringVar(&o.template, "template", "", "template for version string format")
return cmd
}
func (v *versionCmd) run(out io.Writer) error {
if v.template != "" {
tt, err := template.New("_").Parse(v.template)
func (o *versionOptions) run(out io.Writer) error {
if o.template != "" {
tt, err := template.New("_").Parse(o.template)
if err != nil {
return err
}
return tt.Execute(out, version.GetBuildInfo())
}
fmt.Fprintln(out, formatVersion(v.short))
fmt.Fprintln(out, formatVersion(o.short))
return nil
}

Loading…
Cancel
Save