etcd.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. //------------------------------------------------------------------------------
  88. //
  89. // Variables
  90. //
  91. //------------------------------------------------------------------------------
  92. var etcdStore *store.Store
  93. //------------------------------------------------------------------------------
  94. //
  95. // Functions
  96. //
  97. //------------------------------------------------------------------------------
  98. //--------------------------------------
  99. // Main
  100. //--------------------------------------
  101. func main() {
  102. flag.Parse()
  103. if cpuprofile != "" {
  104. runCPUProfile()
  105. }
  106. if veryVerbose {
  107. verbose = true
  108. raft.SetLogLevel(raft.Debug)
  109. }
  110. if machines != "" {
  111. cluster = strings.Split(machines, ",")
  112. } else if machinesFile != "" {
  113. b, err := ioutil.ReadFile(machinesFile)
  114. if err != nil {
  115. fatalf("Unable to read the given machines file: %s", err)
  116. }
  117. cluster = strings.Split(string(b), ",")
  118. }
  119. // Check TLS arguments
  120. raftTLSConfig, ok := tlsConfigFromInfo(argInfo.RaftTLS)
  121. if !ok {
  122. fatal("Please specify cert and key file or cert and key file and CAFile or none of the three")
  123. }
  124. etcdTLSConfig, ok := tlsConfigFromInfo(argInfo.EtcdTLS)
  125. if !ok {
  126. fatal("Please specify cert and key file or cert and key file and CAFile or none of the three")
  127. }
  128. argInfo.Name = strings.TrimSpace(argInfo.Name)
  129. if argInfo.Name == "" {
  130. fatal("ERROR: server name required. e.g. '-n=server_name'")
  131. }
  132. // Check host name arguments
  133. argInfo.RaftURL = sanitizeURL(argInfo.RaftURL, raftTLSConfig.Scheme)
  134. argInfo.EtcdURL = sanitizeURL(argInfo.EtcdURL, etcdTLSConfig.Scheme)
  135. argInfo.WebURL = sanitizeURL(argInfo.WebURL, "http")
  136. // Read server info from file or grab it from user.
  137. if err := os.MkdirAll(dirPath, 0744); err != nil {
  138. fatalf("Unable to create path: %s", err)
  139. }
  140. info := getInfo(dirPath)
  141. // Create etcd key-value store
  142. etcdStore = store.CreateStore(maxSize)
  143. snapConf = newSnapshotConf()
  144. // Create etcd and raft server
  145. e = newEtcdServer(info.Name, info.EtcdURL, &etcdTLSConfig, &info.EtcdTLS)
  146. r = newRaftServer(info.Name, info.RaftURL, &raftTLSConfig, &info.RaftTLS)
  147. startWebInterface()
  148. r.ListenAndServe()
  149. e.ListenAndServe()
  150. }