zdaemon.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. package zdaemon
  2. import (
  3. "fmt"
  4. "git.swzry.com/zry/SatorIPC/golang/sipc_conn"
  5. "git.swzry.com/zry/pathutils"
  6. "github.com/gin-gonic/gin"
  7. "net"
  8. "os"
  9. "os/exec"
  10. "path"
  11. "path/filepath"
  12. "runtime"
  13. "strconv"
  14. )
  15. type ZDaemon struct {
  16. daemonName string
  17. description string
  18. initFunc func() ProgramInterface
  19. executableFileName string
  20. programPath string
  21. zdaemonPath string
  22. daemonConfig *yamldef_DaemonConfig
  23. daemonProgram ProgramInterface
  24. ipcserver *sipc_conn.Server
  25. webserver *gin.Engine
  26. ipclistener net.Listener
  27. ipcurlhost string
  28. startOrder int
  29. stopOrder int
  30. programStdin *os.File
  31. programStdout *os.File
  32. programStderr *os.File
  33. }
  34. func NewZDaemon(cfg *ZDaemonConfig) *ZDaemon {
  35. zd := &ZDaemon{
  36. daemonName: cfg.DaemonName,
  37. initFunc: cfg.InitRunnerFunction,
  38. ipcurlhost: fmt.Sprintf("zdaemon-satoripc-client-pid-%d", os.Getpid()),
  39. startOrder: cfg.StartOrder,
  40. stopOrder: cfg.StopOrder,
  41. description: cfg.Description,
  42. programStdin: cfg.ProgramStdin,
  43. programStdout: cfg.ProgramStdout,
  44. programStderr: cfg.ProgramStderr,
  45. }
  46. if zd.startOrder <= 0 {
  47. zd.startOrder = 99
  48. }
  49. if zd.startOrder <= 0 {
  50. zd.stopOrder = 99
  51. }
  52. return zd
  53. }
  54. func (zd *ZDaemon) Run() {
  55. var err error
  56. zd.executableFileName, err = filepath.Abs(os.Args[0])
  57. if err != nil {
  58. fmt.Println("Failed get executable path: ", err.Error())
  59. return
  60. }
  61. zd.programPath = filepath.Dir(zd.executableFileName)
  62. zd.zdaemonPath = path.Join(zd.programPath, "zdaemon")
  63. zd.makeDir()
  64. zd.getStatus()
  65. if len(os.Args) > 1 {
  66. cmdop := os.Args[1]
  67. switch cmdop {
  68. case "install":
  69. zd.install()
  70. break
  71. case "uninstall":
  72. zd.uninstall()
  73. break
  74. case "start":
  75. zd.start()
  76. break
  77. case "stop":
  78. zd.stop()
  79. break
  80. case "status":
  81. zd.status()
  82. break
  83. case "restart":
  84. zd.restart()
  85. break
  86. case "enable":
  87. zd.enable()
  88. break
  89. case "disable":
  90. zd.disable()
  91. break
  92. case "help":
  93. zd.help()
  94. break
  95. case "__run__":
  96. zd.directRun()
  97. break
  98. default:
  99. zd.otherOp(cmdop)
  100. break
  101. }
  102. } else {
  103. fmt.Println("Usage: ", zd.daemonName, "{help|start|stop|restart|install|uninstall|enable|disable|...}")
  104. }
  105. }
  106. func (zd *ZDaemon) makeDir() {
  107. err := pathutils.MkDirIfNotExist(zd.zdaemonPath, 0777)
  108. if err != nil {
  109. fmt.Println("Failed create 'zdaemon' directory: ", err.Error())
  110. os.Exit(-1)
  111. }
  112. }
  113. func (zd *ZDaemon) install() {
  114. if len(os.Args) == 3 {
  115. mode := os.Args[2]
  116. switch mode {
  117. case "winsvc":
  118. zd.install_winsvc()
  119. break
  120. case "wintray":
  121. zd.install_wintray()
  122. break
  123. case "sysv":
  124. zd.install_sysv()
  125. break
  126. case "systemd":
  127. zd.install_systemd()
  128. break
  129. case "openwrt":
  130. zd.install_openwrt()
  131. break
  132. default:
  133. zd.help_install()
  134. break
  135. }
  136. } else {
  137. zd.help_install()
  138. }
  139. }
  140. func (zd *ZDaemon) enable() {
  141. fmt.Println("Not supported yet.")
  142. }
  143. func (zd *ZDaemon) disable() {
  144. fmt.Println("Not supported yet.")
  145. }
  146. func (zd *ZDaemon) uninstall() {
  147. switch zd.daemonConfig.InstallMode {
  148. case "winsvc":
  149. zd.uninstall_winsvc()
  150. break
  151. case "wintray":
  152. zd.uninstall_wintray()
  153. break
  154. case "sysv":
  155. zd.uninstall_sysv()
  156. break
  157. case "systemd":
  158. zd.uninstall_systemd()
  159. break
  160. case "openwrt":
  161. zd.uninstall_openwrt()
  162. break
  163. default:
  164. fmt.Println("No installed yet.")
  165. break
  166. }
  167. }
  168. func (zd *ZDaemon) forceQuit() {
  169. zd.killProcess(zd.daemonConfig.PID)
  170. zd.daemonConfig.IsRunning = false
  171. zd.daemonConfig.IpcAddr = ""
  172. zd.daemonConfig.PID = -1
  173. }
  174. func (zd *ZDaemon) checkRunning() bool {
  175. if zd.daemonConfig.IsRunning {
  176. if zd.daemonConfig.PID > 0 {
  177. if zd.daemonConfig.IpcAddr == "" {
  178. zd.forceQuit()
  179. return false
  180. } else {
  181. al := zd.ipcAppCheckAlive()
  182. if al {
  183. return true
  184. } else {
  185. zd.forceQuit()
  186. return false
  187. }
  188. }
  189. } else {
  190. zd.daemonConfig.IsRunning = false
  191. return false
  192. }
  193. }
  194. return false
  195. }
  196. func (zd *ZDaemon) stop() {
  197. if !zd.checkRunning() {
  198. fmt.Println("Daemon", zd.daemonName, "not running.")
  199. return
  200. }
  201. ks := zd.ipcAppStop()
  202. if !ks {
  203. fmt.Println("Force killing daemon...")
  204. zd.killProcess(zd.daemonConfig.PID)
  205. fmt.Println("End.")
  206. }
  207. }
  208. func (zd *ZDaemon) restart() {
  209. if zd.checkRunning() {
  210. ks := zd.ipcAppStop()
  211. if !ks {
  212. fmt.Println("Force killing daemon...")
  213. zd.killProcess(zd.daemonConfig.PID)
  214. fmt.Println("End.")
  215. }
  216. } else {
  217. fmt.Println("Daemon", zd.daemonName, "not running.")
  218. }
  219. zd.start()
  220. }
  221. func (zd *ZDaemon) status() {
  222. if zd.checkRunning() {
  223. zd.ipcAppGetStatus()
  224. } else {
  225. fmt.Println("Status: not running.")
  226. return
  227. }
  228. }
  229. func (zd *ZDaemon) otherOp(op string) {
  230. uargs := os.Args[2:]
  231. if zd.checkRunning() {
  232. zd.ipcAppOtherOperation(op, uargs)
  233. } else {
  234. fmt.Println("Faild do operation", op, ": daemon not running.")
  235. return
  236. }
  237. }
  238. func (zd *ZDaemon) killProcess(pid int) {
  239. if pid < 1 {
  240. return
  241. }
  242. if runtime.GOOS == "windows" {
  243. cmd := exec.Command("taskkill.exe", "/F", "/PID", strconv.Itoa(pid))
  244. _ = cmd.Run()
  245. } else {
  246. cmd := exec.Command("kill", strconv.Itoa(pid))
  247. _ = cmd.Run()
  248. cmd = exec.Command("kill", "-9", strconv.Itoa(pid))
  249. _ = cmd.Run()
  250. }
  251. }