1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2026-01-08 11:33:42 +00:00

1. Added plumbing for a Recovery agentcore

2. Added service control features for linux Service Manager
This commit is contained in:
Bryan Roe
2019-03-03 22:04:21 -08:00
parent adbff6baf8
commit 8a923d57c9
3 changed files with 146 additions and 4 deletions

View File

@@ -2248,7 +2248,16 @@ void MeshServer_SendAgentInfo(MeshAgentHostContainer* agent, ILibWebClient_State
// Send mesh agent information to the server
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)info, sizeof(MeshCommand_BinaryPacket_AuthInfo) + hostnamelen, ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
agent->retryTime = 0;
printf("Connected.\n");
if ((agent->capabilities & MeshCommand_AuthInfo_CapabilitiesMask_RECOVERY) == MeshCommand_AuthInfo_CapabilitiesMask_RECOVERY)
{
printf("[Recovery Agent] Connected.\n");
}
else
{
printf("Connected.\n");
}
if (agent->serverAuthState == 3) { MeshServer_ServerAuthenticated(WebStateObject, agent); }
}
@@ -3531,9 +3540,15 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
}
}
}
#endif
int ri;
for (ri = 0; ri < paramLen; ++ri)
{
if (strcmp(param[ri], "-recovery") == 0) { agentHost->capabilities |= MeshCommand_AuthInfo_CapabilitiesMask_RECOVERY; parseCommands = 0; }
}
// We are a Mesh Agent
if (agentHost->masterDb == NULL) { agentHost->masterDb = ILibSimpleDataStore_Create(MeshAgent_MakeAbsolutePath(agentHost->exePath, ".db")); }
if (agentHost->masterDb == NULL)
@@ -3689,6 +3704,7 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
#ifdef WIN32
// If running as a Windows service, set basic values to the registry, this allows other applications to know what the mesh agent is doing.
if((agentHost->capabilities & MeshCommand_AuthInfo_CapabilitiesMask_RECOVERY) == 0)
{
HKEY hKey;

View File

@@ -54,7 +54,8 @@ typedef enum MeshCommand_AuthInfo_CapabilitiesMask
MeshCommand_AuthInfo_CapabilitiesMask_FILES = 0x04,
MeshCommand_AuthInfo_CapabilitiesMask_CONSOLE = 0x08,
MeshCommand_AuthInfo_CapabilitiesMask_JAVASCRIPT = 0x10,
MeshCommand_AuthInfo_CapabilitiesMask_TEMPORARY = 0x20
MeshCommand_AuthInfo_CapabilitiesMask_TEMPORARY = 0x20,
MeshCommand_AuthInfo_CapabilitiesMask_RECOVERY = 0x40
}MeshCommand_AuthInfo_CapabilitiesMask;
typedef enum AgentIdentifiers

View File

@@ -190,6 +190,18 @@ function serviceManager()
require('events').inherits(retVal);
retVal.on('~', function () { this._proxy.CloseServiceHandle(this); this._proxy.CloseServiceHandle(this._scm); });
retVal.name = name;
retVal.isRunning = function ()
{
var bytesNeeded = this._GM.CreateVariable(this._GM.PointerSize);
this._proxy.QueryServiceStatusEx(this._service, 0, 0, 0, bytesNeeded);
var st = this._GM.CreateVariable(bytesNeeded.toBuffer().readUInt32LE());
if(this._proxy.QueryServiceStatusEx(this._service, 0, st, st._size, bytesNeeded).Val != 0)
{
var state = parseServiceStatus(st);
return (state.state == 'RUNNING');
}
return (false);
};
retVal.stop = function () {
if (this.status.state == 'RUNNING') {
var newstate = this._GM.CreateVariable(36);
@@ -230,6 +242,117 @@ function serviceManager()
{
return (require('user-sessions').isRoot());
}
if(process.platform == 'linux')
{
this.getService = function (name, platform)
{
if (!platform) { platform = this.getServiceType(); }
var ret = { name: name };
switch(platform)
{
case 'init':
case 'upstart':
if ((platform == 'init' && require('fs').existsSync('/etc/init.d/' + name)) ||
(platform == 'upstart' && require('fs').existsSync('/etc/init/' + name + '.conf')))
{
ret.isRunning = function isRunning()
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("service " + this.name + " status | awk '{print $2}' | awk -F, '{print $1}'\nexit\n");
child.waitExit();
return (child.stdout.str.trim() == 'start/running');
};
ret.start = function start()
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.on('data', function (chunk) { });
child.stdin.write('service ' + this.name + ' start\nexit\n');
child.waitExit();
};
ret.stop = function stop()
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.on('data', function (chunk) { });
child.stdin.write('service ' + this.name + ' stop\nexit\n');
child.waitExit();
};
ret.restart = function restart()
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.on('data', function (chunk) { });
child.stdin.write('service ' + this.name + ' restart\nexit\n');
child.waitExit();
};
ret.status = function status()
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout._str = '';
child.stdout.on('data', function (chunk) { this._str += chunk.toString(); });
child.stdin.write('service ' + this.name + ' status\nexit\n');
child.waitExit();
return (child.stdout._str);
};
return (ret);
}
else
{
throw (platform + ' Service (' + name + ') NOT FOUND');
}
break;
case 'systemd':
if (require('fs').existsSync('/lib/systemd/system/' + name + '.service') ||
require('fs').existsSync('/usr/lib/systemd/system/' + name + '.service'))
{
ret.isRunning = function isRunning()
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.stdin.write("systemctl status " + this.name + " | grep 'Active:' | awk '{print $2}'\nexit\n");
child.waitExit();
return (child.stdout.str.trim() == 'active');
};
ret.start = function start() {
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.on('data', function (chunk) { });
child.stdin.write('systemctl start ' + this.name + '\nexit\n');
child.waitExit();
};
ret.stop = function stop() {
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.on('data', function (chunk) { });
child.stdin.write('systemctl stop ' + this.name + '\nexit\n');
child.waitExit();
};
ret.restart = function restart() {
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.on('data', function (chunk) { });
child.stdin.write('systemctl restart ' + this.name + '\nexit\n');
child.waitExit();
};
ret.status = function status() {
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout._str = '';
child.stdout.on('data', function (chunk) { this._str += chunk.toString(); });
child.stdin.write('systemctl status ' + this.name + '\nexit\n');
child.waitExit();
return (child.stdout._str);
};
return (ret);
}
else
{
throw (platform + ' Service (' + name + ') NOT FOUND');
}
break;
default:
throw ('Unknown Service Platform: ' + platform);
break;
}
};
}
}
this.installService = function installService(options)
{
@@ -312,7 +435,9 @@ function serviceManager()
if (!this.isAdmin()) { console.log('Installing a Service requires root'); throw ('Installing as Service, requires root'); }
var parameters = options.parameters ? options.parameters.join(' ') : '';
var conf;
switch (this.getServiceType())
if (!options.servicePlatform) { options.servicePlatform = this.getServiceType(); }
switch (options.servicePlatform)
{
case 'init':
if (!require('fs').existsSync('/usr/local/mesh_services/')) { require('fs').mkdirSync('/usr/local/mesh_services'); }