mirror of
https://github.com/Unitech/pm2.git
synced 2025-12-08 20:35:53 +00:00
227 lines
6.2 KiB
JavaScript
227 lines
6.2 KiB
JavaScript
|
|
var Modularizer = module.exports = {};
|
|
|
|
var shelljs = require('shelljs');
|
|
var path = require('path');
|
|
var fs = require('fs');
|
|
var async = require('async');
|
|
var p = path;
|
|
|
|
var Configuration = require('./Configuration.js');
|
|
var cst = require('../constants.js');
|
|
var CLI = require('./CLI.js');
|
|
var Common = require('./Common');
|
|
var UX = require('./CliUx.js');
|
|
|
|
// [X] 1# verify that there is a process.json or process.json5 else not a pm2 module
|
|
// [X] 2# Keep separated list for modules when doing pm2 list
|
|
// [X] Avoid dumping module processes
|
|
// [X] Stats process.json process.json5 package.json ecosystem.json
|
|
// [X] 4# pm2 uninstall <probe> = delete folder and stop process
|
|
// [X] Name of app must be the same than the module name
|
|
// [X] At PM2 initialization start all .pm2/node_modules
|
|
// [X] Block all tentatives to stop a module
|
|
// pm2 generate module = Provide a module skeleton
|
|
// [X] pm2 update=install <module> = not deleting the conf file
|
|
// pm2 publish module (increment version, git push, npm publish)
|
|
// [X] API normalization = dont block adoption, find common way to transform current software into propack
|
|
|
|
Modularizer.launchAll = function(cb) {
|
|
var module_folder = p.join(cst.PM2_ROOT_PATH, 'node_modules');
|
|
|
|
shelljs.config.silent = true;
|
|
var modules = shelljs.ls('-A', module_folder);
|
|
shelljs.config.silent = false;
|
|
|
|
var module_conf = Configuration.getAllSync() || {};
|
|
|
|
async.eachLimit(modules, 1, function(module, next) {
|
|
var pmod = p.join(module_folder, module, cst.DEFAULT_MODULE_JSON);
|
|
|
|
Common.printOut(cst.PREFIX_MSG_MOD + 'Starting module ' + module);
|
|
|
|
CLI.startJson(pmod, {
|
|
cwd : p.join(module_folder, module),
|
|
force_name : module,
|
|
started_as_module : true,
|
|
additional_env : module_conf
|
|
}, function(err, data) {
|
|
return next();
|
|
});
|
|
}, function() {
|
|
return cb ? cb() : false;
|
|
});
|
|
};
|
|
|
|
Modularizer.install = function(module_name, cb) {
|
|
Common.printOut(cst.PREFIX_MSG_MOD + 'Installing module ' + module_name);
|
|
|
|
var path = '',
|
|
cmd = '',
|
|
conf = {},
|
|
development_mode = false;
|
|
|
|
/**
|
|
* Check if module exists
|
|
*/
|
|
if (moduleExist(module_name) === true) {
|
|
Common.printError(cst.PREFIX_MSG_MOD_ERR + 'Module already installed. Installation canceled.');
|
|
return cb({msg:'Module already installed'});
|
|
}
|
|
|
|
if (module_name == '.') {
|
|
/**
|
|
* Development mode
|
|
*/
|
|
Common.printOut(cst.PREFIX_MSG_MOD + 'Installing local module in DEVELOPMENT MODE with WATCH auto restart');
|
|
development_mode = true;
|
|
path = process.cwd();
|
|
}
|
|
else {
|
|
Common.printOut(cst.PREFIX_MSG_MOD + 'Processing...');
|
|
|
|
/**
|
|
* Install npm module via NPM INSTALL
|
|
*/
|
|
var child = shelljs.exec('npm install ' + module_name + ' --prefix ' + cst.PM2_ROOT_PATH);
|
|
|
|
if (child.code != 0) {
|
|
Common.printError(cst.PREFIX_MSG_MOD_ERR + 'Unknown module');
|
|
return cb({msg:'Unknown module'});
|
|
}
|
|
|
|
Common.printOut(cst.PREFIX_MSG_MOD + 'Module downloaded');
|
|
path = p.join(cst.PM2_ROOT_PATH, 'node_modules', module_name);
|
|
}
|
|
|
|
cmd = p.join(path, cst.DEFAULT_MODULE_JSON);
|
|
|
|
var module_conf = Configuration.getAllSync() || {};
|
|
|
|
/**
|
|
* Verify that the module is valid
|
|
* If not, delete
|
|
*/
|
|
if (isValidModule(path) === false) {
|
|
shelljs.rm('-rf', path);
|
|
Common.printError(cst.PREFIX_MSG_MOD + 'Module uninstalled');
|
|
return cb({msg:'Invalid module'});
|
|
}
|
|
|
|
// Start the module
|
|
CLI.startJson(cmd, {
|
|
cwd : path,
|
|
watch : development_mode,
|
|
force_name : module_name,
|
|
started_as_module : true,
|
|
additional_env : module_conf
|
|
}, function(err, data) {
|
|
if (err)
|
|
return cb(err);
|
|
|
|
Common.printOut(cst.PREFIX_MSG_MOD + 'Module succesfully installed and launched');
|
|
Common.printOut(cst.PREFIX_MSG_MOD + ': To configure module use');
|
|
Common.printOut(cst.PREFIX_MSG_MOD + ': $ pm2 set <key> <value>');
|
|
Common.printOut(cst.PREFIX_MSG_MOD + ': $ pm2 restart module-name');
|
|
return cb(null, data);
|
|
});
|
|
|
|
};
|
|
|
|
/**
|
|
* Uninstall module
|
|
*/
|
|
Modularizer.uninstall = function(module_name, cb) {
|
|
Common.printOut(cst.PREFIX_MSG_MOD + 'Uninstalling module ' + module_name);
|
|
var path = p.join(cst.PM2_ROOT_PATH, 'node_modules', module_name);
|
|
|
|
if (moduleExist(module_name) === false && module_name != '.') {
|
|
Common.printError(cst.PREFIX_MSG_MOD_ERR + 'Module unknown.');
|
|
return cb({msg:'Module unknown'});
|
|
}
|
|
|
|
CLI.deleteModule(module_name, function(err, data) {
|
|
if (err) {
|
|
Common.printError(cst.PREFIX_MSG_MOD_ERR + err);
|
|
|
|
if (module_name != '.') {
|
|
console.log(path);
|
|
shelljs.rm('-rf', path);
|
|
}
|
|
|
|
return cb(err);
|
|
}
|
|
|
|
if (module_name != '.') {
|
|
shelljs.rm('-rf', path);
|
|
}
|
|
|
|
return cb();
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Publish a module
|
|
*/
|
|
Modularizer.publish = function(cb) {
|
|
var readline = require('readline');
|
|
|
|
console.error('Not available');
|
|
|
|
return cb();
|
|
|
|
var rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout
|
|
});
|
|
|
|
rl.question("Publish? [Y/N]", function(answer) {
|
|
if (answer != "Y")
|
|
return cb();
|
|
|
|
var package_json = fs.readFileSync(p.join(process.cwd(), 'package.json'));
|
|
|
|
var child = shelljs.exec('npm install ' + module_name + ' --prefix ' + cst.PM2_ROOT_PATH);
|
|
|
|
});
|
|
};
|
|
|
|
|
|
function isValidModule(path) {
|
|
var valid = true;
|
|
|
|
try {
|
|
fs.existsSync(p.join(path, 'package.json'));
|
|
} catch(e) {
|
|
Common.printError(cst.PREFIX_MSG_MOD_ERR + 'package.json or conf.js file not present');
|
|
return false;
|
|
}
|
|
|
|
var conf = require(p.join(path, 'package.json'));
|
|
|
|
if (!conf.apps) {
|
|
Common.printError(cst.PREFIX_MSG_MOD_ERR + 'apps attribute indicating the script to launch is not defined in the package.json');
|
|
return false;
|
|
}
|
|
|
|
conf.apps.forEach(function(app) {
|
|
if (!app.script)
|
|
valid = false;
|
|
});
|
|
|
|
return valid;
|
|
};
|
|
|
|
function moduleExist(module_name) {
|
|
var modules = getModuleInstalled();
|
|
return modules.indexOf(module_name) > -1 ? true : false;
|
|
};
|
|
|
|
function getModuleInstalled() {
|
|
shelljs.config.silent = true;
|
|
var module_folder = p.join(cst.PM2_ROOT_PATH, 'node_modules');
|
|
var modules = shelljs.ls('-A', module_folder);
|
|
shelljs.config.silent = false;
|
|
return modules;
|
|
}
|