X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=main.go;h=ba445f5eb39e9e3b410849573abe394bd9c2498b;hb=c07adb807c41a1545a9a0f5bbf40080d86946538;hp=40617d1c236fd747e5b491f1f4698d41a19963c2;hpb=8983eebdbe74489d62eae4097580fc430d75bd07;p=src%2Fxds%2Fxds-server.git 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) }