main.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package main
  2. import (
  3. "context"
  4. "errors"
  5. "flag"
  6. "fmt"
  7. "log"
  8. "net/http"
  9. "os"
  10. "os/exec"
  11. "strings"
  12. "time"
  13. "github.com/TecharoHQ/anubis/test/cmd/cipra/internal"
  14. "github.com/facebookgo/flagenv"
  15. )
  16. var (
  17. bind = flag.String("bind", ":9090", "TCP host:port to bind HTTP on")
  18. browserBin = flag.String("browser-bin", "palemoon", "browser binary name")
  19. browserContainerName = flag.String("browser-container-name", "palemoon", "browser container name")
  20. composeName = flag.String("compose-name", "", "docker compose base name for resources")
  21. vncServerContainer = flag.String("vnc-container-name", "display", "VNC host:port (NOT a display number)")
  22. )
  23. func main() {
  24. flagenv.Parse()
  25. flag.Parse()
  26. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
  27. defer cancel()
  28. lanip, err := internal.GetLANIP()
  29. if err != nil {
  30. log.Panic(err)
  31. }
  32. os.Setenv("TARGET", fmt.Sprintf("%s%s", lanip.String(), *bind))
  33. http.HandleFunc("/{$}", func(w http.ResponseWriter, r *http.Request) {
  34. http.Error(w, "OK", http.StatusOK)
  35. log.Println("got termination signal", r.RequestURI)
  36. go func() {
  37. time.Sleep(2 * time.Second)
  38. cancel()
  39. }()
  40. })
  41. srv := &http.Server{
  42. Handler: http.DefaultServeMux,
  43. Addr: *bind,
  44. }
  45. go func() {
  46. if err := srv.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
  47. log.Panic(err)
  48. }
  49. }()
  50. if err := RunScript(ctx, "docker", "compose", "up", "-d"); err != nil {
  51. log.Fatalf("can't start project: %v", err)
  52. }
  53. defer RunScript(ctx, "docker", "compose", "down", "-t", "1")
  54. defer RunScript(ctx, "docker", "compose", "rm", "-f")
  55. internal.UnbreakDocker(*composeName + "_default")
  56. if err := RunScript(ctx, "docker", "exec", fmt.Sprintf("%s-%s-1", *composeName, *browserContainerName), "bash", "/hack/scripts/install-cert.sh"); err != nil {
  57. log.Panic(err)
  58. }
  59. if err := RunScript(ctx, "docker", "exec", fmt.Sprintf("%s-%s-1", *composeName, *browserContainerName), *browserBin, "https://relayd"); err != nil {
  60. log.Panic(err)
  61. }
  62. <-ctx.Done()
  63. srv.Close()
  64. time.Sleep(2 * time.Second)
  65. }
  66. func RunScript(ctx context.Context, args ...string) error {
  67. var err error
  68. backoff := 250 * time.Millisecond
  69. for attempt := 0; attempt < 5; attempt++ {
  70. select {
  71. case <-ctx.Done():
  72. return nil
  73. default:
  74. }
  75. log.Printf("Running command: %s", strings.Join(args, " "))
  76. cmd := exec.CommandContext(ctx, args[0], args[1:]...)
  77. cmd.Stdout = os.Stdout
  78. cmd.Stderr = os.Stderr
  79. err = cmd.Run()
  80. if exitErr, ok := err.(*exec.ExitError); ok {
  81. log.Printf("attempt=%d code=%d", attempt, exitErr.ExitCode())
  82. }
  83. if err == nil {
  84. return nil
  85. }
  86. log.Printf("Attempt %d failed: %v %T", attempt+1, err, err)
  87. log.Printf("Retrying in %v...", backoff)
  88. time.Sleep(backoff)
  89. backoff *= 2
  90. }
  91. return fmt.Errorf("script failed after 5 attempts: %w", err)
  92. }