97 lines
2.2 KiB
Go
97 lines
2.2 KiB
Go
package runtime
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"time"
|
|
|
|
yanic "github.com/FreifunkBremen/yanic/runtime"
|
|
|
|
"github.com/FreifunkBremen/freifunkmanager/lib/log"
|
|
"github.com/FreifunkBremen/freifunkmanager/ssh"
|
|
)
|
|
|
|
type Nodes struct {
|
|
List map[string]*Node `json:"nodes"`
|
|
ToUpdate map[string]struct{}
|
|
ssh *ssh.Manager
|
|
statePath string
|
|
iface string
|
|
}
|
|
|
|
func NewNodes(path string, iface string, mgmt *ssh.Manager) *Nodes {
|
|
nodes := &Nodes{
|
|
List: make(map[string]*Node),
|
|
ToUpdate: make(map[string]struct{}),
|
|
ssh: mgmt,
|
|
statePath: path,
|
|
iface: iface,
|
|
}
|
|
nodes.load()
|
|
return nodes
|
|
}
|
|
|
|
func (nodes *Nodes) AddNode(n *yanic.Node) {
|
|
node := NewNode(n)
|
|
if node == nil {
|
|
return
|
|
}
|
|
logger := log.Log.WithField("method", "AddNode").WithField("node_id", node.NodeID)
|
|
|
|
if cNode := nodes.List[node.NodeID]; cNode != nil {
|
|
cNode.Lastseen = time.Now()
|
|
if _, ok := nodes.ToUpdate[node.NodeID]; ok {
|
|
if nodes.List[node.NodeID].IsEqual(node) {
|
|
delete(nodes.ToUpdate, node.NodeID)
|
|
}
|
|
} else {
|
|
nodes.List[node.NodeID] = node
|
|
}
|
|
logger.Debugf("know already these node")
|
|
return
|
|
}
|
|
node.Lastseen = time.Now()
|
|
// session := nodes.ssh.ConnectTo(node.Address)
|
|
result, err := nodes.ssh.RunOn(node.GetAddress(nodes.iface), "uptime")
|
|
if err != nil {
|
|
logger.Error("init ssh command not run")
|
|
return
|
|
}
|
|
uptime := ssh.SSHResultToString(result)
|
|
logger.Infof("new node with uptime: %s", uptime)
|
|
|
|
nodes.List[node.NodeID] = node
|
|
}
|
|
|
|
func (nodes *Nodes) UpdateNode(node *Node) {
|
|
if n, ok := nodes.List[node.NodeID]; ok {
|
|
go node.SSHUpdate(nodes.ssh, nodes.iface, n)
|
|
}
|
|
nodes.List[node.NodeID] = node
|
|
nodes.ToUpdate[node.NodeID] = struct{}{}
|
|
}
|
|
|
|
func (nodes *Nodes) Updater() {
|
|
for nodeid := range nodes.ToUpdate {
|
|
if node := nodes.List[nodeid]; node != nil {
|
|
go node.SSHSet(nodes.ssh, nodes.iface)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (nodes *Nodes) load() {
|
|
if f, err := os.Open(nodes.statePath); err == nil { // transform data to legacy meshviewer
|
|
if err = json.NewDecoder(f).Decode(nodes); err == nil {
|
|
log.Log.Info("loaded", len(nodes.List), "nodes")
|
|
} else {
|
|
log.Log.Error("failed to unmarshal nodes:", err)
|
|
}
|
|
} else {
|
|
log.Log.Error("failed to load cached nodes:", err)
|
|
}
|
|
}
|
|
|
|
func (nodes *Nodes) Saver() {
|
|
yanic.SaveJSON(nodes, nodes.statePath)
|
|
}
|