2013-09-05 16:02:48 +02:00
|
|
|
/**
|
2016-03-12 01:03:50 +01:00
|
|
|
* Copyright 2013, 2016 IBM Corp.
|
2013-09-05 16:02:48 +02:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
**/
|
|
|
|
|
2014-03-06 23:32:23 +01:00
|
|
|
var when = require('when');
|
|
|
|
|
2013-09-05 16:02:48 +02:00
|
|
|
var redNodes = require("./nodes");
|
2014-09-22 15:33:26 +02:00
|
|
|
var storage = require("./storage");
|
2015-02-03 23:02:26 +01:00
|
|
|
var log = require("./log");
|
2015-04-15 21:59:39 +02:00
|
|
|
var i18n = require("./i18n");
|
2015-11-11 23:11:02 +01:00
|
|
|
var events = require("./events");
|
|
|
|
var settings = require("./settings");
|
2017-01-09 23:22:49 +01:00
|
|
|
|
|
|
|
var express = require("express");
|
2015-11-11 23:11:02 +01:00
|
|
|
var path = require('path');
|
|
|
|
var fs = require("fs");
|
2016-02-22 18:47:16 +01:00
|
|
|
var os = require("os");
|
2013-09-05 16:02:48 +02:00
|
|
|
|
2015-02-04 23:28:17 +01:00
|
|
|
var runtimeMetricInterval = null;
|
|
|
|
|
2016-03-12 01:03:50 +01:00
|
|
|
var started = false;
|
|
|
|
|
2015-11-24 23:38:42 +01:00
|
|
|
var stubbedExpressApp = {
|
|
|
|
get: function() {},
|
|
|
|
post: function() {},
|
|
|
|
put: function() {},
|
2016-05-26 11:38:24 +02:00
|
|
|
delete: function() {}
|
2015-11-24 23:38:42 +01:00
|
|
|
}
|
|
|
|
var adminApi = {
|
|
|
|
library: {
|
2016-05-26 11:38:24 +02:00
|
|
|
register: function() {}
|
2015-11-24 23:38:42 +01:00
|
|
|
},
|
|
|
|
auth: {
|
2016-05-26 11:38:24 +02:00
|
|
|
needsPermission: function() {}
|
2015-11-24 23:38:42 +01:00
|
|
|
},
|
|
|
|
comms: {
|
2016-05-26 11:38:24 +02:00
|
|
|
publish: function() {}
|
2015-11-24 23:38:42 +01:00
|
|
|
},
|
|
|
|
adminApp: stubbedExpressApp,
|
|
|
|
server: {}
|
|
|
|
}
|
|
|
|
|
2017-01-09 23:22:49 +01:00
|
|
|
var nodeApp;
|
|
|
|
|
2015-11-24 23:38:42 +01:00
|
|
|
function init(userSettings,_adminApi) {
|
2015-11-16 12:31:55 +01:00
|
|
|
userSettings.version = getVersion();
|
2015-11-11 23:11:02 +01:00
|
|
|
log.init(userSettings);
|
|
|
|
settings.init(userSettings);
|
2017-01-09 23:22:49 +01:00
|
|
|
|
|
|
|
nodeApp = express();
|
|
|
|
|
2015-11-24 23:38:42 +01:00
|
|
|
if (_adminApi) {
|
|
|
|
adminApi = _adminApi;
|
|
|
|
}
|
|
|
|
redNodes.init(runtime);
|
2015-11-11 23:11:02 +01:00
|
|
|
}
|
2015-02-04 23:28:17 +01:00
|
|
|
|
2015-11-16 12:31:55 +01:00
|
|
|
var version;
|
|
|
|
|
|
|
|
function getVersion() {
|
|
|
|
if (!version) {
|
|
|
|
version = require(path.join(__dirname,"..","..","package.json")).version;
|
|
|
|
/* istanbul ignore else */
|
|
|
|
try {
|
|
|
|
fs.statSync(path.join(__dirname,"..","..",".git"));
|
|
|
|
version += "-git";
|
|
|
|
} catch(err) {
|
|
|
|
// No git directory
|
|
|
|
}
|
2015-11-11 23:11:02 +01:00
|
|
|
}
|
2015-11-16 12:31:55 +01:00
|
|
|
return version;
|
2014-11-04 12:34:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function start() {
|
2015-04-15 21:59:39 +02:00
|
|
|
return i18n.init()
|
2015-11-22 00:12:39 +01:00
|
|
|
.then(function() {
|
|
|
|
return i18n.registerMessageCatalog("runtime",path.resolve(path.join(__dirname,"locales")),"runtime.json")
|
|
|
|
})
|
2016-09-21 11:22:04 +02:00
|
|
|
.then(function() { return storage.init(runtime)})
|
2015-03-22 21:55:38 +01:00
|
|
|
.then(function() { return settings.load(storage)})
|
2015-03-14 00:37:59 +01:00
|
|
|
.then(function() {
|
2015-07-02 14:25:15 +02:00
|
|
|
|
2015-02-04 23:28:17 +01:00
|
|
|
if (log.metric()) {
|
|
|
|
runtimeMetricInterval = setInterval(function() {
|
|
|
|
reportMetrics();
|
2015-03-21 18:42:06 +01:00
|
|
|
}, settings.runtimeMetricInterval||15000);
|
2015-02-04 23:28:17 +01:00
|
|
|
}
|
2016-12-23 12:31:23 +01:00
|
|
|
log.info("\n\n"+log._("runtime.welcome")+"\n===================\n");
|
2014-11-04 12:34:49 +01:00
|
|
|
if (settings.version) {
|
2015-05-08 15:21:01 +02:00
|
|
|
log.info(log._("runtime.version",{component:"Node-RED",version:"v"+settings.version}));
|
2014-08-28 01:35:07 +02:00
|
|
|
}
|
2015-05-08 15:21:01 +02:00
|
|
|
log.info(log._("runtime.version",{component:"Node.js ",version:process.version}));
|
2016-02-22 18:47:16 +01:00
|
|
|
log.info(os.type()+" "+os.release()+" "+os.arch()+" "+os.endianness());
|
2015-04-08 21:17:24 +02:00
|
|
|
return redNodes.load().then(function() {
|
2015-07-02 14:25:15 +02:00
|
|
|
|
2014-11-04 12:34:49 +01:00
|
|
|
var i;
|
2015-03-30 22:49:20 +02:00
|
|
|
var nodeErrors = redNodes.getNodeList(function(n) { return n.err!=null;});
|
|
|
|
var nodeMissing = redNodes.getNodeList(function(n) { return n.module && n.enabled && !n.loaded && !n.err;});
|
2014-11-04 12:34:49 +01:00
|
|
|
if (nodeErrors.length > 0) {
|
2016-05-26 11:38:24 +02:00
|
|
|
log.warn("------------------------------------------------------");
|
|
|
|
for (i=0;i<nodeErrors.length;i+=1) {
|
|
|
|
log.warn("["+nodeErrors[i].name+"] "+nodeErrors[i].err);
|
2014-08-28 01:35:07 +02:00
|
|
|
}
|
2016-05-26 11:38:24 +02:00
|
|
|
log.warn("------------------------------------------------------");
|
2014-09-22 15:33:26 +02:00
|
|
|
}
|
2014-11-04 12:34:49 +01:00
|
|
|
if (nodeMissing.length > 0) {
|
2015-05-08 15:21:01 +02:00
|
|
|
log.warn(log._("server.missing-modules"));
|
2014-11-04 12:34:49 +01:00
|
|
|
var missingModules = {};
|
|
|
|
for (i=0;i<nodeMissing.length;i++) {
|
|
|
|
var missing = nodeMissing[i];
|
|
|
|
missingModules[missing.module] = (missingModules[missing.module]||[]).concat(missing.types);
|
|
|
|
}
|
|
|
|
var promises = [];
|
|
|
|
for (i in missingModules) {
|
|
|
|
if (missingModules.hasOwnProperty(i)) {
|
2015-02-03 23:02:26 +01:00
|
|
|
log.warn(" - "+i+": "+missingModules[i].join(", "));
|
2015-02-04 11:27:02 +01:00
|
|
|
if (settings.autoInstallModules && i != "node-red") {
|
2015-11-08 15:06:36 +01:00
|
|
|
redNodes.installModule(i).otherwise(function(err) {
|
2014-11-04 12:34:49 +01:00
|
|
|
// Error already reported. Need the otherwise handler
|
|
|
|
// to stop the error propagating any further
|
|
|
|
});
|
2014-09-22 15:33:26 +02:00
|
|
|
}
|
2014-08-28 01:35:07 +02:00
|
|
|
}
|
|
|
|
}
|
2014-11-04 12:34:49 +01:00
|
|
|
if (!settings.autoInstallModules) {
|
2015-05-08 15:21:01 +02:00
|
|
|
log.info(log._("server.removing-modules"));
|
2014-11-26 17:41:31 +01:00
|
|
|
redNodes.cleanModuleList();
|
2014-11-04 12:34:49 +01:00
|
|
|
}
|
|
|
|
}
|
2015-12-07 00:29:58 +01:00
|
|
|
if (settings.settingsFile) {
|
|
|
|
log.info(log._("runtime.paths.settings",{path:settings.settingsFile}));
|
|
|
|
}
|
2015-10-11 21:37:11 +02:00
|
|
|
redNodes.loadFlows().then(redNodes.startFlows);
|
2016-03-12 01:03:50 +01:00
|
|
|
started = true;
|
2014-11-04 12:34:49 +01:00
|
|
|
}).otherwise(function(err) {
|
|
|
|
console.log(err);
|
|
|
|
});
|
2016-05-26 11:38:24 +02:00
|
|
|
});
|
2014-08-28 01:35:07 +02:00
|
|
|
}
|
2014-11-04 12:34:49 +01:00
|
|
|
|
2015-02-04 23:28:17 +01:00
|
|
|
function reportMetrics() {
|
|
|
|
var memUsage = process.memoryUsage();
|
2015-03-06 11:17:00 +01:00
|
|
|
|
2015-03-21 18:42:06 +01:00
|
|
|
log.log({
|
|
|
|
level: log.METRIC,
|
|
|
|
event: "runtime.memory.rss",
|
|
|
|
value: memUsage.rss
|
|
|
|
});
|
|
|
|
log.log({
|
|
|
|
level: log.METRIC,
|
|
|
|
event: "runtime.memory.heapTotal",
|
|
|
|
value: memUsage.heapTotal
|
|
|
|
});
|
|
|
|
log.log({
|
|
|
|
level: log.METRIC,
|
|
|
|
event: "runtime.memory.heapUsed",
|
|
|
|
value: memUsage.heapUsed
|
|
|
|
});
|
2015-02-04 23:28:17 +01:00
|
|
|
}
|
|
|
|
|
2013-10-13 20:14:39 +02:00
|
|
|
function stop() {
|
2015-02-04 23:28:17 +01:00
|
|
|
if (runtimeMetricInterval) {
|
|
|
|
clearInterval(runtimeMetricInterval);
|
|
|
|
runtimeMetricInterval = null;
|
|
|
|
}
|
2016-03-12 01:03:50 +01:00
|
|
|
started = false;
|
2015-11-12 10:03:03 +01:00
|
|
|
return redNodes.stopFlows();
|
2013-10-13 20:14:39 +02:00
|
|
|
}
|
|
|
|
|
2015-11-11 23:11:02 +01:00
|
|
|
var runtime = module.exports = {
|
2014-11-04 18:05:29 +01:00
|
|
|
init: init,
|
2013-10-13 20:14:39 +02:00
|
|
|
start: start,
|
2014-11-04 12:34:49 +01:00
|
|
|
stop: stop,
|
2014-11-21 17:35:29 +01:00
|
|
|
|
2015-11-16 12:31:55 +01:00
|
|
|
version: getVersion,
|
2015-11-11 23:11:02 +01:00
|
|
|
|
|
|
|
log: log,
|
|
|
|
i18n: i18n,
|
|
|
|
settings: settings,
|
|
|
|
storage: storage,
|
|
|
|
events: events,
|
2015-11-24 23:38:42 +01:00
|
|
|
nodes: redNodes,
|
|
|
|
util: require("./util"),
|
2016-03-12 01:03:50 +01:00
|
|
|
get adminApi() { return adminApi },
|
2017-01-09 23:22:49 +01:00
|
|
|
get nodeApp() { return nodeApp },
|
2016-03-12 01:03:50 +01:00
|
|
|
isStarted: function() {
|
|
|
|
return started;
|
|
|
|
}
|
2015-03-06 11:17:00 +01:00
|
|
|
}
|