etcdserver: retry for 30s on advertise url check

This commit is contained in:
Anthony Romano 2016-12-14 14:21:41 -08:00
parent 13b05aeff8
commit 29c30b2387
2 changed files with 27 additions and 22 deletions

View File

@ -21,6 +21,8 @@ import (
"strings" "strings"
"time" "time"
"golang.org/x/net/context"
"github.com/coreos/etcd/pkg/netutil" "github.com/coreos/etcd/pkg/netutil"
"github.com/coreos/etcd/pkg/transport" "github.com/coreos/etcd/pkg/transport"
"github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/pkg/types"
@ -62,7 +64,10 @@ type ServerConfig struct {
// VerifyBootstrap sanity-checks the initial config for bootstrap case // VerifyBootstrap sanity-checks the initial config for bootstrap case
// and returns an error for things that should never happen. // and returns an error for things that should never happen.
func (c *ServerConfig) VerifyBootstrap() error { func (c *ServerConfig) VerifyBootstrap() error {
if err := c.verifyLocalMember(true); err != nil { if err := c.hasLocalMember(); err != nil {
return err
}
if err := c.advertiseMatchesCluster(); err != nil {
return err return err
} }
if checkDuplicateURL(c.InitialPeerURLsMap) { if checkDuplicateURL(c.InitialPeerURLsMap) {
@ -77,10 +82,9 @@ func (c *ServerConfig) VerifyBootstrap() error {
// VerifyJoinExisting sanity-checks the initial config for join existing cluster // VerifyJoinExisting sanity-checks the initial config for join existing cluster
// case and returns an error for things that should never happen. // case and returns an error for things that should never happen.
func (c *ServerConfig) VerifyJoinExisting() error { func (c *ServerConfig) VerifyJoinExisting() error {
// no need for strict checking since the member have announced its // The member has announced its peer urls to the cluster before starting; no need to
// peer urls to the cluster before starting and do not have to set // set the configuration again.
// it in the configuration again. if err := c.hasLocalMember(); err != nil {
if err := c.verifyLocalMember(false); err != nil {
return err return err
} }
if checkDuplicateURL(c.InitialPeerURLsMap) { if checkDuplicateURL(c.InitialPeerURLsMap) {
@ -92,25 +96,24 @@ func (c *ServerConfig) VerifyJoinExisting() error {
return nil return nil
} }
// verifyLocalMember verifies the configured member is in configured // hasLocalMember checks that the cluster at least contains the local server.
// cluster. If strict is set, it also verifies the configured member func (c *ServerConfig) hasLocalMember() error {
// has the same peer urls as configured advertised peer urls. if urls := c.InitialPeerURLsMap[c.Name]; urls == nil {
func (c *ServerConfig) verifyLocalMember(strict bool) error {
urls := c.InitialPeerURLsMap[c.Name]
// Make sure the cluster at least contains the local server.
if urls == nil {
return fmt.Errorf("couldn't find local name %q in the initial cluster configuration", c.Name) return fmt.Errorf("couldn't find local name %q in the initial cluster configuration", c.Name)
} }
return nil
}
if strict { // advertiseMatchesCluster confirms peer URLs match those in the cluster peer list.
// Advertised peer URLs must match those in the cluster peer list func (c *ServerConfig) advertiseMatchesCluster() error {
apurls := c.PeerURLs.StringSlice() urls, apurls := c.InitialPeerURLsMap[c.Name], c.PeerURLs.StringSlice()
sort.Strings(apurls) urls.Sort()
urls.Sort() sort.Strings(apurls)
if !netutil.URLStringsEqual(apurls, urls.StringSlice()) { ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second)
umap := map[string]types.URLs{c.Name: c.PeerURLs} defer cancel()
return fmt.Errorf("--initial-cluster must include %s given --initial-advertise-peer-urls=%s", types.URLsMap(umap).String(), strings.Join(apurls, ",")) if !netutil.URLStringsEqual(ctx, apurls, urls.StringSlice()) {
} umap := map[string]types.URLs{c.Name: c.PeerURLs}
return fmt.Errorf("--initial-cluster must include %s given --initial-advertise-peer-urls=%s", types.URLsMap(umap).String(), strings.Join(apurls, ","))
} }
return nil return nil
} }

View File

@ -137,7 +137,9 @@ func TestConfigVerifyLocalMember(t *testing.T) {
if tt.apurls != nil { if tt.apurls != nil {
cfg.PeerURLs = mustNewURLs(t, tt.apurls) cfg.PeerURLs = mustNewURLs(t, tt.apurls)
} }
err = cfg.verifyLocalMember(tt.strict) if err = cfg.hasLocalMember(); err == nil && tt.strict {
err = cfg.advertiseMatchesCluster()
}
if (err == nil) && tt.shouldError { if (err == nil) && tt.shouldError {
t.Errorf("#%d: Got no error where one was expected", i) t.Errorf("#%d: Got no error where one was expected", i)
} }