Merge pull request #2690 from adamreese/fix/helm-home-plugins-again-again

fix(helm): fix flag parsing once and for all
pull/2691/head
Adam Reese 7 years ago committed by GitHub
commit 3cf8f2c8b3

@ -23,8 +23,6 @@ import (
"testing" "testing"
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/proto/hapi/chart" "k8s.io/helm/pkg/proto/hapi/chart"
) )
@ -87,13 +85,14 @@ func TestCreateStarterCmd(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
old := helmpath.Home(environment.DefaultHelmHome) cleanup := resetEnv()
settings.Home = thome
defer func() { defer func() {
settings.Home = old
os.RemoveAll(thome.String()) os.RemoveAll(thome.String())
cleanup()
}() }()
settings.Home = thome
// Create a starter. // Create a starter.
starterchart := filepath.Join(thome.String(), "starters") starterchart := filepath.Join(thome.String(), "starters")
os.Mkdir(starterchart, 0755) os.Mkdir(starterchart, 0755)

@ -29,17 +29,18 @@ import (
) )
func TestDependencyBuildCmd(t *testing.T) { func TestDependencyBuildCmd(t *testing.T) {
oldhome := settings.Home
hh, err := tempHelmHome(t) hh, err := tempHelmHome(t)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
settings.Home = hh cleanup := resetEnv()
defer func() { defer func() {
os.RemoveAll(hh.String()) os.RemoveAll(hh.String())
settings.Home = oldhome cleanup()
}() }()
settings.Home = hh
srv := repotest.NewServer(hh.String()) srv := repotest.NewServer(hh.String())
defer srv.Stop() defer srv.Stop()
_, err = srv.CopyCharts("testdata/testcharts/*.tgz") _, err = srv.CopyCharts("testdata/testcharts/*.tgz")

@ -34,18 +34,18 @@ import (
) )
func TestDependencyUpdateCmd(t *testing.T) { func TestDependencyUpdateCmd(t *testing.T) {
// Set up a testing helm home
oldhome := settings.Home
hh, err := tempHelmHome(t) hh, err := tempHelmHome(t)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
settings.Home = hh cleanup := resetEnv()
defer func() { defer func() {
os.RemoveAll(hh.String()) os.RemoveAll(hh.String())
settings.Home = oldhome cleanup()
}() }()
settings.Home = hh
srv := repotest.NewServer(hh.String()) srv := repotest.NewServer(hh.String())
defer srv.Stop() defer srv.Stop()
copied, err := srv.CopyCharts("testdata/testcharts/*.tgz") copied, err := srv.CopyCharts("testdata/testcharts/*.tgz")
@ -129,18 +129,18 @@ func TestDependencyUpdateCmd(t *testing.T) {
} }
func TestDependencyUpdateCmd_SkipRefresh(t *testing.T) { func TestDependencyUpdateCmd_SkipRefresh(t *testing.T) {
// Set up a testing helm home
oldhome := settings.Home
hh, err := tempHelmHome(t) hh, err := tempHelmHome(t)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
settings.Home = hh cleanup := resetEnv()
defer func() { defer func() {
os.RemoveAll(hh.String()) os.RemoveAll(hh.String())
settings.Home = oldhome cleanup()
}() }()
settings.Home = hh
srv := repotest.NewServer(hh.String()) srv := repotest.NewServer(hh.String())
defer srv.Stop() defer srv.Stop()
copied, err := srv.CopyCharts("testdata/testcharts/*.tgz") copied, err := srv.CopyCharts("testdata/testcharts/*.tgz")

@ -24,8 +24,6 @@ import (
"regexp" "regexp"
"testing" "testing"
"k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/repo/repotest" "k8s.io/helm/pkg/repo/repotest"
) )
@ -34,15 +32,16 @@ func TestFetchCmd(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
old := helmpath.Home(environment.DefaultHelmHome) cleanup := resetEnv()
settings.Home = hh
defer func() { defer func() {
settings.Home = old
os.RemoveAll(hh.String()) os.RemoveAll(hh.String())
cleanup()
}() }()
srv := repotest.NewServer(hh.String()) srv := repotest.NewServer(hh.String())
defer srv.Stop() defer srv.Stop()
settings.Home = hh
// all flags will get "--home=TMDIR -d outdir" appended. // all flags will get "--home=TMDIR -d outdir" appended.
tests := []struct { tests := []struct {
name string name string

@ -35,7 +35,6 @@ import (
helm_env "k8s.io/helm/pkg/helm/environment" helm_env "k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/portforwarder" "k8s.io/helm/pkg/helm/portforwarder"
"k8s.io/helm/pkg/kube" "k8s.io/helm/pkg/kube"
tiller_env "k8s.io/helm/pkg/tiller/environment"
"k8s.io/helm/pkg/tlsutil" "k8s.io/helm/pkg/tlsutil"
) )
@ -46,7 +45,6 @@ var (
tlsVerify bool // enable TLS and verify remote certificates tlsVerify bool // enable TLS and verify remote certificates
tlsEnable bool // enable TLS tlsEnable bool // enable TLS
kubeContext string
tillerTunnel *kube.Tunnel tillerTunnel *kube.Tunnel
settings helm_env.EnvSettings settings helm_env.EnvSettings
) )
@ -75,57 +73,25 @@ Environment:
$KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config") $KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config")
` `
func setFlagFromEnv(name, envar string, cmd *cobra.Command) { func newRootCmd(args []string) *cobra.Command {
if cmd.Flags().Changed(name) {
return
}
if v, ok := os.LookupEnv(envar); ok {
cmd.Flags().Set(name, v)
}
}
func setFlagsFromEnv(flags map[string]string, cmd *cobra.Command) {
for name, envar := range flags {
setFlagFromEnv(name, envar, cmd)
}
}
func addRootFlags(cmd *cobra.Command) {
pf := cmd.PersistentFlags()
pf.StringVar((*string)(&settings.Home), "home", helm_env.DefaultHelmHome, "location of your Helm config. Overrides $HELM_HOME")
pf.StringVar(&settings.TillerHost, "host", "", "address of Tiller. Overrides $HELM_HOST")
pf.StringVar(&kubeContext, "kube-context", "", "name of the kubeconfig context to use")
pf.BoolVar(&settings.Debug, "debug", false, "enable verbose output")
pf.StringVar(&settings.TillerNamespace, "tiller-namespace", tiller_env.DefaultTillerNamespace, "namespace of Tiller")
}
func initRootFlags(cmd *cobra.Command) {
setFlagsFromEnv(map[string]string{
"debug": helm_env.DebugEnvVar,
"home": helm_env.HomeEnvVar,
"host": helm_env.HostEnvVar,
"tiller-namespace": tiller_env.TillerNamespaceEnvVar,
}, cmd.Root())
tlsCaCertFile = os.ExpandEnv(tlsCaCertFile)
tlsCertFile = os.ExpandEnv(tlsCertFile)
tlsKeyFile = os.ExpandEnv(tlsKeyFile)
}
func newRootCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "helm", Use: "helm",
Short: "The Helm package manager for Kubernetes.", Short: "The Helm package manager for Kubernetes.",
Long: globalUsage, Long: globalUsage,
SilenceUsage: true, SilenceUsage: true,
PersistentPreRun: func(cmd *cobra.Command, _ []string) { PersistentPreRun: func(*cobra.Command, []string) {
initRootFlags(cmd) tlsCaCertFile = os.ExpandEnv(tlsCaCertFile)
tlsCertFile = os.ExpandEnv(tlsCertFile)
tlsKeyFile = os.ExpandEnv(tlsKeyFile)
}, },
PersistentPostRun: func(*cobra.Command, []string) { PersistentPostRun: func(*cobra.Command, []string) {
teardown() teardown()
}, },
} }
addRootFlags(cmd) flags := cmd.PersistentFlags()
settings.AddFlags(flags)
out := cmd.OutOrStdout() out := cmd.OutOrStdout()
cmd.AddCommand( cmd.AddCommand(
@ -167,6 +133,11 @@ func newRootCmd() *cobra.Command {
markDeprecated(newRepoUpdateCmd(out), "use 'helm repo update'\n"), markDeprecated(newRepoUpdateCmd(out), "use 'helm repo update'\n"),
) )
flags.Parse(args)
// set defaults from environment
settings.Init(flags)
// Find and add plugins // Find and add plugins
loadPlugins(cmd, out) loadPlugins(cmd, out)
@ -179,7 +150,7 @@ func init() {
} }
func main() { func main() {
cmd := newRootCmd() cmd := newRootCmd(os.Args[1:])
if err := cmd.Execute(); err != nil { if err := cmd.Execute(); err != nil {
os.Exit(1) os.Exit(1)
} }
@ -192,7 +163,7 @@ func markDeprecated(cmd *cobra.Command, notice string) *cobra.Command {
func setupConnection(c *cobra.Command, args []string) error { func setupConnection(c *cobra.Command, args []string) error {
if settings.TillerHost == "" { if settings.TillerHost == "" {
config, client, err := getKubeClient(kubeContext) config, client, err := getKubeClient(settings.KubeContext)
if err != nil { if err != nil {
return err return err
} }

@ -25,6 +25,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings"
"testing" "testing"
"github.com/golang/protobuf/ptypes/timestamp" "github.com/golang/protobuf/ptypes/timestamp"
@ -232,8 +233,8 @@ func ensureTestHome(home helmpath.Home, t *testing.T) error {
} }
func TestRootCmd(t *testing.T) { func TestRootCmd(t *testing.T) {
oldhome := os.Getenv("HELM_HOME") cleanup := resetEnv()
defer os.Setenv("HELM_HOME", oldhome) defer cleanup()
tests := []struct { tests := []struct {
name string name string
@ -287,7 +288,7 @@ func TestRootCmd(t *testing.T) {
os.Setenv(k, v) os.Setenv(k, v)
} }
cmd := newRootCmd() cmd := newRootCmd(tt.args)
cmd.SetOutput(ioutil.Discard) cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tt.args) cmd.SetArgs(tt.args)
cmd.Run = func(*cobra.Command, []string) {} cmd.Run = func(*cobra.Command, []string) {}
@ -306,3 +307,15 @@ func TestRootCmd(t *testing.T) {
}) })
} }
} }
func resetEnv() func() {
origSettings := settings
origEnv := os.Environ()
return func() {
settings = origSettings
for _, pair := range origEnv {
kv := strings.SplitN(pair, "=", 2)
os.Setenv(kv[0], kv[1])
}
}
}

@ -230,7 +230,7 @@ func (i *initCmd) run() error {
if !i.clientOnly { if !i.clientOnly {
if i.kubeClient == nil { if i.kubeClient == nil {
_, c, err := getKubeClient(kubeContext) _, c, err := getKubeClient(settings.KubeContext)
if err != nil { if err != nil {
return fmt.Errorf("could not get kubernetes client: %s", err) return fmt.Errorf("could not get kubernetes client: %s", err)
} }

@ -140,13 +140,14 @@ func TestInitCmd_dryRun(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
dbg := settings.Debug cleanup := resetEnv()
settings.Debug = true
defer func() { defer func() {
os.Remove(home) os.Remove(home)
settings.Debug = dbg cleanup()
}() }()
settings.Debug = true
var buf bytes.Buffer var buf bytes.Buffer
fc := fake.NewSimpleClientset() fc := fake.NewSimpleClientset()
cmd := &initCmd{ cmd := &initCmd{

@ -434,7 +434,7 @@ func generateName(nameTemplate string) (string, error) {
} }
func defaultNamespace() string { func defaultNamespace() string {
if ns, _, err := kube.GetConfig(kubeContext).Namespace(); err == nil { if ns, _, err := kube.GetConfig(settings.KubeContext).Namespace(); err == nil {
return ns return ns
} }
return "default" return "default"

@ -24,9 +24,7 @@ import (
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag"
helm_env "k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/plugin" "k8s.io/helm/pkg/plugin"
) )
@ -38,20 +36,11 @@ import (
func loadPlugins(baseCmd *cobra.Command, out io.Writer) { func loadPlugins(baseCmd *cobra.Command, out io.Writer) {
// If HELM_NO_PLUGINS is set to 1, do not load plugins. // If HELM_NO_PLUGINS is set to 1, do not load plugins.
if os.Getenv(helm_env.PluginDisableEnvVar) == "1" { if os.Getenv("HELM_NO_PLUGINS") == "1" {
return return
} }
// manually handel processing of HELM_HOME and --home // debug("HELM_PLUGIN_DIRS=%s", settings.PluginDirs())
helmHome := "$HOME/.helm"
if h, ok := os.LookupEnv("HELM_HOME"); ok {
helmHome = h
}
fs := pflag.NewFlagSet("homer", pflag.ContinueOnError)
fs.StringVar((*string)(&settings.Home), "home", helmHome, "location of your Helm config. Overrides $HELM_HOME")
fs.Parse(os.Args)
found, err := findPlugins(settings.PluginDirs()) found, err := findPlugins(settings.PluginDirs())
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "failed to load plugins: %s", err) fmt.Fprintf(os.Stderr, "failed to load plugins: %s", err)
@ -63,7 +52,6 @@ func loadPlugins(baseCmd *cobra.Command, out io.Writer) {
if err := cmd.Parent().ParseFlags(k); err != nil { if err := cmd.Parent().ParseFlags(k); err != nil {
return nil, err return nil, err
} }
initRootFlags(cmd)
return u, nil return u, nil
} }

@ -143,14 +143,15 @@ func TestPackage(t *testing.T) {
} }
ensureTestHome(helmpath.Home(tmp), t) ensureTestHome(helmpath.Home(tmp), t)
oldhome := settings.Home cleanup := resetEnv()
settings.Home = helmpath.Home(tmp)
defer func() { defer func() {
settings.Home = oldhome
os.Chdir(origDir) os.Chdir(origDir)
os.RemoveAll(tmp) os.RemoveAll(tmp)
cleanup()
}() }()
settings.Home = helmpath.Home(tmp)
for _, tt := range tests { for _, tt := range tests {
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
c := newPackageCmd(buf) c := newPackageCmd(buf)

@ -23,7 +23,6 @@ import (
"strings" "strings"
"testing" "testing"
helm_env "k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/helmpath" "k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/plugin" "k8s.io/helm/pkg/plugin"
@ -64,25 +63,13 @@ func TestManuallyProcessArgs(t *testing.T) {
} }
// resetEnv sets an env var, and returns a defer function to reset the env
func resetEnv(name, val string) func() {
original, ok := os.LookupEnv(name)
os.Setenv(name, val)
if ok {
return func() { os.Setenv(name, original) }
}
return func() { os.Unsetenv(name) }
}
func TestLoadPlugins(t *testing.T) { func TestLoadPlugins(t *testing.T) {
// Set helm home to point to testdata cleanup := resetEnv()
old := settings.Home defer cleanup()
settings.Home = "testdata/helmhome" settings.Home = "testdata/helmhome"
cleanup := resetEnv("HELM_HOME", settings.Home.String())
defer func() { os.Setenv("HELM_HOME", settings.Home.String())
settings.Home = old
cleanup()
}()
hh := settings.Home hh := settings.Home
out := bytes.NewBuffer(nil) out := bytes.NewBuffer(nil)
@ -149,14 +136,12 @@ func TestLoadPlugins(t *testing.T) {
} }
func TestLoadPlugins_HelmNoPlugins(t *testing.T) { func TestLoadPlugins_HelmNoPlugins(t *testing.T) {
// Set helm home to point to testdata cleanup := resetEnv()
old := settings.Home defer cleanup()
settings.Home = "testdata/helmhome" settings.Home = "testdata/helmhome"
os.Setenv(helm_env.PluginDisableEnvVar, "1")
defer func() { os.Setenv("HELM_NO_PLUGINS", "1")
settings.Home = old
os.Unsetenv(helm_env.PluginDisableEnvVar)
}()
out := bytes.NewBuffer(nil) out := bytes.NewBuffer(nil)
cmd := &cobra.Command{} cmd := &cobra.Command{}

@ -33,17 +33,18 @@ func TestRepoAddCmd(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
oldhome := settings.Home cleanup := resetEnv()
settings.Home = thome
defer func() { defer func() {
srv.Stop() srv.Stop()
settings.Home = oldhome
os.Remove(thome.String()) os.Remove(thome.String())
cleanup()
}() }()
if err := ensureTestHome(thome, t); err != nil { if err := ensureTestHome(thome, t); err != nil {
t.Fatal(err) t.Fatal(err)
} }
settings.Home = thome
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "add a repository", name: "add a repository",
@ -67,18 +68,19 @@ func TestRepoAdd(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
oldhome := settings.Home cleanup := resetEnv()
settings.Home = thome
hh := thome hh := thome
defer func() { defer func() {
ts.Stop() ts.Stop()
settings.Home = oldhome
os.Remove(thome.String()) os.Remove(thome.String())
cleanup()
}() }()
if err := ensureTestHome(hh, t); err != nil { if err := ensureTestHome(hh, t); err != nil {
t.Fatal(err) t.Fatal(err)
} }
settings.Home = thome
if err := addRepository(testName, ts.URL(), hh, "", "", "", true); err != nil { if err := addRepository(testName, ts.URL(), hh, "", "", "", true); err != nil {
t.Error(err) t.Error(err)
} }

@ -33,18 +33,19 @@ func TestRepoRemove(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
oldhome := settings.Home
settings.Home = thome
hh := helmpath.Home(thome) hh := helmpath.Home(thome)
cleanup := resetEnv()
defer func() { defer func() {
ts.Stop() ts.Stop()
settings.Home = oldhome
os.Remove(thome.String()) os.Remove(thome.String())
cleanup()
}() }()
if err := ensureTestHome(hh, t); err != nil { if err := ensureTestHome(hh, t); err != nil {
t.Fatal(err) t.Fatal(err)
} }
settings.Home = thome
b := bytes.NewBuffer(nil) b := bytes.NewBuffer(nil)
if err := removeRepoLine(b, testName, hh); err == nil { if err := removeRepoLine(b, testName, hh); err == nil {

@ -34,13 +34,15 @@ func TestUpdateCmd(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
oldhome := settings.Home
settings.Home = thome cleanup := resetEnv()
defer func() { defer func() {
settings.Home = oldhome
os.Remove(thome.String()) os.Remove(thome.String())
cleanup()
}() }()
settings.Home = thome
out := bytes.NewBuffer(nil) out := bytes.NewBuffer(nil)
// Instead of using the HTTP updater, we provide our own for this test. // Instead of using the HTTP updater, we provide our own for this test.
// The TestUpdateCharts test verifies the HTTP behavior independently. // The TestUpdateCharts test verifies the HTTP behavior independently.
@ -69,18 +71,19 @@ func TestUpdateCharts(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
oldhome := settings.Home
settings.Home = thome
hh := helmpath.Home(thome) hh := helmpath.Home(thome)
cleanup := resetEnv()
defer func() { defer func() {
ts.Stop() ts.Stop()
settings.Home = oldhome
os.Remove(thome.String()) os.Remove(thome.String())
cleanup()
}() }()
if err := ensureTestHome(hh, t); err != nil { if err := ensureTestHome(hh, t); err != nil {
t.Fatal(err) t.Fatal(err)
} }
settings.Home = thome
r, err := repo.NewChartRepository(&repo.Entry{ r, err := repo.NewChartRepository(&repo.Entry{
Name: "charts", Name: "charts",
URL: ts.URL(), URL: ts.URL(),

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

@ -68,9 +68,10 @@ func TestSearchCmd(t *testing.T) {
}, },
} }
oldhome := settings.Home cleanup := resetEnv()
defer cleanup()
settings.Home = "testdata/helmhome" settings.Home = "testdata/helmhome"
defer func() { settings.Home = oldhome }()
for _, tt := range tests { for _, tt := range tests {
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)

@ -26,20 +26,9 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"k8s.io/helm/pkg/helm/helmpath" "github.com/spf13/pflag"
)
const ( "k8s.io/helm/pkg/helm/helmpath"
// HomeEnvVar is the HELM_HOME environment variable key.
HomeEnvVar = "HELM_HOME"
// PluginEnvVar is the HELM_PLUGIN environment variable key.
PluginEnvVar = "HELM_PLUGIN"
// PluginDisableEnvVar is the HELM_NO_PLUGINS environment variable key.
PluginDisableEnvVar = "HELM_NO_PLUGINS"
// HostEnvVar is the HELM_HOST environment variable key.
HostEnvVar = "HELM_HOST"
// DebugEnvVar is the HELM_DEBUG environment variable key.
DebugEnvVar = "HELM_DEBUG"
) )
// DefaultHelmHome is the default HELM_HOME. // DefaultHelmHome is the default HELM_HOME.
@ -55,12 +44,56 @@ type EnvSettings struct {
Home helmpath.Home Home helmpath.Home
// Debug indicates whether or not Helm is running in Debug mode. // Debug indicates whether or not Helm is running in Debug mode.
Debug bool Debug bool
// KubeContext is the name of the kubeconfig context.
KubeContext string
}
// AddFlags binds flags to the given flagset.
func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) {
fs.StringVar((*string)(&s.Home), "home", DefaultHelmHome, "location of your Helm config. Overrides $HELM_HOME")
fs.StringVar(&s.TillerHost, "host", "", "address of Tiller. Overrides $HELM_HOST")
fs.StringVar(&s.KubeContext, "kube-context", "", "name of the kubeconfig context to use")
fs.BoolVar(&s.Debug, "debug", false, "enable verbose output")
fs.StringVar(&s.TillerNamespace, "tiller-namespace", "kube-system", "namespace of Tiller")
}
// Init sets values from the environment.
func (s *EnvSettings) Init(fs *pflag.FlagSet) {
for name, envar := range envMap {
setFlagFromEnv(name, envar, fs)
}
} }
// PluginDirs is the path to the plugin directories. // PluginDirs is the path to the plugin directories.
func (s EnvSettings) PluginDirs() string { func (s EnvSettings) PluginDirs() string {
if d := os.Getenv(PluginEnvVar); d != "" { if d, ok := os.LookupEnv("HELM_PLUGIN"); ok {
return d return d
} }
return s.Home.Plugins() return s.Home.Plugins()
} }
// envMap maps flag names to envvars
var envMap = map[string]string{
"debug": "HELM_DEBUG",
"home": "HELM_HOME",
"host": "HELM_HOST",
"tiller-namespace": "TILLER_NAMESPACE",
}
func setFlagFromEnv(name, envar string, fs *pflag.FlagSet) {
if fs.Changed(name) {
return
}
if v, ok := os.LookupEnv(envar); ok {
fs.Set(name, v)
}
}
// Deprecated
const (
HomeEnvVar = "HELM_HOME"
PluginEnvVar = "HELM_PLUGIN"
PluginDisableEnvVar = "HELM_NO_PLUGINS"
HostEnvVar = "HELM_HOST"
DebugEnvVar = "HELM_DEBUG"
)

@ -0,0 +1,134 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package environment
import (
"os"
"strings"
"testing"
"k8s.io/helm/pkg/helm/helmpath"
"github.com/spf13/pflag"
)
func TestEnvSettings(t *testing.T) {
tests := []struct {
name string
// input
args []string
envars map[string]string
// expected values
home, host, ns, kcontext, plugins string
debug bool
}{
{
name: "defaults",
args: []string{},
home: DefaultHelmHome,
plugins: helmpath.Home(DefaultHelmHome).Plugins(),
ns: "kube-system",
},
{
name: "with flags set",
args: []string{"--home", "/foo", "--host=here", "--debug", "--tiller-namespace=myns"},
home: "/foo",
plugins: helmpath.Home("/foo").Plugins(),
host: "here",
ns: "myns",
debug: true,
},
{
name: "with envvars set",
args: []string{},
envars: map[string]string{"HELM_HOME": "/bar", "HELM_HOST": "there", "HELM_DEBUG": "1", "TILLER_NAMESPACE": "yourns"},
home: "/bar",
plugins: helmpath.Home("/bar").Plugins(),
host: "there",
ns: "yourns",
debug: true,
},
{
name: "with flags and envvars set",
args: []string{"--home", "/foo", "--host=here", "--debug", "--tiller-namespace=myns"},
envars: map[string]string{"HELM_HOME": "/bar", "HELM_HOST": "there", "HELM_DEBUG": "1", "TILLER_NAMESPACE": "yourns", "HELM_PLUGIN": "glade"},
home: "/foo",
plugins: "glade",
host: "here",
ns: "myns",
debug: true,
},
}
cleanup := resetEnv()
defer cleanup()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for k, v := range tt.envars {
os.Setenv(k, v)
}
flags := pflag.NewFlagSet("testing", pflag.ContinueOnError)
settings := &EnvSettings{}
settings.AddFlags(flags)
flags.Parse(tt.args)
settings.Init(flags)
if settings.Home != helmpath.Home(tt.home) {
t.Errorf("expected home %q, got %q", tt.home, settings.Home)
}
if settings.PluginDirs() != tt.plugins {
t.Errorf("expected plugins %q, got %q", tt.plugins, settings.PluginDirs())
}
if settings.TillerHost != tt.host {
t.Errorf("expected host %q, got %q", tt.host, settings.TillerHost)
}
if settings.Debug != tt.debug {
t.Errorf("expected debug %t, got %t", tt.debug, settings.Debug)
}
if settings.TillerNamespace != tt.ns {
t.Errorf("expected tiller-namespace %q, got %q", tt.ns, settings.TillerNamespace)
}
if settings.KubeContext != tt.kcontext {
t.Errorf("expected kube-context %q, got %q", tt.kcontext, settings.KubeContext)
}
cleanup()
})
}
}
func resetEnv() func() {
origEnv := os.Environ()
// ensure any local envvars do not hose us
for _, e := range envMap {
os.Unsetenv(e)
}
return func() {
for _, pair := range origEnv {
kv := strings.SplitN(pair, "=", 2)
os.Setenv(kv[0], kv[1])
}
}
}

@ -22,7 +22,6 @@ import (
"strings" "strings"
helm_env "k8s.io/helm/pkg/helm/environment" helm_env "k8s.io/helm/pkg/helm/environment"
tiller_env "k8s.io/helm/pkg/tiller/environment"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
) )
@ -179,8 +178,8 @@ func SetupPluginEnv(settings helm_env.EnvSettings,
// Set vars that may not have been set, and save client the // Set vars that may not have been set, and save client the
// trouble of re-parsing. // trouble of re-parsing.
helm_env.PluginEnvVar: settings.PluginDirs(), "HELM_PLUGIN": settings.PluginDirs(),
helm_env.HomeEnvVar: settings.Home.String(), "HELM_HOME": settings.Home.String(),
// Set vars that convey common information. // Set vars that convey common information.
"HELM_PATH_REPOSITORY": settings.Home.Repository(), "HELM_PATH_REPOSITORY": settings.Home.Repository(),
@ -189,8 +188,8 @@ func SetupPluginEnv(settings helm_env.EnvSettings,
"HELM_PATH_LOCAL_REPOSITORY": settings.Home.LocalRepository(), "HELM_PATH_LOCAL_REPOSITORY": settings.Home.LocalRepository(),
"HELM_PATH_STARTER": settings.Home.Starters(), "HELM_PATH_STARTER": settings.Home.Starters(),
"TILLER_HOST": settings.TillerHost, "TILLER_HOST": settings.TillerHost,
tiller_env.TillerNamespaceEnvVar: settings.TillerNamespace, "TILLER_NAMESPACE": settings.TillerNamespace,
} { } {
os.Setenv(key, val) os.Setenv(key, val)
} }

@ -37,10 +37,6 @@ import (
"k8s.io/helm/pkg/storage/driver" "k8s.io/helm/pkg/storage/driver"
) )
// TillerNamespaceEnvVar is the environment variable name for the Tiller
// namespace in the kubernetes cluster.
const TillerNamespaceEnvVar = "TILLER_NAMESPACE"
// DefaultTillerNamespace is the default namespace for Tiller. // DefaultTillerNamespace is the default namespace for Tiller.
const DefaultTillerNamespace = "kube-system" const DefaultTillerNamespace = "kube-system"

Loading…
Cancel
Save