nallux 2 vuotta sitten
vanhempi
commit
b020d4f34d
4 muutettua tiedostoa jossa 110 lisäystä ja 27 poistoa
  1. 69 19
      broadcast/broadcast.go
  2. 24 8
      config/config.go
  3. 16 0
      docker/docker.go
  4. 1 0
      main.go

+ 69 - 19
broadcast/broadcast.go

@@ -7,8 +7,11 @@ import (
 	"goseg/docker"
 	"goseg/startram"
 	"goseg/structs"
+	"io/ioutil"
 	"log/slog"
+	"math"
 	"os"
+	"path/filepath"
 	"reflect"
 	"strings"
 	"sync"
@@ -57,29 +60,14 @@ func UnregisterClient(conn *websocket.Conn) {
 func bootstrapBroadcastState(config structs.SysConfig) (structs.AuthBroadcast, error) {
 	logger.Info("Bootstrapping state")
 	var res structs.AuthBroadcast
-	currentState := GetState()
 	// get a list of piers from config
 	piers := config.Piers
 	// this returns a map of ship:running status
 	logger.Info("Resolving pier status")
-	pierStatus, err := docker.GetShipStatus(piers)
+	updates, err := constructPierInfo(piers)
 	if err != nil {
-		errmsg := fmt.Sprintf("Unable to bootstrap urbit states: %v", err)
-		logger.Error(errmsg)
 		return res, err
 	}
-	updates := make(map[string]structs.Urbit)
-	// convert the running status into bools
-	for pier, status := range pierStatus {
-		urbit := structs.Urbit{}
-		if existingUrbit, exists := currentState.Urbits[pier]; exists {
-			// If the ship already exists in broadcastState, use its current state
-			urbit = existingUrbit
-		}
-		isRunning := (status == "Up" || strings.HasPrefix(status, "Up "))
-		urbit.Info.Running = isRunning
-		updates[pier] = urbit
-	}
 	// update broadcastState
 	err = UpdateBroadcastState(map[string]interface{}{
 		"Urbits": updates,
@@ -89,11 +77,10 @@ func bootstrapBroadcastState(config structs.SysConfig) (structs.AuthBroadcast, e
 		logger.Error(errmsg)
 		return res, err
 	}
-	currentState = GetState()
+	// wgRegistered := config.WgRegistered
+	// wgOn := config.WgOn
 	// get startram regions
 	logger.Info("Retrieving StarTram region info")
-	//wgRegistered := config.WgRegistered
-	//wgOn := config.WgOn
 	regions, err := startram.GetRegions()
 	if err != nil {
 		logger.Warn("Couldn't get StarTram regions")
@@ -118,6 +105,69 @@ func bootstrapBroadcastState(config structs.SysConfig) (structs.AuthBroadcast, e
 	return res, nil
 }
 
+func constructPierInfo(piers []string) (map[string]structs.Urbit, error) {
+	updates := make(map[string]structs.Urbit)
+	currentState := GetState()
+	shipNetworks := GetContainerNetworks(piers)
+	pierStatus, err := docker.GetShipStatus(piers)
+	if err != nil {
+		errmsg := fmt.Sprintf("Unable to bootstrap urbit states: %v", err)
+		logger.Error(errmsg)
+		return updates, err
+	}
+	hostName, err := os.Hostname()
+	if err != nil {
+		errmsg := fmt.Sprintf("Error getting hostname, defaulting to `nativeplanet`: %v", err)
+		logger.Warn(errmsg)
+		hostName = "nativeplanet"
+	}
+	// convert the running status into bools
+	for pier, status := range pierStatus {
+		// pull docker info from json
+		var dockerConfig structs.UrbitDocker
+		confPath := filepath.Join(config.BasePath, "settings", "pier", pier+".json")
+		file, err := ioutil.ReadFile(confPath)
+		if err != nil {
+			errmsg := fmt.Sprintf("Unable to load %s config: %v", pier, err)
+			logger.Error(errmsg)
+			continue
+		}
+		if err := json.Unmarshal(file, &dockerConfig); err != nil {
+			errmsg := fmt.Sprintf("Error decoding %s JSON: %v", pier, err)
+			logger.Error(errmsg)
+			continue
+		}
+		urbit := structs.Urbit{}
+		if existingUrbit, exists := currentState.Urbits[pier]; exists {
+			// If the ship already exists in broadcastState, use its current state
+			urbit = existingUrbit
+		}
+		isRunning := (status == "Up" || strings.HasPrefix(status, "Up "))
+		urbit.Info.Running = isRunning
+		urbit.Info.Network = shipNetworks[pier]
+		urbit.Info.URL = "http://" + hostName + ":" + string(dockerConfig.HTTPPort)
+		urbit.Info.LoomSize = int(math.Pow(2, float64(dockerConfig.LoomSize)) / math.Pow(1024, 2))
+		updates[pier] = urbit
+	}
+	return updates, nil
+}
+
+// return a map of ships and their networks
+func GetContainerNetworks(containers []string) map[string]string {
+	res := make(map[string]string)
+	for _, container := range containers {
+		network, err := docker.GetContainerNetwork(container)
+		if err != nil {
+			errmsg := fmt.Sprintf("Error getting container network: %v", err)
+			logger.Error(errmsg)
+			continue
+		} else {
+			res[container] = network
+		}
+	}
+	return res
+}
+
 // update broadcastState with a map of items
 func UpdateBroadcastState(values map[string]interface{}) error {
 	mu.Lock()

+ 24 - 8
config/config.go

@@ -17,7 +17,7 @@ import (
 var (
 	globalConfig       structs.SysConfig
 	logger             = slog.New(slog.NewJSONHandler(os.Stdout, nil))
-	basePath           string
+	BasePath           string
 	Version            = "v2.0.0"
 	Ready              = false
 	VersionServerReady = false
@@ -31,6 +31,7 @@ var (
 	WifiNetworks       []string
 	HttpOpen           = false
 	UploadSecret       string
+	checkInterval	   = 5 * time.Minute
 	confMutex          sync.Mutex
 	versMutex          sync.Mutex
 )
@@ -38,12 +39,12 @@ var (
 // try initializing from system.json on disk
 func init() {
 	// try loading existing config
-	basePath, err := os.Getwd()
+	BasePath, err := os.Getwd()
 	if err != nil {
 		errmsg := fmt.Sprintf("Couldn't get cwd: %v", err)
 		logger.Error(errmsg)
 	}
-	confPath := filepath.Join(basePath, "settings", "system.json")
+	confPath := filepath.Join(BasePath, "settings", "system.json")
 	file, err := os.Open(confPath)
 	if err != nil {
 		// create a default if it doesn't exist
@@ -74,7 +75,7 @@ func UpdateConf(values map[string]interface{}) error {
 	// mutex lock to avoid race conditions
 	confMutex.Lock()
 	defer confMutex.Unlock()
-	confPath := filepath.Join(basePath, "settings", "system.json")
+	confPath := filepath.Join(BasePath, "settings", "system.json")
 	file, err := ioutil.ReadFile(confPath)
 	if err != nil {
 		errmsg := fmt.Sprintf("Unable to load config: %v", err)
@@ -125,8 +126,8 @@ func createDefaultConf() error {
 		UpdateUrl:    "https://version.groundseg.app",
 		UpdateBranch: "latest",
 		SwapVal:      16,
-		SwapFile:     filepath.Join(basePath, "settings", "swapfile"),
-		KeyFile:      filepath.Join(basePath, "settings", "session.key"),
+		SwapFile:     filepath.Join(BasePath, "settings", "swapfile"),
+		KeyFile:      filepath.Join(BasePath, "settings", "session.key"),
 		Sessions: struct {
 			Authorized   map[string]structs.SessionInfo `json:"authorized"`
 			Unauthorized map[string]structs.SessionInfo `json:"unauthorized"`
@@ -158,7 +159,7 @@ func createDefaultConf() error {
 		Privkey:        "",
 		Salt:           "",
 	}
-	path := filepath.Join(basePath, "settings", "system.json")
+	path := filepath.Join(BasePath, "settings", "system.json")
 	if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
 		return err
 	}
@@ -237,7 +238,7 @@ func CheckVersion() (structs.Version, bool) {
 			}
 		}
 		// debug: re-marshal and write to disk
-		confPath := filepath.Join(basePath, "settings", "version_info.json")
+		confPath := filepath.Join(BasePath, "settings", "version_info.json")
 		file, err := os.Create(confPath)
 		if err != nil {
 			errmsg := fmt.Sprintf("Failed to create file: %v", err)
@@ -255,3 +256,18 @@ func CheckVersion() (structs.Version, bool) {
 	}
 	return VersionInfo, false
 }
+
+func CheckVersionLoop() {
+	ticker := time.NewTicker(checkInterval)
+	for {
+		select {
+		case <-ticker.C:
+			latestVersion, _ := CheckVersion()
+			currentVersion := VersionInfo
+			if latestVersion != currentVersion {
+				fmt.Printf("New version available! Current: %s, Latest: %s\n", currentVersion, latestVersion)
+				// Handle the update logic here
+			}
+		}
+	}
+}

+ 16 - 0
docker/docker.go

@@ -51,3 +51,19 @@ func GetShipStatus(patps []string) (map[string]string, error) {
 		return statuses, nil
 	}
 }
+
+func GetContainerNetwork(name string) (string, error) {
+	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
+	if err != nil {
+		return "", err
+	}
+	defer cli.Close()
+	containerJSON, err := cli.ContainerInspect(context.Background(), name)
+	if err != nil {
+		return "", err
+	}
+	for networkName := range containerJSON.NetworkSettings.Networks {
+		return networkName, nil
+	}
+	return "", fmt.Errorf("container is not attached to any network")
+}

+ 1 - 0
main.go

@@ -51,6 +51,7 @@ func main() {
 			versionUpdateChannel <- versionUpdate
 		}()
 	}
+	go config.CheckVersionLoop()
 	// just making sure we can parse (debug)
 	var pierList string
 	for _, pier := range conf.Piers {