123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- package main
- import (
- "fmt"
- "os"
- "os/signal"
- "strconv"
- "syscall"
- "time"
- "github.com/gin-gonic/gin"
- "github.com/pkg/profile"
- "gopkg.in/op/go-logging.v1"
- "gopkg.in/urfave/cli.v1"
- tunasync "github.com/tuna/tunasync/internal"
- "github.com/tuna/tunasync/manager"
- "github.com/tuna/tunasync/worker"
- )
- var (
- buildstamp = ""
- githash = "No githash provided"
- )
- var logger = logging.MustGetLogger("tunasync")
- func startManager(c *cli.Context) error {
- tunasync.InitLogger(c.Bool("verbose"), c.Bool("debug"), c.Bool("with-systemd"))
- cfg, err := manager.LoadConfig(c.String("config"), c)
- if err != nil {
- logger.Errorf("Error loading config: %s", err.Error())
- os.Exit(1)
- }
- if !cfg.Debug {
- gin.SetMode(gin.ReleaseMode)
- }
- m := manager.GetTUNASyncManager(cfg)
- if m == nil {
- logger.Errorf("Error intializing TUNA sync worker.")
- os.Exit(1)
- }
- logger.Info("Run tunasync manager server.")
- m.Run()
- return nil
- }
- func startWorker(c *cli.Context) error {
- tunasync.InitLogger(c.Bool("verbose"), c.Bool("debug"), c.Bool("with-systemd"))
- if !c.Bool("debug") {
- gin.SetMode(gin.ReleaseMode)
- }
- cfg, err := worker.LoadConfig(c.String("config"))
- if err != nil {
- logger.Errorf("Error loading config: %s", err.Error())
- os.Exit(1)
- }
- w := worker.GetTUNASyncWorker(cfg)
- if w == nil {
- logger.Errorf("Error intializing TUNA sync worker.")
- os.Exit(1)
- }
- if profPath := c.String("prof-path"); profPath != "" {
- valid := false
- if fi, err := os.Stat(profPath); err == nil {
- if fi.IsDir() {
- valid = true
- defer profile.Start(profile.ProfilePath(profPath)).Stop()
- }
- }
- if !valid {
- logger.Errorf("Invalid profiling path: %s", profPath)
- os.Exit(1)
- }
- }
- go func() {
- time.Sleep(1 * time.Second)
- sigChan := make(chan os.Signal, 1)
- signal.Notify(sigChan, syscall.SIGHUP)
- signal.Notify(sigChan, syscall.SIGINT)
- signal.Notify(sigChan, syscall.SIGTERM)
- for s := range sigChan {
- switch s {
- case syscall.SIGHUP:
- logger.Info("Received reload signal")
- newCfg, err := worker.LoadConfig(c.String("config"))
- if err != nil {
- logger.Errorf("Error loading config: %s", err.Error())
- } else {
- w.ReloadMirrorConfig(newCfg.Mirrors)
- }
- case syscall.SIGINT, syscall.SIGTERM:
- w.Halt()
- }
- }
- }()
- logger.Info("Run tunasync worker.")
- w.Run()
- return nil
- }
- func main() {
- cli.VersionPrinter = func(c *cli.Context) {
- var builddate string
- if buildstamp == "" {
- builddate = "No build date provided"
- } else {
- ts, err := strconv.Atoi(buildstamp)
- if err != nil {
- builddate = "No build date provided"
- } else {
- t := time.Unix(int64(ts), 0)
- builddate = t.String()
- }
- }
- fmt.Printf(
- "Version: %s\n"+
- "Git Hash: %s\n"+
- "Build Date: %s\n",
- c.App.Version, githash, builddate,
- )
- }
- app := cli.NewApp()
- app.Name = "tunasync"
- app.Usage = "tunasync mirror job management tool"
- app.EnableBashCompletion = true
- app.Version = tunasync.Version
- app.Commands = []cli.Command{
- {
- Name: "manager",
- Aliases: []string{"m"},
- Usage: "start the tunasync manager",
- Action: startManager,
- Flags: []cli.Flag{
- cli.StringFlag{
- Name: "config, c",
- Usage: "Load manager configurations from `FILE`",
- },
- cli.StringFlag{
- Name: "addr",
- Usage: "The manager will listen on `ADDR`",
- },
- cli.StringFlag{
- Name: "port",
- Usage: "The manager will bind to `PORT`",
- },
- cli.StringFlag{
- Name: "cert",
- Usage: "Use SSL certificate from `FILE`",
- },
- cli.StringFlag{
- Name: "key",
- Usage: "Use SSL key from `FILE`",
- },
- cli.StringFlag{
- Name: "db-file",
- Usage: "Use `FILE` as the database file",
- },
- cli.StringFlag{
- Name: "db-type",
- Usage: "Use database type `TYPE`",
- },
- cli.BoolFlag{
- Name: "verbose, v",
- Usage: "Enable verbose logging",
- },
- cli.BoolFlag{
- Name: "debug",
- Usage: "Run manager in debug mode",
- },
- cli.BoolFlag{
- Name: "with-systemd",
- Usage: "Enable systemd-compatible logging",
- },
- cli.StringFlag{
- Name: "pidfile",
- Value: "/run/tunasync/tunasync.manager.pid",
- Usage: "The pid file of the manager process",
- },
- },
- },
- {
- Name: "worker",
- Aliases: []string{"w"},
- Usage: "start the tunasync worker",
- Action: startWorker,
- Flags: []cli.Flag{
- cli.StringFlag{
- Name: "config, c",
- Usage: "Load worker configurations from `FILE`",
- },
- cli.BoolFlag{
- Name: "verbose, v",
- Usage: "Enable verbose logging",
- },
- cli.BoolFlag{
- Name: "debug",
- Usage: "Run worker in debug mode",
- },
- cli.BoolFlag{
- Name: "with-systemd",
- Usage: "Enable systemd-compatible logging",
- },
- cli.StringFlag{
- Name: "pidfile",
- Value: "/run/tunasync/tunasync.worker.pid",
- Usage: "The pid file of the worker process",
- },
- cli.StringFlag{
- Name: "prof-path",
- Value: "",
- Usage: "Go profiling file path",
- },
- },
- },
- }
- app.Run(os.Args)
- }
|