github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmg/SubCommand/serviceCmd/command.go.bak (about) 1 package serviceCommand 2 3 import ( 4 "flag" 5 "fmt" 6 "github.com/bronze1man/kmg/kmgConsole" 7 "github.com/kardianos/service" 8 "os" 9 "os/exec" 10 "runtime" 11 "strings" 12 ) 13 14 //TODO 统一进程输出的输出位置,默认不区分err和out. 15 //TODO 添加stopanduninstall命令(停掉,并且卸载),删除或隐藏其他无用命令 16 17 //TODO 添加至少一个平台的测试 18 //TODO kmg gorun 可以在service运行的进程里面,目前是restart 存在bug 19 //TODO 完整描述使用过程 20 //TODO 在osx和linux上达到一致的行为 21 22 func init() { 23 kmgConsole.AddAction(kmgConsole.Command{ 24 Name: "Service.SetAndRestart", 25 Desc: "install the service,and restart the service,uninstall and stop if need", 26 Runner: setAndRestartCmd, 27 }) 28 kmgConsole.AddAction(kmgConsole.Command{ 29 Name: "Service.Install", 30 Desc: "install the service", 31 Runner: installCmd, 32 }) 33 kmgConsole.AddAction(kmgConsole.Command{ 34 Name: "Service.Uninstall", 35 Desc: "uninstall the serivce", 36 Runner: newNameCmd(func(s service.Service) error { return s.Uninstall() }), 37 }) 38 kmgConsole.AddAction(kmgConsole.Command{ 39 Name: "Service.Start", 40 Desc: "start the service", 41 Runner: newNameCmd(func(s service.Service) error { return s.Start() }), 42 }) 43 kmgConsole.AddAction(kmgConsole.Command{ 44 Name: "Service.Stop", 45 Desc: "start the service", 46 Runner: newNameCmd(func(s service.Service) error { return s.Stop() }), 47 }) 48 kmgConsole.AddAction(kmgConsole.Command{ 49 Name: "Service.Restart", 50 Desc: "restart the service,if the service is not running,start it.", 51 Runner: newNameCmd(kmgRestart), 52 }) 53 } 54 55 type installRequest struct { 56 Name string //名字 57 ExecuteArgs []string //执行的命令,第一个是执行命令的进程地址 58 WorkingDirectory string //工作目录(默认是当前目录) 不能在upstart系统上面运行 59 //有下列选项 60 // 'Darwin Launchd' 61 // 'systemd' 62 // 'Upstart' 63 // 'System-V' 64 // 'Windows Service' 65 SystemName string //使用的系统(linux上面可以进行选择) 66 } 67 68 func setAndRestartCmd() { 69 s, err := parseInstallRequest() 70 kmgConsole.ExitOnErr(err) 71 err = s.Install() 72 if err != nil { 73 if !strings.Contains(err.Error(), "already exists") { 74 kmgConsole.ExitOnErr(err) 75 } 76 err = s.Uninstall() 77 kmgConsole.ExitOnErr(err) 78 err = s.Install() 79 kmgConsole.ExitOnErr(err) 80 } 81 err = kmgRestart(s) 82 kmgConsole.ExitOnErr(err) 83 } 84 85 func installCmd() { 86 s, err := parseInstallRequest() 87 kmgConsole.ExitOnErr(err) 88 err = s.Install() 89 kmgConsole.ExitOnErr(err) 90 } 91 92 func parseInstallRequest() (s service.Service, err error) { 93 req := &installRequest{} 94 flag.StringVar(&req.Name, "name", "", "name of the service(require)") 95 var executeString string 96 flag.StringVar(&executeString, "exec", "", "command to run(require,use ' ' to separate args)") 97 flag.StringVar(&req.WorkingDirectory, "cd", "", "working directory(optional),default to currend directory") 98 flag.StringVar(&req.SystemName, "system", "", "system name") 99 flag.Parse() 100 if req.Name == "" { 101 return nil, fmt.Errorf("require name args") 102 } 103 if executeString == "" { 104 return nil, fmt.Errorf("require exec args") 105 } 106 req.ExecuteArgs = strings.Split(executeString, " ") 107 req.ExecuteArgs[0], err = exec.LookPath(req.ExecuteArgs[0]) 108 kmgConsole.ExitOnErr(err) 109 if req.WorkingDirectory == "" { 110 req.WorkingDirectory, err = os.Getwd() 111 if err != nil { 112 return nil, err 113 } 114 } 115 svcConfig := &service.Config{ 116 Name: req.Name, 117 Executable: req.ExecuteArgs[0], 118 Arguments: req.ExecuteArgs[1:], 119 WorkingDirectory: req.WorkingDirectory, 120 Option: service.KeyValue{ 121 "KeepAlive": false, 122 }, 123 } 124 system, err := chooseSystem(req.SystemName) 125 if err != nil { 126 return nil, err 127 } 128 return system.New(nil, svcConfig) 129 130 } 131 132 func newNameCmd(fn func(s service.Service) error) func() { 133 return func() { 134 req := installRequest{} 135 flag.StringVar(&req.Name, "name", "", "name of the service(require)") 136 flag.StringVar(&req.SystemName, "system", "", "system name") 137 flag.Parse() 138 name := "" 139 switch { 140 case req.Name != "": 141 name = req.Name 142 case flag.Arg(0) != "": 143 name = flag.Arg(0) 144 default: 145 fmt.Println("require name args") 146 flag.Usage() 147 return 148 } 149 svcConfig := &service.Config{ 150 Name: name, 151 } 152 system, err := chooseSystem(req.SystemName) 153 kmgConsole.ExitOnErr(err) 154 155 s, err := system.New(nil, svcConfig) 156 kmgConsole.ExitOnErr(err) 157 err = fn(s) 158 kmgConsole.ExitOnErr(err) 159 } 160 } 161 162 // 允许 stop restart 这种用法 163 func kmgRestart(s service.Service) (err error) { 164 err = s.Stop() 165 if err != nil { 166 errS := err.Error() 167 if !(strings.Contains(errS, "Unknown instance")) { 168 return err 169 } 170 } 171 err = s.Start() 172 return err 173 } 174 175 func chooseSystem(SystemName string) (sys service.System, err error) { 176 if runtime.GOOS == "linux" && SystemName == "" { 177 SystemName = "System-V" 178 } 179 if SystemName == "" { 180 return service.ChosenSystem(), nil 181 } 182 avaliableListS := "" 183 for _, thisSystem := range service.AvailableSystems() { 184 if !thisSystem.Detect() { 185 continue 186 } 187 avaliableListS += thisSystem.String() + "," 188 if thisSystem.String() == SystemName { 189 return thisSystem, nil 190 } 191 } 192 return nil, fmt.Errorf("system [%s] not exist,avaliable:[%s]", SystemName, avaliableListS) 193 194 }