Browse Source

main: use initial-cluster and initial-cluster-state flags

In preperation for adding the ability to join a machine to an existing
cluster force the user to specify whether they expect this to me a new
cluster or an active one.

The error for not specifying the initial-cluster-state is:
```
etcd: initial cluster state unset and no wal found
```
Brandon Philips 11 years ago
parent
commit
e2d8037ded
6 changed files with 106 additions and 29 deletions
  1. 31 23
      Documentation/0.5/clustering.md
  2. 3 3
      Procfile
  3. 35 0
      etcdserver/cluster_state.go
  4. 27 0
      etcdserver/cluster_state_test.go
  5. 3 0
      etcdserver/server.go
  6. 7 3
      main.go

+ 31 - 23
Documentation/0.5/clustering.md

@@ -15,12 +15,12 @@ before starting we can use an offline bootstrap configuration. Each machine
 will get either the following command line or environment variables:
 will get either the following command line or environment variables:
 
 
 ```
 ```
-ETCD_INITIAL_CLUSTER=”infra0=http://10.0.1.10:2379,infra1=http://infra1=10.0.1.11:2379,infra2=http://10.0.1.12:2379”
+ETCD_INITIAL_CLUSTER=”infra0=http://10.0.1.10:2379,infra1=http://10.0.1.11:2379,infra2=http://10.0.1.12:2379”
 ETCD_INITIAL_CLUSTER_STATE=new
 ETCD_INITIAL_CLUSTER_STATE=new
 ```
 ```
 
 
 ```
 ```
--initial-cluster infra0=http://10.0.1.10:2379,http://infra1=10.0.1.11:2379,infra2=http://10.0.1.12:2379 \
+-initial-cluster infra0=http://10.0.1.10:2379,http://10.0.1.11:2379,infra2=http://10.0.1.12:2379 \
 	-initial-cluster-state new
 	-initial-cluster-state new
 ```
 ```
 
 
@@ -38,30 +38,27 @@ $ etcd -name infra2 -advertise-peer-urls https://10.0.1.12:2379 \
 	-initial-cluster-state new
 	-initial-cluster-state new
 ```
 ```
 
 
-These initial cluster command line parameters will be ignored on subsequent
-runs of etcd. You are free to remove the environment variables or command line
-flags after the initial bootstrap process. If you need to make changes to the
-configuration later see our guide on runtime configuration(link needed).
+The command line parameters starting with `-initial-cluster` will be ignored on
+subsequent runs of etcd. You are free to remove the environment variables or
+command line flags after the initial bootstrap process. If you need to make
+changes to the configuration later see our guide on runtime configuration.
 
 
 ### Error Cases
 ### Error Cases
 
 
 In the following case we have not included our new host in the list of
 In the following case we have not included our new host in the list of
-enumerated nodes.  If this is a new cluster, the node must be added to the list
-of initial cluster members.  If this is an existing cluster to which a new node
-is being added we must make the corresponding change to the existing cluster’s
-configuration and then bring the new node online.
-
+enumerated nodes. If this is a new cluster, the node must be added to the list
+of initial cluster members.
 ```
 ```
-$ etcd -name infra5 -advertise-peer-urls http://10.0.1.10:2379 \
-	-initial-cluster infra0=http://10.0.1.10:2379,infra1=http://10.0.1.11:2379,infra2=http://10.0.1.12:2379 \
-	-initial-cluster-state=new
-etcd: infra5 not listed in the initial cluster config
+$ etcd -name infra1 -advertise-peer-urls http://10.0.1.11:2379 \
+	-initial-cluster infra0=http://10.0.1.10:2379
+	-initial-cluster-state new
+etcd: infra1 not listed in the initial cluster config
 exit 1
 exit 1
 ```
 ```
 
 
 In this case we are attempting to map a node (infra0) on a different address
 In this case we are attempting to map a node (infra0) on a different address
 (127.0.0.1:2379) than its enumerated address in the cluster list
 (127.0.0.1:2379) than its enumerated address in the cluster list
-(10.0.1.10:2379).  If this node is to listen on multiple addresses, all
+(10.0.1.10:2379). If this node is to listen on multiple addresses, all
 addresses must be reflected in the “initial-cluster” configuration directive.
 addresses must be reflected in the “initial-cluster” configuration directive.
 
 
 ```
 ```
@@ -87,7 +84,10 @@ $ curl https://myetcd.local/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817
 ```
 ```
 
 
 The URL you will use in this case will be
 The URL you will use in this case will be
-`https://myetcd.local/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83`.
+`https://myetcd.local/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83`
+and the machines will use the
+`https://myetcd.local/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83`
+directory for registration as they start.
 
 
 If you do not have access to an existing cluster you can use the hosted
 If you do not have access to an existing cluster you can use the hosted
 discovery.etcd.io service.  You can create a private discovery URL using the
 discovery.etcd.io service.  You can create a private discovery URL using the
@@ -120,24 +120,32 @@ $ etcd -name infra2 -advertise-peer-urls http://10.0.1.12:2379 -discovery https:
 This will cause each machine to register itself with the etcd service and begin
 This will cause each machine to register itself with the etcd service and begin
 the cluster once all machines have been registered.
 the cluster once all machines have been registered.
 
 
-### Error Cases
+### Error and Warning Cases
+
+#### Discovery Server Errors
 
 
 ```
 ```
 $ etcd -name infra0 -advertise-peer-urls http://10.0.1.10:2379 -discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de
 $ etcd -name infra0 -advertise-peer-urls http://10.0.1.10:2379 -discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de
-etcd: error: the cluster using discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de has already started with all 5 members
+etcd: error: the cluster doesn’t have a size configuration value in https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de/_config
 exit 1
 exit 1
 ```
 ```
 
 
+#### User Errors
+
 ```
 ```
 $ etcd -name infra0 -advertise-peer-urls http://10.0.1.10:2379 -discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de
 $ etcd -name infra0 -advertise-peer-urls http://10.0.1.10:2379 -discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de
-etcd: error: the cluster doesn’t have a size configuration value in https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de/_config
+etcd: error: the cluster using discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de has already started with all 5 members
 exit 1
 exit 1
 ```
 ```
 
 
+#### Warnings
+
+This is a harmless warning notifying you that the discovery URL will be
+ignored on this machine.
+
 ```
 ```
 $ etcd -name infra0 -advertise-peer-urls http://10.0.1.10:2379 -discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de
 $ etcd -name infra0 -advertise-peer-urls http://10.0.1.10:2379 -discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de
 etcd: warn: ignoring discovery URL: etcd has already been initialized and has a valid log in /var/lib/etcd
 etcd: warn: ignoring discovery URL: etcd has already been initialized and has a valid log in /var/lib/etcd
-exit 1
 ```
 ```
 
 
 # 0.4 to 0.5+ Migration Guide
 # 0.4 to 0.5+ Migration Guide
@@ -153,6 +161,6 @@ To make understanding this feature easier, we changed the naming of some flags,
 |-----------------------|-----------------------|---------------------------------------------------------------------------------------|
 |-----------------------|-----------------------|---------------------------------------------------------------------------------------|
 |-peer-addr		|-advertise-peer-urls 	|If specified, peer-addr will be used as the only peer URL. Error if both flags specified.|
 |-peer-addr		|-advertise-peer-urls 	|If specified, peer-addr will be used as the only peer URL. Error if both flags specified.|
 |-addr			|-advertise-client-urls	|If specified, addr will be used as the only client URL. Error if both flags specified.|
 |-addr			|-advertise-client-urls	|If specified, addr will be used as the only client URL. Error if both flags specified.|
-|-peer-bind-addr	|-listen-peer-urls	|If specified, peer-bind-addr will be used as the only peer URL. Error if both flags specified.|
-|-bind-addr		|-listen-client-urls	|If specified, bind-addr will be used as the only client URL. Error if both flags specified.|
+|-peer-bind-addr	|-listen-peer-urls	|If specified, peer-bind-addr will be used as the only peer bind URL. Error if both flags specified.|
+|-bind-addr		|-listen-client-urls	|If specified, bind-addr will be used as the only client bind URL. Error if both flags specified.|
 |-peers			|none			|Deprecated. The -initial-cluster flag provides a similar concept with different semantics. Please read this guide on cluster startup.|
 |-peers			|none			|Deprecated. The -initial-cluster flag provides a similar concept with different semantics. Please read this guide on cluster startup.|

+ 3 - 3
Procfile

@@ -1,5 +1,5 @@
 # Use goreman to run `go get github.com/mattn/goreman`
 # Use goreman to run `go get github.com/mattn/goreman`
-etcd1: bin/etcd -name node1 -listen-client-urls http://127.0.0.1:4001 -advertise-client-urls http://127.0.0.1:4001 -listen-peer-urls http://127.0.0.1:7001 -advertise-peer-urls http://127.0.0.1:7001 -bootstrap-config 'node1=http://localhost:7001,node2=http://localhost:7002,node3=http://localhost:7003'
-etcd2: bin/etcd -name node2 -listen-client-urls http://127.0.0.1:4002 -advertise-client-urls http://127.0.0.1:4002 -listen-peer-urls http://127.0.0.1:7002 -advertise-peer-urls http://127.0.0.1:7002 -bootstrap-config 'node1=http://localhost:7001,node2=http://localhost:7002,node3=http://localhost:7003'
-etcd3: bin/etcd -name node3 -listen-client-urls http://127.0.0.1:4003 -advertise-client-urls http://127.0.0.1:4003 -listen-peer-urls http://127.0.0.1:7003 -advertise-peer-urls http://127.0.0.1:7003 -bootstrap-config 'node1=http://localhost:7001,node2=http://localhost:7002,node3=http://localhost:7003'
+etcd1: bin/etcd -name node1 -listen-client-urls http://127.0.0.1:4001 -advertise-client-urls http://127.0.0.1:4001 -listen-peer-urls http://127.0.0.1:7001 -advertise-peer-urls http://127.0.0.1:7001 -initial-cluster 'node1=http://localhost:7001,node2=http://localhost:7002,node3=http://localhost:7003' -initial-cluster-state new
+etcd2: bin/etcd -name node2 -listen-client-urls http://127.0.0.1:4002 -advertise-client-urls http://127.0.0.1:4002 -listen-peer-urls http://127.0.0.1:7002 -advertise-peer-urls http://127.0.0.1:7002 -initial-cluster 'node1=http://localhost:7001,node2=http://localhost:7002,node3=http://localhost:7003' -initial-cluster-state new
+etcd3: bin/etcd -name node3 -listen-client-urls http://127.0.0.1:4003 -advertise-client-urls http://127.0.0.1:4003 -listen-peer-urls http://127.0.0.1:7003 -advertise-peer-urls http://127.0.0.1:7003 -initial-cluster 'node1=http://localhost:7001,node2=http://localhost:7002,node3=http://localhost:7003' -initial-cluster-state new
 #proxy: bin/etcd -proxy=on -bind-addr 127.0.0.1:8080 -peers 'localhost:7001,localhost:7002,localhost:7003'
 #proxy: bin/etcd -proxy=on -bind-addr 127.0.0.1:8080 -peers 'localhost:7001,localhost:7002,localhost:7003'

+ 35 - 0
etcdserver/cluster_state.go

@@ -0,0 +1,35 @@
+package etcdserver
+
+import (
+	"errors"
+)
+
+const (
+	ClusterStateValueNew = "new"
+)
+
+var (
+	ClusterStateValues = []string{
+		ClusterStateValueNew,
+	}
+)
+
+// 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)
+}

+ 27 - 0
etcdserver/cluster_state_test.go

@@ -0,0 +1,27 @@
+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)
+		}
+	}
+}

+ 3 - 0
etcdserver/server.go

@@ -91,6 +91,7 @@ type ServerConfig struct {
 	DataDir      string
 	DataDir      string
 	SnapCount    int64
 	SnapCount    int64
 	Cluster      *Cluster
 	Cluster      *Cluster
+	ClusterState ClusterState
 	Transport    *http.Transport
 	Transport    *http.Transport
 }
 }
 
 
@@ -125,6 +126,8 @@ func NewServer(cfg *ServerConfig) *EtcdServer {
 			if err = cfg.Cluster.Set(s); err != nil {
 			if err = cfg.Cluster.Set(s); err != nil {
 				log.Fatalf("etcd: %v", err)
 				log.Fatalf("etcd: %v", err)
 			}
 			}
+		} else if (cfg.ClusterState) != ClusterStateValueNew {
+			log.Fatalf("etcd: initial cluster state unset and no wal or discovery URL found")
 		}
 		}
 		if w, err = wal.Create(waldir); err != nil {
 		if w, err = wal.Create(waldir); err != nil {
 			log.Fatal(err)
 			log.Fatal(err)

+ 7 - 3
main.go

@@ -31,7 +31,9 @@ var (
 	snapCount    = flag.Uint64("snapshot-count", etcdserver.DefaultSnapCount, "Number of committed transactions to trigger a snapshot")
 	snapCount    = flag.Uint64("snapshot-count", etcdserver.DefaultSnapCount, "Number of committed transactions to trigger a snapshot")
 	printVersion = flag.Bool("version", false, "Print the version and exit")
 	printVersion = flag.Bool("version", false, "Print the version and exit")
 
 
-	cluster   = &etcdserver.Cluster{}
+	cluster      = &etcdserver.Cluster{}
+	clusterState = new(etcdserver.ClusterState)
+
 	cors      = &pkg.CORSInfo{}
 	cors      = &pkg.CORSInfo{}
 	proxyFlag = new(flagtypes.Proxy)
 	proxyFlag = new(flagtypes.Proxy)
 
 
@@ -56,7 +58,8 @@ var (
 )
 )
 
 
 func init() {
 func init() {
-	flag.Var(cluster, "bootstrap-config", "Initial cluster configuration for bootstrapping")
+	flag.Var(cluster, "initial-cluster", "Initial cluster configuration for bootstrapping")
+	flag.Var(clusterState, "initial-cluster-state", "Initial cluster configuration for bootstrapping")
 	cluster.Set("default=http://localhost:2380,default=http://localhost:7001")
 	cluster.Set("default=http://localhost:2380,default=http://localhost:7001")
 
 
 	flag.Var(flagtypes.NewURLsValue("http://localhost:2380,http://localhost:7001"), "advertise-peer-urls", "List of this member's peer URLs to advertise to the rest of the cluster")
 	flag.Var(flagtypes.NewURLsValue("http://localhost:2380,http://localhost:7001"), "advertise-peer-urls", "List of this member's peer URLs to advertise to the rest of the cluster")
@@ -146,8 +149,9 @@ func startEtcd() {
 		DataDir:      *dir,
 		DataDir:      *dir,
 		SnapCount:    int64(*snapCount),
 		SnapCount:    int64(*snapCount),
 		Cluster:      cluster,
 		Cluster:      cluster,
-		Transport:    pt,
 		DiscoveryURL: *durl,
 		DiscoveryURL: *durl,
+		ClusterState: *clusterState,
+		Transport:    pt,
 	}
 	}
 	s := etcdserver.NewServer(cfg)
 	s := etcdserver.NewServer(cfg)
 	s.Start()
 	s.Start()