diff options
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 190 |
1 files changed, 6 insertions, 184 deletions
@@ -5,20 +5,11 @@ package main import ( "fmt" "os" - "os/exec" - "os/signal" - "path/filepath" - "syscall" - "time" "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" - "github.com/iotbzh/xds-server/lib/crosssdk" - "github.com/iotbzh/xds-server/lib/folder" - "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 ( @@ -39,192 +30,23 @@ var AppVersion = "?.?.?" // Should be set by compilation -ldflags "-X main.AppSubVersion=xxx" var AppSubVersion = "unknown-dev" -// Context holds the XDS server context -type Context struct { - ProgName string - Cli *cli.Context - Config *xdsconfig.Config - Log *logrus.Logger - LogLevelSilly bool - SThg *st.SyncThing - SThgCmd *exec.Cmd - SThgInotCmd *exec.Cmd - MFolders *model.Folders - SDKs *crosssdk.SDKs - WWWServer *webserver.Server - 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{} - - sillyVal, sillyLog := os.LookupEnv("XDS_LOG_SILLY") - - // Define default configuration - ctx := Context{ - ProgName: cliCtx.App.Name, - Cli: cliCtx, - Log: log, - LogLevelSilly: (sillyLog && sillyVal == "1"), - 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("Stoping Syncthing... (PID %d)", ctx.SThgCmd.Process.Pid) - ctx.SThg.Stop() - ctx.Log.Infof("Stoping Syncthing-inotify... (PID %d)", ctx.SThgInotCmd.Process.Pid) - ctx.SThg.StopInotify() - } - if ctx.WWWServer != nil { - ctx.Log.Infof("Stoping Web server...") - ctx.WWWServer.Stop() - } - os.Exit(0) -} - -// Helper function to log message on both stdout and logger -func logPrint(ctx *Context, format string, args ...interface{}) { - fmt.Printf(format, args...) - if ctx.Log.Out != os.Stdout { - ctx.Log.Infof(format, args...) - } -} - // XDS Server application main routine func xdsApp(cliCtx *cli.Context) error { var err error // Create XDS server context - ctx := NewContext(cliCtx) + ctxSvr := xdsserver.NewXdsServer(cliCtx) // Load config - cfg, err := xdsconfig.Init(ctx.Cli, ctx.Log) + ctxSvr.Config, err = xdsconfig.Init(cliCtx, ctxSvr.Log) if err != nil { return cli.NewExitError(err, -2) } - ctx.Config = cfg - // Logs redirected into a file when logfile option or logsDir config is set - ctx.Config.LogVerboseOut = os.Stderr - if ctx.Config.FileConf.LogsDir != "" { - if ctx.Config.Options.LogFile != "stdout" { - logFile := ctx.Config.Options.LogFile - - fdL, err := os.OpenFile(logFile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) - if err != nil { - msgErr := fmt.Sprintf("Cannot create log file %s", logFile) - return cli.NewExitError(msgErr, int(syscall.EPERM)) - } - ctx.Log.Out = fdL - - logPrint(ctx, "Logging file: %s\n", logFile) - } - - logFileHTTPReq := filepath.Join(ctx.Config.FileConf.LogsDir, "xds-server-verbose.log") - fdLH, err := os.OpenFile(logFileHTTPReq, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) - if err != nil { - msgErr := fmt.Sprintf("Cannot create log file %s", logFileHTTPReq) - return cli.NewExitError(msgErr, int(syscall.EPERM)) - } - ctx.Config.LogVerboseOut = fdLH - - logPrint(ctx, "Logging file for HTTP requests: %s\n", logFileHTTPReq) - } - - // Create syncthing instance when section "syncthing" is present in config.json - if ctx.Config.FileConf.SThgConf != nil { - ctx.SThg = st.NewSyncThing(ctx.Config, ctx.Log) - } - - // Start local instance of Syncthing and Syncthing-notify - if ctx.SThg != nil { - ctx.Log.Infof("Starting Syncthing...") - ctx.SThgCmd, err = ctx.SThg.Start() - if err != nil { - return cli.NewExitError(err, -4) - } - logPrint(ctx, "Syncthing started (PID %d)\n", ctx.SThgCmd.Process.Pid) - - ctx.Log.Infof("Starting Syncthing-inotify...") - ctx.SThgInotCmd, err = ctx.SThg.StartInotify() - if err != nil { - return cli.NewExitError(err, -4) - } - logPrint(ctx, "Syncthing-inotify started (PID %d)\n", ctx.SThgInotCmd.Process.Pid) - - // Establish connection with local Syncthing (retry if connection fail) - logPrint(ctx, "Establishing connection with Syncthing...\n") - time.Sleep(2 * time.Second) - maxRetry := 30 - retry := maxRetry - err = nil - for retry > 0 { - if err = ctx.SThg.Connect(); err == nil { - break - } - ctx.Log.Warningf("Establishing connection to Syncthing (retry %d/%d)", retry, maxRetry) - time.Sleep(time.Second) - retry-- - } - if err != nil || retry == 0 { - return cli.NewExitError(err, -4) - } - - // FIXME: do we still need Builder notion ? if no cleanup - if ctx.Config.Builder, err = xdsconfig.NewBuilderConfig(ctx.SThg.MyID); err != nil { - return cli.NewExitError(err, -4) - } - ctx.Config.SupportedSharing[folder.TypeCloudSync] = true - } - - // Init model folder - ctx.MFolders = model.FoldersNew(ctx.Config, ctx.SThg) - - // Load initial folders config from disk - if err := ctx.MFolders.LoadConfig(); err != nil { - return cli.NewExitError(err, -5) - } - - // Init cross SDKs - ctx.SDKs, err = crosssdk.Init(ctx.Config, ctx.Log) - if err != nil { - return cli.NewExitError(err, -6) - } - - // Create Web Server - ctx.WWWServer = webserver.New(ctx.Config, ctx.MFolders, ctx.SDKs, ctx.Log, ctx.LogLevelSilly) - - // Run Web Server until exit requested (blocking call) - if err = ctx.WWWServer.Serve(); err != nil { - ctx.Log.Println(err) - return cli.NewExitError(err, -7) - } + // Run XDS Server (main loop) + errCode, err := ctxSvr.Run() - return cli.NewExitError("Program exited ", -99) + return cli.NewExitError(err, errCode) } // main |