diff --git a/cmd/tunasynctl/tunasynctl.go b/cmd/tunasynctl/tunasynctl.go index 98e51e2..4578204 100644 --- a/cmd/tunasynctl/tunasynctl.go +++ b/cmd/tunasynctl/tunasynctl.go @@ -225,6 +225,39 @@ func cmdJob(cmd tunasync.CmdVerb) cli.ActionFunc { } } +func cmdWorker(cmd tunasync.CmdVerb) cli.ActionFunc { + return func(c *cli.Context) error { + cmd := tunasync.ClientCmd{ + Cmd: cmd, + WorkerID: c.String("worker"), + } + resp, err := tunasync.PostJSON(baseURL+cmdPath, cmd, client) + if err != nil { + return cli.NewExitError( + fmt.Sprintf("Failed to correctly send command: %s", + err.Error()), + 1) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return cli.NewExitError( + fmt.Sprintf("Failed to parse response: %s", err.Error()), + 1) + } + + return cli.NewExitError(fmt.Sprintf("Failed to correctly send"+ + " command: HTTP status code is not 200: %s", body), + 1) + } + logger.Info("Succesfully send command") + + return nil + } +} + func main() { app := cli.NewApp() app.EnableBashCompletion = true @@ -304,6 +337,12 @@ func main() { Flags: append(commonFlags, cmdFlags...), Action: initializeWrapper(cmdJob(tunasync.CmdRestart)), }, + { + Name: "reload", + Usage: "Tell worker to reload configurations", + Flags: append(commonFlags, cmdFlags...), + Action: initializeWrapper(cmdWorker(tunasync.CmdReload)), + }, { Name: "ping", Flags: append(commonFlags, cmdFlags...), diff --git a/internal/msg.go b/internal/msg.go index 85337d6..b1164ea 100644 --- a/internal/msg.go +++ b/internal/msg.go @@ -35,6 +35,7 @@ const ( CmdDisable // disable the job (stops goroutine) CmdRestart // restart syncing CmdPing // ensure the goroutine is alive + CmdReload // reload mirror config ) func (c CmdVerb) String() string { @@ -49,6 +50,8 @@ func (c CmdVerb) String() string { return "restart" case CmdPing: return "ping" + case CmdReload: + return "reload" } return "unknown" } diff --git a/worker/worker.go b/worker/worker.go index eff7205..4b6741b 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -3,7 +3,9 @@ package worker import ( "fmt" "net/http" + "os" "sync" + "syscall" "time" "github.com/gin-gonic/gin" @@ -185,16 +187,32 @@ func (w *Worker) makeHTTPServer() { return } + logger.Noticef("Received command: %v", cmd) + + if cmd.MirrorID == "" { + // worker-level commands + switch cmd.Cmd { + case CmdReload: + // send myself a SIGHUP + pid := os.Getpid() + syscall.Kill(pid, syscall.SIGHUP) + default: + c.JSON(http.StatusNotAcceptable, gin.H{"msg": "Invalid Command"}) + return + } + } + + // job level comands job, ok := w.jobs[cmd.MirrorID] if !ok { c.JSON(http.StatusNotFound, gin.H{"msg": fmt.Sprintf("Mirror ``%s'' not found", cmd.MirrorID)}) return } - logger.Noticef("Received command: %v", cmd) // No matter what command, the existing job // schedule should be flushed w.schedule.Remove(job.Name()) + // if job disabled, start them first switch cmd.Cmd { case CmdStart, CmdRestart: