Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Darwin startup script #936

Merged
merged 3 commits into from
Jan 15, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions bin/pm2
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -364,10 +365,10 @@ commander.command('resurrect')
//
// Set pm2 to startup
//
commander.command('startup <platform>')
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);
});


Expand Down
1 change: 1 addition & 0 deletions constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
112 changes: 57 additions & 55 deletions lib/CLI.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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 == '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');
}

if (platform == 'systemd') {
script = fs.readFileSync(path.join(__dirname, cst.SYSTEMD_STARTUP_SCRIPT));
INIT_SCRIPT = '/etc/systemd/system/pm2.service';
if(!!~['systemd', 'centos', 'amazon', 'gentoo', 'darwin'].indexOf(platform)){
script = cst[platform.toUpperCase() + '_STARTUP_SCRIPT'];
}
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));

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);
});
Expand Down
32 changes: 32 additions & 0 deletions lib/scripts/io.keymetrics.PM2.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>io.keymetrics.PM2</string>
<key>UserName</key>
<string>%USER%</string>
<key>ProgramArguments</key>
<array>
<string>%PM2_PATH%</string>
<string>resurrect</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>OnDemand</key>
<false/>
<key>LaunchOnlyOnce</key>
<true/>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>%NODE_PATH%</string>
<key>PM2_HOME</key>
<string>%HOME_PATH%</string>
</dict>
<key>StandardErrorPath</key>
<string>/tmp/io.keymetrics.PM2.err</string>
<key>StandardOutPath</key>
<string>/tmp/io.keymetrics.PM2.out</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion lib/scripts/pm2-init-amazon.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ PM2=%PM2_PATH%
USER=%USER%

export PATH=$PATH:%NODE_PATH%
export HOME="%HOME_PATH%"
export PM2_HOME="%HOME_PATH%"

lockfile="/var/lock/subsys/pm2-init.sh"

Expand Down