From 3905df9509c4ffb82783a27262944c69f55182ab Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 10 Jul 2017 11:53:52 +0200 Subject: [PATCH 1/3] Add listener for installation flow control --- install.go | 7 ++++--- main.go | 27 +++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/install.go b/install.go index 78e41c9e..2bebd3f1 100644 --- a/install.go +++ b/install.go @@ -251,7 +251,8 @@ func requestURL(token string) (string, error) { } type program struct { - Config Config + Config Config + listenFile string } // Start run the program asynchronously @@ -266,7 +267,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{ @@ -277,7 +278,7 @@ func createService(config Config) (service.Service, error) { WorkingDirectory: workingDirectory, } - 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 4544deaf..9ede45f6 100644 --- a/main.go +++ b/main.go @@ -12,11 +12,13 @@ import ( "os/exec" "path/filepath" "strconv" + "strings" "syscall" "time" "github.com/davecgh/go-spew/spew" mqtt "github.com/eclipse/paho.mqtt.golang" + "github.com/hpcloud/tail" "github.com/kardianos/osext" "github.com/namsral/flag" "github.com/pkg/errors" @@ -48,6 +50,7 @@ func main() { config := Config{} var doInstall = flag.Bool("install", false, "Install as a service") + 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") @@ -59,12 +62,14 @@ func main() { flag.Parse() // Create service and install - s, err := createService(config) + s, err := createService(config, *listenFile) check(err, "CreateService") if *doInstall { install(s, config, *token) - return + if len(*listenFile) == 0 { + return + } } err = s.Run() @@ -86,6 +91,10 @@ func (p program) run() { // Create global status status := NewStatus(p.Config.ID, client) + if len(p.listenFile) > 0 { + go tailAndReport(p.listenFile, status) + } + // Subscribe to /upload endpoint client.Subscribe("$aws/things/"+p.Config.ID+"/upload/post", 1, UploadCB(status)) client.Subscribe("$aws/things/"+p.Config.ID+"/sketch", 1, SketchCB(status)) @@ -93,6 +102,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) From d91f181c6203ea8725d9a719f5cbee7dc63851ab Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 10 Jul 2017 12:16:19 +0200 Subject: [PATCH 2/3] split installation and registration --- install.go | 16 ++++++++++------ main.go | 22 ++++++++++++---------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/install.go b/install.go index 2bebd3f1..c59326fb 100644 --- a/install.go +++ b/install.go @@ -31,8 +31,16 @@ const ( devicesAPI = "https://api-dev.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), 0600) 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) diff --git a/main.go b/main.go index 9ede45f6..9d039188 100644 --- a/main.go +++ b/main.go @@ -38,11 +38,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 } @@ -50,6 +50,7 @@ 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") @@ -65,11 +66,12 @@ func main() { s, err := createService(config, *listenFile) check(err, "CreateService") + if *doRegister { + register(config, *token) + } + if *doInstall { - install(s, config, *token) - if len(*listenFile) == 0 { - return - } + install(s) } err = s.Run() @@ -91,7 +93,7 @@ func (p program) run() { // Create global status status := NewStatus(p.Config.ID, client) - if len(p.listenFile) > 0 { + if p.listenFile != "" { go tailAndReport(p.listenFile, status) } From 1047723ec68d24dfdc8c113d4c0f1c2f583d295f Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 13 Jul 2017 11:01:01 +0200 Subject: [PATCH 3/3] add dependencies to service --- install.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install.go b/install.go index c59326fb..2b83e2fb 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" ) @@ -280,6 +280,7 @@ func createService(config Config, listenFile string) (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, listenFile}