Merge pull request #1328 from unihorn/169

skip initial-cluster check when reboot
This commit is contained in:
Yicheng Qin 2014-10-20 13:06:24 -07:00
commit dcaa7f0a37
4 changed files with 36 additions and 31 deletions

View File

@ -22,6 +22,7 @@ import (
"path" "path"
"github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/pkg/types"
"github.com/coreos/etcd/raft"
) )
// ServerConfig holds the configuration of etcd as taken from the command line or discovery. // ServerConfig holds the configuration of etcd as taken from the command line or discovery.
@ -36,14 +37,21 @@ type ServerConfig struct {
Transport *http.Transport Transport *http.Transport
} }
// Verify sanity-checks the config struct and returns an error for things that // VerifyBootstrapConfig sanity-checks the initial config and returns an error
// should never happen. // for things that should never happen.
func (c *ServerConfig) Verify() error { func (c *ServerConfig) VerifyBootstrapConfig() error {
if c.DiscoveryURL == "" && c.ClusterState != ClusterStateValueNew {
return fmt.Errorf("initial cluster state unset and no wal or discovery URL found")
}
// Make sure the cluster at least contains the local server. // Make sure the cluster at least contains the local server.
m := c.Cluster.FindName(c.Name) m := c.Cluster.FindName(c.Name)
if m == nil { if m == nil {
return fmt.Errorf("could not find name %v in cluster", c.Name) return fmt.Errorf("could not find name %v in cluster", c.Name)
} }
if m.ID == raft.None {
return fmt.Errorf("could not use %x as member id", raft.None)
}
// No identical IPs in the cluster peer list // No identical IPs in the cluster peer list
urlMap := make(map[string]bool) urlMap := make(map[string]bool)
@ -67,8 +75,3 @@ func (c *ServerConfig) ID() uint64 { return c.Cluster.FindName(c.Name).ID }
func (c *ServerConfig) ShouldDiscover() bool { func (c *ServerConfig) ShouldDiscover() bool {
return c.DiscoveryURL != "" return c.DiscoveryURL != ""
} }
// IsBootstrap returns true if a bootstrap method is provided.
func (c *ServerConfig) IsBootstrap() bool {
return c.DiscoveryURL != "" || c.ClusterState == ClusterStateValueNew
}

View File

@ -20,14 +20,27 @@ import (
"testing" "testing"
) )
func TestConfigVerify(t *testing.T) { func TestBootstrapConfigVerify(t *testing.T) {
tests := []struct { tests := []struct {
clusterSetting string clusterSetting string
clst ClusterState
disc string
shouldError bool shouldError bool
}{ }{
{"", true}, {"", ClusterStateValueNew, "", true},
{"node1=http://localhost:7001,node2=http://localhost:7001", true}, {"", "", "http://discovery", true},
{"node1=http://localhost:7001,node2=http://localhost:7002", false}, {
"node1=http://localhost:7001,node2=http://localhost:7001",
ClusterStateValueNew, "", true,
},
{
"node1=http://localhost:7001,node2=http://localhost:7002",
ClusterStateValueNew, "", false,
},
{
"node1=http://localhost:7001",
"", "http://discovery", false,
},
} }
for i, tt := range tests { for i, tt := range tests {
@ -35,9 +48,11 @@ func TestConfigVerify(t *testing.T) {
cluster.Set(tt.clusterSetting) cluster.Set(tt.clusterSetting)
cfg := ServerConfig{ cfg := ServerConfig{
Name: "node1", Name: "node1",
DiscoveryURL: tt.disc,
Cluster: cluster, Cluster: cluster,
ClusterState: tt.clst,
} }
err := cfg.Verify() err := cfg.VerifyBootstrapConfig()
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)
} }

View File

@ -159,9 +159,6 @@ type EtcdServer struct {
// NewServer creates a new EtcdServer from the supplied configuration. The // NewServer creates a new EtcdServer from the supplied configuration. The
// configuration is considered static for the lifetime of the EtcdServer. // configuration is considered static for the lifetime of the EtcdServer.
func NewServer(cfg *ServerConfig) *EtcdServer { func NewServer(cfg *ServerConfig) *EtcdServer {
if err := cfg.Verify(); err != nil {
log.Fatalln(err)
}
if err := os.MkdirAll(cfg.SnapDir(), privateDirMode); err != nil { if err := os.MkdirAll(cfg.SnapDir(), privateDirMode); err != nil {
log.Fatalf("etcdserver: cannot create snapshot directory: %v", err) log.Fatalf("etcdserver: cannot create snapshot directory: %v", err)
} }
@ -170,8 +167,8 @@ func NewServer(cfg *ServerConfig) *EtcdServer {
var w *wal.WAL var w *wal.WAL
var n raft.Node var n raft.Node
if !wal.Exist(cfg.WALDir()) { if !wal.Exist(cfg.WALDir()) {
if !cfg.IsBootstrap() { if err := cfg.VerifyBootstrapConfig(); err != nil {
log.Fatalf("etcdserver: initial cluster state unset and no wal or discovery URL found") log.Fatalf("etcdserver: %v", err)
} }
if cfg.ShouldDiscover() { if cfg.ShouldDiscover() {
d, err := discovery.New(cfg.DiscoveryURL, cfg.ID(), cfg.Cluster.String()) d, err := discovery.New(cfg.DiscoveryURL, cfg.ID(), cfg.Cluster.String())

12
main.go
View File

@ -30,7 +30,6 @@ import (
flagtypes "github.com/coreos/etcd/pkg/flags" flagtypes "github.com/coreos/etcd/pkg/flags"
"github.com/coreos/etcd/pkg/transport" "github.com/coreos/etcd/pkg/transport"
"github.com/coreos/etcd/proxy" "github.com/coreos/etcd/proxy"
"github.com/coreos/etcd/raft"
) )
const ( const (
@ -140,17 +139,8 @@ func main() {
// startEtcd launches the etcd server and HTTP handlers for client/server communication. // startEtcd launches the etcd server and HTTP handlers for client/server communication.
func startEtcd() { func startEtcd() {
self := cluster.FindName(*name)
if self == nil {
log.Fatalf("etcd: no member with name=%q exists", *name)
}
if self.ID == raft.None {
log.Fatalf("etcd: cannot use None(%d) as member id", raft.None)
}
if *dir == "" { if *dir == "" {
*dir = fmt.Sprintf("%v_etcd_data", self.Name) *dir = fmt.Sprintf("%v_etcd_data", *name)
log.Printf("etcd: no data-dir provided, using default data-dir ./%s", *dir) log.Printf("etcd: no data-dir provided, using default data-dir ./%s", *dir)
} }
if err := os.MkdirAll(*dir, privateDirMode); err != nil { if err := os.MkdirAll(*dir, privateDirMode); err != nil {