Renamed configuration parameters.

This commit is contained in:
Ben Johnson 2013-11-14 22:58:47 -05:00
parent 3ce1132d5c
commit cba2611c68
35 changed files with 332 additions and 342 deletions

View File

@ -7,4 +7,4 @@ RUN apt-get install -y golang
ADD . /opt/etcd
RUN cd /opt/etcd && ./build
EXPOSE 4001 7001
ENTRYPOINT ["/opt/etcd/etcd", "-c", "0.0.0.0:4001", "-s", "0.0.0.0:7001"]
ENTRYPOINT ["/opt/etcd/etcd", "-addr", "0.0.0.0:4001", "-bind-addr", "0.0.0.0:7001"]

View File

@ -17,7 +17,7 @@ Error code corresponding strerror
EcodeKeyNotFound = 100
EcodeTestFailed = 101
EcodeNotFile = 102
EcodeNoMoreMachine = 103
EcodeNoMorePeer = 103
EcodeNotDir = 104
EcodeNodeExist = 105
EcodeKeyIsPreserved = 106
@ -38,7 +38,7 @@ Error code corresponding strerror
errors[100] = "Key Not Found"
errors[101] = "Test Failed" //test and set
errors[102] = "Not A File"
errors[103] = "Reached the max number of machines in the cluster"
errors[103] = "Reached the max number of peers in the cluster"
errors[104] = "Not A Directory"
errors[105] = "Already exists" // create
errors[106] = "The prefix of given key is a keyword in etcd"

View File

@ -14,34 +14,34 @@ configuration files.
### Required
* `-n` - The node name. Defaults to `default-name`.
* `-name` - The node name. Defaults to the hostname.
### Optional
* `-c` - The advertised public hostname:port for client communication. Defaults to `127.0.0.1:4001`.
* `-cl` - The listening hostname for client communication. Defaults to advertised ip.
* `-C` - A comma separated list of machines in the cluster (i.e `"203.0.113.101:7001,203.0.113.102:7001"`).
* `-CF` - The file path containing a comma separated list of machines in the cluster.
* `-clientCAFile` - The path of the client CAFile. Enables client cert authentication when present.
* `-clientCert` - The cert file of the client.
* `-clientKey` - The key file of the client.
* `-configfile` - The path of the etcd config file. Defaults to `/etc/etcd/etcd.conf`.
* `-cors` - A comma separated white list of origins for cross-origin resource sharing.
* `-addr` - The advertised public hostname:port for client communication. Defaults to `127.0.0.1:4001`.
* `-bind-addr` - The listening hostname for client communication. Defaults to advertised ip.
* `-peers` - A comma separated list of peers in the cluster (i.e `"203.0.113.101:7001,203.0.113.102:7001"`).
* `-peers-file` - The file path containing a comma separated list of peers in the cluster.
* `-ca-file` - The path of the client CAFile. Enables client cert authentication when present.
* `-cert-file` - The cert file of the client.
* `-key-file` - The key file of the client.
* `-config` - The path of the etcd config file. Defaults to `/etc/etcd/etcd.conf`.
* `-cors-origins` - A comma separated white list of origins for cross-origin resource sharing.
* `-cpuprofile` - The path to a file to output cpu profile data. Enables cpu profiling when present.
* `-d` - The directory to store log and snapshot. Defaults to the current working directory.
* `-m` - The max size of result buffer. Defaults to `1024`.
* `-maxsize` - The max size of the cluster. Defaults to `9`.
* `-r` - The max retry attempts when trying to join a cluster. Defaults to `3`.
* `-s` - The advertised public hostname:port for server communication. Defaults to `127.0.0.1:7001`.
* `-sl` - The listening hostname for server communication. Defaults to advertised ip.
* `-serverCAFile` - The path of the CAFile. Enables client/peer cert authentication when present.
* `-serverCert` - The cert file of the server.
* `-serverKey` - The key file of the server.
* `-data-dir` - The directory to store log and snapshot. Defaults to the current working directory.
* `-max-result-buffer` - The max size of result buffer. Defaults to `1024`.
* `-max-cluster-size` - The max size of the cluster. Defaults to `9`.
* `-max-retry-attempts` - The max retry attempts when trying to join a cluster. Defaults to `3`.
* `-peer-addr` - The advertised public hostname:port for server communication. Defaults to `127.0.0.1:7001`.
* `-peer-bind-addr` - The listening hostname for server communication. Defaults to advertised ip.
* `-peer-ca-file` - The path of the CAFile. Enables client/peer cert authentication when present.
* `-peer-cert-file` - The cert file of the server.
* `-peer-key-file` - The key file of the server.
* `-snapshot` - Open or close snapshot. Defaults to `false`.
* `-v` - Enable verbose logging. Defaults to `false`.
* `-vv` - Enable very verbose logging. Defaults to `false`.
* `-version` - Print the version and exit.
* `-w` - The hostname:port of web interface.
* `-web-url` - The hostname:port of web interface.
## Configuration File
@ -49,16 +49,16 @@ The etcd configuration file is written in [TOML](https://github.com/mojombo/toml
and read from `/etc/etcd/etcd.conf` by default.
```TOML
advertised_url = "127.0.0.1:4001"
addr = "127.0.0.1:4001"
bind_addr = "127.0.0.1:4001"
ca_file = ""
cert_file = ""
cors = []
cors_origins = []
cpu_profile_file = ""
datadir = "."
data_dir = "."
key_file = ""
listen_host = "127.0.0.1:4001"
machines = []
machines_file = ""
peers = []
peers_file = ""
max_cluster_size = 9
max_result_buffer = 1024
max_retry_attempts = 3
@ -69,36 +69,36 @@ very_verbose = false
web_url = ""
[peer]
advertised_url = "127.0.0.1:7001"
addr = "127.0.0.1:7001"
bind_addr = "127.0.0.1:7001"
ca_file = ""
cert_file = ""
key_file = ""
listen_host = "127.0.0.1:7001"
```
## Environment Variables
* `ETCD_ADVERTISED_URL`
* `ETCD_ADDR`
* `ETCD_BIND_ADDR`
* `ETCD_CA_FILE`
* `ETCD_CERT_FILE`
* `ETCD_CORS`
* `ETCD_CONFIG_FILE`
* `ETCD_CORS_ORIGINS`
* `ETCD_CONFIG`
* `ETCD_CPU_PROFILE_FILE`
* `ETCD_DATADIR`
* `ETCD_DATA_DIR`
* `ETCD_KEY_FILE`
* `ETCD_LISTEN_HOST`
* `ETCD_MACHINES`
* `ETCD_MACHINES_FILE`
* `ETCD_MAX_RETRY_ATTEMPTS`
* `ETCD_PEERS`
* `ETCD_PEERS_FILE`
* `ETCD_MAX_CLUSTER_SIZE`
* `ETCD_MAX_RESULT_BUFFER`
* `ETCD_MAX_RETRY_ATTEMPTS`
* `ETCD_NAME`
* `ETCD_SNAPSHOT`
* `ETCD_VERBOSE`
* `ETCD_VERY_VERBOSE`
* `ETCD_WEB_URL`
* `ETCD_PEER_ADVERTISED_URL`
* `ETCD_PEER_ADDR`
* `ETCD_PEER_BIND_ADDR`
* `ETCD_PEER_CA_FILE`
* `ETCD_PEER_CERT_FILE`
* `ETCD_PEER_KEY_FILE`
* `ETCD_PEER_LISTEN_HOST`

View File

@ -1,12 +1,12 @@
# Versioning
Goal: We want to be able to upgrade an individual machine in an etcd cluster to a newer version of etcd.
Goal: We want to be able to upgrade an individual peer in an etcd cluster to a newer version of etcd.
The process will take the form of individual followers upgrading to the latest version until the entire cluster is on the new version.
Immediate need: etcd is moving too fast to version the internal API right now.
But, we need to keep mixed version clusters from being started by a rollowing upgrade process (e.g. the CoreOS developer alpha).
Longer term need: Having a mixed version cluster where all machines are not be running the exact same version of etcd itself but are able to speak one version of the internal protocol.
Longer term need: Having a mixed version cluster where all peers are not be running the exact same version of etcd itself but are able to speak one version of the internal protocol.
Solution: The internal protocol needs to be versioned just as the client protocol is.
Initially during the 0.\*.\* series of etcd releases we won't allow mixed versions at all.
@ -58,4 +58,4 @@ https://issues.apache.org/jira/browse/ZOOKEEPER-1633
## doozerd
doozerd stores the version number of the machine in the datastore for other clients to check, no decisions are made off of this number currently.
doozerd stores the version number of the peers in the datastore for other clients to check, no decisions are made off of this number currently.

View File

@ -62,12 +62,12 @@ These examples will use a single node cluster to show you the basics of the etcd
Let's start etcd:
```sh
./etcd -d node0 -n node0
./etcd -data-dir node0 -name node0
```
This will bring up an etcd node listening on port 4001 for client communication and on port 7001 for server-to-server communication.
The `-d node0` argument tells etcd to write node configuration, logs and snapshots to the `./node0/` directory.
The `-n node0` tells the rest of the cluster that this node is named node0.
The `-data-dir node0` argument tells etcd to write node configuration, logs and snapshots to the `./node0/` directory.
The `-name node0` tells the rest of the cluster that this node is named node0.
@ -378,13 +378,13 @@ For testing you can use the certificates in the `fixtures/ca` directory.
Let's configure etcd to use this keypair:
```sh
./etcd -n node0 -d node0 -clientCert=./fixtures/ca/server.crt -clientKey=./fixtures/ca/server.key.insecure -f
./etcd -name node0 -data-dir node0 -cert-file=./fixtures/ca/server.crt -key-file=./fixtures/ca/server.key.insecure -force-config
```
There are a few new options we're using:
* `-f` - forces a new node configuration, even if an existing configuration is found. (WARNING: data loss!)
* `-clientCert` and `-clientKey` specify the location of the cert and key files to be used for for transport layer security between the client and server.
* `-force-config` - forces a new node configuration, even if an existing configuration is found. (WARNING: data loss!)
* `-cert-file` and `-key-file` specify the location of the cert and key files to be used for for transport layer security between the client and server.
You can now test the configuration using HTTPS:
@ -413,10 +413,10 @@ We can also do authentication using CA certs.
The clients will provide their cert to the server and the server will check whether the cert is signed by the CA and decide whether to serve the request.
```sh
./etcd -n node0 -d node0 -clientCAFile=./fixtures/ca/ca.crt -clientCert=./fixtures/ca/server.crt -clientKey=./fixtures/ca/server.key.insecure -f
./etcd -name node0 -data-dir node0 -ca-file=./fixtures/ca/ca.crt -cert-file=./fixtures/ca/server.crt -key-file=./fixtures/ca/server.key.insecure -force-config
```
```-clientCAFile``` is the path to the CA cert.
```-ca-file``` is the path to the CA cert.
Try the same request to this server:
@ -463,20 +463,20 @@ We use Raft as the underlying distributed protocol which provides consistency an
Let start by creating 3 new etcd instances.
We use -s to specify server port and -c to specify client port and -d to specify the directory to store the log and info of the node in the cluster
We use `-peer-addr` to specify server port and `-addr` to specify client port and `-data-dir` to specify the directory to store the log and info of the node in the cluster:
```sh
./etcd -s 127.0.0.1:7001 -c 127.0.0.1:4001 -d nodes/node1 -n node1
./etcd -peer-addr 127.0.0.1:7001 -addr 127.0.0.1:4001 -data-dir nodes/node1 -name node1
```
**Note:** If you want to run etcd on an external IP address and still have access locally, you'll need to add `-cl 0.0.0.0` so that it will listen on both external and localhost addresses.
A similar argument `-sl` is used to setup the listening address for the server port.
**Note:** If you want to run etcd on an external IP address and still have access locally, you'll need to add `-bind-addr 0.0.0.0` so that it will listen on both external and localhost addresses.
A similar argument `-peer-bind-addr` is used to setup the listening address for the server port.
Let's join two more nodes to this cluster using the `-C` argument:
Let's join two more nodes to this cluster using the `-peers` argument:
```sh
./etcd -s 127.0.0.1:7002 -c 127.0.0.1:4002 -C 127.0.0.1:7001 -d nodes/node2 -n node2
./etcd -s 127.0.0.1:7003 -c 127.0.0.1:4003 -C 127.0.0.1:7001 -d nodes/node3 -n node3
./etcd -peer-addr 127.0.0.1:7002 -addr 127.0.0.1:4002 -peers 127.0.0.1:7001 -data-dir nodes/node2 -name node2
./etcd -peer-addr 127.0.0.1:7003 -addr 127.0.0.1:4003 -peers 127.0.0.1:7001 -data-dir nodes/node3 -name node3
```
We can retrieve a list of machines in the cluster using the HTTP API:
@ -569,7 +569,7 @@ curl -L http://127.0.0.1:4002/v1/keys/foo
In the previous example we showed how to use SSL client certs for client-to-server communication.
Etcd can also do internal server-to-server communication using SSL client certs.
To do this just change the `-client*` flags to `-server*`.
To do this just change the `-*-file` flags to `-peer-*-file`.
If you are using SSL for server-to-server communication, you must use it on all instances of etcd.
@ -648,13 +648,13 @@ See [CONTRIBUTING](https://github.com/coreos/etcd/blob/master/CONTRIBUTING.md) f
### What size cluster should I use?
Every command the client sends to the master is broadcast to all of the followers.
The command is not committed until the majority of the cluster machines receive that command.
The command is not committed until the majority of the cluster peers receive that command.
Because of this majority voting property, the ideal cluster should be kept small to keep speed up and be made up of an odd number of machines.
Because of this majority voting property, the ideal cluster should be kept small to keep speed up and be made up of an odd number of peers.
Odd numbers are good because if you have 8 machines the majority will be 5 and if you have 9 machines the majority will still be 5.
The result is that an 8 machine cluster can tolerate 3 machine failures and a 9 machine cluster can tolerate 4 nodes failures.
And in the best case when all 9 machines are responding the cluster will perform at the speed of the fastest 5 nodes.
Odd numbers are good because if you have 8 peers the majority will be 5 and if you have 9 peers the majority will still be 5.
The result is that an 8 peer cluster can tolerate 3 peer failures and a 9 peer cluster can tolerate 4 nodes failures.
And in the best case when all 9 peers are responding the cluster will perform at the speed of the fastest 5 nodes.
### Why SSLv3 alert handshake failure when using SSL client auth?

View File

@ -28,7 +28,7 @@ const (
EcodeKeyNotFound = 100
EcodeTestFailed = 101
EcodeNotFile = 102
EcodeNoMoreMachine = 103
EcodeNoMorePeer = 103
EcodeNotDir = 104
EcodeNodeExist = 105
EcodeKeyIsPreserved = 106
@ -53,7 +53,7 @@ func init() {
errors[EcodeKeyNotFound] = "Key Not Found"
errors[EcodeTestFailed] = "Test Failed" //test and set
errors[EcodeNotFile] = "Not A File"
errors[EcodeNoMoreMachine] = "Reached the max number of machines in the cluster"
errors[EcodeNoMorePeer] = "Reached the max number of peers in the cluster"
errors[EcodeNotDir] = "Not A Directory"
errors[EcodeNodeExist] = "Already exists" // create
errors[EcodeKeyIsPreserved] = "The prefix of given key is a keyword in etcd"

12
etcd.go
View File

@ -55,13 +55,13 @@ func main() {
if info.Name == "" {
host, err := os.Hostname()
if err != nil || host == "" {
log.Fatal("Machine name required and hostname not set. e.g. '-n=machine_name'")
log.Fatal("Node name required and hostname not set. e.g. '-name=name'")
}
log.Warnf("Using hostname %s as the machine name. You must ensure this name is unique among etcd machines.", host)
log.Warnf("Using hostname %s as the node name. You must ensure this name is unique among etcd nodes.", host)
info.Name = host
}
// Setup a default directory based on the machine name
// Setup a default directory based on the node name
if config.DataDir == "" {
config.DataDir = info.Name + ".etcd"
log.Warnf("Using the directory %s as the etcd configuration directory because a directory was not specified. ", config.DataDir)
@ -87,13 +87,13 @@ func main() {
registry := server.NewRegistry(store)
// Create peer server.
ps := server.NewPeerServer(info.Name, config.DataDir, info.RaftURL, info.RaftListenHost, &peerTLSConfig, &info.RaftTLS, registry, store, config.SnapCount)
ps := server.NewPeerServer(info.Name, config.DataDir, info.RaftURL, info.RaftListenHost, &peerTLSConfig, &info.RaftTLS, registry, store, config.SnapshotCount)
ps.MaxClusterSize = config.MaxClusterSize
ps.RetryTimes = config.MaxRetryAttempts
// Create client server.
s := server.New(info.Name, info.EtcdURL, info.EtcdListenHost, &tlsConfig, &info.EtcdTLS, ps, registry, store)
if err := s.AllowOrigins(config.Cors); err != nil {
if err := s.AllowOrigins(config.CorsOrigins); err != nil {
panic(err)
}
@ -101,7 +101,7 @@ func main() {
// Run peer server in separate thread while the client server blocks.
go func() {
log.Fatal(ps.ListenAndServe(config.Snapshot, config.Machines))
log.Fatal(ps.ListenAndServe(config.Snapshot, config.Peers))
}()
log.Fatal(s.ListenAndServe())
}

View File

@ -24,9 +24,9 @@ angular.module('etcdStats', ['ngRoute', 'etcd'])
EtcdV2.getStat('leader').get().success(function(data) {
$scope.leaderStats = data;
$scope.leaderName = data.leader;
$scope.machines = [];
$scope.peers = [];
//hardcode leader stats
$scope.machines.push({
$scope.peers.push({
latency: {
average: 0,
current: 0,
@ -38,10 +38,10 @@ angular.module('etcdStats', ['ngRoute', 'etcd'])
});
$.each(data.followers, function(index, value) {
value.name = index;
$scope.machines.push(value);
$scope.peers.push(value);
});
//sort array so machines don't jump when output
$scope.machines.sort(function(a, b){
//sort array so peers don't jump when output
$scope.peers.sort(function(a, b){
if(a.name < b.name) return -1;
if(a.name > b.name) return 1;
return 0;
@ -64,7 +64,7 @@ angular.module('etcdStats', ['ngRoute', 'etcd'])
chart({
el: $scope.graphContainer,
data: {
'stats': $scope.machines
'stats': $scope.peers
}
}).width(width).height(height).update();
});

View File

@ -636,7 +636,7 @@ body {
background-color: #00DB24;
}
.etcd-container.etcd-stats .etcd-list .etcd-machine-type {
.etcd-container.etcd-stats .etcd-list .etcd-peer-type {
color: #999;
padding-left: 3px;
font-size: 13px;

View File

@ -20,26 +20,26 @@
</div>
</div>
<div class="etcd-graph">
<h2>Machine Latency</h2>
<h2>Peer Latency</h2>
<div class="etcd-graph-container" id="latency">
</div>
</div>
<div class="etcd-list">
<h2>Machine List</h2>
<h2>Peer List</h2>
<table cellpadding="0" cellspacing="0">
<thead>
<td class="etcd-name-header">Machine Name</td>
<td class="etcd-name-header">Peer Name</td>
<td class="etcd-latency">Latency</td>
</thead>
<tbody>
<tr ng-repeat="machine in machines">
<td ng-switch on="{true:'leader', false: 'follower'}[leaderName == machine.name]">
<div ng-switch-when="leader">{{machine.name}}<span class="etcd-machine-type">(leader)</span></div>
<div ng-switch-default>{{machine.name}}</div>
<tr ng-repeat="peer in peers">
<td ng-switch on="{true:'leader', false: 'follower'}[leaderName == peer.name]">
<div ng-switch-when="leader">{{peer.name}}<span class="etcd-peer-type">(leader)</span></div>
<div ng-switch-default>{{peer.name}}</div>
</td>
<td>
<div class="etcd-square ng-class: {'etcd-square-green': machine.latency.current < 25, 'etcd-square-orange': machine.latency.current < 60, 'etcd-square-red': machine.latency.current >= 60}"></div>
<div class="etcd-latency-value">{{machine.latency.current | number:1 }} ms</div>
<div class="etcd-square ng-class: {'etcd-square-green': peer.latency.current < 25, 'etcd-square-orange': peer.latency.current < 60, 'etcd-square-red': peer.latency.current >= 60}"></div>
<div class="etcd-latency-value">{{peer.latency.current | number:1 }} ms</div>
</td>
</tr>
</tbody>

View File

@ -1,2 +1,3 @@
package main
const releaseVersion = "v0.1.2-33-g1a2a9d6"

View File

@ -4,15 +4,15 @@ SESSION=etcd-cluster
tmux new-session -d -s $SESSION
# Setup a window for tailing log files
tmux new-window -t $SESSION:1 -n 'machines'
tmux new-window -t $SESSION:1 -n 'peers'
tmux split-window -h
tmux select-pane -t 0
tmux send-keys "./etcd -s 127.0.0.1:7001 -c 127.0.0.1:4001 -d machine1 -n machine1" C-m
tmux send-keys "./etcd -s 127.0.0.1:7001 -c 127.0.0.1:4001 -d peer1 -n peer1" C-m
for i in 2 3; do
tmux select-pane -t 0
tmux split-window -v
tmux send-keys "./etcd -cors='*' -s 127.0.0.1:700${i} -c 127.0.0.1:400${i} -C 127.0.0.1:7001 -d machine${i} -n machine${i}" C-m
tmux send-keys "./etcd -cors='*' -s 127.0.0.1:700${i} -c 127.0.0.1:400${i} -C 127.0.0.1:7001 -d peer${i} -n peer${i}" C-m
done
# Attach to session

View File

@ -23,31 +23,31 @@ const DefaultSystemConfigPath = "/etc/etcd/etcd.conf"
type Config struct {
SystemPath string
AdvertisedUrl string `toml:"advertised_url" env:"ETCD_ADVERTISED_URL"`
Addr string `toml:"addr" env:"ETCD_ADDR"`
BindAddr string `toml:"bind_addr" env:"ETCD_BIND_ADDR"`
CAFile string `toml:"ca_file" env:"ETCD_CA_FILE"`
CertFile string `toml:"cert_file" env:"ETCD_CERT_FILE"`
Cors []string `toml:"cors" env:"ETCD_CORS"`
DataDir string `toml:"datadir" env:"ETCD_DATADIR"`
CorsOrigins []string `toml:"cors_origins" env:"ETCD_CORS_ORIGINS"`
DataDir string `toml:"data_dir" env:"ETCD_DATA_DIR"`
KeyFile string `toml:"key_file" env:"ETCD_KEY_FILE"`
ListenHost string `toml:"listen_host" env:"ETCD_LISTEN_HOST"`
Machines []string `toml:"machines" env:"ETCD_MACHINES"`
MachinesFile string `toml:"machines_file" env:"ETCD_MACHINES_FILE"`
Peers []string `toml:"peers" env:"ETCD_PEERS"`
PeersFile string `toml:"peers_file" env:"ETCD_PEERS_FILE"`
MaxClusterSize int `toml:"max_cluster_size" env:"ETCD_MAX_CLUSTER_SIZE"`
MaxResultBuffer int `toml:"max_result_buffer" env:"ETCD_MAX_RESULT_BUFFER"`
MaxRetryAttempts int `toml:"max_retry_attempts" env:"ETCD_MAX_RETRY_ATTEMPTS"`
Name string `toml:"name" env:"ETCD_NAME"`
Snapshot bool `toml:"snapshot" env:"ETCD_SNAPSHOT"`
SnapCount int `toml:"snapshot_count" env:"ETCD_SNAPSHOTCOUNT"`
SnapshotCount int `toml:"snapshot_count" env:"ETCD_SNAPSHOTCOUNT"`
Verbose bool `toml:"verbose" env:"ETCD_VERBOSE"`
VeryVerbose bool `toml:"very_verbose" env:"ETCD_VERY_VERBOSE"`
WebURL string `toml:"web_url" env:"ETCD_WEB_URL"`
Peer struct {
AdvertisedUrl string `toml:"advertised_url" env:"ETCD_PEER_ADVERTISED_URL"`
CAFile string `toml:"ca_file" env:"ETCD_PEER_CA_FILE"`
CertFile string `toml:"cert_file" env:"ETCD_PEER_CERT_FILE"`
KeyFile string `toml:"key_file" env:"ETCD_PEER_KEY_FILE"`
ListenHost string `toml:"listen_host" env:"ETCD_PEER_LISTEN_HOST"`
Addr string `toml:"addr" env:"ETCD_PEER_ADDR"`
BindAddr string `toml:"bind_addr" env:"ETCD_PEER_BIND_ADDR"`
CAFile string `toml:"ca_file" env:"ETCD_PEER_CA_FILE"`
CertFile string `toml:"cert_file" env:"ETCD_PEER_CERT_FILE"`
KeyFile string `toml:"key_file" env:"ETCD_PEER_KEY_FILE"`
}
}
@ -55,13 +55,12 @@ type Config struct {
func NewConfig() *Config {
c := new(Config)
c.SystemPath = DefaultSystemConfigPath
c.AdvertisedUrl = "127.0.0.1:4001"
c.AdvertisedUrl = "127.0.0.1:4001"
c.Addr = "127.0.0.1:4001"
c.MaxClusterSize = 9
c.MaxResultBuffer = 1024
c.MaxRetryAttempts = 3
c.Peer.AdvertisedUrl = "127.0.0.1:7001"
c.SnapCount = 10000
c.Peer.Addr = "127.0.0.1:7001"
c.SnapshotCount = 10000
return c
}
@ -96,8 +95,8 @@ func (c *Config) Load(arguments []string) error {
return err
}
// Loads machines if a machine file was specified.
if err := c.LoadMachineFile(); err != nil {
// Loads peers if a peer file was specified.
if err := c.LoadPeersFile(); err != nil {
return err
}
@ -167,42 +166,42 @@ func (c *Config) loadEnv(target interface{}) error {
// Loads configuration from command line flags.
func (c *Config) LoadFlags(arguments []string) error {
var machines, cors string
var peers, cors string
var force bool
f := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
f.BoolVar(&force, "f", false, "force new node configuration if existing is found (WARNING: data loss!)")
f.BoolVar(&force, "force-config", false, "force new node configuration if existing is found (WARNING: data loss!)")
f.BoolVar(&c.Verbose, "v", c.Verbose, "verbose logging")
f.BoolVar(&c.VeryVerbose, "vv", c.Verbose, "very verbose logging")
f.StringVar(&machines, "C", "", "the ip address and port of a existing machines in the cluster, sepearate by comma")
f.StringVar(&c.MachinesFile, "CF", c.MachinesFile, "the file contains a list of existing machines in the cluster, seperate by comma")
f.StringVar(&peers, "peers", "", "the ip address and port of a existing peers in the cluster, sepearate by comma")
f.StringVar(&c.PeersFile, "peers-file", c.PeersFile, "the file contains a list of existing peers in the cluster, seperate by comma")
f.StringVar(&c.Name, "n", c.Name, "the node name (required)")
f.StringVar(&c.AdvertisedUrl, "c", c.AdvertisedUrl, "the advertised public hostname:port for etcd client communication")
f.StringVar(&c.Peer.AdvertisedUrl, "s", c.Peer.AdvertisedUrl, "the advertised public hostname:port for raft server communication")
f.StringVar(&c.ListenHost, "cl", c.ListenHost, "the listening hostname for etcd client communication (defaults to advertised ip)")
f.StringVar(&c.Peer.ListenHost, "sl", c.Peer.ListenHost, "the listening hostname for raft server communication (defaults to advertised ip)")
f.StringVar(&c.WebURL, "w", c.WebURL, "the hostname:port of web interface")
f.StringVar(&c.Name, "name", c.Name, "the node name (required)")
f.StringVar(&c.Addr, "addr", c.Addr, "the advertised public hostname:port for etcd client communication")
f.StringVar(&c.BindAddr, "bind-addr", c.BindAddr, "the listening hostname for etcd client communication (defaults to advertised ip)")
f.StringVar(&c.Peer.Addr, "peer-addr", c.Peer.Addr, "the advertised public hostname:port for raft server communication")
f.StringVar(&c.Peer.BindAddr, "peer-bind-addr", c.Peer.BindAddr, "the listening hostname for raft server communication (defaults to advertised ip)")
f.StringVar(&c.WebURL, "web-url", c.WebURL, "the hostname:port of web interface")
f.StringVar(&c.Peer.CAFile, "serverCAFile", c.Peer.CAFile, "the path of the CAFile")
f.StringVar(&c.Peer.CertFile, "serverCert", c.Peer.CertFile, "the cert file of the server")
f.StringVar(&c.Peer.KeyFile, "serverKey", c.Peer.KeyFile, "the key file of the server")
f.StringVar(&c.Peer.CAFile, "peer-ca-file", c.Peer.CAFile, "the path of the CAFile")
f.StringVar(&c.Peer.CertFile, "peer-cert-file", c.Peer.CertFile, "the cert file of the server")
f.StringVar(&c.Peer.KeyFile, "peer-key-file", c.Peer.KeyFile, "the key file of the server")
f.StringVar(&c.CAFile, "clientCAFile", c.CAFile, "the path of the client CAFile")
f.StringVar(&c.CertFile, "clientCert", c.CertFile, "the cert file of the client")
f.StringVar(&c.KeyFile, "clientKey", c.KeyFile, "the key file of the client")
f.StringVar(&c.CAFile, "ca-file", c.CAFile, "the path of the client CAFile")
f.StringVar(&c.CertFile, "cert-file", c.CertFile, "the cert file of the client")
f.StringVar(&c.KeyFile, "key-file", c.KeyFile, "the key file of the client")
f.StringVar(&c.DataDir, "d", c.DataDir, "the directory to store log and snapshot")
f.IntVar(&c.MaxResultBuffer, "m", c.MaxResultBuffer, "the max size of result buffer")
f.IntVar(&c.MaxRetryAttempts, "r", c.MaxRetryAttempts, "the max retry attempts when trying to join a cluster")
f.IntVar(&c.MaxClusterSize, "maxsize", c.MaxClusterSize, "the max size of the cluster")
f.StringVar(&cors, "cors", "", "whitelist origins for cross-origin resource sharing (e.g. '*' or 'http://localhost:8001,etc')")
f.StringVar(&c.DataDir, "data-dir", c.DataDir, "the directory to store log and snapshot")
f.IntVar(&c.MaxResultBuffer, "max-result-buffer", c.MaxResultBuffer, "the max size of result buffer")
f.IntVar(&c.MaxRetryAttempts, "max-retry-attempts", c.MaxRetryAttempts, "the max retry attempts when trying to join a cluster")
f.IntVar(&c.MaxClusterSize, "max-cluster-size", c.MaxClusterSize, "the max size of the cluster")
f.StringVar(&cors, "cors-origins", "", "whitelist origins for cross-origin resource sharing (e.g. '*' or 'http://localhost:8001,etc')")
f.BoolVar(&c.Snapshot, "snapshot", c.Snapshot, "open or close snapshot")
f.IntVar(&c.SnapCount, "snapshotCount", c.SnapCount, "save the in memory logs and states to a snapshot file after snapCount transactions")
f.IntVar(&c.SnapshotCount, "snapshot-count", c.SnapshotCount, "save the in-memory logs and states to a snapshot file a given number of transactions")
// These flags are ignored since they were already parsed.
var path string
@ -211,11 +210,11 @@ func (c *Config) LoadFlags(arguments []string) error {
f.Parse(arguments)
// Convert some parameters to lists.
if machines != "" {
c.Machines = trimsplit(machines, ",")
if peers != "" {
c.Peers = trimsplit(peers, ",")
}
if cors != "" {
c.Cors = trimsplit(cors, ",")
c.CorsOrigins = trimsplit(cors, ",")
}
// Force remove server configuration if specified.
@ -226,17 +225,17 @@ func (c *Config) LoadFlags(arguments []string) error {
return nil
}
// LoadMachineFile loads the machines listed in the machine file.
func (c *Config) LoadMachineFile() error {
if c.MachinesFile == "" {
// LoadPeersFile loads the peers listed in the peers file.
func (c *Config) LoadPeersFile() error {
if c.PeersFile == "" {
return nil
}
b, err := ioutil.ReadFile(c.MachinesFile)
b, err := ioutil.ReadFile(c.PeersFile)
if err != nil {
return fmt.Errorf("Machines file error: %s", err)
return fmt.Errorf("Peers file error: %s", err)
}
c.Machines = trimsplit(string(b), ",")
c.Peers = trimsplit(string(b), ",")
return nil
}
@ -278,10 +277,10 @@ func (c *Config) Info() (*Info, error) {
// If the file doesn't exist then initialize it.
info.Name = strings.TrimSpace(c.Name)
info.EtcdURL = c.AdvertisedUrl
info.EtcdListenHost = c.ListenHost
info.RaftURL = c.Peer.AdvertisedUrl
info.RaftListenHost = c.Peer.ListenHost
info.EtcdURL = c.Addr
info.EtcdListenHost = c.BindAddr
info.RaftURL = c.Peer.Addr
info.RaftListenHost = c.Peer.BindAddr
info.WebURL = c.WebURL
info.EtcdTLS = c.TLSInfo()
info.RaftTLS = c.PeerTLSInfo()
@ -313,19 +312,19 @@ func (c *Config) Sanitize() error {
}
// Sanitize the URLs first.
if c.AdvertisedUrl, err = sanitizeURL(c.AdvertisedUrl, tlsConfig.Scheme); err != nil {
if c.Addr, err = sanitizeURL(c.Addr, tlsConfig.Scheme); err != nil {
return fmt.Errorf("Advertised URL: %s", err)
}
if c.ListenHost, err = sanitizeListenHost(c.ListenHost, c.AdvertisedUrl); err != nil {
if c.BindAddr, err = sanitizeBindAddr(c.BindAddr, c.Addr); err != nil {
return fmt.Errorf("Listen Host: %s", err)
}
if c.WebURL, err = sanitizeURL(c.WebURL, "http"); err != nil {
return fmt.Errorf("Web URL: %s", err)
}
if c.Peer.AdvertisedUrl, err = sanitizeURL(c.Peer.AdvertisedUrl, peerTlsConfig.Scheme); err != nil {
if c.Peer.Addr, err = sanitizeURL(c.Peer.Addr, peerTlsConfig.Scheme); err != nil {
return fmt.Errorf("Peer Advertised URL: %s", err)
}
if c.Peer.ListenHost, err = sanitizeListenHost(c.Peer.ListenHost, c.Peer.AdvertisedUrl); err != nil {
if c.Peer.BindAddr, err = sanitizeBindAddr(c.Peer.BindAddr, c.Peer.Addr); err != nil {
return fmt.Errorf("Peer Listen Host: %s", err)
}
@ -383,10 +382,10 @@ func sanitizeURL(host string, defaultScheme string) (string, error) {
return p.String(), nil
}
// sanitizeListenHost cleans up the ListenHost parameter and appends a port
// sanitizeBindAddr cleans up the BindAddr parameter and appends a port
// if necessary based on the advertised port.
func sanitizeListenHost(listen string, advertised string) (string, error) {
aurl, err := url.Parse(advertised)
func sanitizeBindAddr(bindAddr string, addr string) (string, error) {
aurl, err := url.Parse(addr)
if err != nil {
return "", err
}
@ -397,9 +396,9 @@ func sanitizeListenHost(listen string, advertised string) (string, error) {
}
// If the listen host isn't set use the advertised host
if listen == "" {
listen = ahost
if bindAddr == "" {
bindAddr = ahost
}
return net.JoinHostPort(listen, aport), nil
return net.JoinHostPort(bindAddr, aport), nil
}

View File

@ -9,20 +9,19 @@ import (
"github.com/stretchr/testify/assert"
)
// Ensures that a configuration can be deserialized from TOML.
func TestConfigTOML(t *testing.T) {
content := `
advertised_url = "127.0.0.1:4002"
addr = "127.0.0.1:4002"
ca_file = "/tmp/file.ca"
cert_file = "/tmp/file.cert"
cors = ["*"]
cors_origins = ["*"]
cpu_profile_file = "XXX"
datadir = "/tmp/data"
data_dir = "/tmp/data"
key_file = "/tmp/file.key"
listen_host = "127.0.0.1:4003"
machines = ["coreos.com:4001", "coreos.com:4002"]
machines_file = "/tmp/machines"
bind_addr = "127.0.0.1:4003"
peers = ["coreos.com:4001", "coreos.com:4002"]
peers_file = "/tmp/peers"
max_cluster_size = 10
max_result_buffer = 512
max_retry_attempts = 5
@ -33,24 +32,24 @@ func TestConfigTOML(t *testing.T) {
web_url = "/web"
[peer]
advertised_url = "127.0.0.1:7002"
addr = "127.0.0.1:7002"
ca_file = "/tmp/peer/file.ca"
cert_file = "/tmp/peer/file.cert"
key_file = "/tmp/peer/file.key"
listen_host = "127.0.0.1:7003"
bind_addr = "127.0.0.1:7003"
`
c := NewConfig()
_, err := toml.Decode(content, &c)
assert.Nil(t, err, "")
assert.Equal(t, c.AdvertisedUrl, "127.0.0.1:4002", "")
assert.Equal(t, c.Addr, "127.0.0.1:4002", "")
assert.Equal(t, c.CAFile, "/tmp/file.ca", "")
assert.Equal(t, c.CertFile, "/tmp/file.cert", "")
assert.Equal(t, c.Cors, []string{"*"}, "")
assert.Equal(t, c.CorsOrigins, []string{"*"}, "")
assert.Equal(t, c.DataDir, "/tmp/data", "")
assert.Equal(t, c.KeyFile, "/tmp/file.key", "")
assert.Equal(t, c.ListenHost, "127.0.0.1:4003", "")
assert.Equal(t, c.Machines, []string{"coreos.com:4001", "coreos.com:4002"}, "")
assert.Equal(t, c.MachinesFile, "/tmp/machines", "")
assert.Equal(t, c.BindAddr, "127.0.0.1:4003", "")
assert.Equal(t, c.Peers, []string{"coreos.com:4001", "coreos.com:4002"}, "")
assert.Equal(t, c.PeersFile, "/tmp/peers", "")
assert.Equal(t, c.MaxClusterSize, 10, "")
assert.Equal(t, c.MaxResultBuffer, 512, "")
assert.Equal(t, c.MaxRetryAttempts, 5, "")
@ -59,11 +58,11 @@ func TestConfigTOML(t *testing.T) {
assert.Equal(t, c.Verbose, true, "")
assert.Equal(t, c.VeryVerbose, true, "")
assert.Equal(t, c.WebURL, "/web", "")
assert.Equal(t, c.Peer.AdvertisedUrl, "127.0.0.1:7002", "")
assert.Equal(t, c.Peer.Addr, "127.0.0.1:7002", "")
assert.Equal(t, c.Peer.CAFile, "/tmp/peer/file.ca", "")
assert.Equal(t, c.Peer.CertFile, "/tmp/peer/file.cert", "")
assert.Equal(t, c.Peer.KeyFile, "/tmp/peer/file.key", "")
assert.Equal(t, c.Peer.ListenHost, "127.0.0.1:7003", "")
assert.Equal(t, c.Peer.BindAddr, "127.0.0.1:7003", "")
}
// Ensures that a configuration can be retrieved from environment variables.
@ -71,12 +70,12 @@ func TestConfigEnv(t *testing.T) {
os.Setenv("ETCD_CA_FILE", "/tmp/file.ca")
os.Setenv("ETCD_CERT_FILE", "/tmp/file.cert")
os.Setenv("ETCD_CPU_PROFILE_FILE", "XXX")
os.Setenv("ETCD_CORS", "localhost:4001,localhost:4002")
os.Setenv("ETCD_DATADIR", "/tmp/data")
os.Setenv("ETCD_CORS_ORIGINS", "localhost:4001,localhost:4002")
os.Setenv("ETCD_DATA_DIR", "/tmp/data")
os.Setenv("ETCD_KEY_FILE", "/tmp/file.key")
os.Setenv("ETCD_LISTEN_HOST", "127.0.0.1:4003")
os.Setenv("ETCD_MACHINES", "coreos.com:4001,coreos.com:4002")
os.Setenv("ETCD_MACHINES_FILE", "/tmp/machines")
os.Setenv("ETCD_BIND_ADDR", "127.0.0.1:4003")
os.Setenv("ETCD_PEERS", "coreos.com:4001,coreos.com:4002")
os.Setenv("ETCD_PEERS_FILE", "/tmp/peers")
os.Setenv("ETCD_MAX_CLUSTER_SIZE", "10")
os.Setenv("ETCD_MAX_RESULT_BUFFER", "512")
os.Setenv("ETCD_MAX_RETRY_ATTEMPTS", "5")
@ -85,22 +84,22 @@ func TestConfigEnv(t *testing.T) {
os.Setenv("ETCD_VERBOSE", "1")
os.Setenv("ETCD_VERY_VERBOSE", "yes")
os.Setenv("ETCD_WEB_URL", "/web")
os.Setenv("ETCD_PEER_ADVERTISED_URL", "127.0.0.1:7002")
os.Setenv("ETCD_PEER_ADDR", "127.0.0.1:7002")
os.Setenv("ETCD_PEER_CA_FILE", "/tmp/peer/file.ca")
os.Setenv("ETCD_PEER_CERT_FILE", "/tmp/peer/file.cert")
os.Setenv("ETCD_PEER_KEY_FILE", "/tmp/peer/file.key")
os.Setenv("ETCD_PEER_LISTEN_HOST", "127.0.0.1:7003")
os.Setenv("ETCD_PEER_BIND_ADDR", "127.0.0.1:7003")
c := NewConfig()
c.LoadEnv()
assert.Equal(t, c.CAFile, "/tmp/file.ca", "")
assert.Equal(t, c.CertFile, "/tmp/file.cert", "")
assert.Equal(t, c.Cors, []string{"localhost:4001", "localhost:4002"}, "")
assert.Equal(t, c.CorsOrigins, []string{"localhost:4001", "localhost:4002"}, "")
assert.Equal(t, c.DataDir, "/tmp/data", "")
assert.Equal(t, c.KeyFile, "/tmp/file.key", "")
assert.Equal(t, c.ListenHost, "127.0.0.1:4003", "")
assert.Equal(t, c.Machines, []string{"coreos.com:4001", "coreos.com:4002"}, "")
assert.Equal(t, c.MachinesFile, "/tmp/machines", "")
assert.Equal(t, c.BindAddr, "127.0.0.1:4003", "")
assert.Equal(t, c.Peers, []string{"coreos.com:4001", "coreos.com:4002"}, "")
assert.Equal(t, c.PeersFile, "/tmp/peers", "")
assert.Equal(t, c.MaxClusterSize, 10, "")
assert.Equal(t, c.MaxResultBuffer, 512, "")
assert.Equal(t, c.MaxRetryAttempts, 5, "")
@ -109,26 +108,26 @@ func TestConfigEnv(t *testing.T) {
assert.Equal(t, c.Verbose, true, "")
assert.Equal(t, c.VeryVerbose, true, "")
assert.Equal(t, c.WebURL, "/web", "")
assert.Equal(t, c.Peer.AdvertisedUrl, "127.0.0.1:7002", "")
assert.Equal(t, c.Peer.Addr, "127.0.0.1:7002", "")
assert.Equal(t, c.Peer.CAFile, "/tmp/peer/file.ca", "")
assert.Equal(t, c.Peer.CertFile, "/tmp/peer/file.cert", "")
assert.Equal(t, c.Peer.KeyFile, "/tmp/peer/file.key", "")
assert.Equal(t, c.Peer.ListenHost, "127.0.0.1:7003", "")
assert.Equal(t, c.Peer.BindAddr, "127.0.0.1:7003", "")
}
// Ensures that a the advertised url can be parsed from the environment.
func TestConfigAdvertisedUrlEnv(t *testing.T) {
withEnv("ETCD_ADVERTISED_URL", "127.0.0.1:4002", func(c *Config) {
func TestConfigAddrEnv(t *testing.T) {
withEnv("ETCD_ADDR", "127.0.0.1:4002", func(c *Config) {
assert.Nil(t, c.LoadEnv(), "")
assert.Equal(t, c.AdvertisedUrl, "127.0.0.1:4002", "")
assert.Equal(t, c.Addr, "127.0.0.1:4002", "")
})
}
// Ensures that a the advertised flag can be parsed.
func TestConfigAdvertisedUrlFlag(t *testing.T) {
func TestConfigAddrFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-c", "127.0.0.1:4002"}), "")
assert.Equal(t, c.AdvertisedUrl, "127.0.0.1:4002", "")
assert.Nil(t, c.LoadFlags([]string{"-addr", "127.0.0.1:4002"}), "")
assert.Equal(t, c.Addr, "127.0.0.1:4002", "")
}
// Ensures that a the CA file can be parsed from the environment.
@ -142,7 +141,7 @@ func TestConfigCAFileEnv(t *testing.T) {
// Ensures that a the CA file flag can be parsed.
func TestConfigCAFileFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-clientCAFile", "/tmp/file.ca"}), "")
assert.Nil(t, c.LoadFlags([]string{"-ca-file", "/tmp/file.ca"}), "")
assert.Equal(t, c.CAFile, "/tmp/file.ca", "")
}
@ -157,7 +156,7 @@ func TestConfigCertFileEnv(t *testing.T) {
// Ensures that a the Cert file flag can be parsed.
func TestConfigCertFileFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-clientCert", "/tmp/file.cert"}), "")
assert.Nil(t, c.LoadFlags([]string{"-cert-file", "/tmp/file.cert"}), "")
assert.Equal(t, c.CertFile, "/tmp/file.cert", "")
}
@ -172,53 +171,53 @@ func TestConfigKeyFileEnv(t *testing.T) {
// Ensures that a the Key file flag can be parsed.
func TestConfigKeyFileFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-clientKey", "/tmp/file.key"}), "")
assert.Nil(t, c.LoadFlags([]string{"-key-file", "/tmp/file.key"}), "")
assert.Equal(t, c.KeyFile, "/tmp/file.key", "")
}
// Ensures that a the Listen Host can be parsed from the environment.
func TestConfigListenHostEnv(t *testing.T) {
withEnv("ETCD_LISTEN_HOST", "127.0.0.1:4003", func(c *Config) {
func TestConfigBindAddrEnv(t *testing.T) {
withEnv("ETCD_BIND_ADDR", "127.0.0.1:4003", func(c *Config) {
assert.Nil(t, c.LoadEnv(), "")
assert.Equal(t, c.ListenHost, "127.0.0.1:4003", "")
assert.Equal(t, c.BindAddr, "127.0.0.1:4003", "")
})
}
// Ensures that a the Listen Host file flag can be parsed.
func TestConfigListenHostFlag(t *testing.T) {
func TestConfigBindAddrFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-cl", "127.0.0.1:4003"}), "")
assert.Equal(t, c.ListenHost, "127.0.0.1:4003", "")
assert.Nil(t, c.LoadFlags([]string{"-bind-addr", "127.0.0.1:4003"}), "")
assert.Equal(t, c.BindAddr, "127.0.0.1:4003", "")
}
// Ensures that the Machines can be parsed from the environment.
func TestConfigMachinesEnv(t *testing.T) {
withEnv("ETCD_MACHINES", "coreos.com:4001,coreos.com:4002", func(c *Config) {
// Ensures that the peers can be parsed from the environment.
func TestConfigPeersEnv(t *testing.T) {
withEnv("ETCD_PEERS", "coreos.com:4001,coreos.com:4002", func(c *Config) {
assert.Nil(t, c.LoadEnv(), "")
assert.Equal(t, c.Machines, []string{"coreos.com:4001", "coreos.com:4002"}, "")
assert.Equal(t, c.Peers, []string{"coreos.com:4001", "coreos.com:4002"}, "")
})
}
// Ensures that a the Machines flag can be parsed.
func TestConfigMachinesFlag(t *testing.T) {
// Ensures that a the Peers flag can be parsed.
func TestConfigPeersFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-C", "coreos.com:4001,coreos.com:4002"}), "")
assert.Equal(t, c.Machines, []string{"coreos.com:4001", "coreos.com:4002"}, "")
assert.Nil(t, c.LoadFlags([]string{"-peers", "coreos.com:4001,coreos.com:4002"}), "")
assert.Equal(t, c.Peers, []string{"coreos.com:4001", "coreos.com:4002"}, "")
}
// Ensures that the Machines File can be parsed from the environment.
func TestConfigMachinesFileEnv(t *testing.T) {
withEnv("ETCD_MACHINES_FILE", "/tmp/machines", func(c *Config) {
// Ensures that the Peers File can be parsed from the environment.
func TestConfigPeersFileEnv(t *testing.T) {
withEnv("ETCD_PEERS_FILE", "/tmp/peers", func(c *Config) {
assert.Nil(t, c.LoadEnv(), "")
assert.Equal(t, c.MachinesFile, "/tmp/machines", "")
assert.Equal(t, c.PeersFile, "/tmp/peers", "")
})
}
// Ensures that a the Machines File flag can be parsed.
func TestConfigMachinesFileFlag(t *testing.T) {
// Ensures that a the Peers File flag can be parsed.
func TestConfigPeersFileFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-CF", "/tmp/machines"}), "")
assert.Equal(t, c.MachinesFile, "/tmp/machines", "")
assert.Nil(t, c.LoadFlags([]string{"-peers-file", "/tmp/peers"}), "")
assert.Equal(t, c.PeersFile, "/tmp/peers", "")
}
// Ensures that the Max Cluster Size can be parsed from the environment.
@ -232,7 +231,7 @@ func TestConfigMaxClusterSizeEnv(t *testing.T) {
// Ensures that a the Max Cluster Size flag can be parsed.
func TestConfigMaxClusterSizeFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-maxsize", "5"}), "")
assert.Nil(t, c.LoadFlags([]string{"-max-cluster-size", "5"}), "")
assert.Equal(t, c.MaxClusterSize, 5, "")
}
@ -247,7 +246,7 @@ func TestConfigMaxResultBufferEnv(t *testing.T) {
// Ensures that a the Max Result Buffer flag can be parsed.
func TestConfigMaxResultBufferFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-m", "512"}), "")
assert.Nil(t, c.LoadFlags([]string{"-max-result-buffer", "512"}), "")
assert.Equal(t, c.MaxResultBuffer, 512, "")
}
@ -262,7 +261,7 @@ func TestConfigMaxRetryAttemptsEnv(t *testing.T) {
// Ensures that a the Max Retry Attempts flag can be parsed.
func TestConfigMaxRetryAttemptsFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-r", "10"}), "")
assert.Nil(t, c.LoadFlags([]string{"-max-retry-attempts", "10"}), "")
assert.Equal(t, c.MaxRetryAttempts, 10, "")
}
@ -277,7 +276,7 @@ func TestConfigNameEnv(t *testing.T) {
// Ensures that a the Name flag can be parsed.
func TestConfigNameFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-n", "test-name"}), "")
assert.Nil(t, c.LoadFlags([]string{"-name", "test-name"}), "")
assert.Equal(t, c.Name, "test-name", "")
}
@ -337,23 +336,23 @@ func TestConfigWebURLEnv(t *testing.T) {
// Ensures that a the Web URL flag can be parsed.
func TestConfigWebURLFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-w", "/web"}), "")
assert.Nil(t, c.LoadFlags([]string{"-web-url", "/web"}), "")
assert.Equal(t, c.WebURL, "/web", "")
}
// Ensures that the Peer Advertised URL can be parsed from the environment.
func TestConfigPeerAdvertisedUrlEnv(t *testing.T) {
withEnv("ETCD_PEER_ADVERTISED_URL", "localhost:7002", func(c *Config) {
func TestConfigPeerAddrEnv(t *testing.T) {
withEnv("ETCD_PEER_ADDR", "localhost:7002", func(c *Config) {
assert.Nil(t, c.LoadEnv(), "")
assert.Equal(t, c.Peer.AdvertisedUrl, "localhost:7002", "")
assert.Equal(t, c.Peer.Addr, "localhost:7002", "")
})
}
// Ensures that a the Peer Advertised URL flag can be parsed.
func TestConfigPeerAdvertisedUrlFlag(t *testing.T) {
func TestConfigPeerAddrFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-s", "localhost:7002"}), "")
assert.Equal(t, c.Peer.AdvertisedUrl, "localhost:7002", "")
assert.Nil(t, c.LoadFlags([]string{"-peer-addr", "localhost:7002"}), "")
assert.Equal(t, c.Peer.Addr, "localhost:7002", "")
}
// Ensures that the Peer CA File can be parsed from the environment.
@ -367,7 +366,7 @@ func TestConfigPeerCAFileEnv(t *testing.T) {
// Ensures that a the Peer CA file flag can be parsed.
func TestConfigPeerCAFileFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-serverCAFile", "/tmp/peer/file.ca"}), "")
assert.Nil(t, c.LoadFlags([]string{"-peer-ca-file", "/tmp/peer/file.ca"}), "")
assert.Equal(t, c.Peer.CAFile, "/tmp/peer/file.ca", "")
}
@ -382,7 +381,7 @@ func TestConfigPeerCertFileEnv(t *testing.T) {
// Ensures that a the Cert file flag can be parsed.
func TestConfigPeerCertFileFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-serverCert", "/tmp/peer/file.cert"}), "")
assert.Nil(t, c.LoadFlags([]string{"-peer-cert-file", "/tmp/peer/file.cert"}), "")
assert.Equal(t, c.Peer.CertFile, "/tmp/peer/file.cert", "")
}
@ -397,66 +396,64 @@ func TestConfigPeerKeyFileEnv(t *testing.T) {
// Ensures that a the Peer Key file flag can be parsed.
func TestConfigPeerKeyFileFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-serverKey", "/tmp/peer/file.key"}), "")
assert.Nil(t, c.LoadFlags([]string{"-peer-key-file", "/tmp/peer/file.key"}), "")
assert.Equal(t, c.Peer.KeyFile, "/tmp/peer/file.key", "")
}
// Ensures that the Peer Listen Host can be parsed from the environment.
func TestConfigPeerListenHostEnv(t *testing.T) {
withEnv("ETCD_PEER_LISTEN_HOST", "localhost:7004", func(c *Config) {
func TestConfigPeerBindAddrEnv(t *testing.T) {
withEnv("ETCD_PEER_BIND_ADDR", "localhost:7004", func(c *Config) {
assert.Nil(t, c.LoadEnv(), "")
assert.Equal(t, c.Peer.ListenHost, "localhost:7004", "")
assert.Equal(t, c.Peer.BindAddr, "localhost:7004", "")
})
}
// Ensures that a the Peer Listen Host file flag can be parsed.
func TestConfigPeerListenHostFlag(t *testing.T) {
func TestConfigPeerBindAddrFlag(t *testing.T) {
c := NewConfig()
assert.Nil(t, c.LoadFlags([]string{"-sl", "127.0.0.1:4003"}), "")
assert.Equal(t, c.Peer.ListenHost, "127.0.0.1:4003", "")
assert.Nil(t, c.LoadFlags([]string{"-peer-bind-addr", "127.0.0.1:4003"}), "")
assert.Equal(t, c.Peer.BindAddr, "127.0.0.1:4003", "")
}
// Ensures that a system config field is overridden by a custom config field.
func TestConfigCustomConfigOverrideSystemConfig(t *testing.T) {
system := `advertised_url = "127.0.0.1:5000"`
custom := `advertised_url = "127.0.0.1:6000"`
system := `addr = "127.0.0.1:5000"`
custom := `addr = "127.0.0.1:6000"`
withTempFile(system, func(p1 string) {
withTempFile(custom, func(p2 string) {
c := NewConfig()
c.SystemPath = p1
assert.Nil(t, c.Load([]string{"-config", p2}), "")
assert.Equal(t, c.AdvertisedUrl, "http://127.0.0.1:6000", "")
assert.Equal(t, c.Addr, "http://127.0.0.1:6000", "")
})
})
}
// Ensures that a custom config field is overridden by an environment variable.
func TestConfigEnvVarOverrideCustomConfig(t *testing.T) {
os.Setenv("ETCD_PEER_ADVERTISED_URL", "127.0.0.1:8000")
defer os.Setenv("ETCD_PEER_ADVERTISED_URL", "")
os.Setenv("ETCD_PEER_ADDR", "127.0.0.1:8000")
defer os.Setenv("ETCD_PEER_ADDR", "")
custom := `[peer]`+"\n"+`advertised_url = "127.0.0.1:9000"`
custom := `[peer]` + "\n" + `advertised_url = "127.0.0.1:9000"`
withTempFile(custom, func(path string) {
c := NewConfig()
c.SystemPath = ""
assert.Nil(t, c.Load([]string{"-config", path}), "")
assert.Equal(t, c.Peer.AdvertisedUrl, "http://127.0.0.1:8000", "")
assert.Equal(t, c.Peer.Addr, "http://127.0.0.1:8000", "")
})
}
// Ensures that an environment variable field is overridden by a command line argument.
func TestConfigCLIArgsOverrideEnvVar(t *testing.T) {
os.Setenv("ETCD_ADVERTISED_URL", "127.0.0.1:1000")
defer os.Setenv("ETCD_ADVERTISED_URL", "")
os.Setenv("ETCD_ADDR", "127.0.0.1:1000")
defer os.Setenv("ETCD_ADDR", "")
c := NewConfig()
c.SystemPath = ""
assert.Nil(t, c.Load([]string{"-c", "127.0.0.1:2000"}), "")
assert.Equal(t, c.AdvertisedUrl, "http://127.0.0.1:2000", "")
assert.Nil(t, c.Load([]string{"-addr", "127.0.0.1:2000"}), "")
assert.Equal(t, c.Addr, "http://127.0.0.1:2000", "")
}
//--------------------------------------
// Helpers
//--------------------------------------

View File

@ -16,4 +16,3 @@ type Info struct {
RaftTLS TLSInfo `json:"raftTLS"`
EtcdTLS TLSInfo `json:"etcdTLS"`
}

View File

@ -46,18 +46,18 @@ func (c *JoinCommand) Apply(server raft.Server) (interface{}, error) {
// Make sure we're not getting a cached value from the registry.
ps.registry.Invalidate(c.Name)
// Check if the join command is from a previous machine, who lost all its previous log.
// Check if the join command is from a previous peer, who lost all its previous log.
if _, ok := ps.registry.ClientURL(c.Name); ok {
return b, nil
}
// Check machine number in the cluster
// Check peer number in the cluster
if ps.registry.Count() == ps.MaxClusterSize {
log.Debug("Reject join request from ", c.Name)
return []byte{0}, etcdErr.NewError(etcdErr.EcodeNoMoreMachine, "", server.CommitIndex())
return []byte{0}, etcdErr.NewError(etcdErr.EcodeNoMorePeer, "", server.CommitIndex())
}
// Add to shared machine registry.
// Add to shared peer registry.
ps.registry.Register(c.Name, c.RaftURL, c.EtcdURL)
// Add peer in raft

View File

@ -28,7 +28,7 @@ type PeerServer struct {
joinIndex uint64
name string
url string
listenHost string
bindAddr string
tlsConf *TLSConfig
tlsInfo *TLSInfo
followersStats *raftFollowersStats
@ -53,16 +53,16 @@ type snapshotConf struct {
writesThr uint64
}
func NewPeerServer(name string, path string, url string, listenHost string, tlsConf *TLSConfig, tlsInfo *TLSInfo, registry *Registry, store store.Store, snapCount int) *PeerServer {
func NewPeerServer(name string, path string, url string, bindAddr string, tlsConf *TLSConfig, tlsInfo *TLSInfo, registry *Registry, store store.Store, snapshotCount int) *PeerServer {
s := &PeerServer{
name: name,
url: url,
listenHost: listenHost,
tlsConf: tlsConf,
tlsInfo: tlsInfo,
registry: registry,
store: store,
snapConf: &snapshotConf{time.Second * 3, 0, uint64(snapCount)},
name: name,
url: url,
bindAddr: bindAddr,
tlsConf: tlsConf,
tlsInfo: tlsInfo,
registry: registry,
store: store,
snapConf: &snapshotConf{time.Second * 3, 0, uint64(snapshotCount)},
followersStats: &raftFollowersStats{
Leader: name,
Followers: make(map[string]*raftFollowerStats),
@ -130,7 +130,7 @@ func (s *PeerServer) ListenAndServe(snapshot bool, cluster []string) error {
}
ok := s.joinCluster(cluster)
if !ok {
log.Warn("the entire cluster is down! this machine will restart the cluster.")
log.Warn("the entire cluster is down! this peer will restart the cluster.")
}
log.Debugf("%s restart as a follower", s.name)
@ -228,23 +228,23 @@ func (s *PeerServer) startAsFollower(cluster []string) {
if ok {
return
}
log.Warnf("cannot join to cluster via given machines, retry in %d seconds", RetryInterval)
log.Warnf("cannot join to cluster via given peers, retry in %d seconds", RetryInterval)
time.Sleep(time.Second * RetryInterval)
}
log.Fatalf("Cannot join the cluster via given machines after %x retries", s.RetryTimes)
log.Fatalf("Cannot join the cluster via given peers after %x retries", s.RetryTimes)
}
// Start to listen and response raft command
func (s *PeerServer) startTransport(scheme string, tlsConf tls.Config) error {
log.Infof("raft server [name %s, listen on %s, advertised url %s]", s.name, s.listenHost, s.url)
log.Infof("raft server [name %s, listen on %s, advertised url %s]", s.name, s.bindAddr, s.url)
router := mux.NewRouter()
s.httpServer = &http.Server{
Handler: router,
TLSConfig: &tlsConf,
Addr: s.listenHost,
Addr: s.bindAddr,
}
// internal commands
@ -312,14 +312,14 @@ func (s *PeerServer) Upgradable() error {
}
func (s *PeerServer) joinCluster(cluster []string) bool {
for _, machine := range cluster {
if len(machine) == 0 {
for _, peer := range cluster {
if len(peer) == 0 {
continue
}
err := s.joinByMachine(s.raftServer, machine, s.tlsConf.Scheme)
err := s.joinByPeer(s.raftServer, peer, s.tlsConf.Scheme)
if err == nil {
log.Debugf("%s success join to the cluster via machine %s", s.name, machine)
log.Debugf("%s success join to the cluster via peer %s", s.name, peer)
return true
} else {
@ -327,21 +327,21 @@ func (s *PeerServer) joinCluster(cluster []string) bool {
log.Fatal(err)
}
log.Debugf("cannot join to cluster via machine %s %s", machine, err)
log.Debugf("cannot join to cluster via peer %s %s", peer, err)
}
}
return false
}
// Send join requests to machine.
func (s *PeerServer) joinByMachine(server raft.Server, machine string, scheme string) error {
// Send join requests to peer.
func (s *PeerServer) joinByPeer(server raft.Server, peer string, scheme string) error {
var b bytes.Buffer
// t must be ok
t, _ := server.Transporter().(*transporter)
// Our version must match the leaders version
versionURL := url.URL{Host: machine, Scheme: scheme, Path: "/version"}
versionURL := url.URL{Host: peer, Scheme: scheme, Path: "/version"}
version, err := getVersion(t, versionURL)
if err != nil {
return fmt.Errorf("Error during join version check: %v", err)
@ -352,7 +352,7 @@ func (s *PeerServer) joinByMachine(server raft.Server, machine string, scheme st
json.NewEncoder(&b).Encode(NewJoinCommand(store.MinVersion(), store.MaxVersion(), server.Name(), s.url, s.server.URL()))
joinURL := url.URL{Host: machine, Scheme: scheme, Path: "/join"}
joinURL := url.URL{Host: peer, Scheme: scheme, Path: "/join"}
log.Debugf("Send Join Request to %s", joinURL.String())
@ -379,7 +379,7 @@ func (s *PeerServer) joinByMachine(server raft.Server, machine string, scheme st
resp, req, err = t.Post(address, &b)
} else if resp.StatusCode == http.StatusBadRequest {
log.Debug("Reach max number machines in the cluster")
log.Debug("Reach max number peers in the cluster")
decoder := json.NewDecoder(resp.Body)
err := &etcdErr.Error{}
decoder.Decode(err)

View File

@ -12,7 +12,7 @@ import (
"github.com/coreos/etcd/store"
)
// The location of the machine URL data.
// The location of the peer URL data.
const RegistryKey = "/_etcd/machines"
// The Registry stores URL information for nodes.
@ -168,7 +168,7 @@ func (r *Registry) load(name string) {
// Parse as a query string.
m, err := url.ParseQuery(e.Value)
if err != nil {
panic(fmt.Sprintf("Failed to parse machines entry: %s", name))
panic(fmt.Sprintf("Failed to parse peers entry: %s", name))
}
// Create node.

View File

@ -36,12 +36,12 @@ type Server struct {
}
// Creates a new Server.
func New(name string, urlStr string, listenHost string, tlsConf *TLSConfig, tlsInfo *TLSInfo, peerServer *PeerServer, registry *Registry, store store.Store) *Server {
func New(name string, urlStr string, bindAddr string, tlsConf *TLSConfig, tlsInfo *TLSInfo, peerServer *PeerServer, registry *Registry, store store.Store) *Server {
s := &Server{
Server: http.Server{
Handler: mux.NewRouter(),
TLSConfig: &tlsConf.Server,
Addr: listenHost,
Addr: bindAddr,
},
name: name,
store: store,
@ -102,7 +102,8 @@ func (s *Server) installV1() {
s.handleFuncV1("/v1/keys/{key:.*}", v1.DeleteKeyHandler).Methods("DELETE")
s.handleFuncV1("/v1/watch/{key:.*}", v1.WatchKeyHandler).Methods("GET", "POST")
s.handleFunc("/v1/leader", s.GetLeaderHandler).Methods("GET")
s.handleFunc("/v1/machines", s.GetMachinesHandler).Methods("GET")
s.handleFunc("/v1/machines", s.GetPeersHandler).Methods("GET")
s.handleFunc("/v1/peers", s.GetPeersHandler).Methods("GET")
s.handleFunc("/v1/stats/self", s.GetStatsHandler).Methods("GET")
s.handleFunc("/v1/stats/leader", s.GetLeaderStatsHandler).Methods("GET")
s.handleFunc("/v1/stats/store", s.GetStoreStatsHandler).Methods("GET")
@ -114,7 +115,8 @@ func (s *Server) installV2() {
s.handleFuncV2("/v2/keys/{key:.*}", v2.PutHandler).Methods("PUT")
s.handleFuncV2("/v2/keys/{key:.*}", v2.DeleteHandler).Methods("DELETE")
s.handleFunc("/v2/leader", s.GetLeaderHandler).Methods("GET")
s.handleFunc("/v2/machines", s.GetMachinesHandler).Methods("GET")
s.handleFunc("/v2/machines", s.GetPeersHandler).Methods("GET")
s.handleFunc("/v2/peers", s.GetPeersHandler).Methods("GET")
s.handleFunc("/v2/stats/self", s.GetStatsHandler).Methods("GET")
s.handleFunc("/v2/stats/leader", s.GetLeaderStatsHandler).Methods("GET")
s.handleFunc("/v2/stats/store", s.GetStoreStatsHandler).Methods("GET")
@ -339,11 +341,11 @@ func (s *Server) GetLeaderHandler(w http.ResponseWriter, req *http.Request) erro
return nil
}
// Handler to return all the known machines in the current cluster.
func (s *Server) GetMachinesHandler(w http.ResponseWriter, req *http.Request) error {
machines := s.registry.ClientURLs(s.peerServer.RaftServer().Leader(), s.name)
// Handler to return all the known peers in the current cluster.
func (s *Server) GetPeersHandler(w http.ResponseWriter, req *http.Request) error {
peers := s.registry.ClientURLs(s.peerServer.RaftServer().Leader(), s.name)
w.WriteHeader(http.StatusOK)
w.Write([]byte(strings.Join(machines, ", ")))
w.Write([]byte(strings.Join(peers, ", ")))
return nil
}

View File

@ -32,7 +32,7 @@ func (info TLSInfo) Config() (TLSConfig, error) {
tlsCert, err := tls.LoadX509KeyPair(info.CertFile, info.KeyFile)
if err != nil {
return t, err
return t, err
}
t.Scheme = "https"

View File

@ -37,10 +37,10 @@ func redirect(hostname string, w http.ResponseWriter, req *http.Request) {
// slice of the substrings between the separator with all leading and trailing
// white space removed, as defined by Unicode.
func trimsplit(s, sep string) []string {
raw := strings.Split(s, ",")
trimmed := make([]string, 0)
for _, r := range raw {
trimmed = append(trimmed, strings.TrimSpace(r))
}
return trimmed
raw := strings.Split(s, ",")
trimmed := make([]string, 0)
for _, r := range raw {
trimmed = append(trimmed, strings.TrimSpace(r))
}
return trimmed
}

View File

@ -31,7 +31,7 @@ func TestInternalVersion(t *testing.T) {
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
args := []string{"etcd", "-n=node1", "-f", "-d=/tmp/node1", "-C=" + fakeURL.Host}
args := []string{"etcd", "-name=node1", "-force-config", "-data-dir=/tmp/node1", "-peers=" + fakeURL.Host}
process, err := os.StartProcess(EtcdBinPath, args, procAttr)
if err != nil {
@ -53,4 +53,3 @@ func TestInternalVersion(t *testing.T) {
return
}
}

View File

@ -55,9 +55,8 @@ func TestKillLeader(t *testing.T) {
totalTime += take
avgTime := totalTime / (time.Duration)(i+1)
fmt.Println("Total time:", totalTime, "; Avg time:", avgTime)
etcds[num], err = os.StartProcess(EtcdBinPath, argGroup[num], procAttr)
}
stop <- true
}

View File

@ -8,8 +8,8 @@ import (
"time"
)
// TestKillRandom kills random machines in the cluster and
// restart them after all other machines agree on the same leader
// TestKillRandom kills random peers in the cluster and
// restart them after all other peers agree on the same leader
func TestKillRandom(t *testing.T) {
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
@ -73,4 +73,3 @@ func TestKillRandom(t *testing.T) {
stop <- true
}

View File

@ -55,4 +55,3 @@ func TestMultiNodeKillOne(t *testing.T) {
stop <- true
<-stop
}

View File

@ -42,7 +42,7 @@ func TestRemoveNode(t *testing.T) {
}
if len(resp) != 2 {
t.Fatal("cannot remove machine")
t.Fatal("cannot remove peer")
}
if i == 1 {
@ -50,7 +50,7 @@ func TestRemoveNode(t *testing.T) {
etcds[2], err = os.StartProcess(EtcdBinPath, argGroup[2], procAttr)
} else {
// rejoin without log
etcds[2], err = os.StartProcess(EtcdBinPath, append(argGroup[2], "-f"), procAttr)
etcds[2], err = os.StartProcess(EtcdBinPath, append(argGroup[2], "-force-config"), procAttr)
}
if err != nil {
@ -66,7 +66,7 @@ func TestRemoveNode(t *testing.T) {
}
if len(resp) != 3 {
t.Fatalf("add machine fails #1 (%d != 3)", len(resp))
t.Fatalf("add peer fails #1 (%d != 3)", len(resp))
}
}
@ -85,7 +85,7 @@ func TestRemoveNode(t *testing.T) {
}
if len(resp) != 2 {
t.Fatal("cannot remove machine")
t.Fatal("cannot remove peer")
}
if i == 1 {
@ -93,7 +93,7 @@ func TestRemoveNode(t *testing.T) {
etcds[2], err = os.StartProcess(EtcdBinPath, append(argGroup[2]), procAttr)
} else {
// rejoin without log
etcds[2], err = os.StartProcess(EtcdBinPath, append(argGroup[2], "-f"), procAttr)
etcds[2], err = os.StartProcess(EtcdBinPath, append(argGroup[2], "-force-config"), procAttr)
}
if err != nil {
@ -109,7 +109,7 @@ func TestRemoveNode(t *testing.T) {
}
if len(resp) != 3 {
t.Fatalf("add machine fails #2 (%d != 3)", len(resp))
t.Fatalf("add peer fails #2 (%d != 3)", len(resp))
}
}
}

View File

@ -14,9 +14,9 @@ import (
func TestSimpleSnapshot(t *testing.T) {
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
args := []string{"etcd", "-n=node1", "-d=/tmp/node1", "-snapshot=true", "-snapshotCount=500"}
args := []string{"etcd", "-name=node1", "-data-dir=/tmp/node1", "-snapshot=true", "-snapshot-count=500"}
process, err := os.StartProcess(EtcdBinPath, append(args, "-f"), procAttr)
process, err := os.StartProcess(EtcdBinPath, append(args, "-force-config"), procAttr)
if err != nil {
t.Fatal("start process failed:" + err.Error())
}

View File

@ -13,9 +13,9 @@ import (
func TestSingleNodeRecovery(t *testing.T) {
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
args := []string{"etcd", "-n=node1", "-d=/tmp/node1"}
args := []string{"etcd", "-name=node1", "-data-dir=/tmp/node1"}
process, err := os.StartProcess(EtcdBinPath, append(args, "-f"), procAttr)
process, err := os.StartProcess(EtcdBinPath, append(args, "-force-config"), procAttr)
if err != nil {
t.Fatal("start process failed:" + err.Error())
return
@ -65,4 +65,3 @@ func TestSingleNodeRecovery(t *testing.T) {
t.Fatalf("Recovery Get failed with %s %s %v", result.Key, result.Value, result.TTL)
}
}

View File

@ -12,7 +12,7 @@ import (
func TestSingleNode(t *testing.T) {
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
args := []string{"etcd", "-n=node1", "-f", "-d=/tmp/node1"}
args := []string{"etcd", "-name=node1", "-force-config", "-data-dir=/tmp/node1"}
process, err := os.StartProcess(EtcdBinPath, args, procAttr)
if err != nil {
@ -74,4 +74,3 @@ func TestSingleNode(t *testing.T) {
t.Fatalf("Set 5 expecting error when setting key with blank (incorrect) previous value")
}
}

View File

@ -73,25 +73,25 @@ func Set(stop chan bool) {
func CreateCluster(size int, procAttr *os.ProcAttr, ssl bool) ([][]string, []*os.Process, error) {
argGroup := make([][]string, size)
sslServer1 := []string{"-serverCAFile=../../fixtures/ca/ca.crt",
"-serverCert=../../fixtures/ca/server.crt",
"-serverKey=../../fixtures/ca/server.key.insecure",
sslServer1 := []string{"-peer-ca-file=../../fixtures/ca/ca.crt",
"-peer-cert-file=../../fixtures/ca/server.crt",
"-peer-key-file=../../fixtures/ca/server.key.insecure",
}
sslServer2 := []string{"-serverCAFile=../../fixtures/ca/ca.crt",
"-serverCert=../../fixtures/ca/server2.crt",
"-serverKey=../../fixtures/ca/server2.key.insecure",
sslServer2 := []string{"-peer-ca-file=../../fixtures/ca/ca.crt",
"-peer-cert-file=../../fixtures/ca/server2.crt",
"-peer-cert-file=../../fixtures/ca/server2.key.insecure",
}
for i := 0; i < size; i++ {
if i == 0 {
argGroup[i] = []string{"etcd", "-d=/tmp/node1", "-n=node1"}
argGroup[i] = []string{"etcd", "-data-dir=/tmp/node1", "-name=node1"}
if ssl {
argGroup[i] = append(argGroup[i], sslServer1...)
}
} else {
strI := strconv.Itoa(i + 1)
argGroup[i] = []string{"etcd", "-n=node" + strI, "-c=127.0.0.1:400" + strI, "-s=127.0.0.1:700" + strI, "-d=/tmp/node" + strI, "-C=127.0.0.1:7001"}
argGroup[i] = []string{"etcd", "-name=node" + strI, "-addr=127.0.0.1:400" + strI, "-peer-addr=127.0.0.1:700" + strI, "-data-dir=/tmp/node" + strI, "-peers=127.0.0.1:7001"}
if ssl {
argGroup[i] = append(argGroup[i], sslServer2...)
}
@ -102,7 +102,7 @@ func CreateCluster(size int, procAttr *os.ProcAttr, ssl bool) ([][]string, []*os
for i, _ := range etcds {
var err error
etcds[i], err = os.StartProcess(EtcdBinPath, append(argGroup[i], "-f"), procAttr)
etcds[i], err = os.StartProcess(EtcdBinPath, append(argGroup[i], "-force-config"), procAttr)
if err != nil {
return nil, nil, err
}

View File

@ -33,9 +33,9 @@ func TestV1SoloMigration(t *testing.T) {
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
args := []string{"etcd", fmt.Sprintf("-d=%s", nodepath)}
args = append(args, "-c", "127.0.0.1:4001")
args = append(args, "-s", "127.0.0.1:7001")
args := []string{"etcd", fmt.Sprintf("-data-dir=%s", nodepath)}
args = append(args, "-addr", "127.0.0.1:4001")
args = append(args, "-peer-addr", "127.0.0.1:7001")
process, err := os.StartProcess(EtcdBinPath, args, procAttr)
if err != nil {
t.Fatal("start process failed:" + err.Error())
@ -75,9 +75,9 @@ func TestV1ClusterMigration(t *testing.T) {
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
args := []string{"etcd", fmt.Sprintf("-d=%s", nodepath)}
args = append(args, "-c", fmt.Sprintf("127.0.0.1:%d", 4001 + i))
args = append(args, "-s", fmt.Sprintf("127.0.0.1:%d", 7001 + i))
args := []string{"etcd", fmt.Sprintf("-data-dir=%s", nodepath)}
args = append(args, "-addr", fmt.Sprintf("127.0.0.1:%d", 4001+i))
args = append(args, "-peer-addr", fmt.Sprintf("127.0.0.1:%d", 7001+i))
process, err := os.StartProcess(EtcdBinPath, args, procAttr)
if err != nil {
t.Fatal("start process failed:" + err.Error())
@ -91,7 +91,7 @@ func TestV1ClusterMigration(t *testing.T) {
resp, err := tests.Get("http://localhost:4001/v2/keys/message")
body := tests.ReadBody(resp)
assert.Nil(t, err, "")
assert.Equal(t, resp.StatusCode, 400, )
assert.Equal(t, resp.StatusCode, 400)
assert.Equal(t, string(body), `{"errorCode":100,"message":"Key Not Found","cause":"/message","index":11}`+"\n")
// Ensure TTL'd message is removed.

View File

@ -11,7 +11,7 @@ import (
func TestVersionCheck(t *testing.T) {
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
args := []string{"etcd", "-n=node1", "-f", "-d=/tmp/version_check"}
args := []string{"etcd", "-name=node1", "-force-config", "-data-dir=/tmp/version_check"}
process, err := os.StartProcess(EtcdBinPath, args, procAttr)
if err != nil {
@ -43,4 +43,3 @@ func TestVersionCheck(t *testing.T) {
t.Fatal("Invalid version check: ", resp.StatusCode)
}
}

View File

@ -63,7 +63,6 @@ func DeleteForm(url string, data url.Values) (*http.Response, error) {
return Delete(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
}
func send(method string, url string, bodyType string, body io.Reader) (*http.Response, error) {
c := NewHTTPClient()
req, err := http.NewRequest(method, url, body)

View File

@ -2,7 +2,7 @@ package mock
import (
"net/http"
"github.com/coreos/etcd/store"
"github.com/coreos/go-raft"
"github.com/stretchr/testify/mock"

View File

@ -10,10 +10,10 @@ import (
)
const (
testName = "ETCDTEST"
testClientURL = "localhost:4401"
testRaftURL = "localhost:7701"
testSnapCount = 10000
testName = "ETCDTEST"
testClientURL = "localhost:4401"
testRaftURL = "localhost:7701"
testSnapshotCount = 10000
)
// Starts a server in a temporary directory.
@ -23,7 +23,7 @@ func RunServer(f func(*server.Server)) {
store := store.New()
registry := server.NewRegistry(store)
ps := server.NewPeerServer(testName, path, testRaftURL, testRaftURL, &server.TLSConfig{Scheme: "http"}, &server.TLSInfo{}, registry, store, testSnapCount)
ps := server.NewPeerServer(testName, path, testRaftURL, testRaftURL, &server.TLSConfig{Scheme: "http"}, &server.TLSInfo{}, registry, store, testSnapshotCount)
s := server.New(testName, testClientURL, testClientURL, &server.TLSConfig{Scheme: "http"}, &server.TLSInfo{}, ps, registry, store)
ps.SetServer(s)