Skip to content

Commit 77d7177

Browse files
committed
feat:add sys service
1 parent 5b94130 commit 77d7177

File tree

8 files changed

+264
-62
lines changed

8 files changed

+264
-62
lines changed

cmd/run/root.go

Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,13 @@ package run
22

33
import (
44
"bytes"
5-
"context"
65
"encoding/json"
76
"fmt"
87
"grm/common"
98
"grm/global"
10-
"grm/router"
11-
"grm/web"
12-
"io/ioutil"
13-
"log"
14-
"net"
15-
"net/http"
169
"os"
17-
"os/signal"
1810
"strings"
19-
"time"
2011

21-
"github.com/gin-gonic/gin"
2212
"github.com/spf13/cobra"
2313
)
2414

@@ -29,28 +19,40 @@ var CmdRun = &cobra.Command{
2919
}
3020

3121
var (
32-
host string
33-
port string
34-
confirm string
22+
host string
23+
port string
24+
confirm string
25+
stop bool
26+
start bool
27+
install bool
28+
uninstall bool
29+
daemon bool
3530
)
3631

3732
func init() {
38-
confirm = "n"
33+
confirm = "y"
3934
CmdRun.Flags().StringVarP(&host, "host", "H", global.GlobalConf.Host, "input hostname")
4035
CmdRun.Flags().StringVarP(&port, "port", "p", global.GlobalConf.Port, "input port")
36+
CmdRun.PersistentFlags().BoolVarP(&install, "install", "i", false, "install service")
37+
CmdRun.PersistentFlags().BoolVarP(&uninstall, "uninstall", "u", false, "uninstall service")
38+
CmdRun.PersistentFlags().BoolVarP(&start, "start", "", false, "start service")
39+
CmdRun.PersistentFlags().BoolVarP(&stop, "stop", "", false, "stop service")
40+
CmdRun.PersistentFlags().BoolVarP(&daemon, "daemon", "", false, "daemon service")
4141
}
4242

4343
func runFunction(cmd *cobra.Command, args []string) {
4444

45-
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 33, "================", 0x1B)
46-
fmt.Printf("%c[%d;%d;%dm Host:%s%c[0m \n", 0x1B, 0, 40, 33, host, 0x1B)
47-
fmt.Printf("%c[%d;%d;%dm Port:%s%c[0m \n", 0x1B, 0, 40, 33, port, 0x1B)
48-
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 33, "================", 0x1B)
49-
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 33, "Do you want to run the app at this address? Y/N", 0x1B)
50-
fmt.Scan(&confirm)
45+
if !uninstall && !start && !stop && !daemon {
46+
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 33, "================", 0x1B)
47+
fmt.Printf("%c[%d;%d;%dm Host:%s%c[0m \n", 0x1B, 0, 40, 33, host, 0x1B)
48+
fmt.Printf("%c[%d;%d;%dm Port:%s%c[0m \n", 0x1B, 0, 40, 33, port, 0x1B)
49+
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 33, "================", 0x1B)
50+
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 33, "Do you want to run the app at this address? Y/N", 0x1B)
51+
fmt.Scan(&confirm)
5152

52-
if strings.ToUpper(confirm) == "N" {
53-
os.Exit(0)
53+
if strings.ToUpper(confirm) == "N" {
54+
os.Exit(0)
55+
}
5456
}
5557

5658
//保存host和port信息
@@ -60,48 +62,57 @@ func runFunction(cmd *cobra.Command, args []string) {
6062
global.GlobalConf.Port = port
6163
err := encoder.Encode(global.GlobalConf)
6264
if err != nil {
63-
fmt.Println(err)
65+
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 31, err.Error(), 0x1B)
66+
os.Exit(0)
6467
}
6568
if err = common.WriteData(buffer.Bytes()); err != nil {
66-
fmt.Println(err)
69+
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 31, err.Error(), 0x1B)
70+
os.Exit(0)
6771
}
6872

69-
gin.SetMode(gin.ReleaseMode)
70-
gin.DefaultWriter = ioutil.Discard
71-
72-
router := router.Init()
73+
s := GetSrv()
7374

74-
router.StaticFS("/static", web.StaticsFs)
75-
76-
srv := &http.Server{
77-
Addr: net.JoinHostPort(host, port),
78-
Handler: router,
79-
}
80-
81-
go func() {
82-
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
83-
log.Fatalf("listen: %s\n", err)
75+
if install || uninstall || start || stop {
76+
if install {
77+
if err := s.Install(); err != nil {
78+
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 31, err.Error(), 0x1B)
79+
return
80+
}
81+
fmt.Printf("服务已安装")
82+
return
8483
}
85-
}()
86-
87-
quit := make(chan os.Signal)
8884

89-
signal.Notify(quit, os.Interrupt)
90-
91-
//输出LOGO
92-
common.ShowLogo(host, port)
93-
94-
<-quit
95-
96-
log.Println("Shutdown Server ...")
85+
if uninstall {
86+
if err := s.Uninstall(); err != nil {
87+
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 31, err.Error(), 0x1B)
88+
return
89+
}
90+
fmt.Printf("服务已卸载")
91+
return
92+
}
9793

98-
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
94+
if start {
95+
if err := s.Start(); err != nil {
96+
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 31, err.Error(), 0x1B)
97+
return
98+
}
99+
fmt.Printf("服务已启动")
100+
return
101+
}
99102

100-
defer cancel()
103+
if stop {
104+
if err := s.Stop(); err != nil {
105+
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 31, err.Error(), 0x1B)
106+
return
107+
}
108+
fmt.Printf("服务已关闭")
109+
return
110+
}
111+
}
101112

102-
if err := srv.Shutdown(ctx); err != nil {
103-
log.Fatal("Server Shutdown:", err)
113+
err = s.Run()
114+
if err != nil {
115+
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 31, err.Error(), 0x1B)
104116
}
105117

106-
log.Println("Server exiting")
107118
}

cmd/run/service.go

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package run
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"grm/common"
7+
"grm/global"
8+
"grm/router"
9+
"grm/web"
10+
"io"
11+
"log"
12+
"net"
13+
"net/http"
14+
"os"
15+
"os/signal"
16+
"time"
17+
18+
"github.com/gin-gonic/gin"
19+
"github.com/kardianos/service"
20+
)
21+
22+
type Services struct {
23+
Log service.Logger
24+
Srv *http.Server
25+
Cfg *service.Config
26+
}
27+
28+
// 获取 service 对象
29+
func GetSrv() service.Service {
30+
31+
path, err := common.RootPath()
32+
if err != nil {
33+
fmt.Println(err)
34+
os.Exit(0)
35+
}
36+
37+
File, err := common.OpenFile(path + "/log/service.log")
38+
if err != nil {
39+
fmt.Println(err)
40+
os.Exit(0)
41+
}
42+
defer File.Close()
43+
44+
log.SetOutput(File)
45+
46+
s := &Services{
47+
Cfg: &service.Config{
48+
Name: "grm",
49+
DisplayName: "grm",
50+
Description: "Redis管理工具",
51+
Arguments: []string{"run", "--daemon"},
52+
}}
53+
serv, err := service.New(s, s.Cfg)
54+
if err != nil {
55+
log.Printf("Set logger error:%s\n", err.Error())
56+
}
57+
s.Log, err = serv.SystemLogger(nil)
58+
if err != nil {
59+
log.Printf("Set logger error:%s\n", err.Error())
60+
}
61+
62+
return serv
63+
}
64+
65+
// 启动windows服务
66+
func (srv *Services) Start(s service.Service) error {
67+
68+
if srv.Log != nil {
69+
srv.Log.Info("Start run http server")
70+
}
71+
72+
go srv.StarServer()
73+
return nil
74+
}
75+
76+
// 停止windows服务
77+
func (srv *Services) Stop(s service.Service) error {
78+
if srv.Log != nil {
79+
srv.Log.Info("Start stop http server")
80+
}
81+
log.Println("Server exiting")
82+
return srv.Srv.Shutdown(context.Background())
83+
}
84+
85+
// 运行web服务
86+
func (srv *Services) StarServer() {
87+
88+
gin.DisableConsoleColor()
89+
gin.SetMode(gin.ReleaseMode)
90+
91+
path, err := common.RootPath()
92+
if err != nil {
93+
fmt.Println(err)
94+
os.Exit(0)
95+
}
96+
97+
// 创建记录日志的文件
98+
f, err := common.OpenFile(path + "/log/grm.log")
99+
if err != nil {
100+
fmt.Println(err)
101+
os.Exit(0)
102+
}
103+
104+
gin.DefaultWriter = io.MultiWriter(f)
105+
106+
router := router.Init()
107+
108+
router.StaticFS("/static", web.StaticsFs)
109+
110+
srv.Srv = &http.Server{
111+
Addr: net.JoinHostPort(global.GlobalConf.Host, global.GlobalConf.Port),
112+
Handler: router,
113+
}
114+
115+
go func() {
116+
if err := srv.Srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
117+
log.Fatalf("listen: %s\n", err)
118+
}
119+
}()
120+
121+
quit := make(chan os.Signal)
122+
123+
signal.Notify(quit, os.Interrupt)
124+
125+
//输出LOGO
126+
common.ShowLogo(host, port)
127+
128+
<-quit
129+
130+
log.Println("Shutdown Server ...")
131+
132+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
133+
134+
defer cancel()
135+
136+
if err := srv.Srv.Shutdown(ctx); err != nil {
137+
log.Fatal("Server Shutdown:", err)
138+
}
139+
140+
log.Println("Server exiting")
141+
}

common/ssh.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
package common
77

88
import (
9-
"fmt"
9+
"log"
1010
"net"
1111
"time"
1212

13+
"github.com/pkg/errors"
1314
"golang.org/x/crypto/ssh"
1415
)
1516

@@ -28,14 +29,14 @@ func GetSSHClient(user, pass, addr string) (*ssh.Client, error) {
2829

2930
sshConn, err := net.Dial("tcp", addr)
3031
if nil != err {
31-
fmt.Println("net dial err: ", err)
32+
log.Printf("%+v", errors.WithStack(err))
3233
return nil, err
3334
}
3435

3536
clientConn, chans, reqs, err := ssh.NewClientConn(sshConn, addr, config)
3637
if nil != err {
3738
sshConn.Close()
38-
fmt.Println("ssh client conn err: ", err)
39+
log.Printf("%+v", errors.WithStack(err))
3940
return nil, err
4041
}
4142

common/storage.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ func aesDecrypt(cipherText []byte) []byte {
3737
}
3838

3939
func WriteData(data []byte) error {
40-
file, err := os.OpenFile("storage.grm", os.O_CREATE|os.O_RDWR, 0644)
40+
41+
path, err := RootPath()
42+
if err != nil {
43+
return err
44+
}
45+
46+
file, err := os.OpenFile(path+"/storage.grm", os.O_CREATE|os.O_RDWR, 0644)
4147
if err != nil {
4248
return err
4349
}
@@ -54,7 +60,12 @@ func WriteData(data []byte) error {
5460

5561
func ReadData() ([]byte, error) {
5662

57-
file, err := os.OpenFile("storage.grm", os.O_CREATE|os.O_RDWR, 0644)
63+
path, err := RootPath()
64+
if err != nil {
65+
return nil, err
66+
}
67+
68+
file, err := os.OpenFile(path+"/storage.grm", os.O_CREATE|os.O_RDWR, 0644)
5869
if err != nil {
5970
return nil, err
6071
}

0 commit comments

Comments
 (0)