main.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "goseg/config"
  6. "goseg/docker"
  7. "goseg/rectify"
  8. "goseg/structs"
  9. "goseg/ws"
  10. "io/ioutil"
  11. "log/slog"
  12. "net/http"
  13. "os"
  14. "path/filepath"
  15. // "time"
  16. "github.com/gorilla/mux"
  17. )
  18. // NativePlanet GroundSeg: Go Edition (goseg)
  19. // This is a Golang rewrite of GroundSeg that serves the v2 json
  20. // object via websocket.
  21. // The v2 rewrite decouples the frontend and backend, which makes it
  22. // straightforward to implement alternative backends.
  23. //
  24. // Under development: reimplementing all pyseg functionality.
  25. // Advantages:
  26. // - Really, really fast
  27. // - Event-driven
  28. // - First-class support for concurrent operations
  29. // - Very good golang Docker libraries
  30. var (
  31. logger = slog.New(slog.NewJSONHandler(os.Stdout, nil))
  32. DevMode = false
  33. )
  34. func loadService(loadFunc func() error, errMsg string) {
  35. go func() {
  36. if err := loadFunc(); err != nil {
  37. logger.Error(fmt.Sprintf("%s %v", errMsg, err))
  38. }
  39. }()
  40. }
  41. func init() {
  42. logger.Info("Starting GroundSeg")
  43. logger.Info("Urbit is love <3")
  44. }
  45. func main() {
  46. // global SysConfig var is managed through config package
  47. conf := config.Conf()
  48. internetAvailable := config.NetCheck("1.1.1.1:53")
  49. availMsg := fmt.Sprintf("Internet available: %t", internetAvailable)
  50. logger.Info(availMsg)
  51. // async operation to retrieve version info if updates are on
  52. versionUpdateChannel := make(chan bool)
  53. remoteVersion := false
  54. if conf.UpdateMode == "auto" {
  55. remoteVersion = true
  56. // get version info from remote server
  57. go func() {
  58. _, versionUpdate := config.CheckVersion()
  59. if versionUpdate {
  60. logger.Info("Version info retrieved")
  61. }
  62. versionUpdateChannel <- versionUpdate
  63. }()
  64. // otherwise use cached if possible, or save hardcoded defaults and use that
  65. } else {
  66. confPath := filepath.Join(config.BasePath, "settings", "version_info.json")
  67. _, err := os.Open(confPath)
  68. if err != nil {
  69. // create a default if it doesn't exist
  70. err = config.CreateDefaultVersion()
  71. if err != nil {
  72. // panic if we can't create it
  73. errmsg := fmt.Sprintf("Unable to write version info! %v", err)
  74. logger.Error(errmsg)
  75. panic(errmsg)
  76. }
  77. }
  78. file, err := ioutil.ReadFile(confPath)
  79. if err != nil {
  80. errmsg := fmt.Sprintf("Unable to load version info: %v", err)
  81. panic(errmsg)
  82. }
  83. var versionStruct structs.Version
  84. if err := json.Unmarshal(file, &versionStruct); err != nil {
  85. errmsg := fmt.Sprintf("Error decoding version JSON: %v", err)
  86. panic(errmsg)
  87. }
  88. // Store in var
  89. releaseChannel := conf.UpdateBranch
  90. targetChan := versionStruct.Groundseg[releaseChannel]
  91. config.VersionInfo = targetChan
  92. }
  93. // infinite version check loop
  94. go config.CheckVersionLoop()
  95. // listen to docker daemon
  96. go docker.DockerListener()
  97. // digest docker events from eventbus
  98. go rectify.DockerSubscriptionHandler()
  99. // just making sure we can parse (debug)
  100. var pierList string
  101. for _, pier := range conf.Piers {
  102. pierList = pierList + ", " + pier
  103. }
  104. logger.Info(pierList)
  105. // block until returns
  106. if remoteVersion == true {
  107. <-versionUpdateChannel
  108. }
  109. // Load Netdata
  110. loadService(docker.LoadNetdata, "Unable to load Netdata!")
  111. // Load Wireguard
  112. loadService(docker.LoadWireguard, "Unable to load Wireguard!")
  113. // Load Urbits
  114. loadService(docker.LoadUrbits, "Unable to load Urbit ships!")
  115. // Load MC
  116. loadService(docker.LoadMC, "Unable to load MinIO Client!")
  117. // Load MinIOs
  118. loadService(docker.LoadMinIOs, "Unable to load MinIO containers!")
  119. // Websocket
  120. r := mux.NewRouter()
  121. r.HandleFunc("/ws", ws.WsHandler)
  122. http.ListenAndServe(":3000", r)
  123. }