mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Renamed configuration parameters.
This commit is contained in:
parent
3ce1132d5c
commit
cba2611c68
@ -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"]
|
||||
|
@ -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"
|
||||
|
@ -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`
|
||||
|
@ -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.
|
||||
|
42
README.md
42
README.md
@ -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?
|
||||
|
@ -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
12
etcd.go
@ -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())
|
||||
}
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -1,2 +1,3 @@
|
||||
package main
|
||||
|
||||
const releaseVersion = "v0.1.2-33-g1a2a9d6"
|
||||
|
@ -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
|
||||
|
125
server/config.go
125
server/config.go
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
//--------------------------------------
|
||||
|
@ -16,4 +16,3 @@ type Info struct {
|
||||
RaftTLS TLSInfo `json:"raftTLS"`
|
||||
EtcdTLS TLSInfo `json:"etcdTLS"`
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -55,4 +55,3 @@ func TestMultiNodeKillOne(t *testing.T) {
|
||||
stop <- true
|
||||
<-stop
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -2,7 +2,7 @@ package mock
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
|
||||
"github.com/coreos/etcd/store"
|
||||
"github.com/coreos/go-raft"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user