You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
5.7 KiB

10 years ago
  1. package main
  2. import (
  3. "errors"
  4. "fmt"
  5. "io/ioutil"
  6. "net"
  7. "net/http"
  8. "os"
  9. "sync"
  10. "time"
  11. "github.com/tendermint/tendermint/binary"
  12. . "github.com/tendermint/tendermint/cmd/barak/types"
  13. . "github.com/tendermint/tendermint/common"
  14. pcm "github.com/tendermint/tendermint/process"
  15. "github.com/tendermint/tendermint/rpc/server"
  16. )
  17. type BarakOptions struct {
  18. Validators []Validator
  19. ListenAddress string
  20. StartNonce uint64
  21. Registries []string
  22. }
  23. // Read options from a file, or stdin if optionsFile is ""
  24. func ReadBarakOptions(optFile string) *BarakOptions {
  25. var optBytes []byte
  26. var err error
  27. if optFile != "" {
  28. optBytes, err = ioutil.ReadFile(optFile)
  29. } else {
  30. optBytes, err = ioutil.ReadAll(os.Stdin)
  31. }
  32. if err != nil {
  33. panic(Fmt("Error reading input: %v", err))
  34. }
  35. opt := binary.ReadJSON(&BarakOptions{}, optBytes, &err).(*BarakOptions)
  36. if err != nil {
  37. panic(Fmt("Error parsing input: %v", err))
  38. }
  39. return opt
  40. }
  41. func ensureRootDir() (rootDir string) {
  42. rootDir = os.Getenv("BRKROOT")
  43. if rootDir == "" {
  44. rootDir = os.Getenv("HOME") + "/.barak"
  45. }
  46. err := EnsureDir(rootDir)
  47. if err != nil {
  48. panic(Fmt("Error creating barak rootDir: %v", err))
  49. }
  50. return
  51. }
  52. func NewBarakFromOptions(opt *BarakOptions) *Barak {
  53. rootDir := ensureRootDir()
  54. barak := NewBarak(rootDir, opt.StartNonce, opt.Validators)
  55. for _, registry := range opt.Registries {
  56. barak.AddRegistry(registry)
  57. }
  58. barak.OpenListener(opt.ListenAddress)
  59. // Debug.
  60. fmt.Printf("Options: %v\n", opt)
  61. fmt.Printf("Barak: %v\n", barak)
  62. return barak
  63. }
  64. //--------------------------------------------------------------------------------
  65. type Barak struct {
  66. mtx sync.Mutex
  67. pid int
  68. nonce uint64
  69. processes map[string]*pcm.Process
  70. validators []Validator
  71. listeners []net.Listener
  72. rootDir string
  73. registries []string
  74. }
  75. func NewBarak(rootDir string, nonce uint64, validators []Validator) *Barak {
  76. return &Barak{
  77. pid: os.Getpid(),
  78. nonce: nonce,
  79. processes: make(map[string]*pcm.Process),
  80. validators: validators,
  81. listeners: nil,
  82. rootDir: rootDir,
  83. registries: nil,
  84. }
  85. }
  86. func (brk *Barak) RootDir() string {
  87. brk.mtx.Lock()
  88. defer brk.mtx.Unlock()
  89. return brk.rootDir
  90. }
  91. func (brk *Barak) ListProcesses() []*pcm.Process {
  92. brk.mtx.Lock()
  93. defer brk.mtx.Unlock()
  94. processes := []*pcm.Process{}
  95. for _, process := range processes {
  96. processes = append(processes, process)
  97. }
  98. return processes
  99. }
  100. func (brk *Barak) GetProcess(label string) *pcm.Process {
  101. brk.mtx.Lock()
  102. defer brk.mtx.Unlock()
  103. return brk.processes[label]
  104. }
  105. func (brk *Barak) AddProcess(label string, process *pcm.Process) error {
  106. brk.mtx.Lock()
  107. defer brk.mtx.Unlock()
  108. existing := brk.processes[label]
  109. if existing != nil && existing.EndTime.IsZero() {
  110. return fmt.Errorf("Process already exists: %v", label)
  111. }
  112. brk.processes[label] = process
  113. return nil
  114. }
  115. func (brk *Barak) StopProcess(label string, kill bool) error {
  116. barak.mtx.Lock()
  117. proc := barak.processes[label]
  118. barak.mtx.Unlock()
  119. if proc == nil {
  120. return fmt.Errorf("Process does not exist: %v", label)
  121. }
  122. err := pcm.Stop(proc, kill)
  123. return err
  124. }
  125. func (brk *Barak) ListValidators() []Validator {
  126. brk.mtx.Lock()
  127. defer brk.mtx.Unlock()
  128. return brk.validators
  129. }
  130. func (brk *Barak) ListListeners() []net.Listener {
  131. brk.mtx.Lock()
  132. defer brk.mtx.Unlock()
  133. return brk.listeners
  134. }
  135. func (brk *Barak) OpenListener(addr string) net.Listener {
  136. brk.mtx.Lock()
  137. defer brk.mtx.Unlock()
  138. // Start rpc server.
  139. mux := http.NewServeMux()
  140. mux.HandleFunc("/download", ServeFileHandler)
  141. mux.HandleFunc("/register", RegisterHandler)
  142. // TODO: mux.HandleFunc("/upload", UploadFile)
  143. rpcserver.RegisterRPCFuncs(mux, Routes)
  144. listener := rpcserver.StartHTTPServer(addr, mux)
  145. brk.listeners = append(brk.listeners, listener)
  146. return listener
  147. }
  148. func (brk *Barak) CloseListener(addr string) {
  149. brk.mtx.Lock()
  150. defer brk.mtx.Unlock()
  151. filtered := []net.Listener{}
  152. for _, listener := range brk.listeners {
  153. if listener.Addr().String() == addr {
  154. continue
  155. }
  156. filtered = append(filtered, listener)
  157. }
  158. brk.listeners = filtered
  159. }
  160. func (brk *Barak) GetRegistries() []string {
  161. brk.mtx.Lock()
  162. defer brk.mtx.Unlock()
  163. return brk.registries
  164. }
  165. func (brk *Barak) AddRegistry(registry string) {
  166. brk.mtx.Lock()
  167. defer brk.mtx.Unlock()
  168. brk.registries = append(brk.registries, registry)
  169. }
  170. func (brk *Barak) RemoveRegistry(registry string) {
  171. brk.mtx.Lock()
  172. defer brk.mtx.Unlock()
  173. filtered := []string{}
  174. for _, reg := range brk.registries {
  175. if registry == reg {
  176. continue
  177. }
  178. filtered = append(filtered, reg)
  179. }
  180. brk.registries = filtered
  181. }
  182. func (brk *Barak) StartRegisterRoutine() {
  183. // Register this barak with central listener
  184. go func() {
  185. // Workaround around issues when registries register on themselves upon startup.
  186. time.Sleep(3 * time.Second)
  187. for {
  188. // Every hour, register with the registries.
  189. for _, registry := range brk.registries {
  190. resp, err := http.Get(registry + "/register")
  191. if err != nil {
  192. fmt.Printf("Error registering to registry %v:\n %v\n", registry, err)
  193. } else if resp.StatusCode != 200 {
  194. body, _ := ioutil.ReadAll(resp.Body)
  195. fmt.Printf("Error registering to registry %v:\n %v\n", registry, string(body))
  196. } else {
  197. body, _ := ioutil.ReadAll(resp.Body)
  198. fmt.Printf("Successfully registered with registry %v\n %v\n", registry, string(body))
  199. }
  200. }
  201. time.Sleep(1 * time.Hour)
  202. }
  203. }()
  204. }
  205. // Write pid to file.
  206. func (brk *Barak) WritePidFile() {
  207. err := WriteFileAtomic(brk.rootDir+"/pidfile", []byte(Fmt("%v", brk.pid)))
  208. if err != nil {
  209. panic(Fmt("Error writing pidfile: %v", err))
  210. }
  211. }
  212. func (brk *Barak) CheckIncrNonce(newNonce uint64) error {
  213. brk.mtx.Lock()
  214. defer brk.mtx.Unlock()
  215. if brk.nonce+1 != newNonce {
  216. return errors.New("Replay error")
  217. }
  218. brk.nonce += 1
  219. return nil
  220. }