mirror of
https://github.com/tuna/tunasync.git
synced 2025-04-20 20:22:46 +00:00
229 lines
4.9 KiB
Go
229 lines
4.9 KiB
Go
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 = "0.1"
|
|
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)
|
|
}
|