Bläddra i källkod

work on ws support

reid 2 år sedan
förälder
incheckning
ccd02025e0
13 ändrade filer med 722 tillägg och 8 borttagningar
  1. 61 0
      broadcast/broadcast.go
  2. 27 6
      config/config.go
  3. 2 0
      go.mod
  4. 4 0
      go.sum
  5. 8 2
      main.go
  6. 71 0
      noun/noun.go
  7. 129 0
      settings/example_broadcast.json
  8. 0 0
      settings/system.json
  9. 36 0
      settings/system_default.json
  10. 163 0
      settings/version_info.json
  11. 10 0
      setup/setup.go
  12. 127 0
      structs/structs.go
  13. 84 0
      ws/ws.go

+ 61 - 0
broadcast/broadcast.go

@@ -0,0 +1,61 @@
+package broadcast
+
+import (
+	"encoding/json"
+	"goseg/structs"
+	"log/slog"
+	"os"
+	"sync"
+
+	"github.com/gorilla/websocket"
+)
+
+var (
+	logger         = slog.New(slog.NewJSONHandler(os.Stdout, nil))
+	clients        = make(map[*websocket.Conn]bool)
+	broadcastState structs.AuthBroadcast
+	mu             sync.RWMutex // synchronize access to broadcastState
+)
+
+// adds ws client
+func RegisterClient(conn *websocket.Conn) {
+	clients[conn] = true
+}
+
+// remove ws client
+func UnregisterClient(conn *websocket.Conn) {
+	delete(clients, conn)
+}
+
+// update the state and broadcast it to all clients
+// ex:
+// newState := structs.AuthBroadcast{ /* ... */ }
+// broadcast.UpdateState(newState)
+func UpdateState(newState structs.AuthBroadcast) {
+	mu.Lock()
+	defer mu.Unlock()
+	broadcastState = newState
+	broadcastToClients()
+}
+
+// mutex return broadcast state
+func GetState() structs.AuthBroadcast {
+	mu.Lock()
+	defer mu.Unlock()
+	return broadcastState
+}
+
+// broadcast the global state to all clients
+func broadcastToClients() {
+	broadcastJson, err := json.Marshal(broadcastState)
+	if err != nil {
+		logger.Error("Error marshalling response:", err)
+		return
+	}
+	for client := range clients {
+		if err := client.WriteMessage(websocket.TextMessage, broadcastJson); err != nil {
+			logger.Error("Error writing response:", err)
+			return
+		}
+	}
+}

+ 27 - 6
config/config.go

@@ -32,12 +32,16 @@ var (
 	HttpOpen           = false
 	UploadSecret       string
 	confMutex          sync.Mutex
+	versMutex          sync.Mutex
 )
 
+// try initializing from system.json on disk
 func init() {
-	confPath := filepath.Join(basePath, "settings", "system2.json")
+	// try loading existing config
+	confPath := filepath.Join(basePath, "settings", "system.json")
 	file, err := os.Open(confPath)
 	if err != nil {
+		// create a default if it doesn't exist
 		err = createDefaultConf()
 		if err != nil {
 			errmsg := fmt.Sprintf("Unable to create config! %v", err)
@@ -53,30 +57,38 @@ func init() {
 	}
 }
 
+// return the global conf var
 func Conf() structs.SysConfig {
+	confMutex.Lock()
+	defer confMutex.Unlock()
 	return globalConfig
 }
 
+// update by passing in a map of key:values you want to modify
 func UpdateConf(values map[string]interface{}) error {
+	// mutex lock to avoid race conditions
 	confMutex.Lock()
 	defer confMutex.Unlock()
-	confPath := filepath.Join(basePath, "settings", "system2.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)
 		logger.Error(errmsg)
 		return err
 	}
+	// unmarshal the config to struct
 	var configMap map[string]interface{}
 	if err := json.Unmarshal(file, &configMap); err != nil {
 		errmsg := fmt.Sprintf("Error decoding JSON: %v", err)
 		logger.Error(errmsg)
 		return err
 	}
+	// update our unmarshaled struct
 	for key, value := range values {
 		configMap[key] = value
 	}
-	updatedJSON, err := json.Marshal(configMap)
+	// marshal and persist it
+	updatedJSON, err := json.MarshalIndent(configMap, "", "    ")
 	if err != nil {
 		errmsg := fmt.Sprintf("Error encoding JSON: %v", err)
 		logger.Error(errmsg)
@@ -95,6 +107,7 @@ func UpdateConf(values map[string]interface{}) error {
 	return nil
 }
 
+// write a default conf to disk
 func createDefaultConf() error {
 	defaultConfig := structs.SysConfig{
 		Setup:        "start",
@@ -139,7 +152,7 @@ func createDefaultConf() error {
 		Privkey:        "",
 		Salt:           "",
 	}
-	path := filepath.Join(basePath, "settings", "system2.json")
+	path := filepath.Join(basePath, "settings", "system.json")
 	if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
 		return err
 	}
@@ -149,12 +162,15 @@ func createDefaultConf() error {
 	}
 	defer file.Close()
 	encoder := json.NewEncoder(file)
+	encoder.SetIndent("", "    ")
 	if err := encoder.Encode(&defaultConfig); err != nil {
 		return err
 	}
 	return nil
 }
 
+// check outbound tcp connectivity
+// takes ip:port
 func NetCheck(netCheck string) bool {
 	logger.Info("Checking internet access")
 	internet := false
@@ -170,7 +186,10 @@ func NetCheck(netCheck string) bool {
 	return internet
 }
 
+// check the version server and return unmarshaled result
 func CheckVersion() (structs.Version, bool) {
+	versMutex.Lock()
+	defer versMutex.Unlock()
 	const retries = 10
 	const delay = time.Second
 	url := globalConfig.UpdateUrl
@@ -186,6 +205,7 @@ func CheckVersion() (structs.Version, bool) {
 				return VersionInfo, false
 			}
 		}
+		// read the body bytes
 		body, err := ioutil.ReadAll(resp.Body)
 		resp.Body.Close()
 		if err != nil {
@@ -198,8 +218,8 @@ func CheckVersion() (structs.Version, bool) {
 				return VersionInfo, false
 			}
 		}
+		// unmarshal values into Version struct
 		err = json.Unmarshal(body, &VersionInfo)
-		fmt.Println(string(body))
 		if err != nil {
 			errmsg := fmt.Sprintf("Error unmarshalling JSON: %v", err)
 			logger.Warn(errmsg)
@@ -210,6 +230,7 @@ func CheckVersion() (structs.Version, bool) {
 				return VersionInfo, false
 			}
 		}
+		// debug: re-marshal and write to disk
 		confPath := filepath.Join(basePath, "settings", "version_info.json")
 		file, err := os.Create(confPath)
 		if err != nil {
@@ -219,11 +240,11 @@ func CheckVersion() (structs.Version, bool) {
 		}
 		defer file.Close()
 		encoder := json.NewEncoder(file)
+		encoder.SetIndent("", "    ")
 		if err := encoder.Encode(&VersionInfo); err != nil {
 			errmsg := fmt.Sprintf("Failed to write JSON: %v", err)
 			logger.Error(errmsg)
 		}
-		fmt.Println(VersionInfo)
 		return VersionInfo, true
 	}
 	return VersionInfo, false

+ 2 - 0
go.mod

@@ -10,6 +10,8 @@ require (
 	github.com/docker/go-connections v0.4.0 // indirect
 	github.com/docker/go-units v0.5.0 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/gorilla/mux v1.8.0 // indirect
+	github.com/gorilla/websocket v1.5.0 // indirect
 	github.com/moby/term v0.5.0 // indirect
 	github.com/morikuni/aec v1.0.0 // indirect
 	github.com/opencontainers/go-digest v1.0.0 // indirect

+ 4 - 0
go.sum

@@ -16,6 +16,10 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
+github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=

+ 8 - 2
main.go

@@ -3,8 +3,12 @@ package main
 import (
 	"fmt"
 	"goseg/config"
+	"goseg/ws"
 	"log/slog"
+	"net/http"
 	"os"
+
+	"github.com/gorilla/mux"
 )
 
 var (
@@ -29,10 +33,9 @@ func main() {
 	versionUpdateChannel := make(chan bool)
 	if conf.UpdateMode == "auto" {
 		go func() {
-			versionInfo, versionUpdate := config.CheckVersion()
+			_, versionUpdate := config.CheckVersion()
 			if versionUpdate {
 				logger.Info("Version info retrieved")
-				fmt.Println(versionInfo)
 			}
 			versionUpdateChannel <- versionUpdate
 		}()
@@ -45,4 +48,7 @@ func main() {
 	logger.Info(pierList)
 	// block until returns (debug)
 	<-versionUpdateChannel
+	r := mux.NewRouter()
+	r.HandleFunc("/ws", ws.WsHandler)
+	http.ListenAndServe(":3000", nil)
 }

+ 71 - 0
noun/noun.go

@@ -0,0 +1,71 @@
+package main
+
+import (
+	"fmt"
+	"github.com/spaolacci/murmur3"
+	"math/bits"
+)
+
+type Cell struct {
+	head, tail interface{}
+	mug        uint64
+}
+
+func byteLength(i uint64) int {
+	lyn := bits.Len64(i)
+	byt := lyn >> 3
+	if lyn&7 != 0 {
+		return byt + 1
+	}
+	return byt
+}
+
+func intbytes(i uint64) []byte {
+	return []byte{byte(i), byte(i >> 8), byte(i >> 16), byte(i >> 24), byte(i >> 32), byte(i >> 40), byte(i >> 48), byte(i >> 56)}
+}
+
+func mum(syd, fal, key uint64) uint64 {
+	k := intbytes(key)
+	for s := syd; s < syd+8; s++ {
+		haz := murmur3.Sum32WithSeed(k, uint32(s))
+		ham := (uint64(haz) >> 31) ^ (uint64(haz) & 0x7fffffff)
+		if ham != 0 {
+			return ham
+		}
+	}
+	return fal
+}
+
+func mugBoth(one, two uint64) uint64 {
+	return mum(0xdeadbeef, 0xfffe, (two<<32)|one)
+}
+
+func (c *Cell) hash() uint64 {
+	if c.mug == 0 {
+		c.mug = mugBoth(mug(c.head), mug(c.tail))
+	}
+	return c.mug
+}
+
+func (c *Cell) equals(other *Cell) bool {
+	// Implement equality logic as per your requirements
+	return false
+}
+
+func deep(n interface{}) bool {
+	_, ok := n.(*Cell)
+	return ok
+}
+
+func mug(n interface{}) uint64 {
+	if deep(n) {
+		return n.(*Cell).hash()
+	}
+	return mum(0xcafebabe, 0x7fff, n.(uint64))
+}
+
+// Implement other functions as needed
+
+func main() {
+	// Test code or main logic
+}

+ 129 - 0
settings/example_broadcast.json

@@ -0,0 +1,129 @@
+{
+    "type": "structure",
+    "auth_level": "authorized",
+    "upload": {
+        "status": "free",
+        "size": 0,
+        "uploaded": 0,
+        "patp": null
+    },
+    "logs": {
+        "containers": {
+            "wireguard": {
+                "logs": []
+            }
+        },
+        "system": {
+            "stream": false,
+            "logs": []
+        }
+    },
+    "system": {
+        "usage": {
+            "ram": [
+                1003937792,
+                465555456
+            ],
+            "cpu": 3,
+            "cpu_temp": 0,
+            "disk": [
+                25821052928,
+                9873883136,
+                15930392576
+            ],
+            "swap": 1
+        },
+        "updates": {
+            "linux": {
+                "state": "pending",
+                "upgrade": 5,
+                "new": 0,
+                "remove": 0,
+                "ignore": 0
+            }
+        },
+        "wifi": {
+            "status": false,
+            "active": null,
+            "networks": []
+        }
+    },
+    "profile": {
+        "startram": {
+            "info": {
+                "registered": false,
+                "running": false,
+                "region": null,
+                "expiry": null,
+                "renew": true,
+                "endpoint": "api.startram.io",
+                "regions": {
+                    "asia": {
+                        "country": "SG",
+                        "desc": "Asia"
+                    },
+                    "europe": {
+                        "country": "NL",
+                        "desc": "Europe"
+                    },
+                    "us-east": {
+                        "country": "US",
+                        "desc": "US (East)"
+                    },
+                    "us-west": {
+                        "country": "US",
+                        "desc": "US (West)"
+                    }
+                }
+            },
+            "transition": {
+                "register": null,
+                "toggle": null
+            }
+        }
+    },
+    "urbits": {
+        "diflep-binbex-nallux-dozryl": {
+            "info": {
+                "network": "none",
+                "running": false,
+                "url": "http://ubuntu-gs-ny.local:8081",
+                "urbAlias": false,
+                "memUsage": 0,
+                "diskUsage": 1035707322,
+                "loomSize": 2048,
+                "devMode": false,
+                "detectBootStatus": true,
+                "remote": false,
+                "vere": null
+            },
+            "transition": {
+                "meld": null,
+                "serviceRegistrationStatus": "ok",
+                "togglePower": null,
+                "deleteShip": null
+            }
+        },
+        "roldef-tanref-sarnyr-nolned": {
+            "info": {
+                "network": "none",
+                "running": false,
+                "url": "http://ubuntu-gs-ny.local:8082",
+                "urbAlias": false,
+                "memUsage": 0,
+                "diskUsage": 1001214952,
+                "loomSize": 2048,
+                "devMode": false,
+                "detectBootStatus": true,
+                "remote": false,
+                "vere": null
+            },
+            "transition": {
+                "meld": null,
+                "serviceRegistrationStatus": "ok",
+                "togglePower": null,
+                "deleteShip": null
+            }
+        }
+    }
+}

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
settings/system.json


+ 36 - 0
settings/system_default.json

@@ -0,0 +1,36 @@
+{
+    "setup": "start",
+    "endpointUrl": "api.startram.io",
+    "apiVersion": "v1",
+    "piers": [],
+    "netCheck": "1.1.1.1:53",
+    "updateMode": "auto",
+    "updateUrl": "https://version.groundseg.app",
+    "updateBranch": "latest",
+    "swapVal": 16,
+    "swapFile": "/home/reid/gits/np/goseg/settings/swapfile",
+    "keyFile": "/home/reid/gits/np/goseg/settings/session.key",
+    "sessions": {
+        "authorized": {},
+        "unauthorized": {}
+    },
+    "linuxUpdates": {
+        "value": 1,
+        "interval": "week",
+        "previous": false
+    },
+    "dockerData": "/var/lib/docker",
+    "wgOn": false,
+    "wgRegistered": false,
+    "pwHash": "",
+    "c2cInterval": 0,
+    "firstBoot": false,
+    "wgRegisterd": false,
+    "gsVersion": "v2.0.0",
+    "CFG_DIR": "",
+    "updateInterval": 0,
+    "binHash": "",
+    "pubkey": "",
+    "privkey": "",
+    "salt": ""
+}

+ 163 - 0
settings/version_info.json

@@ -0,0 +1,163 @@
+{
+    "groundseg": {
+        "canary": {
+            "groundseg": {
+                "amd64_sha256": "58041cd66c692cddd09e83dedf6c803c1a1a5a46a6cc28167a3fb3e736f3e160",
+                "amd64_url": "https://files.native.computer/bin/groundseg_amd64_v1.4.2_latest",
+                "arm64_sha256": "4256fc53658a3bfcde793157951ea587c0992a0de879d8eb016a941097163e47",
+                "arm64_url": "https://files.native.computer/bin/groundseg_arm64_v1.4.2_latest",
+                "major": 1,
+                "minor": 4,
+                "patch": 2
+            },
+            "manual": {
+                "amd64_sha256": "148a2acb946c4c38720cf8994a39b20f655547fd43996f2449ff5b7bc24793c9",
+                "arm64_sha256": "baa87ad152ec14a7df9cd889e970cd1ad9c5f6bbc0e1fbd587f5ed6c89e31f08",
+                "repo": "registry.hub.docker.com/nativeplanet/groundseg-manual",
+                "tag": "latest"
+            },
+            "minio": {
+                "amd64_sha256": "f6a3001a765dc59a8e365149ade0ea628494230e984891877ead016eb24ba9a9",
+                "arm64_sha256": "567779c9f29aca670f84d066051290faeaae6c3ad3a3b7062de4936aaab2a29d",
+                "repo": "registry.hub.docker.com/minio/minio",
+                "tag": "latest"
+            },
+            "miniomc": {
+                "amd64_sha256": "6ffd76764e8ca484de12c6ecaa352db3d8efd5c9d44f393718b29b6600e0a559",
+                "arm64_sha256": "6825aecd2f123c9d4408e660aba8a72f9e547a3774350b8f4d2d9b674e99e424",
+                "repo": "registry.hub.docker.com/minio/mc",
+                "tag": "latest"
+            },
+            "netdata": {
+                "amd64_sha256": "95e74c36f15091bcd7983ee162248f1f91c21207c235fce6b0d6f8ed9a11732a",
+                "arm64_sha256": "cd3dc9d182a4561b162f03c6986f4647bbb704f8e7e4872ee0611b1b9e86e1b0",
+                "repo": "registry.hub.docker.com/netdata/netdata",
+                "tag": "latest"
+            },
+            "vere": {
+                "amd64_sha256": "674a37a736883275991aa094c7b58e1acad4ab4a15b6aeb896d5c72016faa58f",
+                "arm64_sha256": "None",
+                "repo": "registry.hub.docker.com/nativeplanet/urbit",
+                "tag": "edge"
+            },
+            "webui": {
+                "amd64_sha256": "a2c683530d15b1095bcb3e97b1b6236461142e6e19774762991e30c817352797",
+                "arm64_sha256": "0b96f7a02efc0d5c754bd6d89df2b9f738a676c51b529258b99d5b84e30d1725",
+                "repo": "registry.hub.docker.com/nativeplanet/groundseg-webui",
+                "tag": "latest"
+            },
+            "wireguard": {
+                "amd64_sha256": "ae6f8e8cc1303bc9c0b5fa1b1ef4176c25a2c082e29bf8b554ce1196731e7db2",
+                "arm64_sha256": "403d741b1b5bcf5df1e48eab0af8038355fae3e29419ad5980428f9aebd1576c",
+                "repo": "registry.hub.docker.com/linuxserver/wireguard",
+                "tag": "latest"
+            }
+        },
+        "edge": {
+            "groundseg": {
+                "amd64_sha256": "58041cd66c692cddd09e83dedf6c803c1a1a5a46a6cc28167a3fb3e736f3e160",
+                "amd64_url": "https://files.native.computer/bin/groundseg_amd64_v1.4.2_edge",
+                "arm64_sha256": "4256fc53658a3bfcde793157951ea587c0992a0de879d8eb016a941097163e47",
+                "arm64_url": "https://files.native.computer/bin/groundseg_arm64_v1.4.2_edge",
+                "major": 1,
+                "minor": 4,
+                "patch": 2
+            },
+            "manual": {
+                "amd64_sha256": "148a2acb946c4c38720cf8994a39b20f655547fd43996f2449ff5b7bc24793c9",
+                "arm64_sha256": "baa87ad152ec14a7df9cd889e970cd1ad9c5f6bbc0e1fbd587f5ed6c89e31f08",
+                "repo": "registry.hub.docker.com/nativeplanet/groundseg-manual",
+                "tag": "edge"
+            },
+            "minio": {
+                "amd64_sha256": "f6a3001a765dc59a8e365149ade0ea628494230e984891877ead016eb24ba9a9",
+                "arm64_sha256": "567779c9f29aca670f84d066051290faeaae6c3ad3a3b7062de4936aaab2a29d",
+                "repo": "registry.hub.docker.com/minio/minio",
+                "tag": "latest"
+            },
+            "miniomc": {
+                "amd64_sha256": "6ffd76764e8ca484de12c6ecaa352db3d8efd5c9d44f393718b29b6600e0a559",
+                "arm64_sha256": "6825aecd2f123c9d4408e660aba8a72f9e547a3774350b8f4d2d9b674e99e424",
+                "repo": "registry.hub.docker.com/minio/mc",
+                "tag": "latest"
+            },
+            "netdata": {
+                "amd64_sha256": "95e74c36f15091bcd7983ee162248f1f91c21207c235fce6b0d6f8ed9a11732a",
+                "arm64_sha256": "cd3dc9d182a4561b162f03c6986f4647bbb704f8e7e4872ee0611b1b9e86e1b0",
+                "repo": "registry.hub.docker.com/netdata/netdata",
+                "tag": "latest"
+            },
+            "vere": {
+                "amd64_sha256": "7dc0a1f97214101482d9c329a5108471bcf23fafea421e1ae2662c6c20377037",
+                "arm64_sha256": "1dbded539bd99cd789bfe5cbe11bb89baa598e213881389e8138da8fc0a27fa9",
+                "repo": "registry.hub.docker.com/nativeplanet/urbit",
+                "tag": "v2.11"
+            },
+            "webui": {
+                "amd64_sha256": "a2c683530d15b1095bcb3e97b1b6236461142e6e19774762991e30c817352797",
+                "arm64_sha256": "0b96f7a02efc0d5c754bd6d89df2b9f738a676c51b529258b99d5b84e30d1725",
+                "repo": "registry.hub.docker.com/nativeplanet/groundseg-webui",
+                "tag": "edge"
+            },
+            "wireguard": {
+                "amd64_sha256": "ae6f8e8cc1303bc9c0b5fa1b1ef4176c25a2c082e29bf8b554ce1196731e7db2",
+                "arm64_sha256": "403d741b1b5bcf5df1e48eab0af8038355fae3e29419ad5980428f9aebd1576c",
+                "repo": "registry.hub.docker.com/linuxserver/wireguard",
+                "tag": "latest"
+            }
+        },
+        "latest": {
+            "groundseg": {
+                "amd64_sha256": "58041cd66c692cddd09e83dedf6c803c1a1a5a46a6cc28167a3fb3e736f3e160",
+                "amd64_url": "https://files.native.computer/bin/groundseg_amd64_v1.4.2_latest",
+                "arm64_sha256": "4256fc53658a3bfcde793157951ea587c0992a0de879d8eb016a941097163e47",
+                "arm64_url": "https://files.native.computer/bin/groundseg_arm64_v1.4.2_latest",
+                "major": 1,
+                "minor": 4,
+                "patch": 2
+            },
+            "manual": {
+                "amd64_sha256": "148a2acb946c4c38720cf8994a39b20f655547fd43996f2449ff5b7bc24793c9",
+                "arm64_sha256": "baa87ad152ec14a7df9cd889e970cd1ad9c5f6bbc0e1fbd587f5ed6c89e31f08",
+                "repo": "registry.hub.docker.com/nativeplanet/groundseg-manual",
+                "tag": "latest"
+            },
+            "minio": {
+                "amd64_sha256": "f6a3001a765dc59a8e365149ade0ea628494230e984891877ead016eb24ba9a9",
+                "arm64_sha256": "567779c9f29aca670f84d066051290faeaae6c3ad3a3b7062de4936aaab2a29d",
+                "repo": "registry.hub.docker.com/minio/minio",
+                "tag": "latest"
+            },
+            "miniomc": {
+                "amd64_sha256": "6ffd76764e8ca484de12c6ecaa352db3d8efd5c9d44f393718b29b6600e0a559",
+                "arm64_sha256": "6825aecd2f123c9d4408e660aba8a72f9e547a3774350b8f4d2d9b674e99e424",
+                "repo": "registry.hub.docker.com/minio/mc",
+                "tag": "latest"
+            },
+            "netdata": {
+                "amd64_sha256": "95e74c36f15091bcd7983ee162248f1f91c21207c235fce6b0d6f8ed9a11732a",
+                "arm64_sha256": "cd3dc9d182a4561b162f03c6986f4647bbb704f8e7e4872ee0611b1b9e86e1b0",
+                "repo": "registry.hub.docker.com/netdata/netdata",
+                "tag": "latest"
+            },
+            "vere": {
+                "amd64_sha256": "7dc0a1f97214101482d9c329a5108471bcf23fafea421e1ae2662c6c20377037",
+                "arm64_sha256": "1dbded539bd99cd789bfe5cbe11bb89baa598e213881389e8138da8fc0a27fa9",
+                "repo": "registry.hub.docker.com/nativeplanet/urbit",
+                "tag": "v2.11"
+            },
+            "webui": {
+                "amd64_sha256": "a2c683530d15b1095bcb3e97b1b6236461142e6e19774762991e30c817352797",
+                "arm64_sha256": "0b96f7a02efc0d5c754bd6d89df2b9f738a676c51b529258b99d5b84e30d1725",
+                "repo": "registry.hub.docker.com/nativeplanet/groundseg-webui",
+                "tag": "latest"
+            },
+            "wireguard": {
+                "amd64_sha256": "ae6f8e8cc1303bc9c0b5fa1b1ef4176c25a2c082e29bf8b554ce1196731e7db2",
+                "arm64_sha256": "403d741b1b5bcf5df1e48eab0af8038355fae3e29419ad5980428f9aebd1576c",
+                "repo": "registry.hub.docker.com/linuxserver/wireguard",
+                "tag": "latest"
+            }
+        }
+    }
+}

+ 10 - 0
setup/setup.go

@@ -1 +1,11 @@
 package setup
+
+import (
+	"github.com/gorilla/websocket"
+	"goseg/config"
+	"goseg/structs"
+)
+
+func Setup(action structs.WsPayload, conn *websocket.Conn) {
+	return
+}

+ 127 - 0
structs/structs.go

@@ -4,6 +4,11 @@ import (
 	"time"
 )
 
+type WsPayload struct {
+	Type   string `json:"type"`
+	Action string `json:"action"`
+}
+
 type SessionInfo struct {
 	Hash    string `json:"hash"`
 	Created string `json:"created"`
@@ -93,3 +98,125 @@ type VersionDetails struct {
 	Repo        string `json:"repo,omitempty"`
 	Tag         string `json:"tag,omitempty"`
 }
+
+type SystemUsage struct {
+	RAM      []int64 `json:"ram"`
+	CPU      int     `json:"cpu"`
+	CPUTemp  int     `json:"cpu_temp"`
+	Disk     []int64 `json:"disk"`
+	SwapFile int     `json:"swap"`
+}
+
+type SystemUpdates struct {
+	Linux struct {
+		State   string `json:"state"`
+		Upgrade int    `json:"upgrade"`
+		New     int    `json:"new"`
+		Remove  int    `json:"remove"`
+		Ignore  int    `json:"ignore"`
+	} `json:"linux"`
+}
+
+type SystemWifi struct {
+	Status   string   `json:"status"`
+	Active   string   `json:"active"`
+	Networks []string `json:"networks"`
+}
+
+type SystemInfo struct {
+	Usage   SystemUsage   `json:"usage"`
+	Updates SystemUpdates `json:"updates"`
+	Wifi    SystemWifi    `json:"wifi"`
+}
+
+type Profile struct {
+	Startram Startram `json:"startram"`
+}
+
+type Startram struct {
+	Info struct {
+		Registered bool              `json:"registered"`
+		Running    bool              `json:"running"`
+		Region     any               `json:"region"`
+		Expiry     any               `json:"expiry"`
+		Renew      bool              `json:"renew"`
+		Endpoint   string            `json:"endpoint"`
+		Regions    map[string]Region `json:"regions"`
+	} `json:"info"`
+	Transition struct {
+		Register any `json:"register"`
+		Toggle   any `json:"toggle"`
+	} `json:"transition"`
+}
+
+type Urbit struct {
+	Info struct {
+		Network          string `json:"network"`
+		Running          bool   `json:"running"`
+		URL              string `json:"url"`
+		UrbAlias         bool   `json:"urbAlias"`
+		MemUsage         int    `json:"memUsage"`
+		DiskUsage        int    `json:"diskUsage"`
+		LoomSize         int    `json:"loomSize"`
+		DevMode          bool   `json:"devMode"`
+		DetectBootStatus bool   `json:"detectBootStatus"`
+		Remote           bool   `json:"remote"`
+		Vere             any    `json:"vere"`
+	} `json:"info"`
+	Transition struct {
+		Meld                      any    `json:"meld"`
+		ServiceRegistrationStatus string `json:"serviceRegistrationStatus"`
+		TogglePower               any    `json:"togglePower"`
+		DeleteShip                any    `json:"deleteShip"`
+	} `json:"transition"`
+}
+
+type Logs struct {
+	Containers struct {
+		Wireguard struct {
+			Logs []any `json:"logs"`
+		} `json:"wireguard"`
+	} `json:"containers"`
+	System struct {
+		Stream bool  `json:"stream"`
+		Logs   []any `json:"logs"`
+	} `json:"system"`
+}
+
+type AuthBroadcast struct {
+	Type      string           `json:"type"`
+	AuthLevel string           `json:"auth_level"`
+	Upload    Upload           `json:"upload"`
+	Logs      Logs             `json:"logs"`
+	System    SystemInfo       `json:"system"`
+	Profile   Profile          `json:"profile"`
+	Urbits    map[string]Urbit `json:"urbits"`
+}
+
+type Upload struct {
+	Status   string `json:"status"`
+	Size     int    `json:"size"`
+	Uploaded int    `json:"uploaded"`
+	Patp     any    `json:"patp"`
+}
+
+type UnauthBroadcast struct {
+	Type      string `json:"type"`
+	AuthLevel string `json:"auth_level"`
+	Login     struct {
+		Remainder int `json:"remainder"`
+	} `json:"login"`
+}
+
+type SetupBroadcast struct {
+	Type      string            `json:"type"`
+	AuthLevel string            `json:"auth_level"`
+	Stage     string            `json:"stage"`
+	Page      string            `json:"page"`
+	Regions   map[string]Region `json:"regions"`
+}
+
+type Region struct {
+	Country string `json:"country"`
+	Desc    string `json:"desc"`
+}

+ 84 - 0
ws/ws.go

@@ -0,0 +1,84 @@
+package ws
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/gorilla/websocket"
+	"goseg/broadcast"
+	"goseg/structs"
+	"log/slog"
+	"net/http"
+	"os"
+	"time"
+)
+
+var (
+	logger   = slog.New(slog.NewJSONHandler(os.Stdout, nil))
+	upgrader = websocket.Upgrader{
+		ReadBufferSize:  1024,
+		WriteBufferSize: 1024,
+	}
+)
+
+// switch on ws event cases
+func WsHandler(w http.ResponseWriter, r *http.Request) {
+	conn, err := upgrader.Upgrade(w, r, nil)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	// manage broadcasts and clients thru the broadcast package
+	broadcast.RegisterClient(conn)
+	defer broadcast.UnregisterClient(conn)
+	// keepalive for ws
+	conn.SetPongHandler(func(string) error {
+		conn.SetReadDeadline(time.Now().Add(60 * time.Second))
+		return nil
+	})
+	pingInterval := 15 * time.Second
+	go func() {
+		ticker := time.NewTicker(pingInterval)
+		defer ticker.Stop()
+		for {
+			select {
+			case <-ticker.C:
+				if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil {
+					return
+				}
+			}
+		}
+	}()
+	for {
+		_, msg, err := conn.ReadMessage()
+		if err != nil {
+			return
+		}
+		var payload structs.WsPayload
+		if err := json.Unmarshal(msg, &payload); err != nil {
+			fmt.Println("Error unmarshalling message:", err)
+			continue
+		}
+		switch payload.Type {
+		case "setup":
+			logger.Info("Setup")
+			// setup.Setup(payload)
+		case "new_ship":
+			logger.Info("New ship")
+		case "pier_upload":
+			logger.Info("Pier upload")
+		case "password":
+			logger.Info("Password")
+		case "system":
+			logger.Info("System")
+		case "startram":
+			logger.Info("StarTram")
+		case "urbit":
+			logger.Info("Urbit")
+		case "support":
+			logger.Info("Support")
+		default:
+			errmsg := fmt.Sprintf("Unknown request type:", payload.Type)
+			logger.Warn(errmsg)
+		}
+	}
+}

Vissa filer visades inte eftersom för många filer har ändrats