generated from brevdev/seed
-
Notifications
You must be signed in to change notification settings - Fork 9
/
darwin.go
124 lines (110 loc) · 3.04 KB
/
darwin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package autostartconf
import (
"errors"
"os/exec"
"path"
breverrors "github.com/brevdev/brev-cli/pkg/errors"
"github.com/hashicorp/go-multierror"
)
type DarwinServiceType string
const (
System DarwinServiceType = "system"
SingleUser DarwinServiceType = "singleuser"
)
type DarwinPlistConfigurer struct {
Store AutoStartStore
ValueConfigFile string
ServiceName string
ServiceType DarwinServiceType
}
func (dpc DarwinPlistConfigurer) UnInstall() error {
destination, err := dpc.GetDestination()
if err != nil {
return breverrors.WrapAndTrace(err)
}
var allError error
switch dpc.ServiceType {
case System:
_, err = exec.Command("launchctl", "unload", "-w", destination).CombinedOutput() // #nosec G204
if err != nil {
allError = multierror.Append(allError, err)
}
case SingleUser:
_, err = exec.Command("launchctl", "bootout", "guui/"+dpc.Store.GetOSUser(), destination).CombinedOutput() // #nosec G204
if err != nil {
allError = multierror.Append(allError, err)
}
}
err = dpc.Store.Remove(destination)
if err != nil {
allError = multierror.Append(allError, err)
}
// err = dpc.Store.Remove(targetBin)
// if err != nil {
// return breverrors.WrapAndTrace(err)
// }
if allError != nil {
return breverrors.WrapAndTrace(allError)
}
return nil
}
func (dpc DarwinPlistConfigurer) Install() error {
_ = dpc.UnInstall()
err := dpc.Store.CopyBin(targetBin)
if err != nil {
return breverrors.WrapAndTrace(err)
}
destination, err := dpc.GetDestination()
if err != nil {
return breverrors.WrapAndTrace(err)
}
err = dpc.Store.WriteString(destination, dpc.ValueConfigFile)
if err != nil {
return breverrors.WrapAndTrace(err)
}
commands, err := dpc.GetExecCommand()
if err != nil {
return breverrors.WrapAndTrace(err)
}
err = execCommands(commands)
if err != nil {
return breverrors.WrapAndTrace(err)
}
return nil
}
func (dpc DarwinPlistConfigurer) GetDestinationDirectory() (string, error) {
switch dpc.ServiceType {
case System:
return "/Library/LaunchDaemons", nil
case SingleUser:
homeDir, err := dpc.Store.UserHomeDir()
if err != nil {
return "", breverrors.WrapAndTrace(err)
}
return path.Join(homeDir, "/Library/LaunchDaemons"), nil
}
return "", errors.New("invalid service type")
}
func (dpc DarwinPlistConfigurer) GetDestination() (string, error) {
destinationDirectory, err := dpc.GetDestinationDirectory()
if err != nil {
return "", breverrors.WrapAndTrace(err)
}
destination := path.Join(destinationDirectory, dpc.ServiceName+".plist")
return destination, nil
}
func (dpc DarwinPlistConfigurer) GetExecCommand() ([][]string, error) {
destination, err := dpc.GetDestination()
if err != nil {
return [][]string{}, breverrors.WrapAndTrace(err)
}
switch dpc.ServiceType {
case System:
return [][]string{
{"launchctl", "load", "-w", destination},
}, nil
case SingleUser: // todo still not sure if this works
return [][]string{{"launchctl", "bootstrap", "gui/" + dpc.Store.GetOSUser(), destination}}, nil
}
return [][]string{}, errors.New("invalid service type")
}