2013-06-09 21:42:34 +04:00
package main
import (
2014-09-03 00:48:38 +04:00
"flag"
2014-09-05 08:15:39 +04:00
"fmt"
2014-07-06 21:19:23 +04:00
"log"
"net/http"
2014-09-05 08:15:39 +04:00
"os"
2014-09-16 23:32:03 +04:00
"strings"
2014-01-18 22:09:54 +04:00
2014-09-03 08:36:14 +04:00
"github.com/coreos/etcd/etcdserver"
"github.com/coreos/etcd/etcdserver/etcdhttp"
2014-09-25 03:06:28 +04:00
"github.com/coreos/etcd/pkg"
2014-09-28 03:24:26 +04:00
flagtypes "github.com/coreos/etcd/pkg/flags"
2014-09-25 21:47:14 +04:00
"github.com/coreos/etcd/pkg/transport"
2014-09-10 22:19:11 +04:00
"github.com/coreos/etcd/proxy"
2014-09-03 00:48:38 +04:00
"github.com/coreos/etcd/raft"
2014-07-06 21:19:23 +04:00
)
2014-09-09 02:45:58 +04:00
const (
// the owner can make/remove files inside the directory
privateDirMode = 0700
2014-09-18 18:50:52 +04:00
2014-09-25 04:08:42 +04:00
version = "0.5.0-alpha"
2014-07-06 21:19:23 +04:00
)
2014-09-03 00:48:38 +04:00
var (
2014-09-25 06:51:27 +04:00
name = flag . String ( "name" , "default" , "Unique human-readable name for this node" )
2014-09-25 04:08:42 +04:00
dir = flag . String ( "data-dir" , "" , "Path to the data directory" )
2014-10-04 16:20:45 +04:00
durl = flag . String ( "discovery" , "" , "Discovery service used to bootstrap the cluster" )
2014-10-03 03:20:14 +04:00
snapCount = flag . Uint64 ( "snapshot-count" , etcdserver . DefaultSnapCount , "Number of committed transactions to trigger a snapshot" )
2014-09-25 04:08:42 +04:00
printVersion = flag . Bool ( "version" , false , "Print the version and exit" )
2014-09-05 22:59:23 +04:00
2014-10-04 00:10:34 +04:00
cluster = & etcdserver . Cluster { }
clusterState = new ( etcdserver . ClusterState )
2014-09-25 22:43:24 +04:00
cors = & pkg . CORSInfo { }
2014-09-28 03:24:26 +04:00
proxyFlag = new ( flagtypes . Proxy )
2014-09-23 03:50:26 +04:00
clientTLSInfo = transport . TLSInfo { }
2014-09-23 19:21:16 +04:00
peerTLSInfo = transport . TLSInfo { }
2014-09-24 22:28:41 +04:00
2014-10-07 01:06:51 +04:00
ignored = [ ] string {
2014-09-25 03:49:11 +04:00
"cluster-active-size" ,
"cluster-remove-delay" ,
"cluster-sync-interval" ,
2014-09-24 22:28:41 +04:00
"config" ,
2014-09-25 03:49:11 +04:00
"force" ,
2014-09-24 22:28:41 +04:00
"max-result-buffer" ,
"max-retry-attempts" ,
2014-09-25 03:49:11 +04:00
"peer-heartbeat-interval" ,
"peer-election-timeout" ,
2014-09-24 22:28:41 +04:00
"retry-interval" ,
"snapshot" ,
2014-09-25 03:44:32 +04:00
"v" ,
"vv" ,
2014-09-24 22:28:41 +04:00
}
2014-09-03 00:48:38 +04:00
)
2014-07-06 21:19:23 +04:00
2014-09-03 01:46:07 +04:00
func init ( ) {
2014-10-04 00:10:34 +04:00
flag . Var ( cluster , "initial-cluster" , "Initial cluster configuration for bootstrapping" )
2014-10-07 03:10:29 +04:00
if err := cluster . Set ( "default=http://localhost:2380,default=http://localhost:7001" ) ; err != nil {
// Should never happen
log . Panic ( err )
}
2014-10-07 04:28:17 +04:00
flag . Var ( clusterState , "initial-cluster-state" , "Initial cluster configuration for bootstrapping" )
clusterState . Set ( etcdserver . ClusterStateValueNew )
2014-10-01 02:49:13 +04:00
2014-10-02 00:12:24 +04:00
flag . Var ( flagtypes . NewURLsValue ( "http://localhost:2380,http://localhost:7001" ) , "advertise-peer-urls" , "List of this member's peer URLs to advertise to the rest of the cluster" )
flag . Var ( flagtypes . NewURLsValue ( "http://localhost:2379,http://localhost:4001" ) , "advertise-client-urls" , "List of this member's client URLs to advertise to the rest of the cluster" )
2014-10-14 01:52:49 +04:00
flag . Var ( flagtypes . NewURLsValue ( "http://localhost:2380,http://localhost:7001" ) , "listen-peer-urls" , "List of URLs to listen on for peer traffic" )
flag . Var ( flagtypes . NewURLsValue ( "http://localhost:2379,http://localhost:4001" ) , "listen-client-urls" , "List of URLs to listen on for client traffic" )
etcd: support v0.4.6 addr flags
The -addr, -bind-addr, -peer-addr, and peer-bind-addr flags are
superseded by -advertise-client-urls, -listen-client-urls,
-advertise-peer-urls, and -listen-peer-urls, respectively.
If any of the former flags are provided, however, they will still
work. If the new counterparts to the old flags are provided, etcd
will log an error and fail.
2014-10-01 22:46:24 +04:00
flag . Var ( cors , "cors" , "Comma-separated white list of origins for CORS (cross-origin resource sharing)." )
flag . Var ( proxyFlag , "proxy" , fmt . Sprintf ( "Valid values include %s" , strings . Join ( flagtypes . ProxyValues , ", " ) ) )
2014-09-28 03:24:26 +04:00
proxyFlag . Set ( flagtypes . ProxyValueOff )
2014-09-23 03:50:26 +04:00
flag . StringVar ( & clientTLSInfo . CAFile , "ca-file" , "" , "Path to the client server TLS CA file." )
flag . StringVar ( & clientTLSInfo . CertFile , "cert-file" , "" , "Path to the client server TLS cert file." )
flag . StringVar ( & clientTLSInfo . KeyFile , "key-file" , "" , "Path to the client server TLS key file." )
2014-09-23 19:21:16 +04:00
flag . StringVar ( & peerTLSInfo . CAFile , "peer-ca-file" , "" , "Path to the peer server TLS CA file." )
flag . StringVar ( & peerTLSInfo . CertFile , "peer-cert-file" , "" , "Path to the peer server TLS cert file." )
flag . StringVar ( & peerTLSInfo . KeyFile , "peer-key-file" , "" , "Path to the peer server TLS key file." )
2014-09-24 22:28:41 +04:00
etcd: support v0.4.6 addr flags
The -addr, -bind-addr, -peer-addr, and peer-bind-addr flags are
superseded by -advertise-client-urls, -listen-client-urls,
-advertise-peer-urls, and -listen-peer-urls, respectively.
If any of the former flags are provided, however, they will still
work. If the new counterparts to the old flags are provided, etcd
will log an error and fail.
2014-10-01 22:46:24 +04:00
// backwards-compatibility with v0.4.6
flag . Var ( & flagtypes . IPAddressPort { } , "addr" , "DEPRECATED: Use -advertise-client-urls instead." )
flag . Var ( & flagtypes . IPAddressPort { } , "bind-addr" , "DEPRECATED: Use -listen-client-urls instead." )
flag . Var ( & flagtypes . IPAddressPort { } , "peer-addr" , "DEPRECATED: Use -advertise-peer-urls instead." )
flag . Var ( & flagtypes . IPAddressPort { } , "peer-bind-addr" , "DEPRECATED: Use -listen-peer-urls instead." )
2014-10-07 01:06:51 +04:00
for _ , f := range ignored {
flag . Var ( & pkg . IgnoredFlag { f } , f , "" )
2014-09-24 22:28:41 +04:00
}
2014-10-07 01:06:51 +04:00
2014-10-14 01:52:49 +04:00
flag . Var ( & pkg . DeprecatedFlag { "peers" } , "peers" , "DEPRECATED: Use -initial-cluster instead" )
flag . Var ( & pkg . DeprecatedFlag { "peers-file" } , "peers-file" , "DEPRECATED: Use -initial-cluster instead" )
2014-09-03 01:46:07 +04:00
}
2014-09-03 00:48:38 +04:00
func main ( ) {
2014-10-07 01:06:51 +04:00
flag . Usage = pkg . UsageWithIgnoredFlagsFunc ( flag . CommandLine , ignored )
2014-09-03 02:04:57 +04:00
flag . Parse ( )
2014-09-25 04:08:42 +04:00
if * printVersion {
fmt . Println ( "etcd version" , version )
os . Exit ( 0 )
}
2014-09-25 03:29:47 +04:00
pkg . SetFlagsFromEnv ( flag . CommandLine )
2014-10-04 16:20:45 +04:00
if err := setClusterForDiscovery ( ) ; err != nil {
log . Fatalf ( "etcd: %v" , err )
}
2014-09-17 23:05:36 +04:00
2014-09-28 03:24:26 +04:00
if string ( * proxyFlag ) == flagtypes . ProxyValueOff {
2014-09-16 22:36:37 +04:00
startEtcd ( )
2014-09-18 18:50:52 +04:00
} else {
startProxy ( )
2014-09-10 22:19:11 +04:00
}
2014-09-16 23:32:03 +04:00
// Block indefinitely
<- make ( chan struct { } )
2014-09-10 22:06:31 +04:00
}
2014-09-16 22:36:37 +04:00
// startEtcd launches the etcd server and HTTP handlers for client/server communication.
func startEtcd ( ) {
2014-09-25 06:51:27 +04:00
self := cluster . FindName ( * name )
if self == nil {
log . Fatalf ( "etcd: no member with name=%q exists" , * name )
2014-09-15 09:44:59 +04:00
}
2014-09-03 00:48:38 +04:00
2014-09-25 06:51:27 +04:00
if self . ID == raft . None {
log . Fatalf ( "etcd: cannot use None(%d) as member id" , raft . None )
2014-09-03 02:15:10 +04:00
}
2014-09-05 08:15:39 +04:00
if * dir == "" {
2014-10-15 08:50:31 +04:00
* dir = fmt . Sprintf ( "%v_etcd_data" , self . Name )
2014-10-15 09:05:24 +04:00
log . Printf ( "etcd: no data-dir provided, using default data-dir ./%s" , * dir )
2014-09-05 08:15:39 +04:00
}
2014-09-09 02:45:58 +04:00
if err := os . MkdirAll ( * dir , privateDirMode ) ; err != nil {
2014-10-15 09:05:24 +04:00
log . Fatalf ( "etcd: cannot create data directory: %v" , err )
2014-09-05 08:15:39 +04:00
}
2014-09-03 02:57:15 +04:00
2014-09-23 19:21:16 +04:00
pt , err := transport . NewTransport ( peerTLSInfo )
2014-09-23 19:43:20 +04:00
if err != nil {
log . Fatal ( err )
2014-09-23 19:38:26 +04:00
}
2014-10-02 00:12:24 +04:00
acurls , err := pkg . URLsFromFlags ( flag . CommandLine , "advertise-client-urls" , "addr" , clientTLSInfo )
if err != nil {
log . Fatal ( err . Error ( ) )
}
2014-10-03 03:20:14 +04:00
cfg := & etcdserver . ServerConfig {
2014-10-04 16:20:45 +04:00
Name : * name ,
ClientURLs : acurls ,
DataDir : * dir ,
2014-10-08 15:58:53 +04:00
SnapCount : * snapCount ,
2014-10-04 16:20:45 +04:00
Cluster : cluster ,
DiscoveryURL : * durl ,
2014-10-04 00:10:34 +04:00
ClusterState : * clusterState ,
Transport : pt ,
2014-07-09 01:07:25 +04:00
}
2014-10-03 03:20:14 +04:00
s := etcdserver . NewServer ( cfg )
2014-09-30 04:14:22 +04:00
s . Start ( )
2014-09-16 22:36:37 +04:00
2014-09-25 22:43:24 +04:00
ch := & pkg . CORSHandler {
2014-10-04 00:47:34 +04:00
Handler : etcdhttp . NewClientHandler ( s ) ,
2014-09-20 01:58:00 +04:00
Info : cors ,
}
2014-09-25 22:58:11 +04:00
ph := etcdhttp . NewPeerHandler ( s )
2014-09-16 22:36:37 +04:00
2014-10-02 00:12:24 +04:00
lpurls , err := pkg . URLsFromFlags ( flag . CommandLine , "listen-peer-urls" , "peer-bind-addr" , peerTLSInfo )
etcd: support v0.4.6 addr flags
The -addr, -bind-addr, -peer-addr, and peer-bind-addr flags are
superseded by -advertise-client-urls, -listen-client-urls,
-advertise-peer-urls, and -listen-peer-urls, respectively.
If any of the former flags are provided, however, they will still
work. If the new counterparts to the old flags are provided, etcd
will log an error and fail.
2014-10-01 22:46:24 +04:00
if err != nil {
log . Fatal ( err . Error ( ) )
}
for _ , u := range lpurls {
2014-10-01 02:49:13 +04:00
l , err := transport . NewListener ( u . Host , peerTLSInfo )
if err != nil {
log . Fatal ( err )
}
2014-09-23 03:35:00 +04:00
2014-10-01 02:49:13 +04:00
// Start the peer server in a goroutine
2014-10-01 22:07:32 +04:00
urlStr := u . String ( )
2014-10-01 02:49:13 +04:00
go func ( ) {
2014-10-01 22:07:32 +04:00
log . Print ( "Listening for peers on " , urlStr )
2014-10-01 02:49:13 +04:00
log . Fatal ( http . Serve ( l , ph ) )
} ( )
}
2014-09-16 22:36:37 +04:00
etcd: support v0.4.6 addr flags
The -addr, -bind-addr, -peer-addr, and peer-bind-addr flags are
superseded by -advertise-client-urls, -listen-client-urls,
-advertise-peer-urls, and -listen-peer-urls, respectively.
If any of the former flags are provided, however, they will still
work. If the new counterparts to the old flags are provided, etcd
will log an error and fail.
2014-10-01 22:46:24 +04:00
lcurls , err := pkg . URLsFromFlags ( flag . CommandLine , "listen-client-urls" , "bind-addr" , clientTLSInfo )
if err != nil {
log . Fatal ( err . Error ( ) )
}
2014-09-16 23:32:03 +04:00
// Start a client server goroutine for each listen address
etcd: support v0.4.6 addr flags
The -addr, -bind-addr, -peer-addr, and peer-bind-addr flags are
superseded by -advertise-client-urls, -listen-client-urls,
-advertise-peer-urls, and -listen-peer-urls, respectively.
If any of the former flags are provided, however, they will still
work. If the new counterparts to the old flags are provided, etcd
will log an error and fail.
2014-10-01 22:46:24 +04:00
for _ , u := range lcurls {
2014-10-01 02:49:13 +04:00
l , err := transport . NewListener ( u . Host , clientTLSInfo )
2014-09-23 03:35:00 +04:00
if err != nil {
log . Fatal ( err )
}
2014-10-01 22:07:32 +04:00
urlStr := u . String ( )
2014-09-16 23:32:03 +04:00
go func ( ) {
2014-10-01 22:07:32 +04:00
log . Print ( "Listening for client requests on " , urlStr )
2014-09-23 03:35:00 +04:00
log . Fatal ( http . Serve ( l , ch ) )
2014-09-16 23:32:03 +04:00
} ( )
2014-09-16 22:36:37 +04:00
}
2014-07-09 01:07:25 +04:00
}
2014-09-05 21:16:55 +04:00
2014-09-16 23:32:03 +04:00
// startProxy launches an HTTP proxy for client communication which proxies to other etcd nodes.
2014-09-16 22:36:37 +04:00
func startProxy ( ) {
2014-09-23 21:19:01 +04:00
pt , err := transport . NewTransport ( clientTLSInfo )
2014-09-10 22:19:11 +04:00
if err != nil {
log . Fatal ( err )
}
2014-09-23 21:19:01 +04:00
2014-09-29 01:38:40 +04:00
ph , err := proxy . NewHandler ( pt , ( * cluster ) . PeerURLs ( ) )
2014-09-23 21:19:01 +04:00
if err != nil {
log . Fatal ( err )
}
2014-09-25 22:43:24 +04:00
ph = & pkg . CORSHandler {
2014-09-20 01:58:00 +04:00
Handler : ph ,
Info : cors ,
}
2014-09-18 21:34:16 +04:00
2014-09-28 03:24:26 +04:00
if string ( * proxyFlag ) == flagtypes . ProxyValueReadonly {
2014-09-18 21:34:16 +04:00
ph = proxy . NewReadonlyHandler ( ph )
}
etcd: support v0.4.6 addr flags
The -addr, -bind-addr, -peer-addr, and peer-bind-addr flags are
superseded by -advertise-client-urls, -listen-client-urls,
-advertise-peer-urls, and -listen-peer-urls, respectively.
If any of the former flags are provided, however, they will still
work. If the new counterparts to the old flags are provided, etcd
will log an error and fail.
2014-10-01 22:46:24 +04:00
lcurls , err := pkg . URLsFromFlags ( flag . CommandLine , "listen-client-urls" , "bind-addr" , clientTLSInfo )
if err != nil {
log . Fatal ( err . Error ( ) )
}
2014-09-16 23:32:03 +04:00
// Start a proxy server goroutine for each listen address
etcd: support v0.4.6 addr flags
The -addr, -bind-addr, -peer-addr, and peer-bind-addr flags are
superseded by -advertise-client-urls, -listen-client-urls,
-advertise-peer-urls, and -listen-peer-urls, respectively.
If any of the former flags are provided, however, they will still
work. If the new counterparts to the old flags are provided, etcd
will log an error and fail.
2014-10-01 22:46:24 +04:00
for _ , u := range lcurls {
2014-10-01 02:49:13 +04:00
l , err := transport . NewListener ( u . Host , clientTLSInfo )
2014-09-23 03:35:00 +04:00
if err != nil {
log . Fatal ( err )
}
2014-10-01 22:07:32 +04:00
host := u . Host
2014-09-16 23:32:03 +04:00
go func ( ) {
2014-10-01 22:07:32 +04:00
log . Print ( "Listening for client requests on " , host )
2014-09-23 03:35:00 +04:00
log . Fatal ( http . Serve ( l , ph ) )
2014-09-16 23:32:03 +04:00
} ( )
}
}
2014-10-04 16:20:45 +04:00
// setClusterForDiscovery sets cluster to a temporary value if you are using
// the discovery.
func setClusterForDiscovery ( ) error {
set := make ( map [ string ] bool )
flag . Visit ( func ( f * flag . Flag ) {
set [ f . Name ] = true
} )
2014-10-14 01:52:49 +04:00
if set [ "discovery" ] && set [ "initial-cluster" ] {
return fmt . Errorf ( "both discovery and initial-cluster are set" )
2014-10-04 16:20:45 +04:00
}
if set [ "discovery" ] {
2014-10-17 07:06:26 +04:00
apurls , err := pkg . URLsFromFlags ( flag . CommandLine , "advertise-peer-urls" , "peer-addr" , peerTLSInfo )
2014-10-04 16:20:45 +04:00
if err != nil {
return err
}
addrs := make ( [ ] string , len ( apurls ) )
for i := range apurls {
2014-10-07 03:10:29 +04:00
addrs [ i ] = fmt . Sprintf ( "%s=%s" , * name , apurls [ i ] . String ( ) )
}
if err := cluster . Set ( strings . Join ( addrs , "," ) ) ; err != nil {
return err
2014-10-04 16:20:45 +04:00
}
}
return nil
}