Merge pull request #4079 from adamreese/dev-v3-options

ref(cmd): dry up values and chartpath flag options
pull/4091/head
Adam Reese 6 years ago committed by GitHub
commit 61055510ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -49,22 +49,15 @@ result in an error, and the chart will not be saved locally.
`
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
chartPathOptions
}
func newFetchCmd(out io.Writer) *cobra.Command {
@ -94,19 +87,12 @@ func newFetchCmd(out io.Writer) *cobra.Command {
f := cmd.Flags()
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")
o.chartPathOptions.addFlags(f)
return cmd
}
@ -175,8 +161,3 @@ func (o *fetchOptions) run(out io.Writer) error {
}
return nil
}
// defaultKeyring returns the expanded path to the default keyring.
func defaultKeyring() string {
return os.ExpandEnv("$HOME/.gnupg/pubring.gpg")
}

@ -54,15 +54,8 @@ of the README file
type inspectOptions struct {
chartpath string
output string
verify bool
keyring string
version string
repoURL string
username string
password string
certFile string
keyFile string
caFile string
chartPathOptions
}
const (
@ -83,8 +76,7 @@ func newInspectCmd(out io.Writer) *cobra.Command {
Long: inspectDesc,
Args: require.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cp, err := locateChartPath(o.repoURL, o.username, o.password, args[0], o.version, o.verify, o.keyring,
o.certFile, o.keyFile, o.caFile)
cp, err := o.locateChart(args[0])
if err != nil {
return err
}
@ -100,8 +92,7 @@ func newInspectCmd(out io.Writer) *cobra.Command {
Args: require.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
o.output = valuesOnly
cp, err := locateChartPath(o.repoURL, o.username, o.password, args[0], o.version, o.verify, o.keyring,
o.certFile, o.keyFile, o.caFile)
cp, err := o.locateChart(args[0])
if err != nil {
return err
}
@ -117,8 +108,7 @@ func newInspectCmd(out io.Writer) *cobra.Command {
Args: require.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
o.output = chartOnly
cp, err := locateChartPath(o.repoURL, o.username, o.password, args[0], o.version, o.verify, o.keyring,
o.certFile, o.keyFile, o.caFile)
cp, err := o.locateChart(args[0])
if err != nil {
return err
}
@ -134,8 +124,7 @@ func newInspectCmd(out io.Writer) *cobra.Command {
Args: require.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
o.output = readmeOnly
cp, err := locateChartPath(o.repoURL, o.username, o.password, args[0], o.version, o.verify, o.keyring,
o.certFile, o.keyFile, o.caFile)
cp, err := o.locateChart(args[0])
if err != nil {
return err
}
@ -145,59 +134,8 @@ func newInspectCmd(out io.Writer) *cobra.Command {
}
cmds := []*cobra.Command{inspectCommand, readmeSubCmd, valuesSubCmd, chartSubCmd}
vflag := "verify"
vdesc := "verify the provenance data for this chart"
for _, subCmd := range cmds {
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(&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(&o.version, verflag, "", verdesc)
}
repoURL := "repo"
repoURLdesc := "chart repository url where to locate the requested chart"
for _, subCmd := range cmds {
subCmd.Flags().StringVar(&o.repoURL, repoURL, "", repoURLdesc)
}
username := "username"
usernamedesc := "chart repository username where to locate the requested chart"
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(&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(&o.certFile, certFile, "", certFiledesc)
}
keyFile := "key-file"
keyFiledesc := "identify HTTPS client using this SSL key file"
for _, subCmd := range cmds {
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(&o.caFile, caFile, "", caFiledesc)
o.chartPathOptions.addFlags(subCmd.Flags())
}
for _, subCmd := range cmds[1:] {

@ -20,15 +20,10 @@ import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/url"
"os"
"path/filepath"
"strings"
"text/template"
"github.com/Masterminds/sprig"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@ -39,8 +34,6 @@ import (
"k8s.io/helm/pkg/hapi/chart"
"k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/repo"
"k8s.io/helm/pkg/strvals"
)
const installDesc = `
@ -106,49 +99,23 @@ charts in a repository, use 'helm search'.
`
type installOptions struct {
name string // --name
valueFiles valueFiles // --values
dryRun bool // --dry-run
disableHooks bool // --disable-hooks
replace bool // --replace
verify bool // --verify
keyring string // --keyring
values []string // --set
stringValues []string // --set-string
nameTemplate string // --name-template
version string // --version
timeout int64 // --timeout
wait bool // --wait
repoURL string // --repo
username string // --username
password string // --password
devel bool // --devel
depUp bool // --dep-up
certFile string // --cert-file
keyFile string // --key-file
caFile string // --ca-file
chartPath string // arg
name string // --name
dryRun bool // --dry-run
disableHooks bool // --disable-hooks
replace bool // --replace
nameTemplate string // --name-template
timeout int64 // --timeout
wait bool // --wait
devel bool // --devel
depUp bool // --dep-up
chartPath string // arg
valuesOptions
chartPathOptions
client helm.Interface
}
type valueFiles []string
func (v *valueFiles) String() string {
return fmt.Sprint(*v)
}
func (v *valueFiles) Type() string {
return "valueFiles"
}
func (v *valueFiles) Set(value string) error {
for _, filePath := range strings.Split(value, ",") {
*v = append(*v, filePath)
}
return nil
}
func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
o := &installOptions{client: c}
@ -164,8 +131,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
o.version = ">0.0.0-0"
}
cp, err := locateChartPath(o.repoURL, o.username, o.password, args[0], o.version, o.verify, o.keyring,
o.certFile, o.keyFile, o.caFile)
cp, err := o.locateChart(args[0])
if err != nil {
return err
}
@ -176,27 +142,17 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
}
f := cmd.Flags()
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")
o.valuesOptions.addFlags(f)
o.chartPathOptions.addFlags(f)
return cmd
}
@ -204,7 +160,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
func (o *installOptions) run(out io.Writer) error {
debug("CHART PATH: %s\n", o.chartPath)
rawVals, err := vals(o.valueFiles, o.values, o.stringValues)
rawVals, err := o.mergedValues()
if err != nil {
return err
}
@ -235,7 +191,7 @@ func (o *installOptions) run(out io.Writer) error {
Out: out,
ChartPath: o.chartPath,
HelmHome: settings.Home,
Keyring: defaultKeyring(),
Keyring: o.keyring,
SkipUpdate: false,
Getters: getter.All(settings),
}
@ -311,51 +267,6 @@ func mergeValues(dest, src map[string]interface{}) map[string]interface{} {
return dest
}
// vals merges values from files specified via -f/--values and
// directly via --set or --set-string, marshaling them to YAML
func vals(valueFiles valueFiles, values, stringValues []string) ([]byte, error) {
base := map[string]interface{}{}
// User specified a values files via -f/--values
for _, filePath := range valueFiles {
currentMap := map[string]interface{}{}
var bytes []byte
var err error
if strings.TrimSpace(filePath) == "-" {
bytes, err = ioutil.ReadAll(os.Stdin)
} else {
bytes, err = readFile(filePath)
}
if err != nil {
return []byte{}, err
}
if err := yaml.Unmarshal(bytes, &currentMap); err != nil {
return []byte{}, errors.Wrapf(err, "failed to parse %s", filePath)
}
// Merge with the previous map
base = mergeValues(base, currentMap)
}
// User specified a value via --set
for _, value := range values {
if err := strvals.ParseInto(value, base); err != nil {
return []byte{}, errors.Wrap(err, "failed parsing --set data")
}
}
// User specified a value via --set-string
for _, value := range stringValues {
if err := strvals.ParseIntoString(value, base); err != nil {
return []byte{}, errors.Wrap(err, "failed parsing --set-string data")
}
}
return yaml.Marshal(base)
}
// printRelease prints info about a release if the Debug is true.
func (o *installOptions) printRelease(out io.Writer, rel *release.Release) {
if rel == nil {
@ -368,84 +279,6 @@ func (o *installOptions) printRelease(out io.Writer, rel *release.Release) {
}
}
// locateChartPath looks for a chart directory in known places, and returns either the full path or an error.
//
// This does not ensure that the chart is well-formed; only that the requested filename exists.
//
// Order of resolution:
// - current working directory
// - if path is absolute or begins with '.', error out here
// - chart repos in $HELM_HOME
// - URL
//
// If 'verify' is true, this will attempt to also verify the chart.
func locateChartPath(repoURL, username, password, name, version string, verify bool, keyring,
certFile, keyFile, caFile string) (string, error) {
name = strings.TrimSpace(name)
version = strings.TrimSpace(version)
if fi, err := os.Stat(name); err == nil {
abs, err := filepath.Abs(name)
if err != nil {
return abs, err
}
if verify {
if fi.IsDir() {
return "", errors.New("cannot verify a directory")
}
if _, err := downloader.VerifyChart(abs, keyring); err != nil {
return "", err
}
}
return abs, nil
}
if filepath.IsAbs(name) || strings.HasPrefix(name, ".") {
return name, errors.Errorf("path %q not found", name)
}
crepo := filepath.Join(settings.Home.Repository(), name)
if _, err := os.Stat(crepo); err == nil {
return filepath.Abs(crepo)
}
dl := downloader.ChartDownloader{
HelmHome: settings.Home,
Out: os.Stdout,
Keyring: keyring,
Getters: getter.All(settings),
Username: username,
Password: password,
}
if verify {
dl.Verify = downloader.VerifyAlways
}
if repoURL != "" {
chartURL, err := repo.FindChartInAuthRepoURL(repoURL, username, password, name, version,
certFile, keyFile, caFile, getter.All(settings))
if err != nil {
return "", err
}
name = chartURL
}
if _, err := os.Stat(settings.Home.Archive()); os.IsNotExist(err) {
os.MkdirAll(settings.Home.Archive(), 0744)
}
filename, _, err := dl.DownloadTo(name, version, settings.Home.Archive())
if err == nil {
lname, err := filepath.Abs(filename)
if err != nil {
return filename, err
}
debug("Fetched %s to %s\n", name, filename)
return lname, nil
} else if settings.Debug {
return filename, err
}
return filename, errors.Errorf("failed to download %q (hint: running `helm repo update` may help)", name)
}
func generateName(nameTemplate string) (string, error) {
t, err := template.New("name-template").Funcs(sprig.TxtFuncMap()).Parse(nameTemplate)
if err != nil {
@ -481,23 +314,3 @@ func checkDependencies(ch *chart.Chart, reqs *chartutil.Requirements) error {
}
return nil
}
//readFile load a file from the local directory or a remote file with a url.
func readFile(filePath string) ([]byte, error) {
u, _ := url.Parse(filePath)
p := getter.All(settings)
// FIXME: maybe someone handle other protocols like ftp.
getterConstructor, err := p.ByScheme(u.Scheme)
if err != nil {
return ioutil.ReadFile(filePath)
}
getter, err := getterConstructor(filePath, "", "", "")
if err != nil {
return []byte{}, err
}
data, err := getter.Get(filePath)
return data.Bytes(), err
}

@ -44,11 +44,10 @@ or recommendation, it will emit [WARNING] messages.
`
type lintOptions struct {
valueFiles valueFiles
values []string
sValues []string
strict bool
paths []string
strict bool
paths []string
valuesOptions
}
func newLintCmd(out io.Writer) *cobra.Command {
@ -66,10 +65,9 @@ func newLintCmd(out io.Writer) *cobra.Command {
},
}
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")
fs := cmd.Flags()
fs.BoolVar(&o.strict, "strict", false, "fail on lint warnings")
o.valuesOptions.addFlags(fs)
return cmd
}
@ -193,7 +191,7 @@ func (o *lintOptions) vals() ([]byte, error) {
}
// User specified a value via --set-string
for _, value := range o.sValues {
for _, value := range o.stringValues {
if err := strvals.ParseIntoString(value, base); err != nil {
return []byte{}, errors.Wrap(err, "failed parsing --set-string data")
}

@ -74,7 +74,6 @@ type listOptions struct {
sortDesc bool // --reverse
superseded bool // --superseded
// args
filter string
client helm.Interface

@ -0,0 +1,225 @@
/*
Copyright 2018 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main // import "k8s.io/helm/cmd/helm"
import (
"io/ioutil"
"net/url"
"os"
"path/filepath"
"strings"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
"github.com/spf13/pflag"
"k8s.io/helm/pkg/downloader"
"k8s.io/helm/pkg/getter"
"k8s.io/helm/pkg/repo"
"k8s.io/helm/pkg/strvals"
)
// -----------------------------------------------------------------------------
// Values Options
type valuesOptions struct {
valueFiles []string // --values
values []string // --set
stringValues []string // --set-string
}
func (o *valuesOptions) addFlags(fs *pflag.FlagSet) {
fs.StringSliceVarP(&o.valueFiles, "values", "f", []string{}, "specify values in a YAML file or a URL(can specify multiple)")
fs.StringArrayVar(&o.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
fs.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)")
}
// mergeValues merges values from files specified via -f/--values and
// directly via --set or --set-string, marshaling them to YAML
func (o *valuesOptions) mergedValues() ([]byte, error) {
base := map[string]interface{}{}
// User specified a values files via -f/--values
for _, filePath := range o.valueFiles {
currentMap := map[string]interface{}{}
bytes, err := readFile(filePath)
if err != nil {
return []byte{}, err
}
if err := yaml.Unmarshal(bytes, &currentMap); err != nil {
return []byte{}, errors.Wrapf(err, "failed to parse %s", filePath)
}
// Merge with the previous map
base = mergeValues(base, currentMap)
}
// User specified a value via --set
for _, value := range o.values {
if err := strvals.ParseInto(value, base); err != nil {
return []byte{}, errors.Wrap(err, "failed parsing --set data")
}
}
// User specified a value via --set-string
for _, value := range o.stringValues {
if err := strvals.ParseIntoString(value, base); err != nil {
return []byte{}, errors.Wrap(err, "failed parsing --set-string data")
}
}
return yaml.Marshal(base)
}
// readFile load a file from stdin, the local directory, or a remote file with a url.
func readFile(filePath string) ([]byte, error) {
if strings.TrimSpace(filePath) == "-" {
return ioutil.ReadAll(os.Stdin)
}
u, _ := url.Parse(filePath)
p := getter.All(settings)
// FIXME: maybe someone handle other protocols like ftp.
getterConstructor, err := p.ByScheme(u.Scheme)
if err != nil {
return ioutil.ReadFile(filePath)
}
getter, err := getterConstructor(filePath, "", "", "")
if err != nil {
return []byte{}, err
}
data, err := getter.Get(filePath)
return data.Bytes(), err
}
// -----------------------------------------------------------------------------
// Chart Path Options
type chartPathOptions struct {
caFile string // --ca-file
certFile string // --cert-file
keyFile string // --key-file
keyring string // --keyring
password string // --password
repoURL string // --repo
username string // --username
verify bool // --verify
version string // --version
}
// defaultKeyring returns the expanded path to the default keyring.
func defaultKeyring() string {
if v, ok := os.LookupEnv("GNUPGHOME"); ok {
return filepath.Join(v, "pubring.gpg")
}
return os.ExpandEnv("$HOME/.gnupg/pubring.gpg")
}
func (o *chartPathOptions) addFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.version, "version", "", "specify the exact chart version to install. If this is not specified, the latest version is installed")
fs.BoolVar(&o.verify, "verify", false, "verify the package before installing it")
fs.StringVar(&o.keyring, "keyring", defaultKeyring(), "location of public keys used for verification")
fs.StringVar(&o.repoURL, "repo", "", "chart repository url where to locate the requested chart")
fs.StringVar(&o.username, "username", "", "chart repository username where to locate the requested chart")
fs.StringVar(&o.password, "password", "", "chart repository password where to locate the requested chart")
fs.StringVar(&o.certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
fs.StringVar(&o.keyFile, "key-file", "", "identify HTTPS client using this SSL key file")
fs.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
}
func (o *chartPathOptions) locateChart(name string) (string, error) {
return locateChartPath(o.repoURL, o.username, o.password, name, o.version, o.keyring, o.certFile, o.keyFile, o.caFile, o.verify)
}
// locateChartPath looks for a chart directory in known places, and returns either the full path or an error.
//
// This does not ensure that the chart is well-formed; only that the requested filename exists.
//
// Order of resolution:
// - relative to current working directory
// - if path is absolute or begins with '.', error out here
// - chart repos in $HELM_HOME
// - URL
//
// If 'verify' is true, this will attempt to also verify the chart.
func locateChartPath(repoURL, username, password, name, version, keyring,
certFile, keyFile, caFile string, verify bool) (string, error) {
name = strings.TrimSpace(name)
version = strings.TrimSpace(version)
if _, err := os.Stat(name); err == nil {
abs, err := filepath.Abs(name)
if err != nil {
return abs, err
}
if verify {
if _, err := downloader.VerifyChart(abs, keyring); err != nil {
return "", err
}
}
return abs, nil
}
if filepath.IsAbs(name) || strings.HasPrefix(name, ".") {
return name, errors.Errorf("path %q not found", name)
}
crepo := filepath.Join(settings.Home.Repository(), name)
if _, err := os.Stat(crepo); err == nil {
return filepath.Abs(crepo)
}
dl := downloader.ChartDownloader{
HelmHome: settings.Home,
Out: os.Stdout,
Keyring: keyring,
Getters: getter.All(settings),
Username: username,
Password: password,
}
if verify {
dl.Verify = downloader.VerifyAlways
}
if repoURL != "" {
chartURL, err := repo.FindChartInAuthRepoURL(repoURL, username, password, name, version,
certFile, keyFile, caFile, getter.All(settings))
if err != nil {
return "", err
}
name = chartURL
}
if _, err := os.Stat(settings.Home.Archive()); os.IsNotExist(err) {
os.MkdirAll(settings.Home.Archive(), 0744)
}
filename, _, err := dl.DownloadTo(name, version, settings.Home.Archive())
if err == nil {
lname, err := filepath.Abs(filename)
if err != nil {
return filename, err
}
debug("Fetched %s to %s\n", name, filename)
return lname, nil
} else if settings.Debug {
return filename, err
}
return filename, errors.Errorf("failed to download %q (hint: running `helm repo update` may help)", name)
}

@ -50,18 +50,16 @@ Versioned chart archives are used by Helm package repositories.
`
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
appVersion string // --app-version
dependencyUpdate bool // --dependency-update
destination string // --destination
key string // --key
keyring string // --keyring
sign bool // --sign
version string // --version
valuesOptions
path string
home helmpath.Home
@ -98,9 +96,6 @@ func newPackageCmd(out io.Writer) *cobra.Command {
}
f := cmd.Flags()
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")
@ -108,6 +103,7 @@ func newPackageCmd(out io.Writer) *cobra.Command {
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`)
o.valuesOptions.addFlags(f)
return cmd
}
@ -138,7 +134,7 @@ func (o *packageOptions) run(out io.Writer) error {
return err
}
overrideVals, err := vals(o.valueFiles, o.values, o.stringValues)
overrideVals, err := o.mergedValues()
if err != nil {
return err
}

@ -62,16 +62,16 @@ To render just one template in a chart, use '-x':
`
type templateOptions struct {
valueFiles valueFiles
chartPath string
values []string
stringValues []string
nameTemplate string
showNotes bool
releaseName string
renderFiles []string
kubeVersion string
outputDir string
nameTemplate string // --name-template
showNotes bool // --notes
releaseName string // --name
renderFiles []string // --execute
kubeVersion string // --kube-version
outputDir string // --output-dir
valuesOptions
chartPath string
}
func newTemplateCmd(out io.Writer) *cobra.Command {
@ -99,12 +99,10 @@ func newTemplateCmd(out io.Writer) *cobra.Command {
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")
o.valuesOptions.addFlags(f)
return cmd
}
@ -140,7 +138,7 @@ func (o *templateOptions) run(out io.Writer) error {
}
// get combined values and create config
config, err := vals(o.valueFiles, o.values, o.stringValues)
config, err := o.mergedValues()
if err != nil {
return err
}

@ -56,32 +56,24 @@ set for a key called 'foo', the 'newbar' value would take precedence:
`
type upgradeOptions struct {
release string
chart string
client helm.Interface
dryRun bool
recreate bool
force bool
disableHooks bool
valueFiles valueFiles
values []string
stringValues []string
verify bool
keyring string
install bool
version string
timeout int64
resetValues bool
reuseValues bool
wait bool
repoURL string
username string
password string
devel bool
certFile string
keyFile string
caFile string
devel bool // --devel
disableHooks bool // --disable-hooks
dryRun bool // --dry-run
force bool // --force
install bool // --install
recreate bool // --recreate-pods
resetValues bool // --reset-values
reuseValues bool // --reuse-values
timeout int64 // --timeout
wait bool // --wait
valuesOptions
chartPathOptions
release string
chart string
client helm.Interface
}
func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
@ -107,35 +99,25 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
}
f := cmd.Flags()
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.")
o.valuesOptions.addFlags(f)
o.chartPathOptions.addFlags(f)
return cmd
}
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)
chartPath, err := o.locateChart(o.chart)
if err != nil {
return err
}
@ -148,24 +130,21 @@ func (o *upgradeOptions) run(out io.Writer) error {
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: 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,
chartPath: chartPath,
client: o.client,
name: o.release,
dryRun: o.dryRun,
disableHooks: o.disableHooks,
timeout: o.timeout,
wait: o.wait,
valuesOptions: o.valuesOptions,
chartPathOptions: o.chartPathOptions,
}
return io.run(out)
}
}
rawVals, err := vals(o.valueFiles, o.values, o.stringValues)
rawVals, err := o.mergedValues()
if err != nil {
return err
}

Loading…
Cancel
Save