first working stripped html version
This commit is contained in:
parent
684aae7bc7
commit
0222caf32e
|
@ -0,0 +1 @@
|
||||||
|
unnamed-project
|
|
@ -0,0 +1 @@
|
||||||
|
assets_gen.go
|
|
@ -0,0 +1,9 @@
|
||||||
|
package assets
|
||||||
|
|
||||||
|
import (
|
||||||
|
assetfs "github.com/elazarl/go-bindata-assetfs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AssetFS() *assetfs.AssetFS {
|
||||||
|
return &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, AssetInfo: AssetInfo, Prefix: "public"}
|
||||||
|
}
|
2
go.mod
2
go.mod
|
@ -1,3 +1,5 @@
|
||||||
module varia.zone/unnamed-project
|
module varia.zone/unnamed-project
|
||||||
|
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
|
require github.com/elazarl/go-bindata-assetfs v1.0.1
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
|
||||||
|
github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
|
@ -0,0 +1,10 @@
|
||||||
|
default: run
|
||||||
|
|
||||||
|
MAIN := unnamed-project.go
|
||||||
|
ASSETS := assets/assets_gen.go
|
||||||
|
|
||||||
|
generate:
|
||||||
|
@rm -rf $(ASSETS) && go generate $(MAIN)
|
||||||
|
|
||||||
|
run: generate
|
||||||
|
@go run $(MAIN)
|
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="theme-color" content="#000000">
|
||||||
|
<title>Unnamed Project</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>Hello, World!</p>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
request.open('GET', '/api/config', true);
|
||||||
|
request.onload = function() {
|
||||||
|
if (this.status >= 200 && this.status < 400) {
|
||||||
|
var data = JSON.parse(this.response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
request.send();
|
||||||
|
</script>
|
||||||
|
</html>
|
|
@ -1,5 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
//go:generate go-bindata -o assets/assets_gen.go -pkg assets public/...
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/list"
|
"container/list"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -7,12 +9,15 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"varia.zone/unnamed-project/assets"
|
||||||
)
|
)
|
||||||
|
|
||||||
const help = `unnamed-project: WIP
|
const help = `unnamed-project: WIP
|
||||||
|
@ -52,11 +57,11 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
conf := &config{
|
conf := &config{
|
||||||
nodeID: nodeIDFlag,
|
NodeID: nodeIDFlag,
|
||||||
webPort: webPortFlag,
|
WebPort: webPortFlag,
|
||||||
filePort: filePortFlag,
|
FilePort: filePortFlag,
|
||||||
sharePath: pathFlag,
|
SharePath: pathFlag,
|
||||||
debug: debugFlag,
|
Debug: debugFlag,
|
||||||
}
|
}
|
||||||
|
|
||||||
serve(conf)
|
serve(conf)
|
||||||
|
@ -74,11 +79,11 @@ func handleCliFlags(username, sharePath string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
nodeID string
|
NodeID string `json:"nodeID"`
|
||||||
webPort int
|
WebPort int `json:"webPort"`
|
||||||
filePort int
|
FilePort int `json:"filePort"`
|
||||||
sharePath string
|
SharePath string `json:"sharePath"`
|
||||||
debug bool
|
Debug bool `json:"debug"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type announcer struct {
|
type announcer struct {
|
||||||
|
@ -86,10 +91,10 @@ type announcer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type nodeInfo struct {
|
type nodeInfo struct {
|
||||||
nodeID string `json:"nodeID"`
|
NodeID string `json:"nodeID"`
|
||||||
addr string `json:"addr"`
|
Addr string `json:"addr"`
|
||||||
webPort int `json:"webPort"`
|
WebPort int `json:"webPort"`
|
||||||
lastMulticast int64 `json:"lastMulticast"`
|
LastMulticast int64 `json:"lastMulticast"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -152,7 +157,7 @@ func announcedNodeHandler(ninfo *nodeInfo, nodeList *list.List) {
|
||||||
|
|
||||||
fmt.Print("[")
|
fmt.Print("[")
|
||||||
for el := nodeList.Front(); el != nil; el = el.Next() {
|
for el := nodeList.Front(); el != nil; el = el.Next() {
|
||||||
fmt.Print(el.Value.(*nodeInfo).nodeID, " ")
|
fmt.Print(el.Value.(*nodeInfo).NodeID, " ")
|
||||||
}
|
}
|
||||||
fmt.Print("]\n\n")
|
fmt.Print("]\n\n")
|
||||||
}
|
}
|
||||||
|
@ -163,9 +168,9 @@ func updateNodeList(ninfo *nodeInfo, nodeList *list.List) {
|
||||||
tmp := el.Value.(*nodeInfo)
|
tmp := el.Value.(*nodeInfo)
|
||||||
|
|
||||||
// Already in list
|
// Already in list
|
||||||
if tmp.nodeID == ninfo.nodeID {
|
if tmp.NodeID == ninfo.NodeID {
|
||||||
tmp.lastMulticast = time.Now().Unix()
|
tmp.LastMulticast = time.Now().Unix()
|
||||||
fmt.Printf("Updating node %s multicast\n", ninfo.nodeID)
|
fmt.Printf("Updating node %s multicast\n", ninfo.NodeID)
|
||||||
nodeExists = true
|
nodeExists = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -175,20 +180,20 @@ func updateNodeList(ninfo *nodeInfo, nodeList *list.List) {
|
||||||
for el := nodeList.Front(); el != nil; el = el.Next() {
|
for el := nodeList.Front(); el != nil; el = el.Next() {
|
||||||
tmp := el.Value.(*nodeInfo)
|
tmp := el.Value.(*nodeInfo)
|
||||||
if isNodeExpired(tmp, expireTimeoutSec) {
|
if isNodeExpired(tmp, expireTimeoutSec) {
|
||||||
fmt.Println("Node expired, removing: ", tmp.nodeID)
|
fmt.Println("Node expired, removing: ", tmp.NodeID)
|
||||||
nodeList.Remove(el)
|
nodeList.Remove(el)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !nodeExists {
|
if !nodeExists {
|
||||||
fmt.Printf("Adding new node! %p %s\n", ninfo, ninfo.nodeID)
|
fmt.Printf("Adding new node! %p %s\n", ninfo, ninfo.NodeID)
|
||||||
ninfo.lastMulticast = time.Now().Unix()
|
ninfo.LastMulticast = time.Now().Unix()
|
||||||
nodeList.PushBack(ninfo)
|
nodeList.PushBack(ninfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isNodeExpired(nodeInfo *nodeInfo, timeout int) bool {
|
func isNodeExpired(nodeInfo *nodeInfo, timeout int) bool {
|
||||||
diff := time.Now().Unix() - nodeInfo.lastMulticast
|
diff := time.Now().Unix() - nodeInfo.LastMulticast
|
||||||
return diff > int64(timeout)
|
return diff > int64(timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +207,7 @@ func parseAnnouncePacket(size int, addr *net.UDPAddr, packet []byte) (*nodeInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(packet[len(header):len(header)+1]) != nodeAnnounceCommand[0:] {
|
if string(packet[len(header):len(header)+1]) != nodeAnnounceCommand[0:] {
|
||||||
return nil, fmt.Errorf("Command different than NODE_ANNOUNCE_COMMAND")
|
return nil, fmt.Errorf("Command different than nodeAnnounceCommand")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Packet command is nodeAnnounceCommand")
|
fmt.Println("Packet command is nodeAnnounceCommand")
|
||||||
|
@ -213,8 +218,8 @@ func parseAnnouncePacket(size int, addr *net.UDPAddr, packet []byte) (*nodeInfo,
|
||||||
nodeInfo := &nodeInfo{}
|
nodeInfo := &nodeInfo{}
|
||||||
|
|
||||||
err := json.Unmarshal([]byte(payload), nodeInfo)
|
err := json.Unmarshal([]byte(payload), nodeInfo)
|
||||||
nodeInfo.addr = addr.IP.String()
|
nodeInfo.Addr = addr.IP.String()
|
||||||
nodeInfo.nodeID = fmt.Sprintf("%s-%s", nodeInfo.nodeID, nodeInfo.addr)
|
nodeInfo.NodeID = fmt.Sprintf("%s-%s", nodeInfo.NodeID, nodeInfo.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -249,7 +254,7 @@ func listenForNodes(nodeList *list.List) {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fmt.Printf("Received multicast packet from %s Id: %s\n", udpAddr.String(), nodeInfo.nodeID)
|
fmt.Printf("Received multicast packet from %s Id: %s\n", udpAddr.String(), nodeInfo.NodeID)
|
||||||
|
|
||||||
go announcedNodeHandler(nodeInfo, nodeList)
|
go announcedNodeHandler(nodeInfo, nodeList)
|
||||||
}
|
}
|
||||||
|
@ -257,10 +262,10 @@ func listenForNodes(nodeList *list.List) {
|
||||||
|
|
||||||
func (a *announcer) Start(nodeList *list.List) {
|
func (a *announcer) Start(nodeList *list.List) {
|
||||||
nodeInfo := &nodeInfo{
|
nodeInfo := &nodeInfo{
|
||||||
nodeID: a.conf.nodeID,
|
NodeID: a.conf.NodeID,
|
||||||
addr: "",
|
Addr: "",
|
||||||
webPort: a.conf.webPort,
|
WebPort: a.conf.WebPort,
|
||||||
lastMulticast: 0,
|
LastMulticast: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
go announceNode(nodeInfo)
|
go announceNode(nodeInfo)
|
||||||
|
@ -277,12 +282,68 @@ func serve(conf *config) {
|
||||||
|
|
||||||
go startAnnouncer(conf, nodeList)
|
go startAnnouncer(conf, nodeList)
|
||||||
|
|
||||||
// TODO: next steps...
|
go fileServe(conf)
|
||||||
// go fileServe(conf)
|
go dashboardServe(conf, nodeList)
|
||||||
// go dashboardServe(conf, nodeList)
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// TODO: do this context cancel trick to escape cleanly?
|
// TODO: do this context cancel trick to escape cleanly?
|
||||||
time.Sleep(time.Minute * 15)
|
time.Sleep(time.Minute * 15)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fileServe(conf *config) {
|
||||||
|
fileMux := http.NewServeMux()
|
||||||
|
fileMux.Handle("/", http.FileServer(http.Dir(conf.SharePath)))
|
||||||
|
http.ListenAndServe(fmt.Sprintf("0.0.0.0:%v", conf.WebPort), fileMux)
|
||||||
|
}
|
||||||
|
|
||||||
|
func configHandler(conf *config) func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
data, err := json.Marshal(conf)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
w.Write(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func nodesHandler(nodeList *list.List) func(http.ResponseWriter, *http.Request) {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
nodes := make([]*nodeInfo, 0)
|
||||||
|
for el := nodeList.Front(); el != nil; el = el.Next() {
|
||||||
|
tmp := el.Value.(*nodeInfo)
|
||||||
|
nodes = append(nodes, tmp)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := json.Marshal(nodes)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
w.Write(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func dashboardServe(conf *config, nodeList *list.List) {
|
||||||
|
dashboardMux := http.NewServeMux()
|
||||||
|
dashboardMux.Handle("/", http.FileServer(assets.AssetFS()))
|
||||||
|
dashboardMux.HandleFunc("/api/config", configHandler(conf))
|
||||||
|
dashboardMux.HandleFunc("/api/nodes", nodesHandler(nodeList))
|
||||||
|
|
||||||
|
// We don't want the dashboard to be public
|
||||||
|
address := "localhost"
|
||||||
|
if conf.Debug {
|
||||||
|
address = "0.0.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Starting dashboard at %s:%v\n", address, conf.FilePort)
|
||||||
|
err := http.ListenAndServe(fmt.Sprintf("%s:%v", address, conf.FilePort), dashboardMux)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue