remoting web
This commit is contained in:
parent
60cfdbf178
commit
5ef85f2e0b
|
|
@ -20,7 +20,8 @@ An elegant web & terminal interface for Unitech/PM2.
|
|||
|
||||
<a name="feats" />
|
||||
# Features
|
||||
- Curses-like dashboard
|
||||
- Curses-like dashboard.
|
||||
- Remoting monitor / web control.
|
||||
- All the heartbeats (no matter **monitor** or **tail (logs)**) are automatic destroyed.
|
||||
- The `PM2` processes are watched by a subscribed emitter.
|
||||
- Communicated with `PM2` through **RPC** socket directly.
|
||||
|
|
@ -28,10 +29,10 @@ An elegant web & terminal interface for Unitech/PM2.
|
|||
- Monitor CPU and Memory usage of server in a real-time.
|
||||
- Monitor `PM2` processes in a real-time.
|
||||
- PM2 *restart/stop/delete*.
|
||||
- *stopWatch* files before *restart/stop/delete*
|
||||
- *restartWatch* files before *restart*
|
||||
- *stopWatch* files before *restart/stop/delete*.
|
||||
- *restartWatch* files before *restart*.
|
||||
- Supports [ANSI color codes](#ss_logs) by [ansi-html](https://github.com/Tjatse/ansi-html).
|
||||
- High performance. In my case, there are near one hundred processes, but `pm2-gui` works fine.
|
||||
- High performance. In my case, there are near one hundred processes, but `pm2-gui` works without any suck.
|
||||
|
||||
<a name="cauts" />
|
||||
# Cautions
|
||||
|
|
|
|||
|
|
@ -29,10 +29,6 @@ function Layout(options) {
|
|||
this.options = options;
|
||||
this._eles = {};
|
||||
this._procCount = 0;
|
||||
/*
|
||||
Log({
|
||||
level: 1000
|
||||
});*/
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -54,13 +50,22 @@ Layout.prototype.render = function (monitor) {
|
|||
namespace: conf.NSP[ns]
|
||||
}, options);
|
||||
|
||||
monitor.connect(opts, function (err, socket) {
|
||||
if (err) {
|
||||
console.error('Failed due to', err.message, 'when connecting to', socket.nsp);
|
||||
monitor.connect(opts, function (socket) {
|
||||
console.info('Connected to', socket.nsp);
|
||||
!next._called && next(null, socket);
|
||||
next._called = true;
|
||||
}, function (err, socket) {
|
||||
console.log(err);
|
||||
if (!next._called) {
|
||||
next(err, socket);
|
||||
next._called = true;
|
||||
} else {
|
||||
console.info('Connected to', socket.nsp);
|
||||
//Log(options.log);
|
||||
}
|
||||
console.error('Failed due to', err.message, 'when connecting to', socket.nsp);
|
||||
if (next._called) {
|
||||
process.exit(0);
|
||||
}
|
||||
next(err, socket);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -69,6 +74,9 @@ Layout.prototype.render = function (monitor) {
|
|||
if (err) {
|
||||
return process.exit(0);
|
||||
}
|
||||
Log({
|
||||
level: 1000
|
||||
});
|
||||
self.sockets = _.extend(res, options.sockets);
|
||||
delete options.sockets;
|
||||
|
||||
|
|
|
|||
190
lib/monitor.js
190
lib/monitor.js
|
|
@ -5,6 +5,7 @@ var fs = require('fs'),
|
|||
ansiHTML = require('ansi-html'),
|
||||
totalmem = require('os').totalmem(),
|
||||
pidusage = require('pidusage'),
|
||||
url = require('url'),
|
||||
socketIOClient = require('socket.io-client'),
|
||||
pm = require('./pm'),
|
||||
stat = require('./stat'),
|
||||
|
|
@ -33,25 +34,6 @@ Monitor.ACCEPT_KEYS = ['pm2', 'refresh', 'daemonize', 'max_restarts', 'port', 'l
|
|||
Monitor.DEF_CONF_FILE = 'pm2-gui.ini';
|
||||
Monitor.PM2_DAEMON_PROPS = ['DAEMON_RPC_PORT', 'DAEMON_PUB_PORT', 'PM2_LOG_FILE_PATH'];
|
||||
|
||||
/**
|
||||
* Resolve home path.
|
||||
* @param {String} pm2Home
|
||||
* @returns {*}
|
||||
* @private
|
||||
*/
|
||||
Monitor.prototype._resolveHome = function (pm2Home) {
|
||||
if (pm2Home && pm2Home.indexOf('~/') == 0) {
|
||||
// Get root directory of PM2.
|
||||
pm2Home = process.env.PM2_HOME || path.resolve(process.env.HOME || process.env.HOMEPATH, pm2Home.substr(2));
|
||||
|
||||
// Make sure exist.
|
||||
if (!pm2Home || !fs.existsSync(pm2Home)) {
|
||||
throw new Error('PM2 root can not be located, try to initialize PM2 by executing `pm2 ls` or set environment variable vi `export PM2_HOME=[ROOT]`.');
|
||||
}
|
||||
}
|
||||
return pm2Home;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run socket.io server.
|
||||
*/
|
||||
|
|
@ -88,25 +70,47 @@ Monitor.prototype.quit = function () {
|
|||
/**
|
||||
* Connect to socket.io server.
|
||||
* @param {String} ns the namespace.
|
||||
* @param {Function} callback
|
||||
* @param {Function} success
|
||||
* @param {Function} failure
|
||||
*/
|
||||
Monitor.prototype.connect = function (options, callback) {
|
||||
if (!options.port || !options.namespace) {
|
||||
throw new Error('Port and namespace are both required!');
|
||||
Monitor.prototype.connect = function (options, success, failure) {
|
||||
if (!options.port) {
|
||||
throw new Error('Port is required!');
|
||||
}
|
||||
var serverUri = (options.protocol || 'http:') + '//' + (options.hostname || '127.0.0.1') + ':' + options.port + (options.path || '') + options.namespace;
|
||||
var auth,
|
||||
serverUri = Monitor.toConnectionString(options);
|
||||
|
||||
console.info('Connecting to', serverUri);
|
||||
var socket = socketIOClient(serverUri);
|
||||
socket.on('connect', function () {
|
||||
!callback.__called && callback(null, socket);
|
||||
callback.__called = true;
|
||||
!success._called && success(socket);
|
||||
success._called = true;
|
||||
});
|
||||
socket.on('connect_error', function (err) {
|
||||
!callback.__called && callback(err, socket);
|
||||
callback.__called = true;
|
||||
|
||||
socket.on('error', function (err) {
|
||||
!failure._called && failure(err, socket);
|
||||
failure._called = true;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolve home path.
|
||||
* @param {String} pm2Home
|
||||
* @returns {*}
|
||||
* @private
|
||||
*/
|
||||
Monitor.prototype._resolveHome = function (pm2Home) {
|
||||
if (pm2Home && pm2Home.indexOf('~/') == 0) {
|
||||
// Get root directory of PM2.
|
||||
pm2Home = process.env.PM2_HOME || path.resolve(process.env.HOME || process.env.HOMEPATH, pm2Home.substr(2));
|
||||
|
||||
// Make sure exist.
|
||||
if (!pm2Home || !fs.existsSync(pm2Home)) {
|
||||
throw new Error('PM2 root can not be located, try to initialize PM2 by executing `pm2 ls` or set environment variable vi `export PM2_HOME=[ROOT]`.');
|
||||
}
|
||||
}
|
||||
return pm2Home;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize options and configurations.
|
||||
|
|
@ -177,13 +181,13 @@ Monitor.prototype._connectSysSock = function (socket) {
|
|||
|
||||
// Trigger actions of process.
|
||||
socket.on('action', function (action, id) {
|
||||
console.info('[' + id + ']', action, 'sending to pm2 daemon...');
|
||||
console.debug('[pm2:' + id + ']', action, 'sending to pm2 daemon...');
|
||||
pm.action(self.options.pm2Conf.DAEMON_RPC_PORT, action, id, function (err, forceRefresh) {
|
||||
if (err) {
|
||||
console.error(action, err.message);
|
||||
return socket.emit('action', id, err.message);
|
||||
}
|
||||
console.info('[' + id + ']', action, 'completed!');
|
||||
console.debug('[pm2:' + id + ']', action, 'completed!');
|
||||
forceRefresh && self._throttleRefresh();
|
||||
});
|
||||
});
|
||||
|
|
@ -252,7 +256,7 @@ Monitor.prototype._connectLogSock = function (socket) {
|
|||
return emitError(err, pm_id, keepANSI);
|
||||
}
|
||||
|
||||
console.info('[' + pm_id + ']', 'tail starting...');
|
||||
console.info('[pm2:' + pm_id + ']', 'tail starting...');
|
||||
self._tails[pm_id] = tails;
|
||||
});
|
||||
}
|
||||
|
|
@ -282,18 +286,19 @@ Monitor.prototype._connectProcSock = function (socket) {
|
|||
function killObserver() {
|
||||
var socks = self._sockio.of(conf.NSP.PROC).sockets,
|
||||
canNotBeDeleted = {};
|
||||
if (socks && socks.length > 0) {
|
||||
|
||||
if (Array.isArray(socks) && socks.length > 0) {
|
||||
socks.forEach(function (sock) {
|
||||
canNotBeDeleted[sock.pid.toString()] = 1;
|
||||
});
|
||||
}
|
||||
|
||||
for (var pid in this._usages) {
|
||||
for (var pid in self._usages) {
|
||||
var timer;
|
||||
if (!canNotBeDeleted[pid] && (timer = this._usages[pid])) {
|
||||
if (!canNotBeDeleted[pid] && (timer = self._usages[pid])) {
|
||||
clearInterval(timer);
|
||||
delete this._usages[pid];
|
||||
console.info('[' + pid + ']', 'cpu and memory observer destroyed!');
|
||||
delete self._usages[pid];
|
||||
console.debug('[pid:' + pid + ']', 'cpu and memory observer destroyed!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -306,7 +311,7 @@ Monitor.prototype._connectProcSock = function (socket) {
|
|||
return;
|
||||
}
|
||||
|
||||
console.info('[' + pidStr + ']', 'cpu and memory observer is running...');
|
||||
console.debug('[pid:' + pidStr + ']', 'cpu and memory observer is running...');
|
||||
|
||||
function runTimer() {
|
||||
pidusage.stat(pid, function (err, stat) {
|
||||
|
|
@ -493,7 +498,7 @@ Monitor.prototype._killTailProcess = function (pm_id) {
|
|||
} catch (err) {}
|
||||
});
|
||||
delete self._tails[id];
|
||||
console.info('[' + id + ']', 'tail destroyed!');
|
||||
console.info('[pm2:' + id + ']', 'tail destroyed!');
|
||||
}
|
||||
if (!isNaN(pm_id)) {
|
||||
return killTail(pm_id);
|
||||
|
|
@ -529,10 +534,113 @@ Monitor.prototype._listeningSocketIO = function () {
|
|||
console.info('Listening connection event on', nsp.toLowerCase());
|
||||
}
|
||||
|
||||
var auth;
|
||||
if (!(this.options.agent && (auth = this.options.agent.authorization))) {
|
||||
return;
|
||||
}
|
||||
this._sockio.use(function (socket, next) {
|
||||
// console.log(socket.handshake);
|
||||
if (auth !== socket.handshake.query.auth) {
|
||||
return next(new Error('unauthorized'));
|
||||
}
|
||||
next();
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* List all available monitors.
|
||||
* @param {Object} options
|
||||
* @return {Object}
|
||||
*/
|
||||
Monitor.available = function (options) {
|
||||
options.agent = options.agent || {};
|
||||
var remotable = options.remotes && _.keys(options.remotes).length > 0;
|
||||
|
||||
if (options.agent.offline && !remotable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
options.port = options.port || 8088;
|
||||
|
||||
if (!remotable) {
|
||||
return options;
|
||||
}
|
||||
var q = {
|
||||
name: 'socket_server',
|
||||
message: 'Which socket server would you wanna connect to',
|
||||
type: 'list',
|
||||
choices: []
|
||||
},
|
||||
maxShortLength = 0;
|
||||
for (var remote in options.remotes) {
|
||||
var connectionString = options.remotes[remote];
|
||||
q.choices.push({
|
||||
value: connectionString,
|
||||
short: remote
|
||||
});
|
||||
maxShortLength = Math.max(maxShortLength, remote.length);
|
||||
}
|
||||
if (!options.agent.offline) {
|
||||
var short = 'localhost',
|
||||
connectionString = (options.agent && options.agent.authorization ? options.agent.authorization + '@' : '') + '127.0.0.1:' + options.port;
|
||||
q.choices.push({
|
||||
value: connectionString,
|
||||
short: short
|
||||
});
|
||||
maxShortLength = Math.max(maxShortLength, short.length);
|
||||
}
|
||||
|
||||
if (q.choices.length > 1) {
|
||||
q.choices.forEach(function (c) {
|
||||
c.name = '[' + c.short + Array(maxShortLength - c.short.length + 1).join(' ') + '] ' + c.value;
|
||||
});
|
||||
}
|
||||
|
||||
return q;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert connection object to string.
|
||||
* @param {Object} connection
|
||||
* @return {String}
|
||||
*/
|
||||
Monitor.toConnectionString = function (connection) {
|
||||
var uri = (connection.protocol || 'http:') + '//' + (connection.hostname || '127.0.0.1') + ':' + connection.port +
|
||||
(connection.path || '') + (connection.namespace || '');
|
||||
|
||||
if (connection.authorization) {
|
||||
uri += (uri.indexOf('?') > 0 ? '&' : '?') + 'auth=' + connection.authorization;
|
||||
}
|
||||
return uri;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse connection string to an uri object.
|
||||
* @param {String} connectionString
|
||||
* @return {Object}
|
||||
*/
|
||||
Monitor.parseConnectionString = function (connectionString) {
|
||||
var connection = {
|
||||
port: 8088,
|
||||
hostname: '127.0.0.1',
|
||||
authorization: ''
|
||||
};
|
||||
var lastAt = connectionString.lastIndexOf('@');
|
||||
if (lastAt >= 0) {
|
||||
connection.authorization = connectionString.slice(0, lastAt);
|
||||
connectionString = connectionString.slice(lastAt + 1);
|
||||
}
|
||||
if (!/^http(s)?:\/\//i.test(connectionString)) {
|
||||
connectionString = 'http://' + connectionString;
|
||||
}
|
||||
|
||||
if (connectionString) {
|
||||
connectionString = url.parse(connectionString);
|
||||
connection.hostname = connectionString.hostname;
|
||||
connection.port = connectionString.port;
|
||||
connection.path = _.trimLeft(connectionString.path, '/');
|
||||
connection.protocol = connectionString.protocol;
|
||||
}
|
||||
return connection;
|
||||
};
|
||||
|
||||
Object.defineProperty(Monitor.prototype, 'sockio', {
|
||||
|
|
|
|||
|
|
@ -31,17 +31,17 @@ date = false
|
|||
;
|
||||
; Log level, one of debug, log, info, warn, error.
|
||||
;
|
||||
level = log
|
||||
level = debug
|
||||
|
||||
[agent]
|
||||
;
|
||||
; This authorization will be used to authorize socket / web connections if it's set.
|
||||
;
|
||||
; authorization = AuTh
|
||||
authorization = AuTh
|
||||
;
|
||||
; A value indicates whether agent offline or not.
|
||||
;
|
||||
; offline = false
|
||||
; offline = true
|
||||
[remotes]
|
||||
;
|
||||
; the dashboard and web server will use this section to connect remoting socket server
|
||||
|
|
@ -51,3 +51,4 @@ level = log
|
|||
; pm2@172 = 192.168.1.172:9001
|
||||
; pm2@173 = 192.168.1.173:9000
|
||||
;
|
||||
pm2@138 = AuTh107@192.168.100.138:8088
|
||||
|
|
|
|||
113
pm2-gui.js
113
pm2-gui.js
|
|
@ -2,7 +2,6 @@ var chalk = require('chalk'),
|
|||
path = require('path'),
|
||||
fs = require('fs'),
|
||||
_ = require('lodash'),
|
||||
url = require('url'),
|
||||
socketIO = require('socket.io'),
|
||||
inquirer = require("inquirer"),
|
||||
conf = require('./lib/util/conf'),
|
||||
|
|
@ -93,59 +92,28 @@ function dashboard(confFile) {
|
|||
var monitor = slave({
|
||||
confFile: confFile
|
||||
}),
|
||||
options = _.clone(monitor.options);
|
||||
options = _.clone(monitor.options),
|
||||
q = Monitor.available(options);
|
||||
|
||||
options.agent = options.agent || {};
|
||||
var remotable = options.remotes && _.keys(options.remotes).length > 0;
|
||||
|
||||
if (options.agent.offline && remotable) {
|
||||
if (!q) {
|
||||
console.error('No agent is online, can not start it.');
|
||||
return process.exit(0);
|
||||
}
|
||||
|
||||
options.port = options.port || 8088;
|
||||
|
||||
if (!remotable) {
|
||||
return _connectToDashboard(monitor, options);
|
||||
var ql = q.choices.length;
|
||||
if (ql == 1) {
|
||||
console.info('There is just one remoting server online, try to connect it.')
|
||||
return _connectToDashboard(monitor, options, Monitor.parseConnectionString(q.choices[0].value));
|
||||
}
|
||||
|
||||
q.choices.splice(ql - 1, 0, new inquirer.Separator());
|
||||
|
||||
console.info('Remoting servers are online, choose one you are intrested in.')
|
||||
var q = {
|
||||
name: 'socket_server',
|
||||
message: 'Which socket server would you wanna connect to',
|
||||
type: 'list',
|
||||
choices: []
|
||||
},
|
||||
maxShortLength = 0;
|
||||
for (var remote in options.remotes) {
|
||||
var connectionString = options.remotes[remote];
|
||||
q.choices.push({
|
||||
value: connectionString,
|
||||
short: remote
|
||||
});
|
||||
maxShortLength = Math.max(maxShortLength, remote.length);
|
||||
}
|
||||
if (!options.agent.offline) {
|
||||
q.choices.push(new inquirer.Separator());
|
||||
var short = 'localhost',
|
||||
connectionString = (options.agent && options.agent.authorization ? options.agent.authorization + '@' : '') + '127.0.0.1:' + options.port;
|
||||
q.choices.push({
|
||||
value: connectionString,
|
||||
short: short
|
||||
});
|
||||
maxShortLength = Math.max(maxShortLength, short.length);
|
||||
}
|
||||
|
||||
q.choices.forEach(function (c) {
|
||||
if (c.type != 'separator') {
|
||||
c.name = '[' + c.short + Array(maxShortLength - c.short.length + 1).join(' ') + '] ' + c.value;
|
||||
}
|
||||
});
|
||||
|
||||
console.log('');
|
||||
|
||||
inquirer.prompt(q, function (answers) {
|
||||
console.log('');
|
||||
_connectToDashboard(monitor, options, _parseConnectionString(answers.socket_server));
|
||||
_connectToDashboard(monitor, options, Monitor.parseConnectionString(answers.socket_server));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -233,51 +201,24 @@ function slave(options) {
|
|||
}
|
||||
|
||||
function _connectToDashboard(monitor, options, connection) {
|
||||
if (!connection || !!~['127.0.0.1', '0.0.0.0', 'localhost'].indexOf(connection.hostname)) {
|
||||
return monitor.connect(_.extend({
|
||||
namespace: conf.NSP.SYS
|
||||
}, options), function (err, socket) {
|
||||
if (err || !socket) {
|
||||
console.warn('Agent is offline, try to start it.');
|
||||
var sockio = socketIO();
|
||||
sockio.listen(options.port);
|
||||
monitor.sockio = sockio;
|
||||
monitor.run();
|
||||
} else {
|
||||
console.info('Agent is online, try to connect it in dashboard directly.');
|
||||
options.sockets = {};
|
||||
var ns = _.trimLeft(conf.NSP.SYS, '/');
|
||||
options.sockets[ns] = socket;
|
||||
connection = _.extend({}, options, connection);
|
||||
if (!!~['127.0.0.1', '0.0.0.0', 'localhost'].indexOf(connection.hostname)) {
|
||||
return monitor.connect(connection, function (socket) {
|
||||
console.info('Agent is online, try to connect it in dashboard directly.');
|
||||
layout(connection).render(monitor);
|
||||
}, function (err, socket) {
|
||||
if (err == 'unauthorized') {
|
||||
console.error('There was an error with the authentication:', err);
|
||||
return process.exit(0);
|
||||
}
|
||||
|
||||
layout(options).render(monitor);
|
||||
console.warn('Agent is offline, try to start it.');
|
||||
var sockio = socketIO();
|
||||
sockio.listen(connection.port);
|
||||
monitor.sockio = sockio;
|
||||
monitor.run();
|
||||
layout(connection).render(monitor);
|
||||
});
|
||||
}
|
||||
|
||||
layout(connection).render(monitor);
|
||||
}
|
||||
|
||||
function _parseConnectionString(connectionString) {
|
||||
var connection = {
|
||||
port: 8088,
|
||||
hostname: '127.0.0.1',
|
||||
authorization: ''
|
||||
};
|
||||
var lastAt = connectionString.lastIndexOf('@');
|
||||
if (lastAt >= 0) {
|
||||
connection.authorization = connectionString.slice(0, lastAt);
|
||||
connectionString = connectionString.slice(lastAt + 1);
|
||||
}
|
||||
if (!/^http(s)?:\/\//i.test(connectionString)) {
|
||||
connectionString = 'http://' + connectionString;
|
||||
}
|
||||
|
||||
if (connectionString) {
|
||||
connectionString = url.parse(connectionString);
|
||||
connection.hostname = connectionString.hostname;
|
||||
connection.port = connectionString.port;
|
||||
connection.path = _.trimLeft(connectionString.path, '/');
|
||||
connection.protocol = connectionString.protocol;
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,21 +19,6 @@ var sysStat,
|
|||
popupProc,
|
||||
scrolled;
|
||||
|
||||
/**
|
||||
* Initialization.
|
||||
*/
|
||||
$(window).ready(function () {
|
||||
|
||||
prepareDOM();
|
||||
|
||||
initFullPage();
|
||||
|
||||
listenSocket();
|
||||
|
||||
renderFanavi();
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Prepare DOM, cache elements, templates...
|
||||
*/
|
||||
|
|
@ -98,11 +83,11 @@ function initFullPage() {
|
|||
/**
|
||||
* Set fullPage enable or disable.
|
||||
* @param {Boolean} enable
|
||||
* @param {Boolean} exceptScroll
|
||||
* @param {Boolean} unscrollable
|
||||
*/
|
||||
function setFPEnable(enable, exceptScroll) {
|
||||
function setFPEnable(enable, unscrollable) {
|
||||
$.fn.fullpage.setAllowScrolling(enable);
|
||||
if (!exceptScroll) {
|
||||
if (!unscrollable) {
|
||||
$.fn.fullpage.setKeyboardScrolling(enable);
|
||||
eles.fpNav[enable ? 'fadeIn' : 'fadeOut']();
|
||||
}
|
||||
|
|
@ -112,15 +97,40 @@ function setFPEnable(enable, exceptScroll) {
|
|||
* Connect to socket server.
|
||||
*/
|
||||
function connectSocketServer(ns) {
|
||||
var socket = io('127.0.0.1:8088' + ns + '?token=abc');
|
||||
socket.on('error', info);
|
||||
var uri = GUI.connection.value,
|
||||
index = uri.indexOf('?'),
|
||||
query = '';
|
||||
if (index > 0) {
|
||||
query = uri.slice(index);
|
||||
uri = uri.slice(0, index);
|
||||
}
|
||||
console.log('before', uri, query, ns);
|
||||
|
||||
uri = _.trimRight(uri, '/') + (ns || '') + query;
|
||||
if (!ns) {
|
||||
return io.connect(uri).on('error', onError);
|
||||
}
|
||||
var socket = io.connect(uri);
|
||||
socket.on('error', onError);
|
||||
return socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires on error.
|
||||
* @param {String} err
|
||||
*/
|
||||
function onError(err) {
|
||||
if (err == 'unauthorized') {
|
||||
err = 'There was an error with the authentication: ' + err;
|
||||
}
|
||||
info(err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize socket.io client and add listeners.
|
||||
*/
|
||||
function listenSocket() {
|
||||
connectSocketServer();
|
||||
sockets.sys = connectSocketServer(NSP.SYS);
|
||||
// information from server.
|
||||
sockets.sys.on('info', info);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,31 +1,54 @@
|
|||
var Monitor = require('../../lib/monitor');
|
||||
|
||||
// Authorization
|
||||
action(function auth(req, res){/*
|
||||
if (!req._config.password || (req._config.password === req.session['password'])) {
|
||||
action(function auth(req, res) {
|
||||
if (!req._config.agent || (req._config.agent.authorization === req.session['authorization'])) {
|
||||
return res.redirect('/');
|
||||
}*/
|
||||
res.render('auth', {title: 'Authorization'});
|
||||
}
|
||||
res.render('auth', {
|
||||
title: 'Authorization'
|
||||
});
|
||||
});
|
||||
|
||||
// Index
|
||||
action(function(req, res){
|
||||
if (req._config.agent && (req._config.agent.authorization !== req.session['authorization'])) {
|
||||
action(function (req, res) {
|
||||
var auth;
|
||||
if (req._config.agent && ((auth = req._config.agent.authorization) !== req.session['authorization'])) {
|
||||
return res.redirect('/auth');
|
||||
}
|
||||
res.render('index', {title: 'Monitor'});
|
||||
var q = Monitor.available(req._config),
|
||||
connections = [];
|
||||
|
||||
q.choices.forEach(function (c) {
|
||||
c.value = Monitor.toConnectionString(Monitor.parseConnectionString(c.value));
|
||||
connections.push(c);
|
||||
});
|
||||
res.render('index', {
|
||||
title: 'Monitor',
|
||||
connections: connections
|
||||
});
|
||||
});
|
||||
|
||||
// API
|
||||
action(function auth_api(req, res){
|
||||
if(!req._config.agent || !req._config.agent.authorization){
|
||||
return res.json({error: 'Can not found agent[.authorization] config, no need to authorize!'});
|
||||
action(function auth_api(req, res) {
|
||||
if (!req._config.agent || !req._config.agent.authorization) {
|
||||
return res.json({
|
||||
error: 'Can not found agent[.authorization] config, no need to authorize!'
|
||||
});
|
||||
}
|
||||
if (!req.query || !req.query.authorization) {
|
||||
return res.json({error: 'Authorization is required!'});
|
||||
return res.json({
|
||||
error: 'Authorization is required!'
|
||||
});
|
||||
}
|
||||
|
||||
if (req._config.agent && req.query.authorization === req._config.agent.authorization) {
|
||||
req.session['authorization'] = req.query.authorization;
|
||||
return res.json({status: 200});
|
||||
return res.json({
|
||||
status: 200
|
||||
});
|
||||
}
|
||||
return res.json({error: 'Failed, authorization is incorrect.'});
|
||||
});
|
||||
return res.json({
|
||||
error: 'Failed, authorization is incorrect.'
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ block content
|
|||
div
|
||||
div
|
||||
div
|
||||
|
||||
input#authorization(type="hidden")= authorization
|
||||
include ../partials/tmpls
|
||||
|
||||
block js
|
||||
|
|
@ -36,3 +36,18 @@ block js
|
|||
script(src='js/jquery.fullPage.min.js')
|
||||
script(src='js/fanavi.min.js')
|
||||
script(src='js/index.html.js')
|
||||
script.
|
||||
var GUI = {};
|
||||
GUI.connections = !{JSON.stringify(connections)};
|
||||
$(window).ready(function () {
|
||||
if (!Array.isArray(GUI.connections) || GUI.connections.length == 0) {
|
||||
info('No agent is online, can not start it.');
|
||||
} else {
|
||||
GUI.connection = GUI.connections[GUI.connections.length - 1];
|
||||
}
|
||||
prepareDOM();
|
||||
initFullPage();
|
||||
listenSocket();
|
||||
renderFanavi();
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue