main.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. go_lazy_quiter "git.swzry.com/zry/go-lazy-quiter"
  6. "git.swzry.com/zry/pathutils"
  7. "gopkg.in/natefinch/lumberjack.v2"
  8. "gopkg.in/yaml.v2"
  9. "io"
  10. "io/ioutil"
  11. "os"
  12. "os/exec"
  13. "sync"
  14. )
  15. var ConfigData ConfigYAML
  16. var FrontendShellLogger io.Writer
  17. var BackendShellLogger io.Writer
  18. var mainWaitGroup sync.WaitGroup
  19. var showHelp bool
  20. var withDLV bool
  21. var dlvListenString string
  22. var dlvProcess *os.Process
  23. var noFrontEnd bool
  24. func main() {
  25. flag.BoolVar(&showHelp, "h", false, "Show this help")
  26. flag.BoolVar(&withDLV, "d", false, "Start backend with delve debugger")
  27. flag.StringVar(&dlvListenString, "l", "127.0.0.1:7827", "Set delve listening, default is '127.0.0.1:7827'")
  28. flag.BoolVar(&noFrontEnd, "no-front", false, "Not to start front end")
  29. flag.Parse()
  30. if showHelp {
  31. flag.PrintDefaults()
  32. return
  33. }
  34. fmt.Println("zDWSI Windows Test Enviroment Launcher Start.")
  35. LoadYAML()
  36. if !noFrontEnd {
  37. StartFrontend()
  38. }
  39. StartBackend()
  40. //fmt.Println("Launcher Sleeping.")
  41. //RoutineSleep()
  42. q := go_lazy_quiter.NewLazyQuiter()
  43. fmt.Println("Ctrl+C to quit.")
  44. _ = q.Wait()
  45. fmt.Println("Abort by user, quitting...")
  46. if dlvProcess != nil {
  47. err := dlvProcess.Kill()
  48. if err != nil {
  49. fmt.Println("failed kill delve:", err.Error())
  50. }
  51. }
  52. fmt.Println("End.")
  53. os.Exit(0)
  54. }
  55. func LoadYAML() {
  56. fmt.Println("Load Config 'config.yaml'")
  57. jdata, err := ioutil.ReadFile("config.yaml")
  58. if err != nil {
  59. fmt.Println("failed read file 'config.yaml': ", err)
  60. Dead()
  61. }
  62. err = yaml.Unmarshal(jdata, &ConfigData)
  63. if err != nil {
  64. fmt.Println("failed parse 'config.yaml': ", err)
  65. Dead()
  66. }
  67. fmt.Println("Config Loaded.")
  68. }
  69. func Dead() {
  70. fmt.Println("Program Dead By Fatal Error. Please Restart.")
  71. FailureServer()
  72. }
  73. func RoutineSleep() {
  74. mainWaitGroup.Wait()
  75. fmt.Println("All GoRoutine Stopped. Please Restart.")
  76. FailureServer()
  77. }
  78. func InitLogger(cfg LumberjackLoggerYAML) io.Writer {
  79. ljl := &lumberjack.Logger{
  80. Filename: cfg.FileName,
  81. MaxSize: cfg.MaxSize,
  82. MaxAge: cfg.MaxAge,
  83. MaxBackups: cfg.MaxBackups,
  84. LocalTime: cfg.UseLocalTime,
  85. Compress: cfg.Compress,
  86. }
  87. wra := []io.Writer{ljl, os.Stdout}
  88. mwr := io.MultiWriter(wra...)
  89. return mwr
  90. }
  91. func StartFrontend() {
  92. if !ConfigData.Frontend.Enable {
  93. fmt.Println("Frontend Not Enable.")
  94. return
  95. }
  96. pe, err := pathutils.PathExists(ConfigData.Frontend.EntryPoint)
  97. if err != nil || !pe {
  98. fmt.Println("frontend entrypoint not exists")
  99. return
  100. }
  101. FrontendShellLogger = InitLogger(ConfigData.Frontend.ShellLog)
  102. mainWaitGroup.Add(1)
  103. go func() {
  104. runenv := make([]string, 0)
  105. runenv = append(runenv, makeEnvMember("listen", ConfigData.Frontend.ListenAddr))
  106. runenv = append(runenv, makeEnvMember("wwwroot", ConfigData.Frontend.WWWRoot))
  107. runenv = append(runenv, makeEnvMember("backend_prefix", ConfigData.Frontend.BackendProxy.Prefix))
  108. runenv = append(runenv, makeEnvMember("backend_target", ConfigData.Frontend.BackendProxy.ProxyTaret))
  109. runenv = append(runenv, "is_win_test_env=yes")
  110. err = StartProcess(ConfigData.Frontend.EntryPoint, runenv, FrontendShellLogger)
  111. if err != nil {
  112. fmt.Println("failed start frontend or frontend exited with error: ", err)
  113. }
  114. mainWaitGroup.Done()
  115. }()
  116. }
  117. func makeEnvMember(key string, value string) string {
  118. return fmt.Sprintf("%s=%s", key, value)
  119. }
  120. func StartBackend() {
  121. if !ConfigData.Backend.Enable {
  122. fmt.Println("Backend Not Enable.")
  123. return
  124. }
  125. pe, err := pathutils.PathExists(ConfigData.Backend.EntryPoint)
  126. if err != nil || !pe {
  127. fmt.Println("backend entrypoint not exists")
  128. return
  129. }
  130. BackendShellLogger = InitLogger(ConfigData.Backend.ShellLog)
  131. mainWaitGroup.Add(1)
  132. go func() {
  133. runenv := make([]string, 0)
  134. runenv = append(runenv, makeEnvMember("listen", ConfigData.Backend.ListenAddr))
  135. if withDLV {
  136. err = StartProcessWithDLV(ConfigData.Backend.EntryPoint, runenv, BackendShellLogger)
  137. } else {
  138. err = StartProcess(ConfigData.Backend.EntryPoint, runenv, BackendShellLogger)
  139. }
  140. if err != nil {
  141. fmt.Println("failed start backend or backend exited with error: ", err)
  142. }
  143. mainWaitGroup.Done()
  144. }()
  145. }
  146. func StartProcess(entry string, runenv []string, logger io.Writer) error {
  147. cmd := exec.Command(entry)
  148. cmd.Env = runenv
  149. pipe_r, pipe_w := io.Pipe()
  150. cmd.Stdout = pipe_w
  151. cmd.Stderr = pipe_w
  152. go func() {
  153. io.Copy(logger, pipe_r)
  154. }()
  155. err := cmd.Start()
  156. if err != nil {
  157. return err
  158. }
  159. err = cmd.Wait()
  160. return err
  161. }
  162. func StartProcessWithDLV(entry string, runenv []string, logger io.Writer) error {
  163. cmd := exec.Command("dlv")
  164. cmd.Args = []string{
  165. "dlv",
  166. fmt.Sprintf("--listen=%s", dlvListenString),
  167. "--headless=true",
  168. "--api-version=2",
  169. "--accept-multiclient",
  170. "exec",
  171. entry,
  172. }
  173. cmd.Env = runenv
  174. pipe_r, pipe_w := io.Pipe()
  175. cmd.Stdout = pipe_w
  176. cmd.Stderr = pipe_w
  177. go func() {
  178. io.Copy(logger, pipe_r)
  179. }()
  180. err := cmd.Start()
  181. dlvProcess = cmd.Process
  182. if err != nil {
  183. return err
  184. }
  185. err = cmd.Wait()
  186. return err
  187. }