Skip to content

Commit

Permalink
#2144 #1060 #2957 #2033 #1872 #2938 #971 Select application uid/gid v…
Browse files Browse the repository at this point in the history
…ia --uid --gid (CLI+JSON) + pm2 install --uid / --gid
  • Loading branch information
Unitech committed Jul 2, 2017
1 parent dcf4021 commit 7d6f173
Show file tree
Hide file tree
Showing 15 changed files with 306 additions and 50 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
## 2.6

- #2968 pm2 attach <pm_id> + pm2-runtime allows to attach to process stdin / stdout
- #2144 #1060 #2957 #2033 #1872 #2938 #971 Select application uid/gid via --uid --gid (CLI+JSON) + display user via pm2 ls
- pm2 install module-name --uid <uid> --gid <gid> possible
- #2968 pm2 attach <pm_id> to attach to process stdin / stdout
- pm2-runtime -> drop in replacement for the node.js binary
- #2951 pm2 reload command locker via timestamped lock file
- #2977 pm2 reloadLogs protected
- #2958 Allow to delete attribute via --attribute null
- expose cwd on CLI via --cwd
- multiple pm2-docker enhacements
- Alias pm2.link and pm2.unlink to pm2.interact and pm2._pre_interact
- Allow to customize kill signal via PM2_KILL_SIGNAL
Expand Down
5 changes: 4 additions & 1 deletion bin/pm2
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ commander.version(pkg.version)
.option('-x --execute-command', 'execute a program using fork system')
.option('--max-restarts [count]', 'only restart the script COUNT times')
.option('-u --user <username>', 'define user when generating startup script')
.option('--uid <uid>', 'run target script with <uid> rights')
.option('--gid <gid>', 'run target script with <gid> rights')
.option('--cwd <path>', 'run target script as <username>')
.option('--hp <home path>', 'define home path when generating startup script')
.option('-c --cron <cron_pattern>', 'restart a running process based on a cron pattern')
.option('-w --write', 'write configuration in local folder')
Expand Down Expand Up @@ -452,7 +455,7 @@ commander.command('install <module|git:// url>')
.alias('module:install')
.description('install or update a module and run it forever')
.action(function(plugin_name) {
pm2.install(plugin_name);
pm2.install(plugin_name, commander);
});

commander.command('module:update <module|git:// url>')
Expand Down
16 changes: 13 additions & 3 deletions lib/API.js
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,6 @@ API.prototype._startScript = function(script, opts, cb) {
return cb ? cb(Common.retErr(appConf)) : that.exitCli(conf.ERROR_EXIT);

app_conf = appConf[0];

/**
* If -w option, write configuration to configuration.json file
*/
Expand Down Expand Up @@ -913,18 +912,29 @@ API.prototype._startJson = function(file, opts, action, pipe, cb) {
var apps_name = [];
var proc_list = {};

// Here we pick only the field we want from the CLI when starting a JSON
appConf.forEach(function(app) {
// --only <app>
if (opts.only && opts.only != app.name)
return false;
// --watch
if (!app.watch && opts.watch && opts.watch === true)
app.watch = true;
// --ignore-watch
if (!app.ignore_watch && opts.ignore_watch)
app.ignore_watch = opts.ignore_watch;
// --instances <nb>
if (opts.instances && typeof(opts.instances) === 'number')
app.instances = opts.instances;
if (app.append_env_to_name && opts.env) {
// --uid <user>
if (opts.uid)
app.uid = opts.uid;
// --gid <user>
if (opts.gid)
app.gid = opts.gid;
// Specific
if (app.append_env_to_name && opts.env)
app.name += ('-' + opts.env);
}
apps_name.push(app.name);
});

Expand Down
51 changes: 46 additions & 5 deletions lib/API/CliUx.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ var p = require('path');
var chalk = require('chalk');
var Common = require('../Common');
var Spinner = require('./Spinner.js');

var os = require('os');
var UX = module.exports = {};

/**
Expand Down Expand Up @@ -199,9 +199,9 @@ UX.describeTable = function(process) {
UX.dispAsTable = function(list, interact_infos) {
var stacked = (process.stdout.columns || 90) < 90;
var app_head = stacked ? ['Name', 'mode', 'status', '↺', 'cpu', 'memory'] :
['App name', 'id', 'mode', 'pid', 'status', 'restart', 'uptime', 'cpu', 'mem', 'watching'];
['App name', 'id', 'mode', 'pid', 'status', 'restart', 'uptime', 'cpu', 'mem', 'user', 'watching'];
var mod_head = stacked ? ['Module', 'status', 'cpu', 'mem'] :
['Module', 'version', 'target PID', 'status', 'restart', 'cpu', 'memory'];
['Module', 'version', 'target PID', 'status', 'restart', 'cpu', 'memory', 'user'];

var app_table = new Table({
head : app_head,
Expand All @@ -218,6 +218,13 @@ UX.dispAsTable = function(list, interact_infos) {
if (!list)
return console.log('list empty');

var current_user = '';

if (os.userInfo)
current_user = os.userInfo().username;
else
current_user = process.env.USER || process.env.LNAME || process.env.USERNAME || process.env.SUDO_USER || process.env.C9_USER || process.env.LOGNAME;
;
list.sort(function(a, b) {
if (a.pm2_env.name < b.pm2_env.name)
return -1;
Expand Down Expand Up @@ -246,31 +253,65 @@ UX.dispAsTable = function(list, interact_infos) {
}

if (l.pm2_env.pmx_module == true) {
// pm2 ls for Modules
obj[key] = [];

// Module version + PID
if (!stacked)
obj[key].push(chalk.bold(l.pm2_env.axm_options.module_version || 'N/A'),
typeof(l.pm2_env.axm_options.pid) === 'number' ? l.pm2_env.axm_options.pid : 'N/A' );
obj[key].push(chalk.bold(l.pm2_env.axm_options.module_version || 'N/A'), typeof(l.pm2_env.axm_options.pid) === 'number' ? l.pm2_env.axm_options.pid : 'N/A' );

// Status
obj[key].push(colorStatus(status));

// Restart
if (!stacked)
obj[key].push(l.pm2_env.restart_time ? l.pm2_env.restart_time : 0);

// CPU + Memory
obj[key].push(l.monit ? (l.monit.cpu + '%') : 'N/A', l.monit ? UX.bytesToSize(l.monit.memory, 3) : 'N/A' );

// User
if (!stacked)
obj[key].push(chalk.bold(l.pm2_env.uid || current_user));

safe_push(module_table, obj);
}
else {
// pm2 ls for Applications
obj[key] = [];

// PM2 ID
if (!stacked)
obj[key].push(l.pm2_env.pm_id);

// Exec mode
obj[key].push(mode == 'fork_mode' ? chalk.inverse.bold('fork') : chalk.blue.bold('cluster'));

// PID
if (!stacked)
obj[key].push(l.pid);

// Status
obj[key].push(colorStatus(status));

// Restart
obj[key].push(l.pm2_env.restart_time ? l.pm2_env.restart_time : 0);

// Uptime
if (!stacked)
obj[key].push((l.pm2_env.pm_uptime && status == 'online') ? timeSince(l.pm2_env.pm_uptime) : 0);

// CPU
obj[key].push(l.monit ? l.monit.cpu + '%' : 'N/A');

// Memory
obj[key].push(l.monit ? UX.bytesToSize(l.monit.memory, 1) : 'N/A');

// User
if (!stacked)
obj[key].push(chalk.bold(l.pm2_env.uid || current_user));

// Watch status
if (!stacked)
obj[key].push(l.pm2_env.watch ? chalk.green.bold('enabled') : chalk.grey('disabled'));

Expand Down
92 changes: 59 additions & 33 deletions lib/API/Modules/Modularizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
* Use of this source code is governed by a license that
* can be found in the LICENSE file.
*/
var shelljs = require('shelljs');
var path = require('path');
var fs = require('fs');
var async = require('async');
var p = path;
var readline = require('readline');
var spawn = require('child_process').spawn;
var chalk = require('chalk');
var shelljs = require('shelljs');
var path = require('path');
var fs = require('fs');
var async = require('async');
var p = path;
var readline = require('readline');
var spawn = require('child_process').spawn;
var chalk = require('chalk');
var Configuration = require('../../Configuration.js');
var cst = require('../../../constants.js');
var Common = require('../../Common');
var UX = require('../CliUx.js');
var Utility = require('../../Utility.js');
var semver = require('semver');
var semver = require('semver');

var Modularizer = module.exports = {};

Expand Down Expand Up @@ -61,24 +61,31 @@ function startModule(CLI, opts, cb) {
return cb(new Error('Invalid module (script is missing)'));
}

// Start the module
CLI.start(package_json, {
Common.extend(opts, {
cwd : opts.proc_path,
watch : opts.development_mode,
force_name : package_json.name,
started_as_module : true
}, function(err, data) {
});

// Start the module
CLI.start(package_json, opts, function(err, data) {
if (err) return cb(err);
return cb(null, data);
});
};

function installModule(CLI, module_name, cb) {
function installModule(CLI, module_name, opts, cb) {
var proc_path = '',
cmd = '',
conf = {},
development_mode = false;

if (typeof(opts) == 'function') {
cb = opts;
opts = {};
}

if (module_name == '.') {
/**
* Development mode
Expand All @@ -89,11 +96,13 @@ function installModule(CLI, module_name, cb) {

cmd = p.join(proc_path, cst.DEFAULT_MODULE_JSON);

startModule(CLI, {
Common.extend(opts, {
cmd : cmd,
development_mode : development_mode,
proc_path : proc_path
}, function(err, dt) {
});

startModule(CLI, opts, function(err, dt) {
if (err) return cb(err);
Common.printOut(cst.PREFIX_MSG_MOD + 'Module successfully installed and launched');
return cb(null, dt);
Expand Down Expand Up @@ -160,14 +169,23 @@ function installModule(CLI, module_name, cb) {
Common.printError(e);
}

Configuration.set(MODULE_CONF_PREFIX + ':' + canonic_module_name, 'true', function(err, data) {
startModule(CLI, {
cmd : cmd,
development_mode : development_mode,
proc_path : proc_path
}, function(err, dt) {
Common.extend(opts, {
cmd : cmd,
development_mode : development_mode,
proc_path : proc_path
});

Configuration.set(MODULE_CONF_PREFIX + ':' + canonic_module_name, {
uid : opts.uid || null,
gid : opts.gid || null
}, function(err, data) {

startModule(CLI, opts, function(err, dt) {
if (err) return cb(err);

if (process.env.PM2_PROGRAMMATIC === 'true')
return cb(null, dt);

CLI.conf(canonic_module_name, function() {
Common.printOut(cst.PREFIX_MSG_MOD + 'Module successfully installed and launched');
Common.printOut(cst.PREFIX_MSG_MOD + 'Edit configuration via: `pm2 conf`');
Expand Down Expand Up @@ -231,15 +249,15 @@ function installLangModule(module_name, cb) {
*/
var listModules = function() {
var module_folder = p.join(cst.PM2_ROOT_PATH, 'node_modules');
var ret = [];
var ret = {};

shelljs.config.silent = true;
var modules = shelljs.ls(module_folder);
shelljs.config.silent = false;

modules.forEach(function(module_name) {
if (module_name.indexOf('pm2-') > -1)
ret.push(module_name);
ret[module_name] = {};
});

return ret;
Expand All @@ -254,13 +272,13 @@ var listModulesV2 = Modularizer.listModules = function() {
if (!config) {
var modules_already_installed = listModules();

modules_already_installed.forEach(function(module_name) {
Configuration.setSync(MODULE_CONF_PREFIX + ':' + module_name, true);
Object.keys(modules_already_installed).forEach(function(module_name) {
Configuration.setSync(MODULE_CONF_PREFIX + ':' + module_name, {});
});
return modules_already_installed;
}

return Object.keys(config);
return config;
};

Modularizer.getAdditionalConf = function(app_name) {
Expand All @@ -286,16 +304,24 @@ Modularizer.launchAll = function(CLI, cb) {

var modules = listModulesV2();

async.eachLimit(modules, 1, function(module, next) {
async.eachLimit(Object.keys(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);

startModule(CLI, {
var opts = {};

if (modules[module] != true) {
Common.extend(opts, modules[module]);
}

Common.extend(opts, {
cmd : pmod,
development_mode : false,
proc_path : p.join(module_folder, module)
}, function(err, dt) {
});

startModule(CLI, opts, function(err, dt) {
if (err) console.error(err);
return next();
});
Expand All @@ -305,7 +331,7 @@ Modularizer.launchAll = function(CLI, cb) {
});
};

Modularizer.install = function(CLI, module_name, cb) {
Modularizer.install = function(CLI, module_name, opts, cb) {
Common.printOut(cst.PREFIX_MSG_MOD + 'Installing module ' + module_name);

var canonic_module_name = Utility.getCanonicModuleName(module_name);
Expand Down Expand Up @@ -353,7 +379,7 @@ Modularizer.install = function(CLI, module_name, cb) {
Common.printOut(cst.PREFIX_MSG_MOD + 'Module already installed. Updating.');

uninstallModule(CLI, canonic_module_name, function(err) {
return installModule(CLI, module_name, cb);
return installModule(CLI, module_name, opts, cb);
});

return false;
Expand All @@ -362,7 +388,7 @@ Modularizer.install = function(CLI, module_name, cb) {
/**
* Install
*/
installModule(CLI, module_name, cb);
installModule(CLI, module_name, opts, cb);
};

/**
Expand All @@ -377,7 +403,7 @@ Modularizer.uninstall = function(CLI, module_name, cb) {
//}
if (module_name == 'all') {
var modules = listModulesV2();
async.forEachLimit(modules, 1, function(module, next) {
async.forEachLimit(Object.keys(modules), 1, function(module, next) {
uninstallModule(CLI, module, next);
}, cb);
return false;
Expand Down
Loading

0 comments on commit 7d6f173

Please sign in to comment.