From 038acf6a2e26b56b312795cc973f8ab11e651e70 Mon Sep 17 00:00:00 2001 From: Umberto Baldi Date: Fri, 19 May 2023 17:59:55 +0200 Subject: [PATCH 1/2] the agent is now able to detect if the autostart file is updated or not --- config/autostart.go | 59 +++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/config/autostart.go b/config/autostart.go index c6b2b8d52..411809d7e 100644 --- a/config/autostart.go +++ b/config/autostart.go @@ -15,6 +15,7 @@ package config import ( + "bytes" // we need this for the ArduinoCreateAgent.plist in this package _ "embed" "os" @@ -38,22 +39,35 @@ func getLaunchdAgentPath() *paths.Path { func InstallPlistFile() { launchdAgentPath := getLaunchdAgentPath() if !launchdAgentPath.Exist() { - err := writePlistFile(launchdAgentPath) + writeLoadExit(launchdAgentPath) + } else { + // we already have an existing launchd plist file, so we check if it's updated + launchAgentContent, _ := launchdAgentPath.ReadFile() + launchAgentContentNew, _ := getLaunchdAgentDefinition() + if bytes.Equal(launchAgentContent, launchAgentContentNew) { + log.Infof("the autostart file %s already exists: nothing to do", launchdAgentPath) + } else { + log.Infof("the autostart file %s needs to be updated", launchdAgentPath) + removePlistFile() + writeLoadExit(launchdAgentPath) + } + + } +} + +// writeLoadExit function will write the plist file, load it, and then exit, because launchd will start a new instance. +func writeLoadExit(launchdAgentPath *paths.Path) { + err := writePlistFile(launchdAgentPath) + if err != nil { + log.Error(err) + } else { + err = loadLaunchdAgent() // this will load the agent: basically starting a new instance if err != nil { log.Error(err) } else { - err = loadLaunchdAgent() // this will load the agent: basically starting a new instance - if err != nil { - log.Error(err) - } else { - log.Info("Quitting, another instance of the agent has been started by launchd") - os.Exit(0) - } + log.Info("Quitting, another instance of the agent has been started by launchd") + os.Exit(0) } - } else { - // we already have an existing launchd plist file, so we don't have to do anything - log.Infof("the autostart file %s already exists: nothing to do", launchdAgentPath) - } } @@ -61,10 +75,20 @@ func InstallPlistFile() { // it will return nil in case of success, // it will error in any other case func writePlistFile(launchdAgentPath *paths.Path) error { + definition, err := getLaunchdAgentDefinition() + if err != nil { + return err + } + // we need to create a new launchd plist file + return launchdAgentPath.WriteFile(definition) +} + +// getLaunchdAgentDefinition will return the definition of the new LaunchdAgent +func getLaunchdAgentDefinition() ([]byte, error) { src, err := os.Executable() if err != nil { - return err + return nil, err } data := struct { Program string @@ -76,9 +100,12 @@ func writePlistFile(launchdAgentPath *paths.Path) error { t := template.Must(template.New("launchdConfig").Parse(string(launchdAgentDefinition))) - // we need to create a new launchd plist file - plistFile, _ := launchdAgentPath.Create() - return t.Execute(plistFile, data) + buf := bytes.NewBuffer(nil) + err = t.Execute(buf, data) + if err != nil { + return nil, err + } + return buf.Bytes(), nil } // loadLaunchdAgent will use launchctl to load the agent, will return an error if something goes wrong From 21b691e7de58cbdd3bca76a52130627c6aafde55 Mon Sep 17 00:00:00 2001 From: Umberto Baldi Date: Mon, 22 May 2023 15:52:49 +0200 Subject: [PATCH 2/2] exit only if the launchd file not exist Otherwise the agent is not started at all --- config/autostart.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/config/autostart.go b/config/autostart.go index 411809d7e..1f8d81fec 100644 --- a/config/autostart.go +++ b/config/autostart.go @@ -39,7 +39,9 @@ func getLaunchdAgentPath() *paths.Path { func InstallPlistFile() { launchdAgentPath := getLaunchdAgentPath() if !launchdAgentPath.Exist() { - writeLoadExit(launchdAgentPath) + writeAndLoadPlistFile(launchdAgentPath) + log.Info("Quitting, another instance of the agent has been started by launchd") + os.Exit(0) } else { // we already have an existing launchd plist file, so we check if it's updated launchAgentContent, _ := launchdAgentPath.ReadFile() @@ -49,14 +51,14 @@ func InstallPlistFile() { } else { log.Infof("the autostart file %s needs to be updated", launchdAgentPath) removePlistFile() - writeLoadExit(launchdAgentPath) + writeAndLoadPlistFile(launchdAgentPath) } } } -// writeLoadExit function will write the plist file, load it, and then exit, because launchd will start a new instance. -func writeLoadExit(launchdAgentPath *paths.Path) { +// writeAndLoadPlistFile function will write the plist file, load it, and then exit, because launchd will start a new instance. +func writeAndLoadPlistFile(launchdAgentPath *paths.Path) { err := writePlistFile(launchdAgentPath) if err != nil { log.Error(err) @@ -64,9 +66,6 @@ func writeLoadExit(launchdAgentPath *paths.Path) { err = loadLaunchdAgent() // this will load the agent: basically starting a new instance if err != nil { log.Error(err) - } else { - log.Info("Quitting, another instance of the agent has been started by launchd") - os.Exit(0) } } }