[TASK] add console to backend
This commit is contained in:
parent
2e5873a541
commit
7aa5896c4f
|
@ -25,6 +25,7 @@ var (
|
||||||
configFile string
|
configFile string
|
||||||
config *configPackage.Config
|
config *configPackage.Config
|
||||||
nodes *runtime.Nodes
|
nodes *runtime.Nodes
|
||||||
|
commands *runtime.Commands
|
||||||
yanicDialer *yanic.Dialer
|
yanicDialer *yanic.Dialer
|
||||||
stats *runtimeYanic.GlobalStats
|
stats *runtimeYanic.GlobalStats
|
||||||
)
|
)
|
||||||
|
@ -38,14 +39,15 @@ func main() {
|
||||||
log.Log.Info("starting...")
|
log.Log.Info("starting...")
|
||||||
|
|
||||||
sshmanager := ssh.NewManager(config.SSHPrivateKey)
|
sshmanager := ssh.NewManager(config.SSHPrivateKey)
|
||||||
nodes := runtime.NewNodes(config.StatePath, config.SSHInterface, sshmanager)
|
nodes = runtime.NewNodes(config.StatePath, config.SSHInterface, sshmanager)
|
||||||
|
commands = runtime.NewCommands(sshmanager)
|
||||||
nodesUpdateWorker := worker.NewWorker(time.Duration(3)*time.Minute, nodes.Updater)
|
nodesUpdateWorker := worker.NewWorker(time.Duration(3)*time.Minute, nodes.Updater)
|
||||||
nodesSaveWorker := worker.NewWorker(time.Duration(3)*time.Second, nodes.Saver)
|
nodesSaveWorker := worker.NewWorker(time.Duration(3)*time.Second, nodes.Saver)
|
||||||
|
|
||||||
go nodesUpdateWorker.Start()
|
go nodesUpdateWorker.Start()
|
||||||
go nodesSaveWorker.Start()
|
go nodesSaveWorker.Start()
|
||||||
|
|
||||||
websocket.Start(nodes)
|
websocket.Start(nodes, commands)
|
||||||
|
|
||||||
if config.Yanic.Enable {
|
if config.Yanic.Enable {
|
||||||
yanicDialer := yanic.Dial(config.Yanic.Type, config.Yanic.Address)
|
yanicDialer := yanic.Dial(config.Yanic.Type, config.Yanic.Address)
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/FreifunkBremen/freifunkmanager/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Commands struct {
|
||||||
|
List map[string]*Command
|
||||||
|
mgmt *ssh.Manager
|
||||||
|
}
|
||||||
|
|
||||||
|
type Command struct {
|
||||||
|
ssh.List
|
||||||
|
Timestemp time.Time `json:"timestemp"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCommands(mgmt *ssh.Manager) *Commands {
|
||||||
|
return &Commands{
|
||||||
|
mgmt: mgmt,
|
||||||
|
List: make(map[string]*Command),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmds *Commands) AddCommand(c *Command) *Command {
|
||||||
|
cmd := mapCommand(cmds.mgmt, c)
|
||||||
|
cmds.List[cmd.ID] = cmd
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapCommand(mgmt *ssh.Manager, c *Command) *Command {
|
||||||
|
list := mgmt.CreateList(c.Command)
|
||||||
|
command := &Command{List: *list}
|
||||||
|
command.ID = c.ID
|
||||||
|
command.Timestemp = c.Timestemp
|
||||||
|
return command
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *Command) Run(f func()) {
|
||||||
|
cmd.List.Run()
|
||||||
|
f()
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type List struct {
|
type List struct {
|
||||||
cmd string `json:"cmd"`
|
Command string `json:"cmd"`
|
||||||
Clients map[string]*ListResult `json:"clients"`
|
Clients map[string]*ListResult `json:"clients"`
|
||||||
sshManager *Manager
|
sshManager *Manager
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ type ListResult struct {
|
||||||
|
|
||||||
func (m *Manager) CreateList(cmd string) *List {
|
func (m *Manager) CreateList(cmd string) *List {
|
||||||
list := &List{
|
list := &List{
|
||||||
cmd: cmd,
|
Command: cmd,
|
||||||
sshManager: m,
|
sshManager: m,
|
||||||
Clients: make(map[string]*ListResult),
|
Clients: make(map[string]*ListResult),
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ func (l List) Run() {
|
||||||
|
|
||||||
func (l List) runlistelement(host string, client *ListResult, wg *sync.WaitGroup) {
|
func (l List) runlistelement(host string, client *ListResult, wg *sync.WaitGroup) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
result, err := l.sshManager.run(host, client.ssh, l.cmd)
|
result, err := l.sshManager.run(host, client.ssh, l.Command)
|
||||||
client.Running = false
|
client.Running = false
|
||||||
if err != nil {
|
if err != nil {
|
||||||
client.WithError = true
|
client.WithError = true
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
width: 15%;
|
width: 15%;
|
||||||
}
|
}
|
||||||
.console .cmd > div {
|
.console .cmd > div {
|
||||||
clear: both;
|
|
||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
}
|
}
|
||||||
|
@ -34,3 +33,9 @@
|
||||||
width: 15%;
|
width: 15%;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
|
.console .cmd > div > div {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.console .cmd div .status {
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
|
|
@ -120,6 +120,7 @@ const guiConsole = {};
|
||||||
|
|
||||||
if (cmd.clients) {
|
if (cmd.clients) {
|
||||||
Object.keys(cmd.clients).forEach((addr) => {
|
Object.keys(cmd.clients).forEach((addr) => {
|
||||||
|
console.log(cmd, row, addr);
|
||||||
const clientEl = domlib.newAt(row.clientsContainer, 'div'),
|
const clientEl = domlib.newAt(row.clientsContainer, 'div'),
|
||||||
clients = {
|
clients = {
|
||||||
'host': domlib.newAt(clientEl, 'span'),
|
'host': domlib.newAt(clientEl, 'span'),
|
||||||
|
|
|
@ -36,9 +36,7 @@ let socket = {'readyState': 0};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'cmd':
|
case 'cmd':
|
||||||
if (msg.body) {
|
store.updateCMD(msg.cmd);
|
||||||
store.updateCMD(msg.body);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
notify.send('warn', `unable to identify message: ${raw}`);
|
notify.send('warn', `unable to identify message: ${raw}`);
|
||||||
|
@ -69,7 +67,7 @@ let socket = {'readyState': 0};
|
||||||
function sendcmd (cmd) {
|
function sendcmd (cmd) {
|
||||||
const notifyMsg = `Befehl '${cmd.cmd}' wird überall ausgeführt.`,
|
const notifyMsg = `Befehl '${cmd.cmd}' wird überall ausgeführt.`,
|
||||||
socketMsg = JSON.stringify({
|
socketMsg = JSON.stringify({
|
||||||
'body': cmd,
|
'cmd': cmd,
|
||||||
'type': 'cmd'
|
'type': 'cmd'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,10 @@ package websocket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/genofire/golang-lib/log"
|
"github.com/genofire/golang-lib/log"
|
||||||
|
"github.com/genofire/golang-lib/worker"
|
||||||
"golang.org/x/net/websocket"
|
"golang.org/x/net/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -53,23 +55,38 @@ func (c *Client) Close() {
|
||||||
func (c *Client) Listen() {
|
func (c *Client) Listen() {
|
||||||
go c.listenWrite()
|
go c.listenWrite()
|
||||||
c.Write(&Message{Type: MessageTypeStats, Body: stats})
|
c.Write(&Message{Type: MessageTypeStats, Body: stats})
|
||||||
c.allNodes()
|
c.publishAllData()
|
||||||
c.listenRead()
|
c.listenRead()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) allNodes() {
|
func (c *Client) publishAllData() {
|
||||||
for _, node := range nodes.List {
|
for _, node := range nodes.List {
|
||||||
c.Write(&Message{Type: MessageTypeSystemNode, Node: node})
|
c.Write(&Message{Type: MessageTypeSystemNode, Node: node})
|
||||||
}
|
}
|
||||||
for _, node := range nodes.Current {
|
for _, node := range nodes.Current {
|
||||||
c.Write(&Message{Type: MessageTypeCurrentNode, Node: node})
|
c.Write(&Message{Type: MessageTypeCurrentNode, Node: node})
|
||||||
}
|
}
|
||||||
|
for _, cmd := range commands.List {
|
||||||
|
c.Write(&Message{Type: MessageTypeCommand, Command: cmd})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) handleMessage(msg *Message) {
|
func (c *Client) handleMessage(msg *Message) {
|
||||||
switch msg.Type {
|
switch msg.Type {
|
||||||
case MessageTypeSystemNode:
|
case MessageTypeSystemNode:
|
||||||
nodes.UpdateNode(msg.Node)
|
nodes.UpdateNode(msg.Node)
|
||||||
|
break
|
||||||
|
case MessageTypeCommand:
|
||||||
|
cmd := commands.AddCommand(msg.Command)
|
||||||
|
w := worker.NewWorker(time.Millisecond*300, func() {
|
||||||
|
SendAll(Message{Type: MessageTypeCommand, Command: cmd})
|
||||||
|
})
|
||||||
|
go w.Start()
|
||||||
|
go cmd.Run(func() {
|
||||||
|
w.Close()
|
||||||
|
SendAll(Message{Type: MessageTypeCommand, Command: cmd})
|
||||||
|
})
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,15 @@ package websocket
|
||||||
import "github.com/FreifunkBremen/freifunkmanager/runtime"
|
import "github.com/FreifunkBremen/freifunkmanager/runtime"
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Body interface{} `json:"body,omitempty"`
|
Body interface{} `json:"body,omitempty"`
|
||||||
Node *runtime.Node `json:"node,omitempty"`
|
Node *runtime.Node `json:"node,omitempty"`
|
||||||
|
Command *runtime.Command `json:"cmd,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MessageTypeSystemNode = "system"
|
MessageTypeSystemNode = "system"
|
||||||
MessageTypeCurrentNode = "current"
|
MessageTypeCurrentNode = "current"
|
||||||
MessageTypeStats = "stats"
|
MessageTypeStats = "stats"
|
||||||
MessageTypeCmd = "cmd"
|
MessageTypeCommand = "cmd"
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,9 +16,11 @@ var nodes *runtime.Nodes
|
||||||
var clients map[string]*Client
|
var clients map[string]*Client
|
||||||
var clientsMutex sync.Mutex
|
var clientsMutex sync.Mutex
|
||||||
var stats *runtimeYanic.GlobalStats
|
var stats *runtimeYanic.GlobalStats
|
||||||
|
var commands *runtime.Commands
|
||||||
|
|
||||||
func Start(nodeBind *runtime.Nodes) {
|
func Start(nodeBind *runtime.Nodes, commandsBind *runtime.Commands) {
|
||||||
nodes = nodeBind
|
nodes = nodeBind
|
||||||
|
commands = commandsBind
|
||||||
clients = make(map[string]*Client)
|
clients = make(map[string]*Client)
|
||||||
|
|
||||||
http.Handle("/websocket", websocket.Handler(func(ws *websocket.Conn) {
|
http.Handle("/websocket", websocket.Handler(func(ws *websocket.Conn) {
|
||||||
|
|
|
@ -10,8 +10,9 @@ import (
|
||||||
func TestStart(t *testing.T) {
|
func TestStart(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
nodes := &runtime.Nodes{}
|
nodes := &runtime.Nodes{}
|
||||||
|
commands := &runtime.Commands{}
|
||||||
assert.Nil(clients)
|
assert.Nil(clients)
|
||||||
Start(nodes)
|
Start(nodes, commands)
|
||||||
assert.NotNil(clients)
|
assert.NotNil(clients)
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue