5
5
"fmt"
6
6
"os"
7
7
8
+ _ "embed"
9
+
8
10
fakeruntime "github.com/linuxsuren/go-fake-runtime"
9
11
"github.com/spf13/cobra"
10
12
)
@@ -22,22 +24,25 @@ func createServiceCommand(execer fakeruntime.Execer) (c *cobra.Command) {
22
24
}
23
25
flags := c .Flags ()
24
26
flags .StringVarP (& opt .action , "action" , "a" , "" , "The action of service, support actions: install, start, stop, restart, status" )
25
- flags .StringVarP (& opt .scriptPath , "script-path" , "" , "/lib/systemd/system/atest.service " , "The service script file path" )
27
+ flags .StringVarP (& opt .scriptPath , "script-path" , "" , "" , "The service script file path" )
26
28
return
27
29
}
28
30
29
31
type serviceOption struct {
30
32
action string
31
33
scriptPath string
34
+ service Service
32
35
fakeruntime.Execer
33
36
}
34
37
35
38
func (o * serviceOption ) preRunE (c * cobra.Command , args []string ) (err error ) {
36
- if o .Execer .OS () != "linux" {
37
- err = fmt .Errorf ("only support on Linux" )
38
- }
39
- if o .action == "" && len (args ) > 0 {
40
- o .action = args [0 ]
39
+ if o .Execer .OS () != fakeruntime .OSLinux && o .Execer .OS () != fakeruntime .OSDarwin {
40
+ err = fmt .Errorf ("only support on Linux/Darwin instead of %s" , o .Execer .OS ())
41
+ } else {
42
+ if o .action == "" && len (args ) > 0 {
43
+ o .action = args [0 ]
44
+ }
45
+ o .service = newService (o .Execer , o .scriptPath )
41
46
}
42
47
return
43
48
}
@@ -46,17 +51,15 @@ func (o *serviceOption) runE(c *cobra.Command, args []string) (err error) {
46
51
var output string
47
52
switch o .action {
48
53
case "install" , "i" :
49
- if err = os .WriteFile (o .scriptPath , []byte (script ), os .ModeAppend ); err == nil {
50
- output , err = o .Execer .RunCommandAndReturn ("systemctl" , "" , "enable" , "atest" )
51
- }
54
+ output , err = o .service .Install ()
52
55
case "start" :
53
- output , err = o .Execer . RunCommandAndReturn ( "systemctl" , "" , "start" , "atest" )
56
+ output , err = o .service . Start ( )
54
57
case "stop" :
55
- output , err = o .Execer . RunCommandAndReturn ( "systemctl" , "" , "stop" , "atest" )
58
+ output , err = o .service . Stop ( )
56
59
case "restart" :
57
- output , err = o .Execer . RunCommandAndReturn ( "systemctl" , "" , "restart" , "atest" )
60
+ output , err = o .service . Restart ( )
58
61
case "status" :
59
- output , err = o .Execer . RunCommandAndReturn ( "systemctl" , "" , "status" , "atest" )
62
+ output , err = o .service . Status ( )
60
63
default :
61
64
err = fmt .Errorf ("not support action: '%s'" , o .action )
62
65
}
@@ -67,12 +70,117 @@ func (o *serviceOption) runE(c *cobra.Command, args []string) (err error) {
67
70
return
68
71
}
69
72
70
- var script = `[Unit]
71
- Description=API Testing
73
+ // Service is the interface of service
74
+ type Service interface {
75
+ Start () (string , error ) // start the service
76
+ Stop () (string , error ) // stop the service gracefully
77
+ Restart () (string , error ) // restart the service gracefully
78
+ Status () (string , error ) // status of the service
79
+ Install () (string , error ) // install the service
80
+ }
81
+
82
+ func emptyThenDefault (value , defaultValue string ) string {
83
+ if value == "" {
84
+ value = defaultValue
85
+ }
86
+ return value
87
+ }
88
+
89
+ func newService (execer fakeruntime.Execer , scriptPath string ) (service Service ) {
90
+ switch execer .OS () {
91
+ case fakeruntime .OSDarwin :
92
+ service = & macOSService {
93
+ commonService : commonService {
94
+ Execer : execer ,
95
+ scriptPath : emptyThenDefault (scriptPath , "/Library/LaunchDaemons/com.github.linuxsuren.atest.plist" ),
96
+ script : macOSServiceScript ,
97
+ },
98
+ }
99
+ case fakeruntime .OSLinux :
100
+ service = & linuxService {
101
+ commonService : commonService {
102
+ Execer : execer ,
103
+ scriptPath : emptyThenDefault (scriptPath , "/lib/systemd/system/atest.service" ),
104
+ script : linuxServiceScript ,
105
+ },
106
+ }
107
+ }
108
+ return
109
+ }
110
+
111
+ type commonService struct {
112
+ fakeruntime.Execer
113
+ scriptPath string
114
+ script string
115
+ }
116
+
117
+ type macOSService struct {
118
+ commonService
119
+ }
120
+
121
+ var (
122
+ //go:embed data/macos_service.xml
123
+ macOSServiceScript string
124
+ //go:embed data/linux_service.txt
125
+ linuxServiceScript string
126
+ )
72
127
73
- [Service]
74
- ExecStart=/usr/bin/env atest server
128
+ func (s * macOSService ) Start () (output string , err error ) {
129
+ output , err = s .Execer .RunCommandAndReturn ("sudo" , "" , "launchctl" , "start" , "com.github.linuxsuren.atest" )
130
+ return
131
+ }
75
132
76
- [Install]
77
- WantedBy=multi-user.target
78
- `
133
+ func (s * macOSService ) Stop () (output string , err error ) {
134
+ output , err = s .Execer .RunCommandAndReturn ("sudo" , "" , "launchctl" , "stop" , "com.github.linuxsuren.atest" )
135
+ return
136
+ }
137
+
138
+ func (s * macOSService ) Restart () (output string , err error ) {
139
+ if output , err = s .Stop (); err == nil {
140
+ output , err = s .Start ()
141
+ }
142
+ return
143
+ }
144
+
145
+ func (s * macOSService ) Status () (output string , err error ) {
146
+ output , err = s .Execer .RunCommandAndReturn ("sudo" , "" , "launchctl" , "runstats" , "system/com.github.linuxsuren.atest" )
147
+ return
148
+ }
149
+
150
+ func (s * macOSService ) Install () (output string , err error ) {
151
+ if err = os .WriteFile (s .scriptPath , []byte (s .script ), os .ModeAppend ); err == nil {
152
+ output , err = s .Execer .RunCommandAndReturn ("sudo" , "" , "launchctl" , "enable" , "system/com.github.linuxsuren.atest" )
153
+ }
154
+ return
155
+ }
156
+
157
+ type linuxService struct {
158
+ commonService
159
+ }
160
+
161
+ func (s * linuxService ) Start () (output string , err error ) {
162
+ output , err = s .Execer .RunCommandAndReturn ("systemctl" , "" , "start" , "atest" )
163
+ return
164
+ }
165
+
166
+ func (s * linuxService ) Stop () (output string , err error ) {
167
+ output , err = s .Execer .RunCommandAndReturn ("systemctl" , "" , "stop" , "atest" )
168
+ return
169
+ }
170
+
171
+ func (s * linuxService ) Restart () (output string , err error ) {
172
+ output , err = s .Execer .RunCommandAndReturn ("systemctl" , "" , "restart" , "atest" )
173
+ return
174
+ }
175
+
176
+ func (s * linuxService ) Status () (output string , err error ) {
177
+ output , err = s .Execer .RunCommandAndReturn ("systemctl" , "" , "status" , "atest" )
178
+ return
179
+ }
180
+
181
+ func (s * linuxService ) Install () (output string , err error ) {
182
+ if err = os .WriteFile (s .scriptPath , []byte (s .script ), os .ModeAppend ); err == nil {
183
+ output , err = s .Execer .RunCommandAndReturn ("systemctl" , "" , "enable" , "atest" )
184
+ }
185
+ return
186
+ }
0 commit comments