envknob: add time.Duration knob support

Updates #6818

Change-Id: I9c8147c02fb514f9f6f1f272bdb0f974c8b3ccbb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/6831/head
Brad Fitzpatrick 2 years ago committed by Brad Fitzpatrick
parent 14e8afe444
commit e36cdacf70

@ -29,6 +29,7 @@ import (
"strings" "strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time"
"tailscale.com/types/opt" "tailscale.com/types/opt"
"tailscale.com/version" "tailscale.com/version"
@ -41,6 +42,7 @@ var (
regStr = map[string]*string{} regStr = map[string]*string{}
regBool = map[string]*bool{} regBool = map[string]*bool{}
regOptBool = map[string]*opt.Bool{} regOptBool = map[string]*opt.Bool{}
regDuration = map[string]*time.Duration{}
) )
func noteEnv(k, v string) { func noteEnv(k, v string) {
@ -97,6 +99,9 @@ func Setenv(envVar, val string) {
if p := regOptBool[envVar]; p != nil { if p := regOptBool[envVar]; p != nil {
setOptBoolLocked(p, envVar, val) setOptBoolLocked(p, envVar, val)
} }
if p := regDuration[envVar]; p != nil {
setDurationLocked(p, envVar, val)
}
} }
// String returns the named environment variable, using os.Getenv. // String returns the named environment variable, using os.Getenv.
@ -159,6 +164,25 @@ func RegisterOptBool(envVar string) func() opt.Bool {
return func() opt.Bool { return *p } return func() opt.Bool { return *p }
} }
// RegisterDuration returns a func that gets the named environment variable as a
// duration, without a map lookup per call. It assumes that any mutations happen
// via envknob.Setenv.
func RegisterDuration(envVar string) func() time.Duration {
mu.Lock()
defer mu.Unlock()
p, ok := regDuration[envVar]
if !ok {
val := os.Getenv(envVar)
if val != "" {
noteEnvLocked(envVar, val)
}
p = new(time.Duration)
setDurationLocked(p, envVar, val)
regDuration[envVar] = p
}
return func() time.Duration { return *p }
}
func setBoolLocked(p *bool, envVar, val string) { func setBoolLocked(p *bool, envVar, val string) {
noteEnvLocked(envVar, val) noteEnvLocked(envVar, val)
if val == "" { if val == "" {
@ -185,6 +209,19 @@ func setOptBoolLocked(p *opt.Bool, envVar, val string) {
p.Set(b) p.Set(b)
} }
func setDurationLocked(p *time.Duration, envVar, val string) {
noteEnvLocked(envVar, val)
if val == "" {
*p = 0
return
}
var err error
*p, err = time.ParseDuration(val)
if err != nil {
log.Fatalf("invalid duration environment variable %s value %q", envVar, val)
}
}
// Bool returns the boolean value of the named environment variable. // Bool returns the boolean value of the named environment variable.
// If the variable is not set, it returns false. // If the variable is not set, it returns false.
// An invalid value exits the binary with a failure. // An invalid value exits the binary with a failure.

Loading…
Cancel
Save