diff --git a/install.go b/install.go index 5086c288..fd622b9e 100644 --- a/install.go +++ b/install.go @@ -21,8 +21,8 @@ import ( "github.com/bcmi-labs/arduino-connector/auth" mqtt "github.com/eclipse/paho.mqtt.golang" + "github.com/facchinm/service" "github.com/kardianos/osext" - "github.com/kardianos/service" "github.com/pkg/errors" ) @@ -31,8 +31,16 @@ const ( devicesAPI = "https://api.arduino.cc/devices/v1" ) -// Install creates the necessary certificates and configuration files and installs the program as a service -func install(s service.Service, config Config, token string) { +// Install installs the program as a service +func install(s service.Service) { + // InstallService + err := s.Install() + // TODO: implement a fallback strtegy if service installation fails + check(err, "InstallService") +} + +// Register creates the necessary certificates and configuration files +func register(config Config, token string) { // Request token var err error if token == "" { @@ -76,10 +84,6 @@ func install(s service.Service, config Config, token string) { err = ioutil.WriteFile("arduino-connector.cfg", []byte(data), 0660) check(err, "WriteConf") - // InstallService - err = s.Install() - check(err, "InstallService") - // Connect to MQTT and communicate back fmt.Println("Check successful mqtt connection") client, err := setupMQTTConnection("certificate.pem", "certificate.key", config.ID, config.URL) @@ -251,7 +255,8 @@ func requestURL(token string) (string, error) { } type program struct { - Config Config + Config Config + listenFile string } // Start run the program asynchronously @@ -266,7 +271,7 @@ func (p *program) Stop(s service.Service) error { } // createService returns the servcie to be installed -func createService(config Config) (service.Service, error) { +func createService(config Config, listenFile string) (service.Service, error) { workingDirectory, _ := osext.ExecutableFolder() svcConfig := &service.Config{ @@ -275,9 +280,10 @@ func createService(config Config) (service.Service, error) { Description: "Cloud connector and launcher for Intel IoT devices.", Arguments: []string{"-config", configFile}, WorkingDirectory: workingDirectory, + Dependencies: []string{"network-online.target"}, } - prg := &program{config} + prg := &program{config, listenFile} s, err := service.New(prg, svcConfig) if err != nil { return nil, err diff --git a/main.go b/main.go index 8b27a42e..5ce35e72 100644 --- a/main.go +++ b/main.go @@ -5,9 +5,11 @@ import ( "fmt" "log" "os" + "strings" "time" mqtt "github.com/eclipse/paho.mqtt.golang" + "github.com/hpcloud/tail" "github.com/namsral/flag" "github.com/pkg/errors" ) @@ -26,11 +28,11 @@ type Config struct { } func (c Config) String() string { - out := "id " + c.ID + "\r\n" - out += "url " + c.URL + "\r\n" - out += "http_proxy " + c.HTTPProxy + "\r\n" - out += "https_proxy " + c.HTTPSProxy + "\r\n" - out += "all_proxy" + c.ALLProxy + "\r\n" + out := "id=" + c.ID + "\r\n" + out += "url=" + c.URL + "\r\n" + out += "http_proxy=" + c.HTTPProxy + "\r\n" + out += "https_proxy=" + c.HTTPSProxy + "\r\n" + out += "all_proxy=" + c.ALLProxy + "\r\n" return out } @@ -38,6 +40,8 @@ func main() { config := Config{} var doInstall = flag.Bool("install", false, "Install as a service") + var doRegister = flag.Bool("register", false, "Registers on the cloud") + var listenFile = flag.String("listen", "", "Tail given file and report percentage") var token = flag.String("token", "", "an authentication token") flag.String(flag.DefaultConfigFlagname, "", "path to config file") flag.StringVar(&config.ID, "id", "", "id of the thing in aws iot") @@ -49,12 +53,15 @@ func main() { flag.Parse() // Create service and install - s, err := createService(config) + s, err := createService(config, *listenFile) check(err, "CreateService") + if *doRegister { + register(config, *token) + } + if *doInstall { - install(s, config, *token) - return + install(s) } err = s.Run() @@ -76,6 +83,10 @@ func (p program) run() { // Create global status status := NewStatus(p.Config.ID, client) + if p.listenFile != "" { + go tailAndReport(p.listenFile, status) + } + // Subscribe to topics endpoint client.Subscribe("$aws/things/"+p.Config.ID+"/status/post", 1, StatusCB(status)) client.Subscribe("$aws/things/"+p.Config.ID+"/upload/post", 1, UploadCB(status)) @@ -84,6 +95,20 @@ func (p program) run() { select {} } +func tailAndReport(listenFile string, status *Status) { + t, err := tail.TailFile(listenFile, tail.Config{Follow: true}) + for err != nil { + // retry until the file appears + time.Sleep(1 * time.Second) + t, err = tail.TailFile(listenFile, tail.Config{Follow: true}) + } + for line := range t.Lines { + if strings.Contains(line.Text, "$$$") { + status.Info("/install", line.Text) + } + } +} + func (p program) exportProxyEnvVars() { os.Setenv("http_proxy", p.Config.HTTPProxy) os.Setenv("https_proxy", p.Config.HTTPSProxy)