tunasync.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "os/signal"
  6. "strconv"
  7. "syscall"
  8. "time"
  9. "github.com/gin-gonic/gin"
  10. "github.com/pkg/profile"
  11. "gopkg.in/op/go-logging.v1"
  12. "gopkg.in/urfave/cli.v1"
  13. tunasync "github.com/tuna/tunasync/internal"
  14. "github.com/tuna/tunasync/manager"
  15. "github.com/tuna/tunasync/worker"
  16. )
  17. var (
  18. buildstamp = ""
  19. githash = "No githash provided"
  20. )
  21. var logger = logging.MustGetLogger("tunasync")
  22. func startManager(c *cli.Context) error {
  23. tunasync.InitLogger(c.Bool("verbose"), c.Bool("debug"), c.Bool("with-systemd"))
  24. cfg, err := manager.LoadConfig(c.String("config"), c)
  25. if err != nil {
  26. logger.Errorf("Error loading config: %s", err.Error())
  27. os.Exit(1)
  28. }
  29. if !cfg.Debug {
  30. gin.SetMode(gin.ReleaseMode)
  31. }
  32. m := manager.GetTUNASyncManager(cfg)
  33. if m == nil {
  34. logger.Errorf("Error intializing TUNA sync worker.")
  35. os.Exit(1)
  36. }
  37. logger.Info("Run tunasync manager server.")
  38. m.Run()
  39. return nil
  40. }
  41. func startWorker(c *cli.Context) error {
  42. tunasync.InitLogger(c.Bool("verbose"), c.Bool("debug"), c.Bool("with-systemd"))
  43. if !c.Bool("debug") {
  44. gin.SetMode(gin.ReleaseMode)
  45. }
  46. cfg, err := worker.LoadConfig(c.String("config"))
  47. if err != nil {
  48. logger.Errorf("Error loading config: %s", err.Error())
  49. os.Exit(1)
  50. }
  51. w := worker.GetTUNASyncWorker(cfg)
  52. if w == nil {
  53. logger.Errorf("Error intializing TUNA sync worker.")
  54. os.Exit(1)
  55. }
  56. if profPath := c.String("prof-path"); profPath != "" {
  57. valid := false
  58. if fi, err := os.Stat(profPath); err == nil {
  59. if fi.IsDir() {
  60. valid = true
  61. defer profile.Start(profile.ProfilePath(profPath)).Stop()
  62. }
  63. }
  64. if !valid {
  65. logger.Errorf("Invalid profiling path: %s", profPath)
  66. os.Exit(1)
  67. }
  68. }
  69. go func() {
  70. time.Sleep(1 * time.Second)
  71. sigChan := make(chan os.Signal, 1)
  72. signal.Notify(sigChan, syscall.SIGHUP)
  73. signal.Notify(sigChan, syscall.SIGINT)
  74. signal.Notify(sigChan, syscall.SIGTERM)
  75. for s := range sigChan {
  76. switch s {
  77. case syscall.SIGHUP:
  78. logger.Info("Received reload signal")
  79. newCfg, err := worker.LoadConfig(c.String("config"))
  80. if err != nil {
  81. logger.Errorf("Error loading config: %s", err.Error())
  82. } else {
  83. w.ReloadMirrorConfig(newCfg.Mirrors)
  84. }
  85. case syscall.SIGINT, syscall.SIGTERM:
  86. w.Halt()
  87. }
  88. }
  89. }()
  90. logger.Info("Run tunasync worker.")
  91. w.Run()
  92. return nil
  93. }
  94. func main() {
  95. cli.VersionPrinter = func(c *cli.Context) {
  96. var builddate string
  97. if buildstamp == "" {
  98. builddate = "No build date provided"
  99. } else {
  100. ts, err := strconv.Atoi(buildstamp)
  101. if err != nil {
  102. builddate = "No build date provided"
  103. } else {
  104. t := time.Unix(int64(ts), 0)
  105. builddate = t.String()
  106. }
  107. }
  108. fmt.Printf(
  109. "Version: %s\n"+
  110. "Git Hash: %s\n"+
  111. "Build Date: %s\n",
  112. c.App.Version, githash, builddate,
  113. )
  114. }
  115. app := cli.NewApp()
  116. app.Name = "tunasync"
  117. app.Usage = "tunasync mirror job management tool"
  118. app.EnableBashCompletion = true
  119. app.Version = tunasync.Version
  120. app.Commands = []cli.Command{
  121. {
  122. Name: "manager",
  123. Aliases: []string{"m"},
  124. Usage: "start the tunasync manager",
  125. Action: startManager,
  126. Flags: []cli.Flag{
  127. cli.StringFlag{
  128. Name: "config, c",
  129. Usage: "Load manager configurations from `FILE`",
  130. },
  131. cli.StringFlag{
  132. Name: "addr",
  133. Usage: "The manager will listen on `ADDR`",
  134. },
  135. cli.StringFlag{
  136. Name: "port",
  137. Usage: "The manager will bind to `PORT`",
  138. },
  139. cli.StringFlag{
  140. Name: "cert",
  141. Usage: "Use SSL certificate from `FILE`",
  142. },
  143. cli.StringFlag{
  144. Name: "key",
  145. Usage: "Use SSL key from `FILE`",
  146. },
  147. cli.StringFlag{
  148. Name: "db-file",
  149. Usage: "Use `FILE` as the database file",
  150. },
  151. cli.StringFlag{
  152. Name: "db-type",
  153. Usage: "Use database type `TYPE`",
  154. },
  155. cli.BoolFlag{
  156. Name: "verbose, v",
  157. Usage: "Enable verbose logging",
  158. },
  159. cli.BoolFlag{
  160. Name: "debug",
  161. Usage: "Run manager in debug mode",
  162. },
  163. cli.BoolFlag{
  164. Name: "with-systemd",
  165. Usage: "Enable systemd-compatible logging",
  166. },
  167. cli.StringFlag{
  168. Name: "pidfile",
  169. Value: "/run/tunasync/tunasync.manager.pid",
  170. Usage: "The pid file of the manager process",
  171. },
  172. },
  173. },
  174. {
  175. Name: "worker",
  176. Aliases: []string{"w"},
  177. Usage: "start the tunasync worker",
  178. Action: startWorker,
  179. Flags: []cli.Flag{
  180. cli.StringFlag{
  181. Name: "config, c",
  182. Usage: "Load worker configurations from `FILE`",
  183. },
  184. cli.BoolFlag{
  185. Name: "verbose, v",
  186. Usage: "Enable verbose logging",
  187. },
  188. cli.BoolFlag{
  189. Name: "debug",
  190. Usage: "Run worker in debug mode",
  191. },
  192. cli.BoolFlag{
  193. Name: "with-systemd",
  194. Usage: "Enable systemd-compatible logging",
  195. },
  196. cli.StringFlag{
  197. Name: "pidfile",
  198. Value: "/run/tunasync/tunasync.worker.pid",
  199. Usage: "The pid file of the worker process",
  200. },
  201. cli.StringFlag{
  202. Name: "prof-path",
  203. Value: "",
  204. Usage: "Go profiling file path",
  205. },
  206. },
  207. },
  208. }
  209. app.Run(os.Args)
  210. }