Added batch group move, support for agent custom cores.

This commit is contained in:
Ylian Saint-Hilaire 2019-02-18 17:50:10 -08:00
parent 137cfcd0ae
commit eae67b9985
4 changed files with 66 additions and 43 deletions

View File

@ -104,11 +104,25 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
if (cmdid == 11) { // MeshCommand_CoreModuleHash
if (msg.length == 4) { ChangeAgentCoreInfo({ "caps": 0 }); } // If the agent indicated that no core is running, clear the core information string.
// Mesh core hash, sent by agent with the hash of the current mesh core.
if (obj.agentCoreCheck == 1000) return; // If we are using a custom core, don't try to update it.
// If we are using a custom core, don't try to update it.
if (obj.agentCoreCheck == 1000) {
obj.send(obj.common.ShortToStr(16) + obj.common.ShortToStr(0)); // MeshCommand_CoreOk. Indicates to the agent that the core is ok. Start it if it's not already started.
agentCoreIsStable();
return;
}
// Get the current meshcore hash
const agentMeshCoreHash = (msg.length == 52) ? msg.substring(4, 52) : null;
// If the agent indicates this is a custom core, we are done. TODO: Speed up this compare.
if (Buffer.from(agentMeshCoreHash, 'binary').toString('hex') == '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') {
obj.agentCoreCheck = 0;
obj.send(obj.common.ShortToStr(16) + obj.common.ShortToStr(0)); // MeshCommand_CoreOk. Indicates to the agent that the core is ok. Start it if it's not already started.
agentCoreIsStable();
return;
}
// We need to check if the core is current. First, figure out what core we need.
var corename = obj.parent.parent.meshAgentsArchitectureNumbers[obj.agentInfo.agentId].core;
if (obj.agentCoreCheck == 1001) { corename = obj.parent.parent.meshAgentsArchitectureNumbers[obj.agentInfo.agentId].rcore; } // Use the recovery core.

View File

@ -1160,43 +1160,49 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'changeDeviceMesh':
{
if (obj.common.validateString(command.nodeid, 1, 256) == false) break; // Check nodeid string
if (obj.common.validateString(command.meshid, 1, 256) == false) break; // Check meshid string
if (obj.common.validateStrArray(command.nodeids, 1, 256) == false) break; // Check nodeid strings
if (obj.common.validateString(command.meshid, 1, 256) == false) break; // Check target meshid string
obj.db.Get(command.nodeid, function (err, nodes) {
if (nodes.length != 1) return;
var node = nodes[0];
// For each nodeid, change the group
for (var i = 0; i < command.nodeids.length; i++) {
obj.db.Get(command.nodeids[i], function (err, nodes) {
if (nodes.length != 1) return;
var node = nodes[0];
// Check if already in the right mesh
if (node.meshid == command.meshid) return;
// Check if already in the right mesh
if (node.meshid == command.meshid) return;
// Make sure that we have rights on both source and destination mesh
var sourceMeshRights = user.links[node.meshid].rights;
var targetMeshRights = user.links[command.meshid].rights;
if (((sourceMeshRights & 4) == 0) || ((targetMeshRights & 4) == 0)) return;
// Make sure both source and target mesh are the same type
try { if (obj.parent.meshes[node.meshid].mtype != obj.parent.meshes[command.meshid].mtype) return; } catch (e) { return; };
// Perform the switch, start by saving the node with the new meshid.
var oldMeshId = node.meshid;
node.meshid = command.meshid;
obj.db.Set(node);
// Make sure that we have rights on both source and destination mesh
var sourceMeshRights = user.links[node.meshid].rights;
var targetMeshRights = user.links[command.meshid].rights;
if (((sourceMeshRights & 4) == 0) || ((targetMeshRights & 4) == 0)) return;
// If the device is connected on this server, switch it now.
var agentSession = obj.parent.wsagents[command.nodeid];
if (agentSession != null) { agentSession.dbMeshKey = command.meshid; agentSession.meshid = command.meshid.split('/')[2]; }
// Perform the switch, start by saving the node with the new meshid.
var oldMeshId = node.meshid;
node.meshid = command.meshid;
obj.db.Set(node);
// Add the connection state
var state = obj.parent.parent.GetConnectivityState(node._id);
if (state) {
node.conn = state.connectivity;
node.pwr = state.powerState;
if ((state.connectivity & 1) != 0) { var agent = obj.parent.wsagents[node._id]; if (agent != null) { node.agct = agent.connectTime; } }
if ((state.connectivity & 2) != 0) { var cira = obj.parent.parent.mpsserver.ciraConnections[node._id]; if (cira != null) { node.cict = cira.tag.connectTime; } }
}
// If the device is connected on this server, switch it now.
var agentSession = obj.parent.wsagents[node._id];
if (agentSession != null) { agentSession.dbMeshKey = command.meshid; agentSession.meshid = command.meshid.split('/')[2]; }
// Event the node change
var newMesh = obj.parent.meshes[command.meshid];
obj.parent.parent.DispatchEvent(['*', oldMeshId, command.meshid], obj, { etype: 'node', username: user.name, action: 'nodemeshchange', nodeid: node._id, node: node, oldMeshId: oldMeshId, newMeshId: command.meshid, msg: 'Moved device ' + node.name + ' to group ' + newMesh.name, domain: domain.id });
});
// Add the connection state
var state = obj.parent.parent.GetConnectivityState(node._id);
if (state) {
node.conn = state.connectivity;
node.pwr = state.powerState;
if ((state.connectivity & 1) != 0) { var agent = obj.parent.wsagents[node._id]; if (agent != null) { node.agct = agent.connectTime; } }
if ((state.connectivity & 2) != 0) { var cira = obj.parent.parent.mpsserver.ciraConnections[node._id]; if (cira != null) { node.cict = cira.tag.connectTime; } }
}
// Event the node change
var newMesh = obj.parent.meshes[command.meshid];
obj.parent.parent.DispatchEvent(['*', oldMeshId, command.meshid], obj, { etype: 'node', username: user.name, action: 'nodemeshchange', nodeid: node._id, node: node, oldMeshId: oldMeshId, newMeshId: command.meshid, msg: 'Moved device ' + node.name + ' to group ' + newMesh.name, domain: domain.id });
});
}
break;
}
case 'removedevices':

File diff suppressed because one or more lines are too long

View File

@ -2624,7 +2624,7 @@
function groupActionFunction() {
var x = "Select an operation to perform on all selected devices. Actions will be performed only with proper rights.<br /><br />";
x += addHtmlValue('Operation', '<select id=d2groupop style=float:right;width:250px><option value=100>Wake-up devices</option><option value=4>Sleep devices</option><option value=3>Reset devices</option><option value=2>Power off devices</option><option value=101>Delete devices</option></select>');
x += addHtmlValue('Operation', '<select id=d2groupop style=float:right;width:250px><option value=100>Wake-up devices</option><option value=4>Sleep devices</option><option value=3>Reset devices</option><option value=2>Power off devices</option><option value=102>Move group</option><option value=101>Delete devices</option></select>');
setDialogMode(2, "Group Action", 3, groupActionFunctionEx, x);
}
@ -2646,6 +2646,9 @@
x += "<input id=d2check type=checkbox onchange=d2groupActionFunctionDelEx() />Confirm";
setDialogMode(2, "Delete Nodes", 3, groupActionFunctionDelEx, x);
QE('idx_dlgOkButton', false);
} else if (op == 102) {
// Move computers to a different group
p10showChangeGroupDialog(getCheckedDevices());
} else {
// Power operation
meshserver.send({ action: 'poweraction', nodeids: getCheckedDevices(), actiontype: op });
@ -3529,7 +3532,7 @@
x = '<div style=float:right;font-size:x-small>';
if ((meshrights & 4) != 0) {
// TODO: Show change group only if there is another mesh of the same type.
x += '&nbsp;<a style=cursor:pointer onclick=p10showChangeGroupDialog("' + node._id + '") title="Move this device to a different device group">Change Group</a>';
x += '&nbsp;<a style=cursor:pointer onclick=p10showChangeGroupDialog(["' + node._id + '"]) title="Move this device to a different device group">Change Group</a>';
x += '&nbsp;<a style=cursor:pointer onclick=p10showDeleteNodeDialog("' + node._id + '") title="Remove this device">Delete Device</a>';
}
x += '</div><div style=font-size:x-small>';
@ -3795,30 +3798,30 @@
}
}
function p10showChangeGroupDialog(nodeid) {
var node = getNodeFromId(nodeid);
if (xxdialogMode || (node == null)) return;
var mesh1 = meshes[node.meshid];
function p10showChangeGroupDialog(nodeids) {
if (xxdialogMode) return;
var targetMeshId = null;
if (nodeids.length == 1) { try { targetMeshId = meshes[getNodeFromId(nodeids[0])]._id; } catch (ex) { } }
// List all available alternative groups
var y = "<select id=p10newGroup style=width:236px>", count = 0;
for (var i in meshes) {
var meshrights = meshes[i].links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights;
if ((meshes[i]._id != mesh1._id) && (meshes[i].mtype == mesh1.mtype) && (meshrights & 4)) { count++; y += "<option value='" + meshes[i]._id + "'>" + meshes[i].name + "</option>"; }
if ((meshes[i]._id != targetMeshId) && (meshrights & 4)) { count++; y += "<option value='" + meshes[i]._id + "'>" + meshes[i].name + "</option>"; }
}
y += "</select>";
if (count > 0) {
var x = "Select a new group for this device<br /><br />";
var x = (nodeids.length == 1) ? "Select a new group for this device<br /><br />" : "Select a new group for selected devices<br /><br />";
x += addHtmlValue('New Device Group', y);
setDialogMode(2, "Change Group", 3, p10showChangeGroupDialogEx, x, nodeid);
setDialogMode(2, "Change Group", 3, p10showChangeGroupDialogEx, x, nodeids);
} else {
setDialogMode(2, "Change Group", 1, null, "No other device group of same type exists.");
}
}
function p10showChangeGroupDialogEx(b, nodeid) {
meshserver.send({ action: 'changeDeviceMesh', nodeid: nodeid, meshid: Q('p10newGroup').value });
function p10showChangeGroupDialogEx(b, nodeids) {
meshserver.send({ action: 'changeDeviceMesh', nodeids: nodeids, meshid: Q('p10newGroup').value });
}
function p10showDeleteNodeDialog(nodeid) {