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
```
This commit is contained in:
Brandon Philips 2014-10-03 13:10:34 -07:00
parent 6bc160b4e3
commit e2d8037ded
6 changed files with 109 additions and 32 deletions

View File

@ -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,24 +38,21 @@ $ 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 The command line parameters starting with `-initial-cluster` will be ignored on
runs of etcd. You are free to remove the environment variables or command line subsequent runs of etcd. You are free to remove the environment variables or
flags after the initial bootstrap process. If you need to make changes to the command line flags after the initial bootstrap process. If you need to make
configuration later see our guide on runtime configuration(link needed). 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 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 of initial cluster members.
is being added we must make the corresponding change to the existing clusters
configuration and then bring the new node online.
``` ```
$ etcd -name infra5 -advertise-peer-urls http://10.0.1.10:2379 \ $ etcd -name infra1 -advertise-peer-urls http://10.0.1.11: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 infra0=http://10.0.1.10:2379
-initial-cluster-state=new -initial-cluster-state new
etcd: infra5 not listed in the initial cluster config etcd: infra1 not listed in the initial cluster config
exit 1 exit 1
``` ```
@ -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,13 +120,9 @@ $ 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: error: the cluster using discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de has already started with all 5 members
exit 1
```
``` ```
$ 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
@ -134,10 +130,22 @@ etcd: error: the cluster doesnt have a size configuration value in https://di
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: error: the cluster using discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de has already started with all 5 members
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.| |-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 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.|

View File

@ -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' 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 -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 -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 -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 -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'

View File

@ -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)
}

View File

@ -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)
}
}
}

View File

@ -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)

View File

@ -32,6 +32,8 @@ var (
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()