| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package main
- import (
- "encoding/json"
- "fmt"
- "goseg/config"
- "goseg/docker"
- "goseg/rectify"
- "goseg/structs"
- "goseg/ws"
- "io/ioutil"
- "log/slog"
- "net/http"
- "os"
- "path/filepath"
- // "time"
- "github.com/gorilla/mux"
- )
- // NativePlanet GroundSeg: Go Edition (goseg)
- // This is a Golang rewrite of GroundSeg that serves the v2 json
- // object via websocket.
- // The v2 rewrite decouples the frontend and backend, which makes it
- // straightforward to implement alternative backends.
- //
- // Under development: reimplementing all pyseg functionality.
- // Advantages:
- // - Really, really fast
- // - Event-driven
- // - First-class support for concurrent operations
- // - Very good golang Docker libraries
- var (
- logger = slog.New(slog.NewJSONHandler(os.Stdout, nil))
- DevMode = false
- )
- func loadService(loadFunc func() error, errMsg string) {
- go func() {
- if err := loadFunc(); err != nil {
- logger.Error(fmt.Sprintf("%s %v", errMsg, err))
- }
- }()
- }
- func main() {
- logger.Info("Starting GroundSeg")
- logger.Info("Urbit is love <3")
- // global SysConfig var is managed through config package
- conf := config.Conf()
- internetAvailable := config.NetCheck("1.1.1.1:53")
- availMsg := fmt.Sprintf("Internet available: %t", internetAvailable)
- logger.Info(availMsg)
- // async operation to retrieve version info if updates are on
- versionUpdateChannel := make(chan bool)
- remoteVersion := false
- if conf.UpdateMode == "auto" {
- remoteVersion = true
- // get version info from remote server
- go func() {
- _, versionUpdate := config.CheckVersion()
- if versionUpdate {
- logger.Info("Version info retrieved")
- }
- versionUpdateChannel <- versionUpdate
- }()
- // otherwise use cached if possible, or save hardcoded defaults and use that
- } else {
- confPath := filepath.Join(config.BasePath, "settings", "version_info.json")
- _, err := os.Open(confPath)
- if err != nil {
- // create a default if it doesn't exist
- err = config.CreateDefaultVersion()
- if err != nil {
- // panic if we can't create it
- errmsg := fmt.Sprintf("Unable to write version info! %v", err)
- logger.Error(errmsg)
- panic(errmsg)
- }
- }
- file, err := ioutil.ReadFile(confPath)
- if err != nil {
- errmsg := fmt.Sprintf("Unable to load version info: %v", err)
- panic(errmsg)
- }
- var versionStruct structs.Version
- if err := json.Unmarshal(file, &versionStruct); err != nil {
- errmsg := fmt.Sprintf("Error decoding version JSON: %v", err)
- panic(errmsg)
- }
- // Store in var
- releaseChannel := conf.UpdateBranch
- targetChan := versionStruct.Groundseg[releaseChannel]
- config.VersionInfo = targetChan
- }
- // infinite version check loop
- go config.CheckVersionLoop()
- // listen to docker daemon
- go docker.DockerListener()
- // digest docker events from eventbus
- go rectify.DockerSubscriptionHandler()
- // just making sure we can parse (debug)
- var pierList string
- for _, pier := range conf.Piers {
- pierList = pierList + ", " + pier
- }
- logger.Info(pierList)
- // block until returns
- if remoteVersion == true {
- <-versionUpdateChannel
- }
- // Load Netdata
- loadService(docker.LoadNetdata, "Unable to load Netdata!")
- // Load Wireguard
- loadService(docker.LoadWireguard, "Unable to load Wireguard!")
- // Load Urbits
- loadService(docker.LoadUrbits, "Unable to load Urbit ships!")
- // Load MC
- loadService(docker.LoadMC, "Unable to load MinIO Client!")
- // Load MinIOs
- loadService(docker.LoadMinIOs, "Unable to load MinIO containers!")
- // Websocket
- r := mux.NewRouter()
- r.HandleFunc("/ws", ws.WsHandler)
- http.ListenAndServe(":3000", r)
- }
|