Skip to content

Commit

Permalink
feat:add sys service
Browse files Browse the repository at this point in the history
  • Loading branch information
gphper committed Sep 25, 2022
1 parent 5b94130 commit 77d7177
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 62 deletions.
119 changes: 65 additions & 54 deletions cmd/run/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,13 @@ package run

import (
"bytes"
"context"
"encoding/json"
"fmt"
"grm/common"
"grm/global"
"grm/router"
"grm/web"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"os/signal"
"strings"
"time"

"github.com/gin-gonic/gin"
"github.com/spf13/cobra"
)

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

var (
host string
port string
confirm string
host string
port string
confirm string
stop bool
start bool
install bool
uninstall bool
daemon bool
)

func init() {
confirm = "n"
confirm = "y"
CmdRun.Flags().StringVarP(&host, "host", "H", global.GlobalConf.Host, "input hostname")
CmdRun.Flags().StringVarP(&port, "port", "p", global.GlobalConf.Port, "input port")
CmdRun.PersistentFlags().BoolVarP(&install, "install", "i", false, "install service")
CmdRun.PersistentFlags().BoolVarP(&uninstall, "uninstall", "u", false, "uninstall service")
CmdRun.PersistentFlags().BoolVarP(&start, "start", "", false, "start service")
CmdRun.PersistentFlags().BoolVarP(&stop, "stop", "", false, "stop service")
CmdRun.PersistentFlags().BoolVarP(&daemon, "daemon", "", false, "daemon service")
}

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

fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 33, "================", 0x1B)
fmt.Printf("%c[%d;%d;%dm Host:%s%c[0m \n", 0x1B, 0, 40, 33, host, 0x1B)
fmt.Printf("%c[%d;%d;%dm Port:%s%c[0m \n", 0x1B, 0, 40, 33, port, 0x1B)
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 33, "================", 0x1B)
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)
fmt.Scan(&confirm)
if !uninstall && !start && !stop && !daemon {
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 33, "================", 0x1B)
fmt.Printf("%c[%d;%d;%dm Host:%s%c[0m \n", 0x1B, 0, 40, 33, host, 0x1B)
fmt.Printf("%c[%d;%d;%dm Port:%s%c[0m \n", 0x1B, 0, 40, 33, port, 0x1B)
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 33, "================", 0x1B)
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)
fmt.Scan(&confirm)

if strings.ToUpper(confirm) == "N" {
os.Exit(0)
if strings.ToUpper(confirm) == "N" {
os.Exit(0)
}
}

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

gin.SetMode(gin.ReleaseMode)
gin.DefaultWriter = ioutil.Discard

router := router.Init()
s := GetSrv()

router.StaticFS("/static", web.StaticsFs)

srv := &http.Server{
Addr: net.JoinHostPort(host, port),
Handler: router,
}

go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
if install || uninstall || start || stop {
if install {
if err := s.Install(); err != nil {
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 31, err.Error(), 0x1B)
return
}
fmt.Printf("服务已安装")
return
}
}()

quit := make(chan os.Signal)

signal.Notify(quit, os.Interrupt)

//输出LOGO
common.ShowLogo(host, port)

<-quit

log.Println("Shutdown Server ...")
if uninstall {
if err := s.Uninstall(); err != nil {
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 31, err.Error(), 0x1B)
return
}
fmt.Printf("服务已卸载")
return
}

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

defer cancel()
if stop {
if err := s.Stop(); err != nil {
fmt.Printf("%c[%d;%d;%dm%s%c[0m \n", 0x1B, 0, 40, 31, err.Error(), 0x1B)
return
}
fmt.Printf("服务已关闭")
return
}
}

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

log.Println("Server exiting")
}
141 changes: 141 additions & 0 deletions cmd/run/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package run

import (
"context"
"fmt"
"grm/common"
"grm/global"
"grm/router"
"grm/web"
"io"
"log"
"net"
"net/http"
"os"
"os/signal"
"time"

"github.com/gin-gonic/gin"
"github.com/kardianos/service"
)

type Services struct {
Log service.Logger
Srv *http.Server
Cfg *service.Config
}

// 获取 service 对象
func GetSrv() service.Service {

path, err := common.RootPath()
if err != nil {
fmt.Println(err)
os.Exit(0)
}

File, err := common.OpenFile(path + "/log/service.log")
if err != nil {
fmt.Println(err)
os.Exit(0)
}
defer File.Close()

log.SetOutput(File)

s := &Services{
Cfg: &service.Config{
Name: "grm",
DisplayName: "grm",
Description: "Redis管理工具",
Arguments: []string{"run", "--daemon"},
}}
serv, err := service.New(s, s.Cfg)
if err != nil {
log.Printf("Set logger error:%s\n", err.Error())
}
s.Log, err = serv.SystemLogger(nil)
if err != nil {
log.Printf("Set logger error:%s\n", err.Error())
}

return serv
}

// 启动windows服务
func (srv *Services) Start(s service.Service) error {

if srv.Log != nil {
srv.Log.Info("Start run http server")
}

go srv.StarServer()
return nil
}

// 停止windows服务
func (srv *Services) Stop(s service.Service) error {
if srv.Log != nil {
srv.Log.Info("Start stop http server")
}
log.Println("Server exiting")
return srv.Srv.Shutdown(context.Background())
}

// 运行web服务
func (srv *Services) StarServer() {

gin.DisableConsoleColor()
gin.SetMode(gin.ReleaseMode)

path, err := common.RootPath()
if err != nil {
fmt.Println(err)
os.Exit(0)
}

// 创建记录日志的文件
f, err := common.OpenFile(path + "/log/grm.log")
if err != nil {
fmt.Println(err)
os.Exit(0)
}

gin.DefaultWriter = io.MultiWriter(f)

router := router.Init()

router.StaticFS("/static", web.StaticsFs)

srv.Srv = &http.Server{
Addr: net.JoinHostPort(global.GlobalConf.Host, global.GlobalConf.Port),
Handler: router,
}

go func() {
if err := srv.Srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()

quit := make(chan os.Signal)

signal.Notify(quit, os.Interrupt)

//输出LOGO
common.ShowLogo(host, port)

<-quit

log.Println("Shutdown Server ...")

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)

defer cancel()

if err := srv.Srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}

log.Println("Server exiting")
}
7 changes: 4 additions & 3 deletions common/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
package common

import (
"fmt"
"log"
"net"
"time"

"github.com/pkg/errors"
"golang.org/x/crypto/ssh"
)

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

sshConn, err := net.Dial("tcp", addr)
if nil != err {
fmt.Println("net dial err: ", err)
log.Printf("%+v", errors.WithStack(err))
return nil, err
}

clientConn, chans, reqs, err := ssh.NewClientConn(sshConn, addr, config)
if nil != err {
sshConn.Close()
fmt.Println("ssh client conn err: ", err)
log.Printf("%+v", errors.WithStack(err))
return nil, err
}

Expand Down
15 changes: 13 additions & 2 deletions common/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@ func aesDecrypt(cipherText []byte) []byte {
}

func WriteData(data []byte) error {
file, err := os.OpenFile("storage.grm", os.O_CREATE|os.O_RDWR, 0644)

path, err := RootPath()
if err != nil {
return err
}

file, err := os.OpenFile(path+"/storage.grm", os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
return err
}
Expand All @@ -54,7 +60,12 @@ func WriteData(data []byte) error {

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

file, err := os.OpenFile("storage.grm", os.O_CREATE|os.O_RDWR, 0644)
path, err := RootPath()
if err != nil {
return nil, err
}

file, err := os.OpenFile(path+"/storage.grm", os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 77d7177

Please sign in to comment.