diff --git a/etcd-manager/pkg/etcd/etcdserver.go b/etcd-manager/pkg/etcd/etcdserver.go index 40501ee96..57ba0a577 100644 --- a/etcd-manager/pkg/etcd/etcdserver.go +++ b/etcd-manager/pkg/etcd/etcdserver.go @@ -88,7 +88,7 @@ func NewEtcdServer(baseDir string, clusterName string, listenAddress string, lis } // Make sure we have read state from disk before serving - if err := s.initState(); err != nil { + if err := s.initStateOnStartup(); err != nil { return nil, err } @@ -118,7 +118,11 @@ func (s *EtcdServer) Run(ctx context.Context) { }) } -func readState(baseDir string) (*protoetcd.EtcdState, error) { +// readState loads the saved state from the directory. +// If no state is found, returns (nil, nil). +// If replaceEtcdVersion is true, we will "bump" old etcd patch versions to a supported version. +// replaceEtcdVersion means we don't need to have every etcd version available. +func readState(baseDir string, replaceEtcdVersion bool) (*protoetcd.EtcdState, error) { p := filepath.Join(baseDir, "state") b, err := os.ReadFile(p) if err != nil { @@ -134,6 +138,16 @@ func readState(baseDir string) (*protoetcd.EtcdState, error) { return nil, fmt.Errorf("error parsing state file: %v", err) } + // Maybe use the recommended etcd version + if replaceEtcdVersion && state.EtcdVersion != "" { + etcdVersion := state.EtcdVersion + startWith := etcdversions.EtcdVersionForAdoption(etcdVersion) + if startWith != "" && startWith != etcdVersion { + klog.Warningf("starting server from etcd %q, will start with %q", etcdVersion, startWith) + state.EtcdVersion = startWith + } + } + return state, nil } @@ -151,12 +165,16 @@ func writeState(baseDir string, state *protoetcd.EtcdState) error { return nil } -func (s *EtcdServer) initState() error { +// initStateOnStartup populates the state from local disk. +// It should only be called on initial startup; after that +// we are under control of the leader. +func (s *EtcdServer) initStateOnStartup() error { s.mutex.Lock() defer s.mutex.Unlock() if s.state == nil { - state, err := readState(s.baseDir) + replaceEtcdVersion := true + state, err := readState(s.baseDir, replaceEtcdVersion) if err != nil { return err } @@ -170,7 +188,7 @@ func (s *EtcdServer) initState() error { } func (s *EtcdServer) runOnce() error { - if err := s.initState(); err != nil { + if err := s.initStateOnStartup(); err != nil { return err } @@ -330,6 +348,7 @@ func (s *EtcdServer) JoinCluster(ctx context.Context, request *protoetcd.JoinClu Nodes: request.Nodes, } s.state.Quarantined = true + s.state.EtcdVersion = request.EtcdVersion if err := writeState(s.baseDir, s.state); err != nil { @@ -605,18 +624,9 @@ func (s *EtcdServer) startEtcdProcess(state *protoetcd.EtcdState) error { return err } - etcdVersion := state.EtcdVersion - // Use the recommended etcd version - { - startWith := etcdversions.EtcdVersionForAdoption(etcdVersion) - if startWith != "" && startWith != etcdVersion { - klog.Warningf("starting server from etcd %q, will start with %q", etcdVersion, startWith) - etcdVersion = startWith - } - } - p.EtcdVersion = etcdVersion + p.EtcdVersion = state.EtcdVersion - binDir, err := BindirForEtcdVersion(etcdVersion, "etcd") + binDir, err := BindirForEtcdVersion(p.EtcdVersion, "etcd") if err != nil { return err }