etcd.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. package main
  2. import (
  3. "flag"
  4. "io/ioutil"
  5. "os"
  6. "strings"
  7. "github.com/coreos/etcd/log"
  8. "github.com/coreos/etcd/server"
  9. "github.com/coreos/etcd/store"
  10. "github.com/coreos/go-raft"
  11. )
  12. //------------------------------------------------------------------------------
  13. //
  14. // Initialization
  15. //
  16. //------------------------------------------------------------------------------
  17. var (
  18. veryVerbose bool
  19. machines string
  20. machinesFile string
  21. cluster []string
  22. argInfo Info
  23. dirPath string
  24. force bool
  25. maxSize int
  26. snapshot bool
  27. retryTimes int
  28. maxClusterSize int
  29. cpuprofile string
  30. cors string
  31. )
  32. func init() {
  33. flag.BoolVar(&log.Verbose, "v", false, "verbose logging")
  34. flag.BoolVar(&veryVerbose, "vv", false, "very verbose logging")
  35. flag.StringVar(&machines, "C", "", "the ip address and port of a existing machines in the cluster, sepearate by comma")
  36. flag.StringVar(&machinesFile, "CF", "", "the file contains a list of existing machines in the cluster, seperate by comma")
  37. flag.StringVar(&argInfo.Name, "n", "default-name", "the node name (required)")
  38. flag.StringVar(&argInfo.EtcdURL, "c", "127.0.0.1:4001", "the advertised public hostname:port for etcd client communication")
  39. flag.StringVar(&argInfo.RaftURL, "s", "127.0.0.1:7001", "the advertised public hostname:port for raft server communication")
  40. flag.StringVar(&argInfo.EtcdListenHost, "cl", "", "the listening hostname for etcd client communication (defaults to advertised ip)")
  41. flag.StringVar(&argInfo.RaftListenHost, "sl", "", "the listening hostname for raft server communication (defaults to advertised ip)")
  42. flag.StringVar(&argInfo.WebURL, "w", "", "the hostname:port of web interface")
  43. flag.StringVar(&argInfo.RaftTLS.CAFile, "serverCAFile", "", "the path of the CAFile")
  44. flag.StringVar(&argInfo.RaftTLS.CertFile, "serverCert", "", "the cert file of the server")
  45. flag.StringVar(&argInfo.RaftTLS.KeyFile, "serverKey", "", "the key file of the server")
  46. flag.StringVar(&argInfo.EtcdTLS.CAFile, "clientCAFile", "", "the path of the client CAFile")
  47. flag.StringVar(&argInfo.EtcdTLS.CertFile, "clientCert", "", "the cert file of the client")
  48. flag.StringVar(&argInfo.EtcdTLS.KeyFile, "clientKey", "", "the key file of the client")
  49. flag.StringVar(&dirPath, "d", ".", "the directory to store log and snapshot")
  50. flag.BoolVar(&force, "f", false, "force new node configuration if existing is found (WARNING: data loss!)")
  51. flag.BoolVar(&snapshot, "snapshot", false, "open or close snapshot")
  52. flag.IntVar(&maxSize, "m", 1024, "the max size of result buffer")
  53. flag.IntVar(&retryTimes, "r", 3, "the max retry attempts when trying to join a cluster")
  54. flag.IntVar(&maxClusterSize, "maxsize", 9, "the max size of the cluster")
  55. flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to file")
  56. flag.StringVar(&cors, "cors", "", "whitelist origins for cross-origin resource sharing (e.g. '*' or 'http://localhost:8001,etc')")
  57. }
  58. //------------------------------------------------------------------------------
  59. //
  60. // Typedefs
  61. //
  62. //------------------------------------------------------------------------------
  63. type Info struct {
  64. Name string `json:"name"`
  65. RaftURL string `json:"raftURL"`
  66. EtcdURL string `json:"etcdURL"`
  67. WebURL string `json:"webURL"`
  68. RaftListenHost string `json:"raftListenHost"`
  69. EtcdListenHost string `json:"etcdListenHost"`
  70. RaftTLS server.TLSInfo `json:"raftTLS"`
  71. EtcdTLS server.TLSInfo `json:"etcdTLS"`
  72. }
  73. //------------------------------------------------------------------------------
  74. //
  75. // Functions
  76. //
  77. //------------------------------------------------------------------------------
  78. //--------------------------------------
  79. // Main
  80. //--------------------------------------
  81. func main() {
  82. flag.Parse()
  83. if cpuprofile != "" {
  84. runCPUProfile()
  85. }
  86. if veryVerbose {
  87. log.Verbose = true
  88. raft.SetLogLevel(raft.Debug)
  89. }
  90. if machines != "" {
  91. cluster = strings.Split(machines, ",")
  92. } else if machinesFile != "" {
  93. b, err := ioutil.ReadFile(machinesFile)
  94. if err != nil {
  95. log.Fatalf("Unable to read the given machines file: %s", err)
  96. }
  97. cluster = strings.Split(string(b), ",")
  98. }
  99. // Check TLS arguments
  100. raftTLSConfig, ok := tlsConfigFromInfo(argInfo.RaftTLS)
  101. if !ok {
  102. log.Fatal("Please specify cert and key file or cert and key file and CAFile or none of the three")
  103. }
  104. etcdTLSConfig, ok := tlsConfigFromInfo(argInfo.EtcdTLS)
  105. if !ok {
  106. log.Fatal("Please specify cert and key file or cert and key file and CAFile or none of the three")
  107. }
  108. argInfo.Name = strings.TrimSpace(argInfo.Name)
  109. if argInfo.Name == "" {
  110. log.Fatal("ERROR: server name required. e.g. '-n=server_name'")
  111. }
  112. // Check host name arguments
  113. argInfo.RaftURL = sanitizeURL(argInfo.RaftURL, raftTLSConfig.Scheme)
  114. argInfo.EtcdURL = sanitizeURL(argInfo.EtcdURL, etcdTLSConfig.Scheme)
  115. argInfo.WebURL = sanitizeURL(argInfo.WebURL, "http")
  116. argInfo.RaftListenHost = sanitizeListenHost(argInfo.RaftListenHost, argInfo.RaftURL)
  117. argInfo.EtcdListenHost = sanitizeListenHost(argInfo.EtcdListenHost, argInfo.EtcdURL)
  118. // Read server info from file or grab it from user.
  119. if err := os.MkdirAll(dirPath, 0744); err != nil {
  120. log.Fatalf("Unable to create path: %s", err)
  121. }
  122. info := getInfo(dirPath)
  123. // Create etcd key-value store
  124. store := store.New()
  125. // Create a shared node registry.
  126. registry := server.NewRegistry(store)
  127. // Create peer server.
  128. ps := server.NewPeerServer(info.Name, dirPath, info.RaftURL, info.RaftListenHost, &raftTLSConfig, &info.RaftTLS, registry, store)
  129. ps.MaxClusterSize = maxClusterSize
  130. ps.RetryTimes = retryTimes
  131. s := server.New(info.Name, info.EtcdURL, info.EtcdListenHost, &etcdTLSConfig, &info.EtcdTLS, ps, registry, store)
  132. if err := s.AllowOrigins(cors); err != nil {
  133. panic(err)
  134. }
  135. ps.SetServer(s)
  136. ps.ListenAndServe(snapshot, cluster)
  137. s.ListenAndServe()
  138. }