From 448aeec6e7cb58208ec9b540e728a955ca0e2768 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Sun, 5 Dec 2021 16:12:58 -0800 Subject: [PATCH] Added IP-KVM port status tracking. --- meshipkvm.js | 39 ++++++++++++++++++++------------- meshuser.js | 6 +++++ views/default-mobile.handlebars | 16 +++++++++----- views/default.handlebars | 12 ++++++---- 4 files changed, 48 insertions(+), 25 deletions(-) diff --git a/meshipkvm.js b/meshipkvm.js index 2242d774..13006ece 100644 --- a/meshipkvm.js +++ b/meshipkvm.js @@ -9,12 +9,11 @@ function CreateIPKVMManager(parent) { const obj = {}; const managedGroups = {} // meshid --> Manager - const managedPorts = {} // nodeid --> PortInfo + obj.managedPorts = {} // nodeid --> PortInfo // Subscribe for mesh creation events parent.AddEventDispatch(['server-createmesh', 'server-deletemesh'], obj); obj.HandleEvent = function (source, event, ids, id) { - console.log(); if ((event != null) && (event.action == 'createmesh') && (event.mtype == 4)) { // Start managing this new device group startManagement(parent.webserver.meshes[event.meshid]); @@ -54,7 +53,7 @@ function CreateIPKVMManager(parent) { for (var i = 0; i < manager.ports.length; i++) { const port = manager.ports[i]; const nodeid = generateIpKvmNodeId(manager.meshid, port.PortId, manager.domainid); - delete managedPorts[nodeid]; // Remove the managed port + delete obj.managedPorts[nodeid]; // Remove the managed port } // Remove the manager @@ -65,11 +64,13 @@ function CreateIPKVMManager(parent) { // Called when a KVM device changes state function onStateChanged(sender, state) { + /* console.log('State: ' + ['Disconnected', 'Connecting', 'Connected'][state]); if (state == 2) { console.log('DeviceModel:', sender.deviceModel); console.log('FirmwareVersion:', sender.firmwareVersion); } + */ } // Called when a KVM device changes state @@ -78,8 +79,8 @@ function CreateIPKVMManager(parent) { const port = sender.ports[updatedPorts[i]]; const nodeid = generateIpKvmNodeId(sender.meshid, port.PortId, sender.domainid); if ((port.Status == 1) && (port.Class == 'KVM')) { - console.log(port.PortNumber + ', ' + port.PortId + ', ' + port.Name + ', ' + port.Type + ', ' + ((port.StatAvailable == 0) ? 'Idle' : 'Connected')); - if ((managedPorts[nodeid] == null) || (managedPorts[nodeid].name != port.Name)) { + //console.log(port.PortNumber + ', ' + port.PortId + ', ' + port.Name + ', ' + port.Type + ', ' + ((port.StatAvailable == 0) ? 'Idle' : 'Connected')); + if ((obj.managedPorts[nodeid] == null) || (obj.managedPorts[nodeid].name != port.Name)) { parent.db.Get(nodeid, function (err, nodes) { if ((err != null) || (nodes == null)) return; const mesh = parent.webserver.meshes[sender.meshid]; @@ -104,26 +105,34 @@ function CreateIPKVMManager(parent) { } // Set the connectivity state if needed - if (managedPorts[nodeid] == null) { + if (obj.managedPorts[nodeid] == null) { parent.SetConnectivityState(sender.meshid, nodeid, Date.now(), 1, 1, null, null); - managedPorts[nodeid] = { name: port.Name, busy: false }; + obj.managedPorts[nodeid] = { name: port.Name }; } // Update busy state - const portInfo = managedPorts[nodeid]; - if (portInfo.busy != (port.StatAvailable != 0)) { - console.log('Busy state', (port.StatAvailable != 0)); + const portInfo = obj.managedPorts[nodeid]; + if ((portInfo.sessions != null) != (port.StatAvailable != 0)) { + if (port.StatAvailable != 0) { portInfo.sessions = { kvm: { 'busy': 1 } } } else { delete portInfo.sessions; } + + // Event the new sessions, this will notify everyone that agent sessions have changed + var event = { etype: 'node', action: 'devicesessions', nodeid: nodeid, domain: sender.domainid, sessions: portInfo.sessions, nolog: 1 }; + parent.DispatchEvent(parent.webserver.CreateMeshDispatchTargets(sender.meshid, [nodeid]), obj, event); } }); } else { // Update busy state - const portInfo = managedPorts[nodeid]; - if (portInfo.busy != (port.StatAvailable != 0)) { - console.log('Busy state', (port.StatAvailable != 0)); + const portInfo = obj.managedPorts[nodeid]; + if ((portInfo.sessions != null) != (port.StatAvailable != 0)) { + if (port.StatAvailable != 0) { portInfo.sessions = { kvm: { 'busy': 1 } } } else { delete portInfo.sessions; } + + // Event the new sessions, this will notify everyone that agent sessions have changed + var event = { etype: 'node', action: 'devicesessions', nodeid: nodeid, domain: sender.domainid, sessions: portInfo.sessions, nolog: 1 }; + parent.DispatchEvent(parent.webserver.CreateMeshDispatchTargets(sender.meshid, [nodeid]), obj, event); } } } else { - if (managedPorts[nodeid] != null) { + if (obj.managedPorts[nodeid] != null) { // This port is no longer connected parent.ClearConnectivityState(sender.meshid, nodeid, 1, null, null); @@ -141,7 +150,7 @@ function CreateIPKVMManager(parent) { } // Remove the managed port - delete managedPorts[nodeid]; + delete obj.managedPorts[nodeid]; } } } diff --git a/meshuser.js b/meshuser.js index f1911553..4a5ff73d 100644 --- a/meshuser.js +++ b/meshuser.js @@ -816,6 +816,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use const xagent = parent.wsagents[docs[i]._id]; if ((xagent != null) && (xagent.sessions != null)) { docs[i].sessions = xagent.sessions; } + // Add IP-KVM sessions + if (parent.parent.ipKvmManager != null) { + const xipkvmport = parent.parent.ipKvmManager.managedPorts[docs[i]._id]; + if ((xipkvmport != null) && (xipkvmport.sessions != null)) { docs[i].sessions = xipkvmport.sessions; } + } + r[meshid].push(docs[i]); } try { ws.send(JSON.stringify({ action: 'nodes', responseid: command.responseid, nodes: r, tag: command.tag })); } catch (ex) { } diff --git a/views/default-mobile.handlebars b/views/default-mobile.handlebars index f1efe098..6fdfdb32 100644 --- a/views/default-mobile.handlebars +++ b/views/default-mobile.handlebars @@ -3136,9 +3136,13 @@ if ((i == 'kvm') && (node.sessions.multidesk == null)) { x += '' + "Remote Desktop" + ''; for (var j in node.sessions.kvm) { - var trash = ''; - if ((j == userinfo._id) || (GetNodeRights(node) == 0xFFFFFFFF)) { trash = ' '; } - x += addHtmlValue4(getUserName(j), ((node.sessions.kvm[j] == 1) ? "1 session" : nobreak(format("{0} sessions", node.sessions.kvm[j]))) + trash); + if (j.startsWith('user/')) { + var trash = ''; + if ((j == userinfo._id) || (GetNodeRights(node) == 0xFFFFFFFF)) { trash = ' '; } + x += addHtmlValue4(getUserName(j), ((node.sessions.kvm[j] == 1) ? "1 session" : nobreak(format("{0} sessions", node.sessions.kvm[j]))) + trash); + } else if (j == 'busy') { + x += addHtmlValue2("Device is busy", ((node.sessions.kvm[j] == 1) ? "1 session" : nobreak(format("{0} sessions", node.sessions.kvm[j])))); + } } } else if (i == 'multidesk') { x += '' + "Remote Desktop" + ''; @@ -3218,7 +3222,7 @@ var states = []; if (node.state > 0 && node.state < powerStatetable.length) state.push(powerStatetable[node.state]); if (node.conn) { - if ((node.conn & 1) != 0) { if (node.mtype == 4) { states.push('' + ((node.mtype == 4)?"IP-KVM":"Agent") + ''); } else { states.push('' + "IP KVM" + ''); } } + if ((node.conn & 1) != 0) { states.push('' + ((node.mtype == 4)?"IP-KVM":"Agent") + ''); } if ((node.conn & 2) != 0) { states.push('' + "CIRA" + ''); } else if ((node.conn & 4) != 0) { states.push('' + "Intel® AMT" + ''); } if ((node.conn & 8) != 0) { states.push('' + "Relay" + ''); } @@ -3514,7 +3518,7 @@ x += '
'; // Show action button, only show if we have permissions 4, 8, 64 - if (((meshrights & (4 + 8 + 64)) != 0) && (node.mtype != 3)) { x += ''; } + if (((meshrights & (4 + 8 + 64)) != 0) && (node.mtype < 3)) { x += ''; } x += ''; //if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += ''; } @@ -3542,7 +3546,7 @@ // Set the node power state var powerstate = PowerStateStr(node.state); //if (node.state == 0) { powerstate = 'Unknown State'; } - if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += ((mesh.mtype == 4) ? "IP-KVM" : "Mesh Agent"); } + if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += ((node.mtype == 4) ? "IP-KVM" : "Mesh Agent"); } if ((connectivity & 2) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += "Intel® AMT connected"; } else if ((connectivity & 4) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += "Intel® AMT detected"; } if ((connectivity & 16) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += "MQTT channel connected"; } diff --git a/views/default.handlebars b/views/default.handlebars index 61181e01..eb140142 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -3994,7 +3994,7 @@ else if ((sort == 3) || (sort == 4)) { collapseName = 'tag:**xx**xx*TaG*xx**xx**'; } var collapsed = (sort != 3) & (sort != 4) & CollapsedGroups[collapseName]; r += ''; - } else if (((view == 3) || (view == 5)) && (node.conn & 1) && (((meshrights & 8) || (meshrights & 256)) != 0) && ((node.agent.caps & 1) != 0)) { // Check if we have rights and agent is capable of KVM. + } else if (((view == 3) || (view == 5)) && (node.conn & 1) && (((meshrights & 8) || (meshrights & 256)) != 0) && (node.agent) && ((node.agent.caps & 1) != 0)) { // Check if we have rights and agent is capable of KVM. // Draw the device (TODO: See if we can replace this with a standin in the future) if ((Object.keys(checkedNodeids).length == 0) || checkedNodeids[node._id]) { r += updateDeviceViewHtml(view, null, node); @@ -4494,9 +4494,13 @@ if ((i == 'kvm') && (node.sessions.multidesk == null)) { x += '' + "Remote Desktop" + ''; for (var j in node.sessions.kvm) { - var trash = ''; - if ((j == userinfo._id) || (GetNodeRights(node) == 0xFFFFFFFF)) { trash = ' '; } - x += addHtmlValue2(getUserName(j), ((node.sessions.kvm[j] == 1)?"1 session":nobreak(format("{0} sessions", node.sessions.kvm[j]))) + trash); + if (j.startsWith('user/')) { + var trash = ''; + if (((j == userinfo._id) || (GetNodeRights(node) == 0xFFFFFFFF))) { trash = ' '; } + x += addHtmlValue2(getUserName(j), ((node.sessions.kvm[j] == 1)?"1 session":nobreak(format("{0} sessions", node.sessions.kvm[j]))) + trash); + } else if (j == 'busy') { + x += addHtmlValue2("Device is busy", ((node.sessions.kvm[j] == 1)?"1 session":nobreak(format("{0} sessions", node.sessions.kvm[j])))); + } } } else if (i == 'multidesk') { x += '' + "Remote Desktop" + '';