etcd.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package main
  2. import (
  3. "crypto/tls"
  4. "flag"
  5. "github.com/coreos/etcd/store"
  6. "github.com/coreos/go-raft"
  7. "io/ioutil"
  8. "os"
  9. "strings"
  10. "time"
  11. )
  12. //------------------------------------------------------------------------------
  13. //
  14. // Initialization
  15. //
  16. //------------------------------------------------------------------------------
  17. var (
  18. verbose bool
  19. veryVerbose bool
  20. machines string
  21. machinesFile string
  22. cluster []string
  23. argInfo Info
  24. dirPath string
  25. force bool
  26. maxSize int
  27. snapshot bool
  28. retryTimes int
  29. maxClusterSize int
  30. cpuprofile string
  31. )
  32. func init() {
  33. flag.BoolVar(&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 hostname:port for etcd client communication")
  39. flag.StringVar(&argInfo.RaftURL, "s", "127.0.0.1:7001", "the hostname:port for raft server communication")
  40. flag.StringVar(&argInfo.WebURL, "w", "", "the hostname:port of web interface")
  41. flag.StringVar(&argInfo.RaftTLS.CAFile, "serverCAFile", "", "the path of the CAFile")
  42. flag.StringVar(&argInfo.RaftTLS.CertFile, "serverCert", "", "the cert file of the server")
  43. flag.StringVar(&argInfo.RaftTLS.KeyFile, "serverKey", "", "the key file of the server")
  44. flag.StringVar(&argInfo.EtcdTLS.CAFile, "clientCAFile", "", "the path of the client CAFile")
  45. flag.StringVar(&argInfo.EtcdTLS.CertFile, "clientCert", "", "the cert file of the client")
  46. flag.StringVar(&argInfo.EtcdTLS.KeyFile, "clientKey", "", "the key file of the client")
  47. flag.StringVar(&dirPath, "d", ".", "the directory to store log and snapshot")
  48. flag.BoolVar(&force, "f", false, "force new node configuration if existing is found (WARNING: data loss!)")
  49. flag.BoolVar(&snapshot, "snapshot", false, "open or close snapshot")
  50. flag.IntVar(&maxSize, "m", 1024, "the max size of result buffer")
  51. flag.IntVar(&retryTimes, "r", 3, "the max retry attempts when trying to join a cluster")
  52. flag.IntVar(&maxClusterSize, "maxsize", 9, "the max size of the cluster")
  53. flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to file")
  54. }
  55. const (
  56. ElectionTimeout = 200 * time.Millisecond
  57. HeartbeatTimeout = 50 * time.Millisecond
  58. // Timeout for internal raft http connection
  59. // The original timeout for http is 45 seconds
  60. // which is too long for our usage.
  61. HTTPTimeout = 10 * time.Second
  62. RetryInterval = 10
  63. )
  64. //------------------------------------------------------------------------------
  65. //
  66. // Typedefs
  67. //
  68. //------------------------------------------------------------------------------
  69. type TLSInfo struct {
  70. CertFile string `json:"CertFile"`
  71. KeyFile string `json:"KeyFile"`
  72. CAFile string `json:"CAFile"`
  73. }
  74. type Info struct {
  75. Name string `json:"name"`
  76. RaftURL string `json:"raftURL"`
  77. EtcdURL string `json:"etcdURL"`
  78. WebURL string `json:"webURL"`
  79. RaftTLS TLSInfo `json:"raftTLS"`
  80. EtcdTLS TLSInfo `json:"etcdTLS"`
  81. }
  82. type TLSConfig struct {
  83. Scheme string
  84. Server tls.Config
  85. Client tls.Config
  86. }
  87. type EtcdServer struct {
  88. }
  89. //------------------------------------------------------------------------------
  90. //
  91. // Variables
  92. //
  93. //------------------------------------------------------------------------------
  94. var etcdStore *store.Store
  95. //------------------------------------------------------------------------------
  96. //
  97. // Functions
  98. //
  99. //------------------------------------------------------------------------------
  100. //--------------------------------------
  101. // Main
  102. //--------------------------------------
  103. func main() {
  104. flag.Parse()
  105. if cpuprofile != "" {
  106. runCPUProfile()
  107. }
  108. if veryVerbose {
  109. verbose = true
  110. raft.SetLogLevel(raft.Debug)
  111. }
  112. if machines != "" {
  113. cluster = strings.Split(machines, ",")
  114. } else if machinesFile != "" {
  115. b, err := ioutil.ReadFile(machinesFile)
  116. if err != nil {
  117. fatalf("Unable to read the given machines file: %s", err)
  118. }
  119. cluster = strings.Split(string(b), ",")
  120. }
  121. // Check TLS arguments
  122. raftTLSConfig, ok := tlsConfigFromInfo(argInfo.RaftTLS)
  123. if !ok {
  124. fatal("Please specify cert and key file or cert and key file and CAFile or none of the three")
  125. }
  126. etcdTLSConfig, ok := tlsConfigFromInfo(argInfo.EtcdTLS)
  127. if !ok {
  128. fatal("Please specify cert and key file or cert and key file and CAFile or none of the three")
  129. }
  130. argInfo.Name = strings.TrimSpace(argInfo.Name)
  131. if argInfo.Name == "" {
  132. fatal("ERROR: server name required. e.g. '-n=server_name'")
  133. }
  134. // Check host name arguments
  135. argInfo.RaftURL = sanitizeURL(argInfo.RaftURL, raftTLSConfig.Scheme)
  136. argInfo.EtcdURL = sanitizeURL(argInfo.EtcdURL, etcdTLSConfig.Scheme)
  137. argInfo.WebURL = sanitizeURL(argInfo.WebURL, "http")
  138. // Read server info from file or grab it from user.
  139. if err := os.MkdirAll(dirPath, 0744); err != nil {
  140. fatalf("Unable to create path: %s", err)
  141. }
  142. info := getInfo(dirPath)
  143. // Create etcd key-value store
  144. etcdStore = store.CreateStore(maxSize)
  145. snapConf = newSnapshotConf()
  146. // Create etcd and raft server
  147. e = newEtcdServer(info.Name, info.EtcdURL, &etcdTLSConfig, &info.EtcdTLS)
  148. r = newRaftServer(info.Name, info.RaftURL, &raftTLSConfig, &info.RaftTLS)
  149. startWebInterface()
  150. r.start()
  151. e.start()
  152. }