2022-01-24 18:52:57 +00:00
|
|
|
// 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
|
|
|
|
}
|
2022-02-13 00:21:41 +00:00
|
|
|
log.Fatalf("invalid boolean environment variable %s value %q", envVar, val)
|
2022-01-24 18:52:57 +00:00
|
|
|
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
|
|
|
|
}
|
2022-02-13 00:21:41 +00:00
|
|
|
log.Fatalf("invalid boolean environment variable %s value %q", envVar, val)
|
2022-01-24 18:52:57 +00:00
|
|
|
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
|
|
|
|
}
|
2022-02-13 00:21:41 +00:00
|
|
|
log.Fatalf("invalid integer environment variable %s: %v", envVar, val)
|
2022-01-24 18:52:57 +00:00
|
|
|
panic("unreachable")
|
|
|
|
}
|
2021-08-26 21:50:55 +00:00
|
|
|
|
|
|
|
// UseWIPCode is whether TAILSCALE_USE_WIP_CODE is set to permit use
|
|
|
|
// of Work-In-Progress code.
|
|
|
|
func UseWIPCode() bool { return Bool("TAILSCALE_USE_WIP_CODE") }
|