Bootstrapping doesn't need bootstrap-expect

It's the Store object that needs it.
This commit is contained in:
Philip O'Toole
2022-10-28 16:40:40 -04:00
parent cd45070f8c
commit f7c6ce6696
3 changed files with 23 additions and 24 deletions

View File

@@ -35,7 +35,6 @@ type AddressProvider interface {
// Bootstrapper performs a bootstrap of this node. // Bootstrapper performs a bootstrap of this node.
type Bootstrapper struct { type Bootstrapper struct {
provider AddressProvider provider AddressProvider
expect int
tlsConfig *tls.Config tlsConfig *tls.Config
joiner *Joiner joiner *Joiner
@@ -48,10 +47,9 @@ type Bootstrapper struct {
} }
// NewBootstrapper returns an instance of a Bootstrapper. // NewBootstrapper returns an instance of a Bootstrapper.
func NewBootstrapper(p AddressProvider, expect int, tlsConfig *tls.Config) *Bootstrapper { func NewBootstrapper(p AddressProvider, tlsConfig *tls.Config) *Bootstrapper {
bs := &Bootstrapper{ bs := &Bootstrapper{
provider: p, provider: p,
expect: expect,
tlsConfig: &tls.Config{InsecureSkipVerify: true}, tlsConfig: &tls.Config{InsecureSkipVerify: true},
joiner: NewJoiner("", 1, 0, tlsConfig), joiner: NewJoiner("", 1, 0, tlsConfig),
logger: log.New(os.Stderr, "[cluster-bootstrap] ", log.LstdFlags), logger: log.New(os.Stderr, "[cluster-bootstrap] ", log.LstdFlags),
@@ -87,7 +85,6 @@ func (b *Bootstrapper) Boot(id, raftAddr string, done func() bool, timeout time.
tickerT := time.NewTimer(jitter(time.Millisecond)) tickerT := time.NewTimer(jitter(time.Millisecond))
defer tickerT.Stop() defer tickerT.Stop()
notifySuccess := false
for { for {
select { select {
case <-timeoutT.C: case <-timeoutT.C:
@@ -104,7 +101,8 @@ func (b *Bootstrapper) Boot(id, raftAddr string, done func() bool, timeout time.
if err != nil { if err != nil {
b.logger.Printf("provider lookup failed %s", err.Error()) b.logger.Printf("provider lookup failed %s", err.Error())
} }
if len(targets) < b.expect {
if len(targets) == 0 {
continue continue
} }
@@ -115,16 +113,18 @@ func (b *Bootstrapper) Boot(id, raftAddr string, done func() bool, timeout time.
return nil return nil
} }
// Join didn't work, so perhaps perform a notify if we haven't done // This is where we have to be careful. This node failed to join with any node
// one yet. // in the targets list. This could be because none of the nodes are contactable,
if !notifySuccess { // or none of the nodes are in a functioning cluster with a leader. That means that
if err := b.notify(targets, id, raftAddr); err != nil { // this node could be part of a set nodes that are bootstrapping to form a cluster
b.logger.Printf("failed to notify all targets: %s (%s, will retry)", targets, // de novo. For that to happen it needs to now let the otehr nodes know it is here.
err.Error()) // If this is a new cluster, some node will then reach the bootstrap-expect value,
} else { // form the cluster, beating all other nodes to it.
b.logger.Printf("succeeded notifying all targets: %s", targets) if err := b.notify(targets, id, raftAddr); err != nil {
notifySuccess = true b.logger.Printf("failed to notify all targets: %s (%s, will retry)", targets,
} err.Error())
} else {
b.logger.Printf("succeeded notifying all targets: %s", targets)
} }
} }
} }

View File

@@ -24,7 +24,7 @@ func Test_AddressProviderString(t *testing.T) {
} }
func Test_NewBootstrapper(t *testing.T) { func Test_NewBootstrapper(t *testing.T) {
bs := NewBootstrapper(nil, 1, nil) bs := NewBootstrapper(nil, nil)
if bs == nil { if bs == nil {
t.Fatalf("failed to create a simple Bootstrapper") t.Fatalf("failed to create a simple Bootstrapper")
} }
@@ -39,7 +39,7 @@ func Test_BootstrapperBootDoneImmediately(t *testing.T) {
return true return true
} }
p := NewAddressProviderString([]string{ts.URL}) p := NewAddressProviderString([]string{ts.URL})
bs := NewBootstrapper(p, 1, nil) bs := NewBootstrapper(p, nil)
if err := bs.Boot("node1", "192.168.1.1:1234", done, 10*time.Second); err != nil { if err := bs.Boot("node1", "192.168.1.1:1234", done, 10*time.Second); err != nil {
t.Fatalf("failed to boot: %s", err) t.Fatalf("failed to boot: %s", err)
} }
@@ -54,7 +54,7 @@ func Test_BootstrapperBootTimeout(t *testing.T) {
return false return false
} }
p := NewAddressProviderString([]string{ts.URL}) p := NewAddressProviderString([]string{ts.URL})
bs := NewBootstrapper(p, 1, nil) bs := NewBootstrapper(p, nil)
bs.Interval = time.Second bs.Interval = time.Second
err := bs.Boot("node1", "192.168.1.1:1234", done, 5*time.Second) err := bs.Boot("node1", "192.168.1.1:1234", done, 5*time.Second)
if err == nil { if err == nil {
@@ -97,7 +97,7 @@ func Test_BootstrapperBootSingleNotify(t *testing.T) {
} }
p := NewAddressProviderString([]string{ts.URL}) p := NewAddressProviderString([]string{ts.URL})
bs := NewBootstrapper(p, 1, nil) bs := NewBootstrapper(p, nil)
bs.Interval = time.Second bs.Interval = time.Second
err := bs.Boot("node1", "192.168.1.1:1234", done, 60*time.Second) err := bs.Boot("node1", "192.168.1.1:1234", done, 60*time.Second)
@@ -145,7 +145,7 @@ func Test_BootstrapperBootSingleNotifyAuth(t *testing.T) {
} }
p := NewAddressProviderString([]string{ts.URL}) p := NewAddressProviderString([]string{ts.URL})
bs := NewBootstrapper(p, 1, nil) bs := NewBootstrapper(p, nil)
bs.SetBasicAuth("username1", "password1") bs.SetBasicAuth("username1", "password1")
bs.Interval = time.Second bs.Interval = time.Second
@@ -192,7 +192,7 @@ func Test_BootstrapperBootMultiNotify(t *testing.T) {
} }
p := NewAddressProviderString([]string{ts1.URL, ts2.URL}) p := NewAddressProviderString([]string{ts1.URL, ts2.URL})
bs := NewBootstrapper(p, 2, nil) bs := NewBootstrapper(p, nil)
bs.Interval = time.Second bs.Interval = time.Second
err := bs.Boot("node1", "192.168.1.1:1234", done, 60*time.Second) err := bs.Boot("node1", "192.168.1.1:1234", done, 60*time.Second)

View File

@@ -373,8 +373,7 @@ func createCluster(cfg *Config, tlsConfig *tls.Config, hasPeers bool, str *store
return nil return nil
} }
bs := cluster.NewBootstrapper(cluster.NewAddressProviderString(joins), bs := cluster.NewBootstrapper(cluster.NewAddressProviderString(joins), tlsConfig)
cfg.BootstrapExpect, tlsConfig)
if cfg.JoinAs != "" { if cfg.JoinAs != "" {
pw, ok := credStr.Password(cfg.JoinAs) pw, ok := credStr.Password(cfg.JoinAs)
if !ok { if !ok {
@@ -424,7 +423,7 @@ func createCluster(cfg *Config, tlsConfig *tls.Config, hasPeers bool, str *store
provider = dnssrv.New(dnssrvCfg) provider = dnssrv.New(dnssrvCfg)
} }
bs := cluster.NewBootstrapper(provider, cfg.BootstrapExpect, tlsConfig) bs := cluster.NewBootstrapper(provider, tlsConfig)
if cfg.JoinAs != "" { if cfg.JoinAs != "" {
pw, ok := credStr.Password(cfg.JoinAs) pw, ok := credStr.Password(cfg.JoinAs)
if !ok { if !ok {