aboutsummaryrefslogtreecommitdiffstats
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go158
1 files changed, 148 insertions, 10 deletions
diff --git a/main.go b/main.go
index 40617d1..ba445f5 100644
--- a/main.go
+++ b/main.go
@@ -3,13 +3,20 @@
package main
import (
- "log"
+ "fmt"
"os"
+ "os/exec"
+ "os/signal"
+ "strings"
+ "syscall"
+ "time"
"github.com/Sirupsen/logrus"
"github.com/codegangsta/cli"
+ "github.com/iotbzh/xds-server/lib/model"
+ "github.com/iotbzh/xds-server/lib/syncthing"
+ "github.com/iotbzh/xds-server/lib/webserver"
"github.com/iotbzh/xds-server/lib/xdsconfig"
- "github.com/iotbzh/xds-server/lib/xdsserver"
)
const (
@@ -30,19 +37,150 @@ var AppVersion = "?.?.?"
// Should be set by compilation -ldflags "-X main.AppSubVersion=xxx"
var AppSubVersion = "unknown-dev"
-// Web server main routine
-func webServer(ctx *cli.Context) error {
+// Context holds the XDS server context
+type Context struct {
+ ProgName string
+ Cli *cli.Context
+ Config *xdsconfig.Config
+ Log *logrus.Logger
+ SThg *st.SyncThing
+ SThgCmd *exec.Cmd
+ MFolder *model.Folder
+ WWWServer *webserver.ServerService
+ Exit chan os.Signal
+}
+
+// NewContext Create a new instance of XDS server
+func NewContext(cliCtx *cli.Context) *Context {
+ var err error
+
+ // Set logger level and formatter
+ log := cliCtx.App.Metadata["logger"].(*logrus.Logger)
+
+ logLevel := cliCtx.GlobalString("log")
+ if logLevel == "" {
+ logLevel = "error" // FIXME get from Config DefaultLogLevel
+ }
+ if log.Level, err = logrus.ParseLevel(logLevel); err != nil {
+ fmt.Printf("Invalid log level : \"%v\"\n", logLevel)
+ os.Exit(1)
+ }
+ log.Formatter = &logrus.TextFormatter{}
+
+ // Define default configuration
+ ctx := Context{
+ ProgName: cliCtx.App.Name,
+ Cli: cliCtx,
+ Log: log,
+ Exit: make(chan os.Signal, 1),
+ }
+
+ // register handler on SIGTERM / exit
+ signal.Notify(ctx.Exit, os.Interrupt, syscall.SIGTERM)
+ go handlerSigTerm(&ctx)
+
+ return &ctx
+}
+
+// Handle exit and properly stop/close all stuff
+func handlerSigTerm(ctx *Context) {
+ <-ctx.Exit
+ if ctx.SThg != nil {
+ ctx.Log.Infof("Stopping Syncthing... (PID %d)",
+ ctx.SThgCmd.Process.Pid)
+ ctx.SThg.Stop()
+ }
+ if ctx.WWWServer != nil {
+ ctx.Log.Infof("Stoping Web server...")
+ ctx.WWWServer.Stop()
+ }
+ os.Exit(1)
+}
- // Init config
- cfg, err := xdsconfig.Init(ctx)
+// xdsServer main routine
+func xdsApp(cliCtx *cli.Context) error {
+ var err error
+
+ // Create XDS server context
+ ctx := NewContext(cliCtx)
+
+ // Load config
+ cfg, err := xdsconfig.Init(ctx.Cli, ctx.Log)
if err != nil {
return cli.NewExitError(err, 2)
}
+ ctx.Config = cfg
+
+ // TODO allow to redirect stdout/sterr into logs file
+ //logFilename := filepath.Join(ctx.Config.FileConf.LogsDir + "xds-server.log")
+
+ // FIXME - add a builder interface and support other builder type (eg. native)
+ builderType := "syncthing"
+
+ switch builderType {
+ case "syncthing":
+
+ // Start local instance of Syncthing and Syncthing-notify
+ ctx.SThg = st.NewSyncThing(ctx.Config, ctx.Log)
+
+ ctx.Log.Infof("Starting Syncthing...")
+ ctx.SThgCmd, err = ctx.SThg.Start()
+ if err != nil {
+ return cli.NewExitError(err, 2)
+ }
+ ctx.Log.Infof("Syncthing started (PID %d)", ctx.SThgCmd.Process.Pid)
+
+ // Establish connection with local Syncthing (retry if connection fail)
+ retry := 10
+ err = nil
+ for retry > 0 {
+ if err = ctx.SThg.Connect(); err == nil {
+ break
+ }
+ ctx.Log.Warningf("Establishing connection to Syncthing (retry %d/10)", retry)
+ time.Sleep(time.Second)
+ retry--
+ }
+ if err != nil || retry == 0 {
+ return cli.NewExitError(err, 2)
+ }
+
+ // Retrieve Syncthing config
+ id, err := ctx.SThg.IDGet()
+ if err != nil {
+ return cli.NewExitError(err, 2)
+ }
+
+ if ctx.Config.Builder, err = xdsconfig.NewBuilderConfig(id); err != nil {
+ return cli.NewExitError(err, 2)
+ }
+
+ // Retrieve initial Syncthing config
+ stCfg, err := ctx.SThg.ConfigGet()
+ if err != nil {
+ return cli.NewExitError(err, 2)
+ }
+ for _, stFld := range stCfg.Folders {
+ relativePath := strings.TrimPrefix(stFld.RawPath, ctx.Config.ShareRootDir)
+ if relativePath == "" {
+ relativePath = stFld.RawPath
+ }
+ newFld := xdsconfig.NewFolderConfig(stFld.ID, stFld.Label, ctx.Config.ShareRootDir, strings.Trim(relativePath, "/"))
+ ctx.Config.Folders = ctx.Config.Folders.Update(xdsconfig.FoldersConfig{newFld})
+ }
+
+ // Init model folder
+ ctx.MFolder = model.NewFolder(ctx.Config, ctx.SThg)
+
+ default:
+ err = fmt.Errorf("Unsupported builder type")
+ return cli.NewExitError(err, 3)
+ }
// Create and start Web Server
- svr := xdsserver.NewServer(cfg)
- if err = svr.Serve(); err != nil {
- log.Println(err)
+ ctx.WWWServer = webserver.NewServer(ctx.Config, ctx.MFolder, ctx.Log)
+ if err = ctx.WWWServer.Serve(); err != nil {
+ ctx.Log.Println(err)
return cli.NewExitError(err, 3)
}
@@ -83,7 +221,7 @@ func main() {
}
// only one action: Web Server
- app.Action = webServer
+ app.Action = xdsApp
app.Run(os.Args)
}