mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-18 17:23:16 +00:00
1. Updated enumerability of some properties on MeshAgent
2. Updated selftest, and fixed a related crash
This commit is contained in:
@@ -1915,12 +1915,12 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
|
|||||||
ILibDuktape_CreateInstanceMethod(ctx, "hostname", ILibDuktape_MeshAgent_hostname, 0);
|
ILibDuktape_CreateInstanceMethod(ctx, "hostname", ILibDuktape_MeshAgent_hostname, 0);
|
||||||
|
|
||||||
Duktape_CreateEnum(ctx, "ContainerPermissions", (char*[]) { "DEFAULT", "NO_AGENT", "NO_MARSHAL", "NO_PROCESS_SPAWNING", "NO_FILE_SYSTEM_ACCESS", "NO_NETWORK_ACCESS" }, (int[]) { 0x00, 0x10000000, 0x08000000, 0x04000000, 0x00000001, 0x00000002 }, 6);
|
Duktape_CreateEnum(ctx, "ContainerPermissions", (char*[]) { "DEFAULT", "NO_AGENT", "NO_MARSHAL", "NO_PROCESS_SPAWNING", "NO_FILE_SYSTEM_ACCESS", "NO_NETWORK_ACCESS" }, (int[]) { 0x00, 0x10000000, 0x08000000, 0x04000000, 0x00000001, 0x00000002 }, 6);
|
||||||
duk_push_string(ctx, agent->displayName); ILibDuktape_CreateReadonlyProperty(ctx, "displayName");
|
duk_push_string(ctx, agent->displayName); ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, "displayName",1);
|
||||||
|
|
||||||
if (agent->JSRunningAsService)
|
if (agent->JSRunningAsService)
|
||||||
{
|
{
|
||||||
duk_push_string(ctx, agent->meshServiceName);
|
duk_push_string(ctx, agent->meshServiceName);
|
||||||
ILibDuktape_CreateReadonlyProperty(ctx, "serviceName");
|
ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, "serviceName", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1930,13 +1930,13 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
|
|||||||
#else
|
#else
|
||||||
duk_push_false(ctx);
|
duk_push_false(ctx);
|
||||||
#endif
|
#endif
|
||||||
ILibDuktape_CreateReadonlyProperty(ctx, "isService");
|
ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, "isService",1);
|
||||||
#else
|
#else
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
// Determine if we're running as service on Linux
|
// Determine if we're running as service on Linux
|
||||||
if (duk_peval_string(ctx, "require('service-manager').manager.getService('meshagent').isMe();") == 0)
|
if (duk_peval_string(ctx, "require('service-manager').manager.getService('meshagent').isMe();") == 0)
|
||||||
{
|
{
|
||||||
ILibDuktape_CreateReadonlyProperty(ctx, "isService");
|
ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, "isService",1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1336,9 +1336,12 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
|
|||||||
if (Reader->OnData != NULL)
|
if (Reader->OnData != NULL)
|
||||||
{
|
{
|
||||||
Reader->OnData(Reader, Reader->buffer + Reader->BeginPointer, &(iPointer), Reader->EndPointer - Reader->BeginPointer, &(Reader->OnInterrupt), &(Reader->user), &(Reader->PAUSE));
|
Reader->OnData(Reader, Reader->buffer + Reader->BeginPointer, &(iPointer), Reader->EndPointer - Reader->BeginPointer, &(Reader->OnInterrupt), &(Reader->user), &(Reader->PAUSE));
|
||||||
assert(iPointer <= (Reader->EndPointer - Reader->BeginPointer));
|
if (Reader->buffer != NULL)
|
||||||
if (iPointer == 0) { break; }
|
{
|
||||||
Reader->BeginPointer += iPointer;
|
assert(iPointer <= (Reader->EndPointer - Reader->BeginPointer));
|
||||||
|
if (iPointer == 0) { break; }
|
||||||
|
Reader->BeginPointer += iPointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Reader->BeginPointer == Reader->EndPointer) { Reader->BeginPointer = Reader->EndPointer = 0; }
|
if (Reader->BeginPointer == Reader->EndPointer) { Reader->BeginPointer = Reader->EndPointer = 0; }
|
||||||
|
|||||||
@@ -39,25 +39,157 @@ limitations under the License.
|
|||||||
// amtPolicy
|
// amtPolicy
|
||||||
// sysinfo
|
// sysinfo
|
||||||
|
|
||||||
|
Object.defineProperty(Array.prototype, 'getParameterEx',
|
||||||
|
{
|
||||||
|
value: function (name, defaultValue)
|
||||||
|
{
|
||||||
|
var i, ret;
|
||||||
|
for (i = 0; i < this.length; ++i)
|
||||||
|
{
|
||||||
|
if (this[i].startsWith(name + '='))
|
||||||
|
{
|
||||||
|
ret = this[i].substring(name.length + 1);
|
||||||
|
if (ret.startsWith('"')) { ret = ret.substring(1, ret.length - 1); }
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (defaultValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(Array.prototype, 'getParameter',
|
||||||
|
{
|
||||||
|
value: function (name, defaultValue)
|
||||||
|
{
|
||||||
|
return (this.getParameterEx('--' + name, defaultValue));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(Array.prototype, 'getParameterIndex',
|
||||||
|
{
|
||||||
|
value: function (name)
|
||||||
|
{
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < this.length; ++i)
|
||||||
|
{
|
||||||
|
if (this[i].startsWith('--' + name + '='))
|
||||||
|
{
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
var promise = require('promise');
|
var promise = require('promise');
|
||||||
|
var localmode = true;
|
||||||
|
|
||||||
|
function agentConnect(test, ipcPath)
|
||||||
|
{
|
||||||
|
if (global.agentipc_next)
|
||||||
|
{
|
||||||
|
global.agentipc = global.agentipc_next;
|
||||||
|
global.agentipc_next = new promise(function (r, j) { this._res = r; this._rej = j; });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
global.agentipc = new promise(function (r, j) { this._res = r; this._rej = j; });
|
||||||
|
}
|
||||||
|
global.client = require('net').createConnection({ path: ipcPath });
|
||||||
|
global.client.test = test;
|
||||||
|
global.client.on('error', function () { global.agentipc._rej(); });
|
||||||
|
global.client.on('end', function ()
|
||||||
|
{
|
||||||
|
console.log(' -> Agent connection lost');
|
||||||
|
console.log(' -> Reconnecting...');
|
||||||
|
this.removeAllListeners('data');
|
||||||
|
|
||||||
|
global._timeout = setTimeout(function (a, b) { agentConnect(a, b); }, 8000, test, ipcPath);
|
||||||
|
});
|
||||||
|
global.client.on('data', function (chunk)
|
||||||
|
{
|
||||||
|
//console.log('DATA: ' + chunk.length, chunk.toString());
|
||||||
|
var len;
|
||||||
|
if (chunk.length < 4) { this.unshift(chunk); return; }
|
||||||
|
if ((len = chunk.readUInt32LE(0)) > chunk.length) { this.unshift(chunk); return; }
|
||||||
|
|
||||||
|
var data = chunk.slice(4, len + 4);
|
||||||
|
var payload = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
payload = JSON.parse(data.toString());
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//console.log('DATA: ' + data.toString());
|
||||||
|
this.test.emit('command', payload);
|
||||||
|
if ((len + 4) < chunk.length)
|
||||||
|
{
|
||||||
|
console.log('UNSHIFT');
|
||||||
|
this.unshift(chunk.slice(4 + len));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
global.client.on('connect', function ()
|
||||||
|
{
|
||||||
|
// Register on the IPC for responses
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var cmd = "_sendConsoleText = sendConsoleText; sendConsoleText = function(msg,id){ for(i in obj.DAIPC._daipc) { obj.DAIPC._daipc[i]._send({cmd: 'console', value: msg});}};";
|
||||||
|
|
||||||
|
//var cmd = "for(i in obj.DAIPC._daipc){ if(obj.DAIPC._daipc[i]._registered==null) { obj.DAIPC._daipc[i]._registered='agentSelfTest'; } }";
|
||||||
|
var reg = { cmd: 'console', value: 'eval "' + cmd + '"' };
|
||||||
|
var ocmd = Buffer.from(JSON.stringify(reg));
|
||||||
|
var buf = Buffer.alloc(4 + ocmd.length);
|
||||||
|
buf.writeUInt32LE(ocmd.length + 4, 0);
|
||||||
|
ocmd.copy(buf, 4);
|
||||||
|
this.write(buf);
|
||||||
|
global.agentipc._res();
|
||||||
|
}
|
||||||
|
catch (f)
|
||||||
|
{
|
||||||
|
console.log(f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function start()
|
function start()
|
||||||
{
|
{
|
||||||
var isservice = false;
|
var isservice = false;
|
||||||
var service = null;
|
var nodeid = process.argv.getParameter('nodeID');
|
||||||
try
|
var ipcPath = process.platform == 'win32' ? ('\\\\.\\pipe\\' + nodeid + '-DAIPC') : (process.cwd() + '/DAIPC');
|
||||||
{
|
|
||||||
service = require('service-manager').manager.getService(process.platform == 'win32' ? 'Mesh Agent' : 'meshagent');
|
|
||||||
isservice = service.isMe();
|
|
||||||
}
|
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isservice)
|
if (nodeid != null)
|
||||||
{
|
{
|
||||||
console.setDestination(console.Destinations.LOGFILE);
|
localmode = false;
|
||||||
|
console.log(' -> Connecting to agent...');
|
||||||
|
agentConnect(this, ipcPath);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
promise.wait(global.agentipc);
|
||||||
|
console.log(' -> Connected........................[OK]');
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
console.log(' -> ERROR........................[FAILED]');
|
||||||
|
process._exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.toAgent = function remote_toAgent(inner)
|
||||||
|
{
|
||||||
|
inner.sessionid = 'pipe';
|
||||||
|
var icmd = "Buffer.from('" + Buffer.from(JSON.stringify(inner)).toString('base64') + "','base64').toString()";
|
||||||
|
var ocmd = { cmd: 'console', value: 'eval "require(\'MeshAgent\').emit(\'Command\', JSON.parse(' + icmd + '));"'};
|
||||||
|
ocmd = Buffer.from(JSON.stringify(ocmd));
|
||||||
|
|
||||||
|
var buf = Buffer.alloc(4 + ocmd.length);
|
||||||
|
buf.writeUInt32LE(ocmd.length + 4, 0);
|
||||||
|
ocmd.copy(buf, 4);
|
||||||
|
global.client.write(buf);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Starting Self Test...');
|
console.log('Starting Self Test...');
|
||||||
@@ -69,6 +201,8 @@ function start()
|
|||||||
.then(function () { return (testTerminal()); })
|
.then(function () { return (testTerminal()); })
|
||||||
.then(function () { return (testKVM()); })
|
.then(function () { return (testKVM()); })
|
||||||
.then(function () { return (testFileDownload()); })
|
.then(function () { return (testFileDownload()); })
|
||||||
|
.then(function () { return (testCoreDump()); })
|
||||||
|
.then(function () { return (testServiceRestart()); })
|
||||||
.then(function ()
|
.then(function ()
|
||||||
{
|
{
|
||||||
console.log('End of Self Test');
|
console.log('End of Self Test');
|
||||||
@@ -297,6 +431,121 @@ function coreInfo()
|
|||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testServiceRestart()
|
||||||
|
{
|
||||||
|
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
|
||||||
|
|
||||||
|
if (localmode)
|
||||||
|
{
|
||||||
|
ret._res();
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
console.log(' => Service Restart Test');
|
||||||
|
ret.self = this;
|
||||||
|
//ret._part1 = this.consoleCommand("eval \"var _A=setTimeout(function(){sendConsoleText(require('MeshAgent').serviceName);},1000);\"");
|
||||||
|
ret._part1 = this.agentQueryValue("require('MeshAgent').serviceName");
|
||||||
|
ret._part1.then(function (c)
|
||||||
|
{
|
||||||
|
console.log(' => Service Name = ' + c);
|
||||||
|
ret._servicename = c;
|
||||||
|
|
||||||
|
var nextp = new promise(function (r, j) { this._res = r; this._rej = j; });
|
||||||
|
global.agentipc_next = nextp
|
||||||
|
|
||||||
|
console.log(' -> Restarting Service...');
|
||||||
|
ret.self.consoleCommand("service restart").catch(function (x)
|
||||||
|
{
|
||||||
|
//ret._rej(' -> Restarted.....................[FAILED]');
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
promise.wait(nextp);
|
||||||
|
console.log(' -> Restarted.....................[OK]');
|
||||||
|
ret._res();
|
||||||
|
}
|
||||||
|
catch(f)
|
||||||
|
{
|
||||||
|
ret._rej(' -> Restarted.....................[FAILED]');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoreDump()
|
||||||
|
{
|
||||||
|
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
|
||||||
|
|
||||||
|
if (localmode)
|
||||||
|
{
|
||||||
|
ret._res();
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
console.log(' => Mesh Core Dump Test');
|
||||||
|
ret.self = this;
|
||||||
|
ret.consoleTest = this.consoleCommand('eval process.pid');
|
||||||
|
ret.consoleTest.ret = ret;
|
||||||
|
ret.consoleTest.self = this;
|
||||||
|
ret.consoleTest.then(function (c)
|
||||||
|
{
|
||||||
|
var pid = c;
|
||||||
|
console.log(' -> Agent PID = ' + c);
|
||||||
|
console.log(' -> Initiating KVM for dump test');
|
||||||
|
ret.tunnel = this.self.createTunnel(0x1FF, 0x00);
|
||||||
|
ret.tunnel.then(function (c)
|
||||||
|
{
|
||||||
|
this.connection = c;
|
||||||
|
c.ret = this.ret;
|
||||||
|
c.jumbosize = 0;
|
||||||
|
c.on('data', function (buf)
|
||||||
|
{
|
||||||
|
if (typeof (buf) == 'string') { return; }
|
||||||
|
var type = buf.readUInt16BE(0);
|
||||||
|
var sz = buf.readUInt16BE(2);
|
||||||
|
|
||||||
|
if (type == 3 && sz == buf.length)
|
||||||
|
{
|
||||||
|
this.removeAllListeners('data');
|
||||||
|
var nextp = new promise(function (r, j) { this._res = r; this._rej = j; });
|
||||||
|
global.agentipc_next = nextp
|
||||||
|
|
||||||
|
console.log(' -> KVM initiated, dumping core');
|
||||||
|
ret.self.consoleCommand("eval require('MeshAgent').restartCore();");
|
||||||
|
// ret.self.consoleCommand("eval _debugCrash()");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
promise.wait(nextp);
|
||||||
|
ret.self.agentQueryValue('process.pid').then(function (cc)
|
||||||
|
{
|
||||||
|
if(cc==pid)
|
||||||
|
{
|
||||||
|
console.log(' -> Core Restarted without crashing..[OK]');
|
||||||
|
ret._res();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret._rej(' -> Core Restart resulted in crash...[FAILED]');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch(z)
|
||||||
|
{
|
||||||
|
console.log(' -> ERROR', z);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
c.write('c');
|
||||||
|
c.write('2'); // Request KVM
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
function testFileDownload()
|
function testFileDownload()
|
||||||
{
|
{
|
||||||
console.log(' => File Transfer Test');
|
console.log(' => File Transfer Test');
|
||||||
@@ -664,6 +913,35 @@ function setup()
|
|||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.agentQueryValue = function agentQueryValue(value)
|
||||||
|
{
|
||||||
|
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
|
||||||
|
//ret._part1 = this.consoleCommand("eval \"var _A=setTimeout(function(){sendConsoleText(require('MeshAgent').serviceName);},1000);\"");
|
||||||
|
|
||||||
|
var cmd = 'eval "var _A=setTimeout(function(){for(i in obj.DAIPC._daipc){ obj.DAIPC._daipc[i]._send({cmd: \'queryResponse\', value: ' + value + '});}},500);"';
|
||||||
|
ret.parent = this;
|
||||||
|
ret.handler = function handler(j)
|
||||||
|
{
|
||||||
|
//console.log('handler', JSON.stringify(j));
|
||||||
|
if (j.cmd == 'queryResponse')
|
||||||
|
{
|
||||||
|
clearTimeout(handler.promise.timeout);
|
||||||
|
handler.promise.parent.removeListener('command', handler);
|
||||||
|
handler.promise._res(j.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ret.handler.promise = ret;
|
||||||
|
ret.timeout = setTimeout(function (r)
|
||||||
|
{
|
||||||
|
r.parent.removeListener('command', r.handler);
|
||||||
|
r._rej('timeout');
|
||||||
|
}, 5000, ret);
|
||||||
|
this.on('command', ret.handler);
|
||||||
|
this.toAgent({ action: 'msg', type: 'console', value: cmd, sessionid: -1 });
|
||||||
|
return (ret);
|
||||||
|
};
|
||||||
|
|
||||||
this.consoleCommand = function consoleCommand(cmd)
|
this.consoleCommand = function consoleCommand(cmd)
|
||||||
{
|
{
|
||||||
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
|
var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; });
|
||||||
@@ -671,7 +949,7 @@ function setup()
|
|||||||
ret.tester = this;
|
ret.tester = this;
|
||||||
ret.handler = function handler(j)
|
ret.handler = function handler(j)
|
||||||
{
|
{
|
||||||
if(j.action == 'msg' && j.type == 'console')
|
if((j.action == 'msg' && j.type == 'console') || j.cmd=='console')
|
||||||
{
|
{
|
||||||
clearTimeout(handler.promise.timeout);
|
clearTimeout(handler.promise.timeout);
|
||||||
handler.promise.tester.removeListener('command', handler);
|
handler.promise.tester.removeListener('command', handler);
|
||||||
|
|||||||
Reference in New Issue
Block a user