mirror of
https://github.com/helm/helm.git
synced 2026-05-28 04:35:48 -04:00
Merge pull request #4027 from adamreese/dev-v3-ref-cmd
ref(cmd): consistent naming of cmd variables
This commit is contained in:
commit
b5f52905df
40 changed files with 813 additions and 884 deletions
|
|
@ -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,38 +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
|
||||
name string
|
||||
out io.Writer
|
||||
starter string
|
||||
type createOptions struct {
|
||||
starter string // --starter
|
||||
|
||||
// args
|
||||
name string
|
||||
|
||||
home helmpath.Home
|
||||
}
|
||||
|
||||
func newCreateCmd(out io.Writer) *cobra.Command {
|
||||
cc := &createCmd{out: out}
|
||||
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()
|
||||
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() error {
|
||||
fmt.Fprintf(c.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",
|
||||
|
|
@ -94,12 +91,12 @@ func (c *createCmd) run() 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,22 +34,20 @@ Use the '--dry-run' flag to see which releases will be deleted without actually
|
|||
deleting them.
|
||||
`
|
||||
|
||||
type deleteCmd struct {
|
||||
name string
|
||||
dryRun bool
|
||||
disableHooks bool
|
||||
purge bool
|
||||
timeout int64
|
||||
type deleteOptions struct {
|
||||
disableHooks bool // --no-hooks
|
||||
dryRun bool // --dry-run
|
||||
purge bool // --purge
|
||||
timeout int64 // --timeout
|
||||
|
||||
// args
|
||||
name string
|
||||
|
||||
out io.Writer
|
||||
client helm.Interface
|
||||
}
|
||||
|
||||
func newDeleteCmd(c helm.Interface, out io.Writer) *cobra.Command {
|
||||
del := &deleteCmd{
|
||||
out: out,
|
||||
client: c,
|
||||
}
|
||||
o := &deleteOptions{client: c}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete [flags] RELEASE_NAME [...]",
|
||||
|
|
@ -61,39 +59,39 @@ 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(); 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() 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(d.out, res.Info)
|
||||
fmt.Fprintln(out, res.Info)
|
||||
}
|
||||
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -102,13 +102,14 @@ func newDependencyCmd(out io.Writer) *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
type dependencyListCmd struct {
|
||||
out io.Writer
|
||||
type dependencyLisOptions struct {
|
||||
chartpath string
|
||||
}
|
||||
|
||||
func newDependencyListCmd(out io.Writer) *cobra.Command {
|
||||
dlc := &dependencyListCmd{out: out}
|
||||
o := &dependencyLisOptions{
|
||||
chartpath: ".",
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "list [flags] CHART",
|
||||
|
|
@ -116,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() 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
|
||||
}
|
||||
|
|
@ -137,21 +135,21 @@ func (l *dependencyListCmd) run() error {
|
|||
r, err := chartutil.LoadRequirements(c)
|
||||
if err != nil {
|
||||
if err == chartutil.ErrRequirementsNotFound {
|
||||
fmt.Fprintf(l.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(r, l.out)
|
||||
fmt.Fprintln(l.out)
|
||||
l.printMissing(r)
|
||||
o.printRequirements(out, r)
|
||||
fmt.Fprintln(out)
|
||||
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 {
|
||||
|
|
@ -187,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() {
|
||||
|
|
@ -224,29 +222,29 @@ func (l *dependencyListCmd) dependencyStatus(dep *chartutil.Dependency) string {
|
|||
}
|
||||
|
||||
// printRequirements prints all of the requirements in the yaml file.
|
||||
func (l *dependencyListCmd) printRequirements(reqs *chartutil.Requirements, out io.Writer) {
|
||||
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(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(l.out, err)
|
||||
fmt.Fprintln(out, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
fi, err := os.Stat(f)
|
||||
if err != nil {
|
||||
fmt.Fprintf(l.out, "Warning: %s\n", err)
|
||||
fmt.Fprintf(out, "Warning: %s\n", err)
|
||||
}
|
||||
// Skip anything that is not a directory and not a tgz file.
|
||||
if !fi.IsDir() && filepath.Ext(f) != ".tgz" {
|
||||
|
|
@ -254,7 +252,7 @@ func (l *dependencyListCmd) printMissing(reqs *chartutil.Requirements) {
|
|||
}
|
||||
c, err := chartutil.Load(f)
|
||||
if err != nil {
|
||||
fmt.Fprintf(l.out, "WARNING: %q is not a chart.\n", f)
|
||||
fmt.Fprintf(out, "WARNING: %q is not a chart.\n", f)
|
||||
continue
|
||||
}
|
||||
found := false
|
||||
|
|
@ -265,7 +263,7 @@ func (l *dependencyListCmd) printMissing(reqs *chartutil.Requirements) {
|
|||
}
|
||||
}
|
||||
if !found {
|
||||
fmt.Fprintf(l.out, "WARNING: %q is not in requirements.yaml.\n", f)
|
||||
fmt.Fprintf(out, "WARNING: %q is not in requirements.yaml.\n", f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,48 +36,50 @@ If no lock file is found, 'helm dependency build' will mirror the behavior
|
|||
of 'helm dependency update'.
|
||||
`
|
||||
|
||||
type dependencyBuildCmd struct {
|
||||
out io.Writer
|
||||
type dependencyBuildOptions struct {
|
||||
keyring string // --keyring
|
||||
verify bool // --verify
|
||||
|
||||
// args
|
||||
chartpath string
|
||||
verify bool
|
||||
keyring string
|
||||
helmhome helmpath.Home
|
||||
|
||||
helmhome helmpath.Home
|
||||
}
|
||||
|
||||
func newDependencyBuildCmd(out io.Writer) *cobra.Command {
|
||||
dbc := &dependencyBuildCmd{out: out}
|
||||
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()
|
||||
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() error {
|
||||
func (o *dependencyBuildOptions) run(out io.Writer) error {
|
||||
man := &downloader.Manager{
|
||||
Out: d.out,
|
||||
ChartPath: d.chartpath,
|
||||
HelmHome: d.helmhome,
|
||||
Keyring: d.keyring,
|
||||
Out: out,
|
||||
ChartPath: o.chartpath,
|
||||
HelmHome: o.helmhome,
|
||||
Keyring: o.keyring,
|
||||
Getters: getter.All(settings),
|
||||
}
|
||||
if d.verify {
|
||||
if o.verify {
|
||||
man.Verify = downloader.VerifyIfPossible
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,19 +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 {
|
||||
out io.Writer
|
||||
chartpath string
|
||||
helmhome helmpath.Home
|
||||
verify bool
|
||||
keyring string
|
||||
skipRefresh bool
|
||||
// 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
|
||||
}
|
||||
|
||||
// newDependencyUpdateCmd creates a new dependency update command.
|
||||
func newDependencyUpdateCmd(out io.Writer) *cobra.Command {
|
||||
duc := &dependencyUpdateCmd{out: out}
|
||||
o := &dependencyUpdateOptions{
|
||||
chartpath: ".",
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "update [flags] CHART",
|
||||
|
|
@ -61,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()
|
||||
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() error {
|
||||
func (o *dependencyUpdateOptions) run(out io.Writer) error {
|
||||
man := &downloader.Manager{
|
||||
Out: d.out,
|
||||
ChartPath: d.chartpath,
|
||||
HelmHome: d.helmhome,
|
||||
Keyring: d.keyring,
|
||||
SkipUpdate: d.skipRefresh,
|
||||
Out: out,
|
||||
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{out: out}
|
||||
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(); 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(); 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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"path/filepath"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/helm/pkg/chartutil"
|
||||
"k8s.io/helm/pkg/downloader"
|
||||
"k8s.io/helm/pkg/getter"
|
||||
|
|
@ -45,31 +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
|
||||
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
|
||||
|
||||
chartRef string
|
||||
destdir string
|
||||
version string
|
||||
repoURL string
|
||||
username string
|
||||
password string
|
||||
|
||||
verify bool
|
||||
verifyLater bool
|
||||
keyring string
|
||||
|
||||
certFile string
|
||||
keyFile string
|
||||
caFile string
|
||||
|
||||
devel bool
|
||||
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
func newFetchCmd(out io.Writer) *cobra.Command {
|
||||
fch := &fetchCmd{out: out}
|
||||
o := &fetchOptions{}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "fetch [flags] [chart URL | repo/chartname] [...]",
|
||||
|
|
@ -80,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(); err != nil {
|
||||
o.chartRef = args[i]
|
||||
if err := o.run(out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -96,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() error {
|
||||
func (o *fetchOptions) run(out io.Writer) error {
|
||||
c := downloader.ChartDownloader{
|
||||
HelmHome: settings.Home,
|
||||
Out: f.out,
|
||||
Keyring: f.keyring,
|
||||
Out: out,
|
||||
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 {
|
||||
|
|
@ -143,28 +140,28 @@ func (f *fetchCmd) run() 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 {
|
||||
fmt.Fprintf(f.out, "Verification: %v\n", v)
|
||||
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,19 +40,16 @@ chart, the supplied values, and the generated manifest file.
|
|||
|
||||
var errReleaseRequired = errors.New("release name is required")
|
||||
|
||||
type getCmd struct {
|
||||
release string
|
||||
version int
|
||||
type getOptions struct {
|
||||
version int // --revision
|
||||
|
||||
release string
|
||||
|
||||
out io.Writer
|
||||
client helm.Interface
|
||||
}
|
||||
|
||||
func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
|
||||
get := &getCmd{
|
||||
out: out,
|
||||
client: client,
|
||||
}
|
||||
o := &getOptions{client: client}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "get [flags] RELEASE_NAME",
|
||||
|
|
@ -62,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()
|
||||
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))
|
||||
|
|
@ -77,11 +74,10 @@ func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
// getCmd is the command that implements 'helm get'
|
||||
func (g *getCmd) run() error {
|
||||
func (g *getOptions) run(out io.Writer) error {
|
||||
res, err := g.client.ReleaseContent(g.release, g.version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return printRelease(g.out, res)
|
||||
return printRelease(out, res)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,18 +31,15 @@ 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
|
||||
out io.Writer
|
||||
client helm.Interface
|
||||
version int
|
||||
}
|
||||
|
||||
func newGetHooksCmd(client helm.Interface, out io.Writer) *cobra.Command {
|
||||
ghc := &getHooksCmd{
|
||||
out: out,
|
||||
client: client,
|
||||
}
|
||||
o := &getHooksOptions{client: client}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "hooks [flags] RELEASE_NAME",
|
||||
Short: "download all hooks for a named release",
|
||||
|
|
@ -51,24 +48,24 @@ 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()
|
||||
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() 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(g.out, g.release)
|
||||
fmt.Fprintln(out, o.release)
|
||||
return err
|
||||
}
|
||||
|
||||
for _, hook := range res.Hooks {
|
||||
fmt.Fprintf(g.out, "---\n# %s\n%s", hook.Name, hook.Manifest)
|
||||
fmt.Fprintf(out, "---\n# %s\n%s", hook.Name, hook.Manifest)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,18 +33,17 @@ 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
|
||||
out io.Writer
|
||||
client helm.Interface
|
||||
version int
|
||||
|
||||
client helm.Interface
|
||||
}
|
||||
|
||||
func newGetManifestCmd(client helm.Interface, out io.Writer) *cobra.Command {
|
||||
get := &getManifestCmd{
|
||||
out: out,
|
||||
client: client,
|
||||
}
|
||||
o := &getManifestOptions{client: client}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "manifest [flags] RELEASE_NAME",
|
||||
Short: "download the manifest for a named release",
|
||||
|
|
@ -53,22 +52,22 @@ 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()
|
||||
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() 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
|
||||
}
|
||||
fmt.Fprintln(g.out, res.Manifest)
|
||||
fmt.Fprintln(out, res.Manifest)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,19 +30,18 @@ var getValuesHelp = `
|
|||
This command downloads a values file for a given release.
|
||||
`
|
||||
|
||||
type getValuesCmd struct {
|
||||
release string
|
||||
allValues bool
|
||||
out io.Writer
|
||||
client helm.Interface
|
||||
version int
|
||||
type getValuesOptions struct {
|
||||
allValues bool // --all
|
||||
version int // --revision
|
||||
|
||||
release string
|
||||
|
||||
client helm.Interface
|
||||
}
|
||||
|
||||
func newGetValuesCmd(client helm.Interface, out io.Writer) *cobra.Command {
|
||||
get := &getValuesCmd{
|
||||
out: out,
|
||||
client: client,
|
||||
}
|
||||
o := &getValuesOptions{client: client}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "values [flags] RELEASE_NAME",
|
||||
Short: "download the values file for a named release",
|
||||
|
|
@ -51,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()
|
||||
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() 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
|
||||
|
|
@ -79,10 +78,10 @@ func (g *getValuesCmd) run() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(g.out, cfgStr)
|
||||
fmt.Fprintln(out, cfgStr)
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, string(res.Config))
|
||||
fmt.Fprintln(out, string(res.Config))
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,17 +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
|
||||
out io.Writer
|
||||
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, w io.Writer) *cobra.Command {
|
||||
his := &historyCmd{out: w, helmc: c}
|
||||
func newHistoryCmd(c helm.Interface, out io.Writer) *cobra.Command {
|
||||
o := &historyOptions{client: c}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "history [flags] RELEASE_NAME",
|
||||
|
|
@ -77,22 +78,22 @@ func newHistoryCmd(c helm.Interface, w io.Writer) *cobra.Command {
|
|||
if len(args) == 0 {
|
||||
return errReleaseRequired
|
||||
}
|
||||
his.helmc = ensureHelmClient(his.helmc, false)
|
||||
his.rls = args[0]
|
||||
return his.run()
|
||||
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() 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
|
||||
}
|
||||
|
|
@ -105,22 +106,22 @@ func (cmd *historyCmd) run() 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 {
|
||||
return formattingError
|
||||
}
|
||||
|
||||
fmt.Fprintln(cmd.out, string(history))
|
||||
fmt.Fprintln(out, string(history))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,18 +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
|
||||
out io.Writer
|
||||
home helmpath.Home
|
||||
home helmpath.Home
|
||||
}
|
||||
|
||||
func newInitCmd(out io.Writer) *cobra.Command {
|
||||
i := &initCmd{out: out}
|
||||
o := &initOptions{}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "init",
|
||||
|
|
@ -54,31 +56,31 @@ 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()
|
||||
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() error {
|
||||
if err := ensureDirectories(i.home, i.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, i.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(), i.out); err != nil {
|
||||
if err := ensureRepoFileFormat(o.home.RepositoryFile(), out); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(i.out, "$HELM_HOME has been configured at %s.\n", settings.Home)
|
||||
fmt.Fprintln(i.out, "Happy Helming!")
|
||||
fmt.Fprintf(out, "$HELM_HOME has been configured at %s.\n", settings.Home)
|
||||
fmt.Fprintln(out, "Happy Helming!")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -108,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
|
||||
}
|
||||
|
|
@ -127,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))
|
||||
|
|
@ -146,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,20 +50,18 @@ 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
|
||||
keyring string
|
||||
out io.Writer
|
||||
version string
|
||||
repoURL string
|
||||
username string
|
||||
password string
|
||||
|
||||
certFile string
|
||||
keyFile string
|
||||
caFile string
|
||||
certFile string
|
||||
keyFile string
|
||||
caFile string
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
@ -76,10 +74,7 @@ const (
|
|||
var readmeFileNames = []string{"readme.md", "readme.txt", "readme"}
|
||||
|
||||
func newInspectCmd(out io.Writer) *cobra.Command {
|
||||
insp := &inspectCmd{
|
||||
out: out,
|
||||
output: all,
|
||||
}
|
||||
o := &inspectOptions{output: all}
|
||||
|
||||
inspectCommand := &cobra.Command{
|
||||
Use: "inspect [CHART]",
|
||||
|
|
@ -89,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()
|
||||
o.chartpath = cp
|
||||
return o.run(out)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -104,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()
|
||||
o.chartpath = cp
|
||||
return o.run(out)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -123,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()
|
||||
o.chartpath = cp
|
||||
return o.run(out)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -142,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()
|
||||
o.chartpath = cp
|
||||
return o.run(out)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -160,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:] {
|
||||
|
|
@ -219,7 +214,7 @@ func newInspectCmd(out io.Writer) *cobra.Command {
|
|||
return inspectCommand
|
||||
}
|
||||
|
||||
func (i *inspectCmd) run() error {
|
||||
func (i *inspectOptions) run(out io.Writer) error {
|
||||
chrt, err := chartutil.Load(i.chartpath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -230,25 +225,25 @@ func (i *inspectCmd) run() error {
|
|||
}
|
||||
|
||||
if i.output == chartOnly || i.output == all {
|
||||
fmt.Fprintln(i.out, string(cf))
|
||||
fmt.Fprintln(out, string(cf))
|
||||
}
|
||||
|
||||
if (i.output == valuesOnly || i.output == all) && chrt.Values != nil {
|
||||
if i.output == all {
|
||||
fmt.Fprintln(i.out, "---")
|
||||
fmt.Fprintln(out, "---")
|
||||
}
|
||||
fmt.Fprintln(i.out, string(chrt.Values))
|
||||
fmt.Fprintln(out, string(chrt.Values))
|
||||
}
|
||||
|
||||
if i.output == readmeOnly || i.output == all {
|
||||
if i.output == all {
|
||||
fmt.Fprintln(i.out, "---")
|
||||
fmt.Fprintln(out, "---")
|
||||
}
|
||||
readme := findReadme(chrt.Files)
|
||||
if readme == nil {
|
||||
return nil
|
||||
}
|
||||
fmt.Fprintln(i.out, string(readme.Data))
|
||||
fmt.Fprintln(out, string(readme.Data))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,12 +26,11 @@ import (
|
|||
func TestInspect(t *testing.T) {
|
||||
b := bytes.NewBuffer(nil)
|
||||
|
||||
insp := &inspectCmd{
|
||||
o := &inspectOptions{
|
||||
chartpath: "testdata/testcharts/alpine",
|
||||
output: all,
|
||||
out: b,
|
||||
}
|
||||
insp.run()
|
||||
o.run(b)
|
||||
|
||||
// Load the data from the textfixture directly.
|
||||
cdata, err := ioutil.ReadFile("testdata/testcharts/alpine/Chart.yaml")
|
||||
|
|
@ -68,12 +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",
|
||||
out: b,
|
||||
}
|
||||
insp.run()
|
||||
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
|
||||
|
|
@ -128,7 +128,6 @@ type installCmd struct {
|
|||
caFile string // --ca-file
|
||||
chartPath string // arg
|
||||
|
||||
out io.Writer
|
||||
client helm.Interface
|
||||
}
|
||||
|
||||
|
|
@ -150,10 +149,7 @@ func (v *valueFiles) Set(value string) error {
|
|||
}
|
||||
|
||||
func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
|
||||
inst := &installCmd{
|
||||
out: out,
|
||||
client: c,
|
||||
}
|
||||
o := &installOptions{client: c}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "install [CHART]",
|
||||
|
|
@ -164,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()
|
||||
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() 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
|
||||
}
|
||||
|
|
@ -236,10 +232,10 @@ func (i *installCmd) run() 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: i.out,
|
||||
ChartPath: i.chartPath,
|
||||
Out: out,
|
||||
ChartPath: o.chartPath,
|
||||
HelmHome: settings.Home,
|
||||
Keyring: defaultKeyring(),
|
||||
SkipUpdate: false,
|
||||
|
|
@ -257,16 +253,16 @@ func (i *installCmd) run() 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
|
||||
}
|
||||
|
|
@ -274,19 +270,19 @@ func (i *installCmd) run() error {
|
|||
if rel == nil {
|
||||
return nil
|
||||
}
|
||||
i.printRelease(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
|
||||
}
|
||||
PrintStatus(i.out, status)
|
||||
PrintStatus(out, status)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -363,14 +359,14 @@ func vals(valueFiles valueFiles, values []string, stringValues []string) ([]byte
|
|||
}
|
||||
|
||||
// printRelease prints info about a release if the Debug is true.
|
||||
func (i *installCmd) printRelease(rel *release.Release) {
|
||||
func (o *installOptions) printRelease(out io.Writer, rel *release.Release) {
|
||||
if rel == nil {
|
||||
return
|
||||
}
|
||||
// TODO: Switch to text/template like everything else.
|
||||
fmt.Fprintf(i.out, "NAME: %s\n", rel.Name)
|
||||
fmt.Fprintf(out, "NAME: %s\n", rel.Name)
|
||||
if settings.Debug {
|
||||
printRelease(i.out, rel)
|
||||
printRelease(out, rel)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,60 +43,57 @@ 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
|
||||
strict bool
|
||||
paths []string
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
func newLintCmd(out io.Writer) *cobra.Command {
|
||||
l := &lintCmd{
|
||||
paths: []string{"."},
|
||||
out: out,
|
||||
}
|
||||
o := &lintOptions{paths: []string{"."}}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "lint [flags] PATH",
|
||||
Short: "examines a chart for possible issues",
|
||||
Long: longLintHelp,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) > 0 {
|
||||
l.paths = args
|
||||
o.paths = args
|
||||
}
|
||||
return l.run()
|
||||
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() 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 {
|
||||
|
|
@ -126,7 +123,7 @@ func (l *lintCmd) run() error {
|
|||
return fmt.Errorf("%s, %d chart(s) failed", msg, failures)
|
||||
}
|
||||
|
||||
fmt.Fprintf(l.out, "%s, no failures\n", msg)
|
||||
fmt.Fprintf(out, "%s, no failures\n", msg)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -170,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 {
|
||||
|
|
@ -189,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)
|
||||
}
|
||||
|
|
|
|||
115
cmd/helm/list.go
115
cmd/helm/list.go
|
|
@ -56,31 +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 {
|
||||
filter string
|
||||
short bool
|
||||
limit int
|
||||
offset string
|
||||
byDate bool
|
||||
sortDesc bool
|
||||
out io.Writer
|
||||
all bool
|
||||
deleted bool
|
||||
deleting bool
|
||||
deployed bool
|
||||
failed bool
|
||||
superseded bool
|
||||
pending bool
|
||||
client helm.Interface
|
||||
colWidth uint
|
||||
allNamespaces bool
|
||||
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
|
||||
|
||||
client helm.Interface
|
||||
}
|
||||
|
||||
func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
|
||||
list := &listCmd{
|
||||
out: out,
|
||||
client: client,
|
||||
}
|
||||
o := &listOptions{client: client}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "list [flags] [FILTER]",
|
||||
|
|
@ -89,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()
|
||||
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() 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),
|
||||
|
|
@ -146,13 +147,13 @@ func (l *listCmd) run() error {
|
|||
|
||||
rels := filterList(res)
|
||||
|
||||
if l.short {
|
||||
if o.short {
|
||||
for _, r := range rels {
|
||||
fmt.Fprintln(l.out, r.Name)
|
||||
fmt.Fprintln(out, r.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
fmt.Fprintln(l.out, formatList(rels, l.colWidth))
|
||||
fmt.Fprintln(out, formatList(rels, o.colWidth))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -181,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,
|
||||
|
|
@ -195,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,46 +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
|
||||
path string
|
||||
valueFiles valueFiles
|
||||
values []string
|
||||
stringValues []string
|
||||
key string
|
||||
keyring string
|
||||
version string
|
||||
appVersion string
|
||||
destination string
|
||||
dependencyUpdate 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
|
||||
|
||||
out io.Writer
|
||||
home helmpath.Home
|
||||
}
|
||||
|
||||
func newPackageCmd(out io.Writer) *cobra.Command {
|
||||
pkg := &packageCmd{out: out}
|
||||
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(); err != nil {
|
||||
o.path = args[i]
|
||||
if err := o.run(out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -97,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() 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: p.out,
|
||||
Out: out,
|
||||
ChartPath: path,
|
||||
HelmHome: settings.Home,
|
||||
Keyring: p.keyring,
|
||||
Keyring: o.keyring,
|
||||
Getters: getter.All(settings),
|
||||
Debug: settings.Debug,
|
||||
}
|
||||
|
|
@ -137,7 +138,7 @@ func (p *packageCmd) run() 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
|
||||
}
|
||||
|
|
@ -152,16 +153,16 @@ func (p *packageCmd) run() 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 {
|
||||
|
|
@ -179,7 +180,7 @@ func (p *packageCmd) run() error {
|
|||
}
|
||||
|
||||
var dest string
|
||||
if p.destination == "." {
|
||||
if o.destination == "." {
|
||||
// Save to the current working directory.
|
||||
dest, err = os.Getwd()
|
||||
if err != nil {
|
||||
|
|
@ -187,18 +188,18 @@ func (p *packageCmd) run() error {
|
|||
}
|
||||
} else {
|
||||
// Otherwise save to set destination
|
||||
dest = p.destination
|
||||
dest = o.destination
|
||||
}
|
||||
|
||||
name, err := chartutil.Save(ch, dest)
|
||||
if err == nil {
|
||||
fmt.Fprintf(p.out, "Successfully packaged chart and saved it to: %s\n", name)
|
||||
fmt.Fprintf(out, "Successfully packaged chart and saved it to: %s\n", name)
|
||||
} else {
|
||||
return fmt.Errorf("Failed to save: %s", err)
|
||||
}
|
||||
|
||||
if p.sign {
|
||||
err = p.clearsign(name)
|
||||
if o.sign {
|
||||
err = o.clearsign(name)
|
||||
}
|
||||
|
||||
return err
|
||||
|
|
@ -215,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,25 +25,24 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type pluginListCmd struct {
|
||||
type pluginListOptions struct {
|
||||
home helmpath.Home
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
func newPluginListCmd(out io.Writer) *cobra.Command {
|
||||
pcmd := &pluginListCmd{out: out}
|
||||
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()
|
||||
o.home = settings.Home
|
||||
return o.run(out)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (pcmd *pluginListCmd) run() error {
|
||||
func (o *pluginListOptions) run(out io.Writer) error {
|
||||
debug("pluginDirs: %s", settings.PluginDirs())
|
||||
plugins, err := findPlugins(settings.PluginDirs())
|
||||
if err != nil {
|
||||
|
|
@ -55,6 +54,6 @@ func (pcmd *pluginListCmd) run() error {
|
|||
for _, p := range plugins {
|
||||
table.AddRow(p.Metadata.Name, p.Metadata.Version, p.Metadata.Description)
|
||||
}
|
||||
fmt.Fprintln(pcmd.out, table)
|
||||
fmt.Fprintln(out, table)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,49 +28,48 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type pluginRemoveCmd struct {
|
||||
type pluginRemoveOptions struct {
|
||||
names []string
|
||||
home helmpath.Home
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
func newPluginRemoveCmd(out io.Writer) *cobra.Command {
|
||||
pcmd := &pluginRemoveCmd{out: out}
|
||||
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()
|
||||
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() 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))
|
||||
} else {
|
||||
fmt.Fprintf(pcmd.out, "Removed plugin: %s\n", name)
|
||||
fmt.Fprintf(out, "Removed plugin: %s\n", name)
|
||||
}
|
||||
} else {
|
||||
errorPlugins = append(errorPlugins, fmt.Sprintf("Plugin: %s not found", name))
|
||||
|
|
|
|||
|
|
@ -29,37 +29,36 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type pluginUpdateCmd struct {
|
||||
type pluginUpdateOptions struct {
|
||||
names []string
|
||||
home helmpath.Home
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
func newPluginUpdateCmd(out io.Writer) *cobra.Command {
|
||||
pcmd := &pluginUpdateCmd{out: out}
|
||||
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()
|
||||
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() 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())
|
||||
|
|
@ -68,12 +67,12 @@ func (pcmd *pluginUpdateCmd) run() 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(pcmd.out, "Updated plugin: %s\n", name)
|
||||
fmt.Fprintf(out, "Updated plugin: %s\n", name)
|
||||
}
|
||||
} else {
|
||||
errorPlugins = append(errorPlugins, fmt.Sprintf("Plugin: %s not found", name))
|
||||
|
|
|
|||
|
|
@ -33,19 +33,15 @@ 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
|
||||
out io.Writer
|
||||
client helm.Interface
|
||||
timeout int64
|
||||
cleanup bool
|
||||
}
|
||||
|
||||
func newReleaseTestCmd(c helm.Interface, out io.Writer) *cobra.Command {
|
||||
rlsTest := &releaseTestCmd{
|
||||
out: out,
|
||||
client: c,
|
||||
}
|
||||
o := &releaseTestOptions{client: c}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "test [RELEASE]",
|
||||
|
|
@ -56,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()
|
||||
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() (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{}
|
||||
|
||||
|
|
@ -92,12 +88,9 @@ func (t *releaseTestCmd) run() (err error) {
|
|||
if res.Status == release.TestRunFailure {
|
||||
testErr.failed++
|
||||
}
|
||||
|
||||
fmt.Fprintf(t.out, res.Msg+"\n")
|
||||
|
||||
fmt.Fprintf(out, res.Msg+"\n")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type testErr struct {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import (
|
|||
"k8s.io/helm/pkg/repo"
|
||||
)
|
||||
|
||||
type repoAddCmd struct {
|
||||
type repoAddOptions struct {
|
||||
name string
|
||||
url string
|
||||
username string
|
||||
|
|
@ -38,12 +38,10 @@ type repoAddCmd struct {
|
|||
certFile string
|
||||
keyFile string
|
||||
caFile string
|
||||
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
func newRepoAddCmd(out io.Writer) *cobra.Command {
|
||||
add := &repoAddCmd{out: out}
|
||||
o := &repoAddOptions{}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "add [flags] [NAME] [URL]",
|
||||
|
|
@ -53,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()
|
||||
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() 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(a.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,15 +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
|
||||
out io.Writer
|
||||
merge string
|
||||
}
|
||||
|
||||
func newRepoIndexCmd(out io.Writer) *cobra.Command {
|
||||
index := &repoIndexCmd{out: out}
|
||||
o := &repoIndexOptions{}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "index [flags] [DIR]",
|
||||
|
|
@ -57,20 +56,20 @@ func newRepoIndexCmd(out io.Writer) *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
index.dir = args[0]
|
||||
o.dir = args[0]
|
||||
|
||||
return index.run()
|
||||
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() error {
|
||||
func (i *repoIndexOptions) run(out io.Writer) error {
|
||||
path, err := filepath.Abs(i.dir)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -28,28 +28,27 @@ import (
|
|||
"k8s.io/helm/pkg/repo"
|
||||
)
|
||||
|
||||
type repoListCmd struct {
|
||||
out io.Writer
|
||||
type repoListOptions struct {
|
||||
home helmpath.Home
|
||||
}
|
||||
|
||||
func newRepoListCmd(out io.Writer) *cobra.Command {
|
||||
list := &repoListCmd{out: out}
|
||||
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()
|
||||
o.home = settings.Home
|
||||
return o.run(out)
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (a *repoListCmd) run() 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
|
||||
}
|
||||
|
|
@ -61,6 +60,6 @@ func (a *repoListCmd) run() error {
|
|||
for _, re := range f.Repositories {
|
||||
table.AddRow(re.Name, re.URL)
|
||||
}
|
||||
fmt.Fprintln(a.out, table)
|
||||
fmt.Fprintln(out, table)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,14 +27,13 @@ import (
|
|||
"k8s.io/helm/pkg/repo"
|
||||
)
|
||||
|
||||
type repoRemoveCmd struct {
|
||||
out io.Writer
|
||||
type repoRemoveOptions struct {
|
||||
name string
|
||||
home helmpath.Home
|
||||
}
|
||||
|
||||
func newRepoRemoveCmd(out io.Writer) *cobra.Command {
|
||||
remove := &repoRemoveCmd{out: out}
|
||||
o := &repoRemoveOptions{}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "remove [flags] [NAME]",
|
||||
|
|
@ -44,18 +43,18 @@ 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()
|
||||
return o.run(out)
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (r *repoRemoveCmd) run() error {
|
||||
return removeRepoLine(r.out, r.name, r.home)
|
||||
func (r *repoRemoveOptions) run(out io.Writer) error {
|
||||
return removeRepoLine(out, r.name, r.home)
|
||||
}
|
||||
|
||||
func removeRepoLine(out io.Writer, name string, home helmpath.Home) error {
|
||||
|
|
|
|||
|
|
@ -39,32 +39,29 @@ 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
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
func newRepoUpdateCmd(out io.Writer) *cobra.Command {
|
||||
u := &repoUpdateCmd{
|
||||
out: out,
|
||||
update: updateCharts,
|
||||
}
|
||||
o := &repoUpdateOptions{update: updateCharts}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Aliases: []string{"up"},
|
||||
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()
|
||||
o.home = settings.Home
|
||||
return o.run(out)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (u *repoUpdateCmd) run() 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
|
||||
}
|
||||
|
|
@ -81,7 +78,7 @@ func (u *repoUpdateCmd) run() error {
|
|||
repos = append(repos, r)
|
||||
}
|
||||
|
||||
u.update(repos, u.out, u.home)
|
||||
o.update(repos, out, o.home)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,12 +51,11 @@ func TestUpdateCmd(t *testing.T) {
|
|||
fmt.Fprintln(out, re.Config.Name)
|
||||
}
|
||||
}
|
||||
uc := &repoUpdateCmd{
|
||||
o := &repoUpdateOptions{
|
||||
update: updater,
|
||||
home: helmpath.Home(thome),
|
||||
out: out,
|
||||
}
|
||||
if err := uc.run(); err != nil {
|
||||
if err := o.run(out); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,24 +34,20 @@ 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
|
||||
recreate bool
|
||||
force bool
|
||||
disableHooks bool
|
||||
out io.Writer
|
||||
client helm.Interface
|
||||
timeout int64
|
||||
wait bool
|
||||
}
|
||||
|
||||
func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
|
||||
rollback := &rollbackCmd{
|
||||
out: out,
|
||||
client: c,
|
||||
}
|
||||
o := &rollbackOptions{client: c}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "rollback [flags] [RELEASE] [REVISION]",
|
||||
|
|
@ -62,45 +58,45 @@ 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()
|
||||
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() 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
|
||||
}
|
||||
|
||||
fmt.Fprintf(r.out, "Rollback was a success! Happy Helming!\n")
|
||||
fmt.Fprintf(out, "Rollback was a success! Happy Helming!\n")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,8 +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 {
|
||||
out io.Writer
|
||||
type searchOptions struct {
|
||||
helmhome helmpath.Home
|
||||
|
||||
versions bool
|
||||
|
|
@ -50,28 +49,28 @@ type searchCmd struct {
|
|||
}
|
||||
|
||||
func newSearchCmd(out io.Writer) *cobra.Command {
|
||||
sc := &searchCmd{out: out}
|
||||
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(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(args []string) error {
|
||||
index, err := s.buildIndex()
|
||||
func (o *searchOptions) run(out io.Writer, args []string) error {
|
||||
index, err := o.buildIndex(out)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -81,29 +80,29 @@ func (s *searchCmd) run(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(s.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)
|
||||
}
|
||||
|
|
@ -117,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
|
||||
}
|
||||
}
|
||||
|
|
@ -126,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"
|
||||
}
|
||||
|
|
@ -139,9 +138,9 @@ func (s *searchCmd) formatSearchResults(res []*search.Result) string {
|
|||
return table.String()
|
||||
}
|
||||
|
||||
func (s *searchCmd) buildIndex() (*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
|
||||
}
|
||||
|
|
@ -149,14 +148,15 @@ func (s *searchCmd) buildIndex() (*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 {
|
||||
fmt.Fprintf(s.out, "WARNING: Repo %q is corrupt or missing. Try 'helm repo update'.", n)
|
||||
// TODO should print to stderr
|
||||
fmt.Fprintf(out, "WARNING: Repo %q is corrupt or missing. Try 'helm repo update'.", n)
|
||||
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,19 +44,15 @@ The status consists of:
|
|||
- additional notes provided by the chart
|
||||
`
|
||||
|
||||
type statusCmd struct {
|
||||
type statusOptions struct {
|
||||
release string
|
||||
out io.Writer
|
||||
client helm.Interface
|
||||
version int
|
||||
outfmt string
|
||||
}
|
||||
|
||||
func newStatusCmd(client helm.Interface, out io.Writer) *cobra.Command {
|
||||
status := &statusCmd{
|
||||
out: out,
|
||||
client: client,
|
||||
}
|
||||
o := &statusOptions{client: client}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "status [flags] RELEASE_NAME",
|
||||
|
|
@ -66,45 +62,45 @@ 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()
|
||||
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() 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(s.out, res)
|
||||
PrintStatus(out, res)
|
||||
return nil
|
||||
case "json":
|
||||
data, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to Marshal JSON output: %s", err)
|
||||
}
|
||||
s.out.Write(data)
|
||||
out.Write(data)
|
||||
return nil
|
||||
case "yaml":
|
||||
data, err := yaml.Marshal(res)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to Marshal YAML output: %s", err)
|
||||
}
|
||||
s.out.Write(data)
|
||||
out.Write(data)
|
||||
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,10 +60,9 @@ 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
|
||||
out io.Writer
|
||||
values []string
|
||||
stringValues []string
|
||||
nameTemplate string
|
||||
|
|
@ -75,52 +74,51 @@ type templateCmd struct {
|
|||
}
|
||||
|
||||
func newTemplateCmd(out io.Writer) *cobra.Command {
|
||||
|
||||
t := &templateCmd{
|
||||
out: out,
|
||||
}
|
||||
o := &templateOptions{}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "template [flags] CHART",
|
||||
Short: fmt.Sprintf("locally render templates"),
|
||||
Long: templateDesc,
|
||||
RunE: t.run,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return errors.New("chart is required")
|
||||
}
|
||||
// verify chart path exists
|
||||
if _, err := os.Stat(args[0]); err == nil {
|
||||
if o.chartPath, err = filepath.Abs(args[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
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(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return errors.New("chart is required")
|
||||
}
|
||||
// verify chart path exists
|
||||
if _, err := os.Stat(args[0]); err == nil {
|
||||
if t.chartPath, err = filepath.Abs(args[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
|
@ -136,29 +134,29 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) 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
|
||||
}
|
||||
|
|
@ -171,7 +169,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
|
|||
return fmt.Errorf("cannot load requirements: %v", err)
|
||||
}
|
||||
options := chartutil.ReleaseOptions{
|
||||
Name: t.releaseName,
|
||||
Name: o.releaseName,
|
||||
Time: time.Now(),
|
||||
Namespace: getNamespace(),
|
||||
}
|
||||
|
|
@ -195,7 +193,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) 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)
|
||||
}
|
||||
|
|
@ -208,14 +206,14 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
out, err := renderer.Render(c, vals)
|
||||
rendered, err := renderer.Render(c, vals)
|
||||
listManifests := []tiller.Manifest{}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// extract kind and name
|
||||
re := regexp.MustCompile("kind:(.*)\n")
|
||||
for k, v := range out {
|
||||
for k, v := range rendered {
|
||||
match := re.FindStringSubmatch(v)
|
||||
h := "Unknown"
|
||||
if len(match) == 2 {
|
||||
|
|
@ -228,7 +226,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) 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 {
|
||||
|
|
@ -239,34 +237,34 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
if settings.Debug {
|
||||
rel := &release.Release{
|
||||
Name: t.releaseName,
|
||||
Name: o.releaseName,
|
||||
Chart: c,
|
||||
Config: config,
|
||||
Version: 1,
|
||||
Info: &release.Info{LastDeployed: time.Now()},
|
||||
}
|
||||
printRelease(os.Stdout, rel)
|
||||
printRelease(out, rel)
|
||||
}
|
||||
|
||||
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,10 +53,9 @@ 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
|
||||
out io.Writer
|
||||
client helm.Interface
|
||||
dryRun bool
|
||||
recreate bool
|
||||
|
|
@ -84,11 +83,7 @@ type upgradeCmd struct {
|
|||
}
|
||||
|
||||
func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
|
||||
|
||||
upgrade := &upgradeCmd{
|
||||
out: out,
|
||||
client: client,
|
||||
}
|
||||
o := &upgradeOptions{client: client}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "upgrade [RELEASE] [CHART]",
|
||||
|
|
@ -99,82 +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()
|
||||
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() 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(u.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,
|
||||
out: u.out,
|
||||
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()
|
||||
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
|
||||
}
|
||||
|
|
@ -192,34 +186,34 @@ func (u *upgradeCmd) run() 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)
|
||||
}
|
||||
|
||||
if settings.Debug {
|
||||
printRelease(u.out, resp)
|
||||
printRelease(out, resp)
|
||||
}
|
||||
|
||||
fmt.Fprintf(u.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
|
||||
}
|
||||
PrintStatus(u.out, status)
|
||||
PrintStatus(out, status)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,15 +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
|
||||
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
func newVerifyCmd(out io.Writer) *cobra.Command {
|
||||
vc := &verifyCmd{out: out}
|
||||
o := &verifyOptions{}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "verify [flags] PATH",
|
||||
|
|
@ -53,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()
|
||||
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() 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,39 +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 {
|
||||
out io.Writer
|
||||
type versionOptions struct {
|
||||
short bool
|
||||
template string
|
||||
}
|
||||
|
||||
func newVersionCmd(out io.Writer) *cobra.Command {
|
||||
version := &versionCmd{out: out}
|
||||
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()
|
||||
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() 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(v.out, version.GetBuildInfo())
|
||||
return tt.Execute(out, version.GetBuildInfo())
|
||||
}
|
||||
fmt.Fprintln(v.out, formatVersion(v.short))
|
||||
fmt.Fprintln(out, formatVersion(o.short))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue