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