A new package can also later record/report which knobs are checked and set. It also makes the code cleaner & easier to grep for env knobs. Change-Id: Id8a123ab7539f1fadbd27e0cbeac79c2e4f09751 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>main
parent
6feb8f4c51
commit
41fd4eab5c
@ -0,0 +1,102 @@ |
||||
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package envknob provides access to environment-variable tweakable
|
||||
// debug settings.
|
||||
//
|
||||
// These are primarily knobs used by Tailscale developers during
|
||||
// development or by users when instructed to by Tailscale developers
|
||||
// when debugging something. They are not a stable interface and may
|
||||
// be removed or any time.
|
||||
//
|
||||
// A related package, control/controlknobs, are knobs that can be
|
||||
// changed at runtime by the control plane. Sometimes both are used:
|
||||
// an envknob for the default/explicit value, else falling back
|
||||
// to the controlknob value.
|
||||
package envknob |
||||
|
||||
import ( |
||||
"log" |
||||
"os" |
||||
"strconv" |
||||
|
||||
"tailscale.com/types/opt" |
||||
) |
||||
|
||||
// String returns the named environment variable, using os.Getenv.
|
||||
//
|
||||
// In the future it will also track usage for reporting on debug pages.
|
||||
func String(envVar string) string { |
||||
return os.Getenv(envVar) |
||||
} |
||||
|
||||
// Bool returns the boolean value of the named environment variable.
|
||||
// If the variable is not set, it returns false.
|
||||
// An invalid value exits the binary with a failure.
|
||||
func Bool(envVar string) bool { |
||||
return boolOr(envVar, false) |
||||
} |
||||
|
||||
// BoolDefaultTrue is like Bool, but returns true by default if the
|
||||
// environment variable isn't present.
|
||||
func BoolDefaultTrue(envVar string) bool { |
||||
return boolOr(envVar, true) |
||||
} |
||||
|
||||
func boolOr(envVar string, implicitValue bool) bool { |
||||
val := os.Getenv(envVar) |
||||
if val == "" { |
||||
return implicitValue |
||||
} |
||||
b, err := strconv.ParseBool(val) |
||||
if err == nil { |
||||
return b |
||||
} |
||||
log.Fatalf("invalid environment variable %s value %q: %v", envVar, val, err) |
||||
panic("unreachable") |
||||
} |
||||
|
||||
// LookupBool returns the boolean value of the named environment value.
|
||||
// The ok result is whether a value was set.
|
||||
// If the value isn't a valid int, it exits the program with a failure.
|
||||
func LookupBool(envVar string) (v bool, ok bool) { |
||||
val := os.Getenv(envVar) |
||||
if val == "" { |
||||
return false, false |
||||
} |
||||
b, err := strconv.ParseBool(val) |
||||
if err == nil { |
||||
return b, true |
||||
} |
||||
log.Fatalf("invalid environment variable %s value %q: %v", envVar, val, err) |
||||
panic("unreachable") |
||||
} |
||||
|
||||
// OptBool is like Bool, but returns an opt.Bool, so the caller can
|
||||
// distinguish between implicitly and explicitly false.
|
||||
func OptBool(envVar string) opt.Bool { |
||||
b, ok := LookupBool(envVar) |
||||
if !ok { |
||||
return "" |
||||
} |
||||
var ret opt.Bool |
||||
ret.Set(b) |
||||
return ret |
||||
} |
||||
|
||||
// LookupInt returns the integer value of the named environment value.
|
||||
// The ok result is whether a value was set.
|
||||
// If the value isn't a valid int, it exits the program with a failure.
|
||||
func LookupInt(envVar string) (v int, ok bool) { |
||||
val := os.Getenv(envVar) |
||||
if val == "" { |
||||
return 0, false |
||||
} |
||||
v, err := strconv.Atoi(val) |
||||
if err == nil { |
||||
return v, true |
||||
} |
||||
log.Fatalf("invalid environment variable %s value %q: %v", envVar, val, err) |
||||
panic("unreachable") |
||||
} |
||||
Loading…
Reference in new issue