From 618e2da660e64d171b5d021dc40c434b96e88aa4 Mon Sep 17 00:00:00 2001 From: Tjatse Date: Tue, 13 Jan 2015 15:56:25 +0800 Subject: [PATCH] 1. Make platform auto detecting. 2. Support darwin startup script. --- bin/pm2 | 7 +- constants.js | 1 + lib/CLI.js | 114 ++++++++++++++-------------- lib/scripts/io.keymetrics.PM2.plist | 32 ++++++++ 4 files changed, 95 insertions(+), 59 deletions(-) create mode 100644 lib/scripts/io.keymetrics.PM2.plist diff --git a/bin/pm2 b/bin/pm2 index 3fa635eb..a9bff667 100755 --- a/bin/pm2 +++ b/bin/pm2 @@ -15,6 +15,7 @@ var Satan = require('../lib/Satan'); var CLI = require('../lib/CLI'); var cst = require('../constants.js'); var pkg = require('../package.json'); +var platform = require('os').platform(); CLI.pm2Init(); @@ -364,10 +365,10 @@ commander.command('resurrect') // // Set pm2 to startup // -commander.command('startup ') +commander.command('startup [platform]') .description('auto resurrect process at startup. [platform] = ubuntu, centos, gentoo or systemd') - .action(function(platform) { - CLI.startup(platform, commander); + .action(function(_platform, cmd) { + CLI.startup(_platform || platform, commander); }); diff --git a/constants.js b/constants.js index 44fcd116..ad44e198 100644 --- a/constants.js +++ b/constants.js @@ -36,6 +36,7 @@ var csts = { SYSTEMD_STARTUP_SCRIPT : '../lib/scripts/pm2.service', AMAZON_STARTUP_SCRIPT : '../lib/scripts/pm2-init-amazon.sh', GENTOO_STARTUP_SCRIPT : '../lib/scripts/pm2', + DARWIN_STARTUP_SCRIPT : '../lib/scripts/io.keymetrics.PM2.plist', SUCCESS_EXIT : 0, ERROR_EXIT : 1, diff --git a/lib/CLI.js b/lib/CLI.js index 4e391bd4..35baa9e1 100644 --- a/lib/CLI.js +++ b/lib/CLI.js @@ -5,6 +5,7 @@ var async = require('async'); var debug = require('debug')('pm2:monit'); var util = require('util'); var chalk = require('chalk'); +var exec = require('child_process').exec; var Monit = require('./Monit'); var UX = require('./CliUx'); @@ -341,90 +342,91 @@ CLI.startJson = function(cmd, opts, jsonVia, cb) { * @param {string} platform type (centos|redhat|amazon|gentoo|systemd) */ CLI.startup = function(platform, opts, cb) { - var exec = require('child_process').exec; - if (process.getuid() != 0) { - - exec('whoami', function(err, stdout, stderr) { - console.error(cst.PREFIX_MSG + 'You have to run this command as root'); - console.error(cst.PREFIX_MSG + 'Execute the following command :'); - if (platform === undefined) platform = ''; - console.error(cst.PREFIX_MSG + 'sudo env PATH=$PATH:' + p.dirname(process.execPath) + ' pm2 startup ' + platform + ' -u ' + stdout.trim()); - return cb ? cb({msg:'You have to run this with elevated rights'}) : exitCli(cst.ERROR_EXIT); + return exec('whoami', function(err, stdout, stderr) { + console.error(cst.PREFIX_MSG + 'You have to run this command as root. Execute the following command:\n' + + chalk.grey(' sudo env PATH=$PATH:' + p.dirname(process.execPath) + ' pm2 startup ' + platform + ' -u ' + stdout.trim())); + cb ? cb({msg: 'You have to run this with elevated rights'}) : exitCli(cst.ERROR_EXIT); }); - return false; } - var INIT_SCRIPT = "/etc/init.d/pm2-init.sh"; + var scriptFile = '/etc/init.d/pm2-init.sh', + script = cst.UBUNTU_STARTUP_SCRIPT; - var script; - - if (platform == 'systemd') { - script = fs.readFileSync(path.join(__dirname, cst.SYSTEMD_STARTUP_SCRIPT)); - INIT_SCRIPT = '/etc/systemd/system/pm2.service'; + if(platform == 'redhat'){ + platform = 'centos'; + }else if (platform == 'systemd') { + scriptFile = '/etc/systemd/system/pm2.service'; + }else if (platform == 'darwin') { + scriptFile = path.join(process.env.HOME, 'Library/LaunchAgents/io.keymetrics.PM2.plist'); } - else if (platform == 'centos' || platform == 'redhat') - script = fs.readFileSync(path.join(__dirname, cst.CENTOS_STARTUP_SCRIPT)); - else if (platform == 'amazon') - script = fs.readFileSync(path.join(__dirname, cst.AMAZON_STARTUP_SCRIPT)); - else if (platform == 'gentoo') - script = fs.readFileSync(path.join(__dirname, cst.GENTOO_STARTUP_SCRIPT)); - else - script = fs.readFileSync(path.join(__dirname, cst.UBUNTU_STARTUP_SCRIPT)); + + if(!!~['systemd', 'centos', 'amazon', 'gentoo', 'darwin'].indexOf(platform)){ + script = cst[platform.toUpperCase() + '_STARTUP_SCRIPT']; + } + + script = fs.readFileSync(path.join(__dirname, script), {encoding: 'utf8'}); var user = opts.user || 'root'; - script = script.toString().replace(/%PM2_PATH%/g, process.mainModule.filename); - script = script.toString().replace(/%HOME_PATH%/g, (process.env.PM2_HOME || process.env.HOME)); - script = script.toString().replace(/%NODE_PATH%/g, p.dirname(process.execPath)); - script = script.toString().replace(/%USER%/g, user); + script = script.replace(/%PM2_PATH%/g, process.mainModule.filename) + .replace(/%HOME_PATH%/g, cst.PM2_ROOT_PATH) + .replace(/%NODE_PATH%/g, platform == 'darwin' ? p.dirname(process.execPath) : process.env.PATH) + .replace(/%USER%/g, user); - printOut(cst.PREFIX_MSG + 'Generating system init script in ' + INIT_SCRIPT); + printOut(cst.PREFIX_MSG + 'Generating system init script in ' + scriptFile); - fs.writeFileSync(INIT_SCRIPT, script); + fs.writeFileSync(scriptFile, script); - if (fs.existsSync(INIT_SCRIPT) == false) { + if (!fs.existsSync(scriptFile)) { printOut(script); - printOut(cst.PREFIX_MSG_ERR + ' There is a problem when trying to write file : ' + INIT_SCRIPT); - return cb ? cb({msg:'Problem with ' + INIT_SCRIPT}) : exitCli(cst.ERROR_EXIT); + printOut(cst.PREFIX_MSG_ERR + ' There is a problem when trying to write file : ' + scriptFile); + return cb ? cb({msg:'Problem with ' + scriptFile}) : exitCli(cst.ERROR_EXIT); } var cmd; printOut(cst.PREFIX_MSG + 'Making script booting at startup...'); - if (platform == 'systemd') { - cmd = [ - 'pm2 dump', //We need an empty dump so that the first resurrect works correctly - 'pm2 kill', - 'systemctl daemon-reload', - 'systemctl enable pm2', - 'systemctl start pm2' - ].join(' && '); - } - else if (platform == 'centos' || platform == 'redhat' || platform == 'amazon') { - cmd = 'chmod +x ' + INIT_SCRIPT + '; chkconfig --add ' + p.basename(INIT_SCRIPT); - fs.closeSync(fs.openSync('/var/lock/subsys/pm2-init.sh', 'w')); - printOut('/var/lock/subsys/pm2-init.sh lockfile has been added'); - } - else if (platform == 'gentoo') { - cmd = 'chmod +x ' + INIT_SCRIPT + '; rc-update add ' + p.basename(INIT_SCRIPT) + ' default'; - } - else { - cmd = 'chmod +x ' + INIT_SCRIPT + ' && update-rc.d ' + p.basename(INIT_SCRIPT) + ' defaults'; + switch (platform) { + case 'systemd': + cmd = [ + 'pm2 dump', //We need an empty dump so that the first resurrect works correctly + 'pm2 kill', + 'systemctl daemon-reload', + 'systemctl enable pm2', + 'systemctl start pm2' + ].join(' && '); + break; + case 'centos': + case 'amazon': + cmd = 'chmod +x ' + scriptFile + '; chkconfig --add ' + p.basename(scriptFile); + fs.closeSync(fs.openSync('/var/lock/subsys/pm2-init.sh', 'w')); + printOut(cst.PREFIX_MSG + '/var/lock/subsys/pm2-init.sh lockfile has been added'); + break; + case 'gentoo': + cmd = 'chmod +x ' + scriptFile + '; rc-update add ' + p.basename(scriptFile) + ' default'; + break; + default : + cmd = 'chmod +x ' + scriptFile + ' && update-rc.d ' + p.basename(scriptFile) + ' defaults'; + break; } - cmd = 'su -c "' + cmd + '"'; + if (platform != 'darwin') { + cmd = 'su -c "' + cmd + '"'; + }else{ + cmd = 'pm2 dump'; + } - printOut(cst.PREFIX_MSG + '-'+platform+'- Using the command %s', cmd); + printOut(cst.PREFIX_MSG + '-' + platform + '- Using the command:\n %s', chalk.grey(cmd)); exec(cmd, function(err, stdo, stde) { if (err) { printError(err); - printError('----- Are you sure you use the right platform command line option ? centos / redhat, amazon, ubuntu, gentoo or systemd?'); + printError('----- Are you sure you use the right platform command line option ? centos / redhat, amazon, ubuntu, gentoo, systemd or darwin?'); return cb ? cb({msg:err}) : exitCli(cst.ERROR_EXIT); } - printOut(stdo); + printOut(stdo.toString().replace(/[\r\n]$/, '')); printOut(cst.PREFIX_MSG + 'Done.'); return cb ? cb(null, {success:true}) : exitCli(cst.SUCCESS_EXIT); }); diff --git a/lib/scripts/io.keymetrics.PM2.plist b/lib/scripts/io.keymetrics.PM2.plist new file mode 100644 index 00000000..2915488c --- /dev/null +++ b/lib/scripts/io.keymetrics.PM2.plist @@ -0,0 +1,32 @@ + + + + + Label + io.keymetrics.PM2 + UserName + %USER% + ProgramArguments + + %PM2_PATH% + resurrect + + RunAtLoad + + OnDemand + + LaunchOnlyOnce + + EnvironmentVariables + + PATH + %NODE_PATH% + PM2_HOME + %HOME_PATH% + + StandardErrorPath + /tmp/io.keymetrics.PM2.err + StandardOutPath + /tmp/io.keymetrics.PM2.out + +