Merge pull request #1632 from jonboulle/cs_flag

etcdmain: use StringsFlag for initialclusterstate
release-2.0
Jonathan Boulle 2014-11-06 12:36:22 -08:00
commit b65dd84e1a
7 changed files with 27 additions and 119 deletions

View File

@ -47,6 +47,9 @@ const (
fallbackFlagExit = "exit"
fallbackFlagProxy = "proxy"
clusterStateFlagNew = "new"
clusterStateFlagExisting = "existing"
)
var (
@ -59,9 +62,11 @@ var (
initialCluster = fs.String("initial-cluster", "default=http://localhost:2380,default=http://localhost:7001", "Initial cluster configuration for bootstrapping")
initialClusterToken = fs.String("initial-cluster-token", "etcd-cluster", "Initial cluster token for the etcd cluster during bootstrap")
clusterState = new(etcdserver.ClusterState)
corsInfo = &cors.CORSInfo{}
corsInfo = &cors.CORSInfo{}
clientTLSInfo = transport.TLSInfo{}
peerTLSInfo = transport.TLSInfo{}
proxyFlag = flags.NewStringsFlag(
proxyFlagOff,
proxyFlagReadonly,
@ -71,9 +76,10 @@ var (
fallbackFlagExit,
fallbackFlagProxy,
)
clientTLSInfo = transport.TLSInfo{}
peerTLSInfo = transport.TLSInfo{}
clusterStateFlag = flags.NewStringsFlag(
clusterStateFlagNew,
clusterStateFlagExisting,
)
ignored = []string{
"cluster-active-size",
@ -93,10 +99,10 @@ var (
)
func init() {
fs.Var(clusterState, "initial-cluster-state", "Initial cluster configuration for bootstrapping")
if err := clusterState.Set(etcdserver.ClusterStateValueNew); err != nil {
fs.Var(clusterStateFlag, "initial-cluster-state", "Initial cluster configuration for bootstrapping")
if err := clusterStateFlag.Set(clusterStateFlagNew); err != nil {
// Should never happen.
log.Panicf("unexpected error setting up clusterState: %v", err)
log.Panicf("unexpected error setting up clusterStateFlag: %v", err)
}
fs.Var(flags.NewURLsValue("http://localhost:2380,http://localhost:7001"), "initial-advertise-peer-urls", "List of this member's peer URLs to advertise to the rest of the cluster")
@ -259,7 +265,7 @@ func startEtcd() error {
SnapCount: *snapCount,
Cluster: cls,
DiscoveryURL: *durl,
ClusterState: *clusterState,
NewCluster: clusterStateFlag.String() == clusterStateFlagNew,
Transport: pt,
}
var s *etcdserver.EtcdServer

View File

@ -1,53 +0,0 @@
/*
Copyright 2014 CoreOS, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package etcdserver
import (
"errors"
)
const (
ClusterStateValueNew = "new"
ClusterStateValueExisting = "existing"
)
var (
ClusterStateValues = []string{
ClusterStateValueNew,
ClusterStateValueExisting,
}
)
// ClusterState implements the flag.Value interface.
type ClusterState string
// Set verifies the argument to be a valid member of ClusterStateFlagValues
// before setting the underlying flag value.
func (cs *ClusterState) Set(s string) error {
for _, v := range ClusterStateValues {
if s == v {
*cs = ClusterState(s)
return nil
}
}
return errors.New("invalid value")
}
func (cs *ClusterState) String() string {
return string(*cs)
}

View File

@ -1,43 +0,0 @@
/*
Copyright 2014 CoreOS, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package etcdserver
import (
"testing"
)
func TestClusterStateSet(t *testing.T) {
tests := []struct {
val string
pass bool
}{
// known values
{"new", true},
// unrecognized values
{"foo", false},
{"", false},
}
for i, tt := range tests {
pf := new(ClusterState)
err := pf.Set(tt.val)
if tt.pass != (err == nil) {
t.Errorf("#%d: want pass=%t, but got err=%v", i, tt.pass, err)
}
}
}

View File

@ -33,7 +33,7 @@ type ServerConfig struct {
DataDir string
SnapCount uint64
Cluster *Cluster
ClusterState ClusterState
NewCluster bool
Transport *http.Transport
}
@ -49,7 +49,7 @@ func (c *ServerConfig) VerifyBootstrapConfig() error {
return fmt.Errorf("cannot use %x as member id", raft.None)
}
if c.DiscoveryURL == "" && c.ClusterState != ClusterStateValueNew {
if c.DiscoveryURL == "" && !c.NewCluster {
return fmt.Errorf("initial cluster state unset and no wal or discovery URL found")
}

View File

@ -21,44 +21,42 @@ import "testing"
func TestBootstrapConfigVerify(t *testing.T) {
tests := []struct {
clusterSetting string
clst ClusterState
newclst bool
disc string
shouldError bool
}{
{
// Node must exist in cluster
"",
ClusterStateValueNew,
true,
"",
true,
},
{
// Cannot have duplicate URLs in cluster config
"node1=http://localhost:7001,node2=http://localhost:7001,node2=http://localhost:7002",
ClusterStateValueNew,
true,
"",
true,
},
{
// Node defined, ClusterState OK
"node1=http://localhost:7001,node2=http://localhost:7002",
ClusterStateValueNew,
true,
"",
false,
},
{
// Node defined, discovery OK
"node1=http://localhost:7001",
// TODO(jonboulle): replace with ClusterStateExisting once it exists
"",
false,
"http://discovery",
false,
},
{
// Cannot have ClusterState!=new && !discovery
"node1=http://localhost:7001",
// TODO(jonboulle): replace with ClusterStateExisting once it exists
ClusterState("foo"),
false,
"",
true,
},
@ -74,7 +72,7 @@ func TestBootstrapConfigVerify(t *testing.T) {
Name: "node1",
DiscoveryURL: tt.disc,
Cluster: cluster,
ClusterState: tt.clst,
NewCluster: tt.newclst,
}
err = cfg.VerifyBootstrapConfig()
if (err == nil) && tt.shouldError {

View File

@ -187,7 +187,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
var id types.ID
haveWAL := wal.Exist(cfg.WALDir())
switch {
case !haveWAL && cfg.ClusterState == ClusterStateValueExisting:
case !haveWAL && !cfg.NewCluster:
cl, err := GetClusterFromPeers(cfg.Cluster.PeerURLs())
if err != nil {
return nil, fmt.Errorf("cannot fetch cluster info from peer urls: %v", err)
@ -198,7 +198,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
cfg.Cluster.SetID(cl.id)
cfg.Cluster.SetStore(st)
id, n, w = startNode(cfg, nil)
case !haveWAL && cfg.ClusterState == ClusterStateValueNew:
case !haveWAL && cfg.NewCluster:
if err := cfg.VerifyBootstrapConfig(); err != nil {
return nil, err
}

View File

@ -129,7 +129,7 @@ func (c *cluster) Launch(t *testing.T) {
if err != nil {
t.Fatal(err)
}
m.ClusterState = etcdserver.ClusterStateValueNew
m.NewCluster = true
m.Transport, err = transport.NewTransport(transport.TLSInfo{})
if err != nil {
t.Fatal(err)