Initial commit.
[src/xds/xds-agent.git] / main.go
1 // TODO add Doc
2 //
3 package main
4
5 import (
6         "log"
7         "os"
8         "time"
9
10         "fmt"
11
12         "github.com/Sirupsen/logrus"
13         "github.com/codegangsta/cli"
14         "github.com/iotbzh/xds-agent/lib/agent"
15         "github.com/iotbzh/xds-agent/lib/syncthing"
16         "github.com/iotbzh/xds-agent/lib/xdsconfig"
17         "github.com/iotbzh/xds-agent/lib/xdsserver"
18 )
19
20 const (
21         appName        = "xds-agent"
22         appDescription = "X(cross) Development System Agent is a web server that allows to remotely cross build applications."
23         appCopyright   = "Apache-2.0"
24         appUsage       = "X(cross) Development System Agent"
25 )
26
27 var appAuthors = []cli.Author{
28         cli.Author{Name: "Sebastien Douheret", Email: "sebastien@iot.bzh"},
29 }
30
31 // AppVersion is the version of this application
32 var AppVersion = "?.?.?"
33
34 // AppSubVersion is the git tag id added to version string
35 // Should be set by compilation -ldflags "-X main.AppSubVersion=xxx"
36 var AppSubVersion = "unknown-dev"
37
38 // xdsAgent main routine
39 func xdsAgent(cliCtx *cli.Context) error {
40
41         // Create Agent context
42         ctx := agent.NewAgent(cliCtx)
43
44         // Load config
45         cfg, err := xdsconfig.Init(cliCtx, ctx.Log)
46         if err != nil {
47                 return cli.NewExitError(err, 2)
48         }
49         ctx.Config = &cfg
50
51         // Start local instance of Syncthing and Syncthing-notify
52         ctx.SThg = st.NewSyncThing(ctx.Config.FileConf.SThgConf, ctx.Log)
53
54         ctx.Log.Infof("Starting Syncthing...")
55         ctx.SThgCmd, err = ctx.SThg.Start()
56         if err != nil {
57                 return cli.NewExitError(err, 2)
58         }
59         ctx.Log.Infof("Syncthing started (PID %d)", ctx.SThgCmd.Process.Pid)
60
61         ctx.Log.Infof("Starting Syncthing-inotify...")
62         ctx.SThgInotCmd, err = ctx.SThg.StartInotify()
63         if err != nil {
64                 return cli.NewExitError(err, 2)
65         }
66         ctx.Log.Infof("Syncthing-inotify started (PID %d)", ctx.SThgInotCmd.Process.Pid)
67
68         // Establish connection with local Syncthing (retry if connection fail)
69         time.Sleep(3 * time.Second)
70         retry := 10
71         for retry > 0 {
72                 if err := ctx.SThg.Connect(); err == nil {
73                         break
74                 }
75                 ctx.Log.Infof("Establishing connection to Syncthing (retry %d/5)", retry)
76                 time.Sleep(time.Second)
77                 retry--
78         }
79         if ctx.SThg == nil {
80                 err = fmt.Errorf("ERROR: cannot connect to Syncthing (url: %s)", ctx.SThg.BaseURL)
81                 return cli.NewExitError(err, 2)
82         }
83
84         // Retrieve Syncthing config
85         id, err := ctx.SThg.IDGet()
86         if err != nil {
87                 return cli.NewExitError(err, 2)
88         }
89         ctx.Log.Infof("Local Syncthing ID: %s", id)
90
91         // Create and start Web Server
92         ctx.WWWServer = xdsserver.NewServer(ctx.Config, ctx.Log)
93         if err = ctx.WWWServer.Serve(); err != nil {
94                 log.Println(err)
95                 return cli.NewExitError(err, 3)
96         }
97
98         return cli.NewExitError("Program exited ", 4)
99 }
100
101 // main
102 func main() {
103
104         // Create a new instance of the logger
105         log := logrus.New()
106
107         // Create a new App instance
108         app := cli.NewApp()
109         app.Name = appName
110         app.Description = appDescription
111         app.Usage = appUsage
112         app.Version = AppVersion + " (" + AppSubVersion + ")"
113         app.Authors = appAuthors
114         app.Copyright = appCopyright
115         app.Metadata = make(map[string]interface{})
116         app.Metadata["version"] = AppVersion
117         app.Metadata["git-tag"] = AppSubVersion
118         app.Metadata["logger"] = log
119
120         app.Flags = []cli.Flag{
121                 cli.StringFlag{
122                         Name:   "config, c",
123                         Usage:  "JSON config file to use\n\t",
124                         EnvVar: "XDS_CONFIGFILE",
125                 },
126                 cli.StringFlag{
127                         Name:   "log, l",
128                         Value:  "error",
129                         Usage:  "logging level (supported levels: panic, fatal, error, warn, info, debug)\n\t",
130                         EnvVar: "LOG_LEVEL",
131                 },
132         }
133
134         // only one action
135         app.Action = xdsAgent
136
137         app.Run(os.Args)
138 }