diff --git a/etcdmain/etcd.go b/etcdmain/etcd.go index e1fc77642..6b028fcfb 100644 --- a/etcdmain/etcd.go +++ b/etcdmain/etcd.go @@ -161,9 +161,11 @@ func Main() { os.Exit(0) } - flags.SetFlagsFromEnv(fs) + err := flags.SetFlagsFromEnv(fs) + if err != nil { + log.Fatalf("etcd: %v", err) + } - var err error shouldProxy := proxyFlag.String() != proxyFlagOff if !shouldProxy { err = startEtcd() diff --git a/pkg/flags/flag.go b/pkg/flags/flag.go index 5090add83..ca2400524 100644 --- a/pkg/flags/flag.go +++ b/pkg/flags/flag.go @@ -85,7 +85,7 @@ func UsageWithIgnoredFlagsFunc(fs *flag.FlagSet, ignore []string) func() { // environment variables. Environment variables take the name of the flag but // are UPPERCASE, have the prefix "ETCD_", and any dashes are replaced by // underscores - for example: some-flag => ETCD_SOME_FLAG -func SetFlagsFromEnv(fs *flag.FlagSet) { +func SetFlagsFromEnv(fs *flag.FlagSet) (err error) { alreadySet := make(map[string]bool) fs.Visit(func(f *flag.Flag) { alreadySet[f.Name] = true @@ -95,13 +95,13 @@ func SetFlagsFromEnv(fs *flag.FlagSet) { key := "ETCD_" + strings.ToUpper(strings.Replace(f.Name, "-", "_", -1)) val := os.Getenv(key) if val != "" { - if err := fs.Set(f.Name, val); err != nil { - // Should never happen - log.Panicf("error setting flag from env: %v", err) + if serr := fs.Set(f.Name, val); serr != nil { + err = fmt.Errorf("invalid value %q for %s: %v", val, key, serr) } } } }) + return } // URLsFromFlags decides what URLs should be using two different flags diff --git a/pkg/flags/flag_test.go b/pkg/flags/flag_test.go index a33387e25..85f53692c 100644 --- a/pkg/flags/flag_test.go +++ b/pkg/flags/flag_test.go @@ -58,7 +58,10 @@ func TestSetFlagsFromEnv(t *testing.T) { } // now read the env and verify flags were updated as expected - SetFlagsFromEnv(fs) + err := SetFlagsFromEnv(fs) + if err != nil { + t.Errorf("err=%v, want nil", err) + } for f, want := range map[string]string{ "a": "foo", "b": "bar", @@ -68,6 +71,15 @@ func TestSetFlagsFromEnv(t *testing.T) { t.Errorf("flag %q=%q, want %q", f, got, want) } } + + // now verify that an error is propagated + fs = flag.NewFlagSet("testing", flag.ExitOnError) + fs.Int("x", 0, "") + os.Setenv("ETCD_X", "not_a_number") + err = SetFlagsFromEnv(fs) + if err == nil { + t.Errorf("err=nil, want != nil") + } } func TestURLsFromFlags(t *testing.T) {