Skip to content

Update the autostart file when it's required #791

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 43 additions & 17 deletions config/autostart.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package config

import (
"bytes"
// we need this for the ArduinoCreateAgent.plist in this package
_ "embed"
"os"
Expand All @@ -38,33 +39,55 @@ func getLaunchdAgentPath() *paths.Path {
func InstallPlistFile() {
launchdAgentPath := getLaunchdAgentPath()
if !launchdAgentPath.Exist() {
err := writePlistFile(launchdAgentPath)
if err != nil {
log.Error(err)
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()
launchAgentContentNew, _ := getLaunchdAgentDefinition()
if bytes.Equal(launchAgentContent, launchAgentContentNew) {
log.Infof("the autostart file %s already exists: nothing to do", launchdAgentPath)
} 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.Infof("the autostart file %s needs to be updated", launchdAgentPath)
removePlistFile()
writeAndLoadPlistFile(launchdAgentPath)
}
} 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)

}
}

// 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)
} else {
err = loadLaunchdAgent() // this will load the agent: basically starting a new instance
if err != nil {
log.Error(err)
}
}
}

// writePlistFile function will write the required plist file to launchdAgentPath
// 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
Expand All @@ -76,9 +99,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
Expand Down