occaecatidicta
Version:
149 lines (129 loc) • 4.14 kB
text/typescript
/*!
* Omelox -- consoleModule runScript
* Copyright(c) 2012 fantasyni <fantasyni@163.com>
* MIT Licensed
*/
import { getLogger } from 'omelox-logger';
import * as monitor from 'omelox-monitor';
import * as vm from 'vm';
import * as fs from 'fs';
import * as util from 'util';
import * as path from 'path';
import { IModule, MonitorCallback, MasterCallback } from '../consoleService';
import { MonitorAgent } from '../monitor/monitorAgent';
import { MasterAgent } from '../master/masterAgent';
let logger = getLogger('omelox-admin', path.basename(__filename));
export class ScriptsModule implements IModule {
app: any;
root: string;
commands: {[key: string]: Function};
static moduleId = 'scripts';
constructor(opts: {app: string , path: string}) {
this.app = opts.app;
this.root = opts.path;
this.commands = {
'list': list,
'get': get,
'save': save,
'run': run
};
}
monitorHandler(agent: MonitorAgent, msg: any, cb: MonitorCallback) {
let context = {
app: this.app,
require: require,
os: require('os'),
fs: require('fs'),
process: process,
util: util,
result: undefined as any
};
try {
vm.createContext(context);
vm.runInNewContext(msg.script, context);
let result = context.result;
if (!result) {
cb(null, 'script result should be assigned to result value to script module context');
} else {
cb(null, result);
}
} catch (e) {
cb(null, e.toString());
}
// cb(null, vm.runInContext(msg.script, context));
}
clientHandler(agent: MasterAgent, msg: any, cb: MasterCallback) {
let fun = this.commands[msg.command];
if (!fun || typeof fun !== 'function') {
cb('unknown command:' + msg.command);
return;
}
fun(this, agent, msg, cb);
}
}
/**
* List server id and scripts file name
*/
let list = function(scriptModule: ScriptsModule, agent: MasterAgent, msg: any, cb: MasterCallback) {
let servers: string[] = [];
let scripts: string[] = [];
let idMap = agent.idMap;
for (let sid in idMap) {
servers.push(sid);
}
fs.readdir(scriptModule.root, function(err, filenames) {
if (err) {
filenames = [];
}
for (let i = 0, l = filenames.length; i < l; i++) {
scripts.push(filenames[i]);
}
cb(null, {
servers: servers,
scripts: scripts
});
});
};
/**
* Get the content of the script file
*/
let get = function(scriptModule: ScriptsModule, agent: MasterAgent, msg: any, cb: MasterCallback) {
let filename = msg.filename;
if (!filename) {
cb('empty filename');
return;
}
fs.readFile(path.join(scriptModule.root, filename), 'utf-8', function(err, data) {
if (err) {
logger.error('fail to read script file:' + filename + ', ' + err.stack);
cb('fail to read script with name:' + filename);
}
cb(null, data);
});
};
/**
* Save a script file that posted from admin console
*/
let save = function(scriptModule: ScriptsModule, agent: MasterAgent, msg: any, cb: MasterCallback) {
let filepath = path.join(scriptModule.root, msg.filename);
fs.writeFile(filepath, msg.body, function(err) {
if (err) {
logger.error('fail to write script file:' + msg.filename + ', ' + err.stack);
cb('fail to write script file:' + msg.filename);
return;
}
cb();
});
};
/**
* Run the script on the specified server
*/
let run = function(scriptModule: ScriptsModule, agent: MasterAgent, msg: any, cb: MasterCallback) {
agent.request(msg.serverId, ScriptsModule.moduleId, msg, function(err, res) {
if (err) {
logger.error('fail to run script for ' + err.stack);
return;
}
cb(null, res);
});
};