55 "fmt"
66 "os"
77
8+ _ "embed"
9+
810 fakeruntime "github.com/linuxsuren/go-fake-runtime"
911 "github.com/spf13/cobra"
1012)
@@ -22,22 +24,25 @@ func createServiceCommand(execer fakeruntime.Execer) (c *cobra.Command) {
2224 }
2325 flags := c .Flags ()
2426 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" )
2628 return
2729}
2830
2931type serviceOption struct {
3032 action string
3133 scriptPath string
34+ service Service
3235 fakeruntime.Execer
3336}
3437
3538func (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 )
4146 }
4247 return
4348}
@@ -46,17 +51,15 @@ func (o *serviceOption) runE(c *cobra.Command, args []string) (err error) {
4651 var output string
4752 switch o .action {
4853 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 ()
5255 case "start" :
53- output , err = o .Execer . RunCommandAndReturn ( "systemctl" , "" , "start" , "atest" )
56+ output , err = o .service . Start ( )
5457 case "stop" :
55- output , err = o .Execer . RunCommandAndReturn ( "systemctl" , "" , "stop" , "atest" )
58+ output , err = o .service . Stop ( )
5659 case "restart" :
57- output , err = o .Execer . RunCommandAndReturn ( "systemctl" , "" , "restart" , "atest" )
60+ output , err = o .service . Restart ( )
5861 case "status" :
59- output , err = o .Execer . RunCommandAndReturn ( "systemctl" , "" , "status" , "atest" )
62+ output , err = o .service . Status ( )
6063 default :
6164 err = fmt .Errorf ("not support action: '%s'" , o .action )
6265 }
@@ -67,12 +70,117 @@ func (o *serviceOption) runE(c *cobra.Command, args []string) (err error) {
6770 return
6871}
6972
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+ )
72127
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+ }
75132
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