[add] yao service command
This commit is contained in:
parent
deb6ba9135
commit
5332efc532
5 changed files with 210 additions and 2 deletions
|
|
@ -91,6 +91,7 @@ func init() {
|
|||
startCmd,
|
||||
runCmd,
|
||||
initCmd,
|
||||
serviceCmd,
|
||||
)
|
||||
// rootCmd.SetHelpCommand(helpCmd)
|
||||
rootCmd.PersistentFlags().StringVarP(&appPath, "app", "a", "", L("Application directory"))
|
||||
|
|
|
|||
173
cmd/service.go
Normal file
173
cmd/service.go
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/yao/config"
|
||||
"github.com/yaoapp/yao/share"
|
||||
)
|
||||
|
||||
var serviceCmd = &cobra.Command{
|
||||
Use: "service",
|
||||
Short: L("Service manager"),
|
||||
Long: L("Service manager"),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
loadService(config.Conf)
|
||||
command := "ps"
|
||||
if len(args) > 0 {
|
||||
command = args[0]
|
||||
}
|
||||
|
||||
if len(args) > 1 {
|
||||
args = args[1:]
|
||||
} else {
|
||||
args = []string{}
|
||||
}
|
||||
|
||||
switch command {
|
||||
case "ps":
|
||||
services()
|
||||
break
|
||||
case "install", "start", "stop", "remove", "status":
|
||||
serviceManage(command, args)
|
||||
break
|
||||
default:
|
||||
serviceHelp()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func serviceHelp() {
|
||||
fmt.Println("Usage:")
|
||||
fmt.Println(" ", color.GreenString(L("%s service [ps|start|stop|install|status] [all|name]"), share.BUILDNAME))
|
||||
fmt.Println("")
|
||||
}
|
||||
|
||||
func serviceManageAll(command string) {
|
||||
for name := range gou.Services {
|
||||
if name == "all" {
|
||||
continue
|
||||
}
|
||||
serviceManage(command, []string{name})
|
||||
}
|
||||
}
|
||||
|
||||
func serviceManage(command string, args []string) {
|
||||
if len(args) == 0 {
|
||||
serviceHelp()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err := exception.Catch(recover())
|
||||
if err != nil {
|
||||
fmt.Println(color.RedString(L("Fatal: %s"), err.Error()))
|
||||
}
|
||||
}()
|
||||
|
||||
name := args[0]
|
||||
if name == "all" {
|
||||
serviceManageAll(command)
|
||||
return
|
||||
}
|
||||
|
||||
srv := gou.SelectService(name)
|
||||
var status = ""
|
||||
var err error
|
||||
switch command {
|
||||
case "install":
|
||||
status, err = srv.Install()
|
||||
break
|
||||
case "start":
|
||||
status, err = srv.Start()
|
||||
break
|
||||
case "stop":
|
||||
status, err = srv.Stop()
|
||||
break
|
||||
case "remove":
|
||||
status, err = srv.Remove()
|
||||
break
|
||||
case "status":
|
||||
status, err = srv.Status()
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println(color.RedString(L("Fatal: %s"), err.Error()))
|
||||
}
|
||||
|
||||
fmt.Println(status)
|
||||
}
|
||||
|
||||
func services() {
|
||||
for name, srv := range gou.Services {
|
||||
status, err := srv.Status()
|
||||
if err != nil {
|
||||
status = err.Error()
|
||||
}
|
||||
fmt.Println(
|
||||
color.GreenString("%s", name),
|
||||
srv.Name, "....",
|
||||
statusInfo(status),
|
||||
)
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
|
||||
func statusInfo(message string) string {
|
||||
if strings.Contains(message, "stopped") {
|
||||
return statusStop()
|
||||
} else if strings.Contains(message, "not installed") {
|
||||
return statusNotInstalled()
|
||||
} else if strings.Contains(message, "running") {
|
||||
return statusRunning()
|
||||
}
|
||||
return statusUnknown()
|
||||
}
|
||||
|
||||
func statusUnknown() string {
|
||||
return fmt.Sprintf("[ %s ]", color.WhiteString("UNKNOWN"))
|
||||
}
|
||||
|
||||
func statusRunning() string {
|
||||
return fmt.Sprintf("[ %s ]", color.GreenString("RUNNING"))
|
||||
}
|
||||
|
||||
func statusNotInstalled() string {
|
||||
return fmt.Sprintf("[ %s ]", color.YellowString("NOT INSTALLED"))
|
||||
}
|
||||
|
||||
func statusStop() string {
|
||||
return fmt.Sprintf("[ %s ]", color.RedString("STOPED"))
|
||||
}
|
||||
|
||||
// Load 加载API
|
||||
func loadService(cfg config.Config) {
|
||||
var root = filepath.Join(cfg.Root, "services")
|
||||
loadServiceFrom(root, "")
|
||||
}
|
||||
|
||||
func loadServiceFrom(dir string, prefix string) error {
|
||||
|
||||
if share.DirNotExists(dir) {
|
||||
return fmt.Errorf("%s does not exists", dir)
|
||||
}
|
||||
|
||||
err := share.Walk(dir, ".srv.json", func(root, filename string) {
|
||||
name := prefix + share.SpecName(root, filename)
|
||||
content := share.ReadFile(filename)
|
||||
_, err := gou.LoadService(string(content), name)
|
||||
if err != nil {
|
||||
fmt.Println(color.RedString(L("Fatal: %s"), err.Error()))
|
||||
os.Exit(1)
|
||||
}
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
8
go.sum
8
go.sum
|
|
@ -403,6 +403,7 @@ github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9
|
|||
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f h1:a7clxaGmmqtdNTXyvrp/lVO/Gnkzlhc/+dLs5v965GM=
|
||||
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f/go.mod h1:/mK7FZ3mFYEn9zvNPhpngTyatyehSwte5bJZ4ehL5Xw=
|
||||
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
|
|
@ -445,6 +446,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/takama/daemon v1.0.0 h1:XS3VLnFKmqw2Z7fQ/dHRarrVjdir9G3z7BEP8osjizQ=
|
||||
github.com/takama/daemon v1.0.0/go.mod h1:gKlhcjbqtBODg5v9H1nj5dU1a2j2GemtuWSNLD5rxOE=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
|
||||
|
|
@ -638,6 +641,7 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -661,8 +665,8 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d h1:Bm7BNOQt2Qv7ZqysjeLjgCBanX+88Z/OtdvsrEv1Djc=
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs=
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
|
|||
15
tests/services/cmd.srv.json
Normal file
15
tests/services/cmd.srv.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "Service for receiving RFID",
|
||||
"description": "Service for receiving RFID",
|
||||
"version": "0.9.2",
|
||||
"restart": "on-failure",
|
||||
"requires": ["syslog"],
|
||||
"after": ["syslog"],
|
||||
"error": "/var/log/test.err",
|
||||
"output": "/var/log/test.log",
|
||||
"workdir": "~",
|
||||
"command": "tail",
|
||||
"args": ["-f", "/dev/null"],
|
||||
"user": "root",
|
||||
"group": "root"
|
||||
}
|
||||
15
tests/services/process.srv.json
Normal file
15
tests/services/process.srv.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "Service for receiving RFID",
|
||||
"description": "Service for receiving RFID",
|
||||
"version": "0.9.2",
|
||||
"restart": "on-failure",
|
||||
"requires": ["syslog"],
|
||||
"after": ["syslog"],
|
||||
"error": "/var/log/test.err",
|
||||
"output": "/var/log/test.log",
|
||||
"workdir": "~",
|
||||
"process": "xiang.sys.ping",
|
||||
"args": [],
|
||||
"user": "root",
|
||||
"group": "root"
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue