diff --git a/cmd/cli/cli.go b/cmd/cli/cli.go index 84fa2e0..0c4503e 100644 --- a/cmd/cli/cli.go +++ b/cmd/cli/cli.go @@ -22,6 +22,7 @@ import ( "sort" "strconv" "strings" + "sync/atomic" "time" "github.com/Masterminds/semver" @@ -1552,11 +1553,15 @@ func processNoConfigFlags(noConfigStart bool) { const defaultDeactivationPin = -1 // cdDeactivationPin is used in cd mode to decide whether stop and uninstall commands can be run. -var cdDeactivationPin int64 = defaultDeactivationPin +var cdDeactivationPin atomic.Int64 + +func init() { + cdDeactivationPin.Store(defaultDeactivationPin) +} // deactivationPinNotSet reports whether cdDeactivationPin was not set by processCDFlags. func deactivationPinNotSet() bool { - return cdDeactivationPin == defaultDeactivationPin + return cdDeactivationPin.Load() == defaultDeactivationPin } func processCDFlags(cfg *ctrld.Config) error { @@ -1585,7 +1590,7 @@ func processCDFlags(cfg *ctrld.Config) error { if resolverConfig.DeactivationPin != nil { logger.Debug().Msg("saving deactivation pin") - cdDeactivationPin = *resolverConfig.DeactivationPin + cdDeactivationPin.Store(*resolverConfig.DeactivationPin) } logger.Info().Msg("generating ctrld config from Control-D configuration") diff --git a/cmd/cli/control_server.go b/cmd/cli/control_server.go index f69c301..c31fd13 100644 --- a/cmd/cli/control_server.go +++ b/cmd/cli/control_server.go @@ -11,10 +11,10 @@ import ( "time" "github.com/kardianos/service" - dto "github.com/prometheus/client_model/go" "github.com/Control-D-Inc/ctrld" + "github.com/Control-D-Inc/ctrld/internal/controld" ) const ( @@ -152,8 +152,25 @@ func (p *prog) registerControlServerHandler() { w.WriteHeader(http.StatusOK) })) p.cs.register(deactivationPath, http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) { - // Non-cd mode or pin code not set, always allowing deactivation. - if cdUID == "" || deactivationPinNotSet() { + // Non-cd mode always allowing deactivation. + if cdUID == "" { + w.WriteHeader(http.StatusOK) + return + } + + // Re-fetch pin code from API. + if rc, err := controld.FetchResolverConfig(cdUID, rootCmd.Version, cdDev); rc != nil { + if rc.DeactivationPin != nil { + cdDeactivationPin.Store(*rc.DeactivationPin) + } else { + cdDeactivationPin.Store(defaultDeactivationPin) + } + } else { + mainLog.Load().Warn().Err(err).Msg("could not re-fetch deactivation pin code") + } + + // If pin code not set, allowing deactivation. + if deactivationPinNotSet() { w.WriteHeader(http.StatusOK) return } @@ -167,7 +184,7 @@ func (p *prog) registerControlServerHandler() { code := http.StatusForbidden switch req.Pin { - case cdDeactivationPin: + case cdDeactivationPin.Load(): code = http.StatusOK case defaultDeactivationPin: // If the pin code was set, but users do not provide --pin, return proper code to client. diff --git a/cmd/cli/prog.go b/cmd/cli/prog.go index a8f3fc0..f6d83ab 100644 --- a/cmd/cli/prog.go +++ b/cmd/cli/prog.go @@ -275,15 +275,16 @@ func (p *prog) apiConfigReload() { if resolverConfig.DeactivationPin != nil { newDeactivationPin := *resolverConfig.DeactivationPin + curDeactivationPin := cdDeactivationPin.Load() switch { - case deactivationPin != defaultDeactivationPin: + case curDeactivationPin != defaultDeactivationPin: logger.Debug().Msg("saving deactivation pin") - case deactivationPin != newDeactivationPin: + case curDeactivationPin != newDeactivationPin: logger.Debug().Msg("update deactivation pin") } - cdDeactivationPin = *resolverConfig.DeactivationPin + cdDeactivationPin.Store(newDeactivationPin) } else { - deactivationPin = defaultDeactivationPin + cdDeactivationPin.Store(defaultDeactivationPin) } if resolverConfig.Ctrld.CustomConfig == "" { diff --git a/cmd/cli/self_kill_unix.go b/cmd/cli/self_kill_unix.go index 9e494b4..9a68e60 100644 --- a/cmd/cli/self_kill_unix.go +++ b/cmd/cli/self_kill_unix.go @@ -23,7 +23,7 @@ func selfUninstall(p *prog, logger zerolog.Logger) { } args := []string{"uninstall"} if !deactivationPinNotSet() { - args = append(args, fmt.Sprintf("--pin=%d", cdDeactivationPin)) + args = append(args, fmt.Sprintf("--pin=%d", cdDeactivationPin.Load())) } cmd := exec.Command(bin, args...) cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}