Skip to content

Commit

Permalink
Merge pull request #3001 from bisubus/dump-backup
Browse files Browse the repository at this point in the history
Dump backup
  • Loading branch information
Unitech committed Aug 29, 2017
2 parents 00bd4b0 + 829d95d commit de0f88e
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 15 deletions.
68 changes: 60 additions & 8 deletions lib/API/Startup.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,29 @@ module.exports = function(CLI) {
* @return
*/
function fin(err) {
// Back up dump file
try {
if (fs.existsSync(cst.DUMP_FILE_PATH)) {
if (fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)) {
fs.unlinkSync(cst.DUMP_BACKUP_FILE_PATH);
}
fs.renameSync(cst.DUMP_FILE_PATH, cst.DUMP_BACKUP_FILE_PATH);
}
} catch (e) {
console.error(e.stack || e);
Common.printOut(cst.PREFIX_MSG_ERR + 'Failed to back up dump file in %s', cst.DUMP_BACKUP_FILE_PATH);
}

// Overwrite dump file, delete if broken and exit
try {
fs.writeFileSync(cst.DUMP_FILE_PATH, JSON.stringify(env_arr, '', 2));
} catch (e) {
console.error(e.stack || e);
try {
fs.unlinkSync(cst.DUMP_FILE_PATH);
} catch (e) {
console.error(e.stack || e);
}
Common.printOut(cst.PREFIX_MSG_ERR + 'Failed to save dump file in %s', cst.DUMP_FILE_PATH);
return that.exitCli(cst.ERROR_EXIT);
}
Expand Down Expand Up @@ -393,19 +412,52 @@ module.exports = function(CLI) {
var apps = {};
var that = this;

Common.printOut(cst.PREFIX_MSG + 'Restoring processes located in %s', cst.DUMP_FILE_PATH);
var processes;

function readDumpFile(dumpFilePath) {
Common.printOut(cst.PREFIX_MSG + 'Restoring processes located in %s', cst.DUMP_FILE_PATH);
try {
var apps = fs.readFileSync(dumpFilePath);
} catch (e) {
Common.printError(cst.PREFIX_MSG_ERR + 'Failed to read dump file in %s', dumpFilePath);
throw e;
}

return apps;
}

function parseDumpFile(dumpFilePath, apps) {
try {
var processes = Common.parseConfig(apps, 'none');
} catch (e) {
Common.printError(cst.PREFIX_MSG_ERR + 'Failed to parse dump file in %s', dumpFilePath);
try {
fs.unlinkSync(dumpFilePath);
} catch (e) {
console.error(e.stack || e);
}
throw e;
}

return processes;
}

// Read dump file, fall back to backup, delete if broken
try {
apps = fs.readFileSync(cst.DUMP_FILE_PATH);
apps = readDumpFile(cst.DUMP_FILE_PATH);
processes = parseDumpFile(cst.DUMP_FILE_PATH, apps);
} catch(e) {
Common.printError(cst.PREFIX_MSG_ERR + 'No processes saved; DUMP file doesn\'t exist');
// if (cb) return cb(Common.retErr(e));
// else return that.exitCli(cst.ERROR_EXIT);
return that.speedList();
try {
apps = readDumpFile(cst.DUMP_BACKUP_FILE_PATH);
processes = parseDumpFile(cst.DUMP_BACKUP_FILE_PATH, apps);
} catch(e) {
Common.printError(cst.PREFIX_MSG_ERR + 'No processes saved; DUMP file doesn\'t exist');
// if (cb) return cb(Common.retErr(e));
// else return that.exitCli(cst.ERROR_EXIT);
return that.speedList();
}
}

var processes = Common.parseConfig(apps, 'none');

that.Client.executeRemote('getMonitorData', {}, function(err, list) {
if (err) {
Common.printError(err);
Expand Down
19 changes: 19 additions & 0 deletions lib/God/ActionMethods.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,30 @@ module.exports = function(God) {
}

function fin(err) {
// Back up dump file
try {
if (fs.existsSync(cst.DUMP_FILE_PATH)) {
if (fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)) {
fs.unlinkSync(cst.DUMP_BACKUP_FILE_PATH);
}
fs.renameSync(cst.DUMP_FILE_PATH, cst.DUMP_BACKUP_FILE_PATH);
}
} catch (e) {
console.error(e.stack || e);
}

// Overwrite dump file, delete if broken
try {
fs.writeFileSync(cst.DUMP_FILE_PATH, JSON.stringify(process_list));
} catch (e) {
console.error(e.stack || e);
try {
fs.unlinkSync(cst.DUMP_FILE_PATH);
} catch (e) {
console.error(e.stack || e);
}
}

return cb(null, {success:true, process_list: process_list});
}

Expand Down
1 change: 1 addition & 0 deletions paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ module.exports = function(PM2_HOME) {
DEFAULT_MODULE_PATH : p.resolve(PM2_HOME, 'node_modules'),
KM_ACCESS_TOKEN : p.resolve(PM2_HOME, 'km-access-token'),
DUMP_FILE_PATH : p.resolve(PM2_HOME, 'dump.pm2'),
DUMP_BACKUP_FILE_PATH : p.resolve(PM2_HOME, 'dump.pm2.bak'),

DAEMON_RPC_PORT : p.resolve(PM2_HOME, 'rpc.sock'),
DAEMON_PUB_PORT : p.resolve(PM2_HOME, 'pub.sock'),
Expand Down
24 changes: 24 additions & 0 deletions test/bash/dump.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

SRC=$(cd $(dirname "$0"); pwd)
source "${SRC}/include.sh"
cd $file_path

$pm2 start echo.js -i 4
spec "should start 4 processes"
should 'should have 4 apps started' 'online' 4

rm -f ~/.pm2/dump.pm2 ~/.pm2/dump.pm2.bak
$pm2 save
spec "should save process list"
ls ~/.pm2/dump.pm2
spec "dump file should exist"
ls ~/.pm2/dump.pm2.bak
ispec "dump backup file should not exist"

$pm2 save
spec "should save and backup process list"
ls ~/.pm2/dump.pm2
spec "dump file should exist"
ls ~/.pm2/dump.pm2.bak
spec "dump backup file should exist"
18 changes: 14 additions & 4 deletions test/bash/resurrect.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,23 @@ cd $file_path

$pm2 start echo.js -i 4
spec "should start 4 processes"
should 'should have 4 apps started' 'online' 4

$pm2 save
spec "should save process list"
ls ~/.pm2/dump.pm2
spec "should dump file exists"
$pm2 resurrect
spec "should resurrect"
spec "should resurrect from dump"
should 'should have still 4 apps started' 'online' 4

$pm2 save
$pm2 delete all
echo "[{" > ~/.pm2/dump.pm2
$pm2 resurrect
spec "should resurrect from backup if dump is broken"
ls ~/.pm2/dump.pm2
ispec "should delete broken dump"
should 'should have still 4 apps started' 'online' 4

$pm2 delete all
$pm2 resurrect
spec "should resurrect from backup if dump is missing"
should 'should have still 4 apps started' 'online' 4
2 changes: 2 additions & 0 deletions test/pm2_behavior_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ bash ./test/bash/pm2-runtime.sh
spec "pm2-runtime"
bash ./test/bash/startup.sh
spec "upstart startup test"
bash ./test/bash/dump.sh
spec "dump test"
bash ./test/bash/resurrect.sh
spec "resurrect test"
# bash ./test/bash/docker.sh
Expand Down
91 changes: 88 additions & 3 deletions test/programmatic/misc_commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
var PM2 = require('../..');
var should = require('should');
var path = require('path');
var fs = require('fs');

var cst = require('../../constants.js');

describe('Misc commands', function() {
var pm2 = new PM2.custom({
Expand Down Expand Up @@ -31,7 +34,7 @@ describe('Misc commands', function() {
should(err).be.null();
done();
});
});
});

it('should restart them', function(done) {
pm2.restart('all', function(err, data) {
Expand Down Expand Up @@ -70,9 +73,34 @@ describe('Misc commands', function() {
});
});

it('should save process list', function(done) {
it('should save process list to dump', function(done) {
if (fs.existsSync(cst.DUMP_FILE_PATH)) {
fs.unlinkSync(cst.DUMP_FILE_PATH);
}

if (fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)) {
fs.unlinkSync(cst.DUMP_BACKUP_FILE_PATH);
}

pm2.dump(function(err, data) {
should(fs.existsSync(cst.DUMP_FILE_PATH)).be.true();
should(fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)).be.false();
should(err).be.null();
done();
});
});

it('should back up dump and re-save process list', function(done) {
var origDump = fs.readFileSync(cst.DUMP_FILE_PATH).toString();

pm2.dump(function(err, data) {
should(fs.existsSync(cst.DUMP_FILE_PATH)).be.true();
should(fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)).be.true();
should(err).be.null();

var dumpBackup = fs.readFileSync(cst.DUMP_BACKUP_FILE_PATH).toString();

should(origDump).be.equal(dumpBackup);
done();
});
});
Expand All @@ -89,7 +117,7 @@ describe('Misc commands', function() {
});
});

it('should resurrect previous processes', function(done) {
it('should resurrect previous processes from dump', function(done) {
pm2.resurrect(function(err, data) {
should(err).be.null();

Expand All @@ -101,5 +129,62 @@ describe('Misc commands', function() {
});
});

it('should resurrect previous processes from backup if dump is broken', function(done) {
fs.writeFileSync(cst.DUMP_FILE_PATH, '[{');

pm2.resurrect(function(err, data) {
should(err).be.null();

pm2.list(function(err, procs) {
should(err).be.null();
procs.length.should.eql(4);
done();
});
});
});

it('should delete broken dump', function() {
should(fs.existsSync(cst.DUMP_FILE_PATH)).be.false();
});

it('should resurrect previous processes from backup if dump is missing', function(done) {
if (fs.existsSync(cst.DUMP_FILE_PATH)) {
fs.unlinkSync(cst.DUMP_FILE_PATH);
}

pm2.resurrect(function(err, data) {
should(err).be.null();

pm2.list(function(err, procs) {
should(err).be.null();
procs.length.should.eql(4);
done();
});
});
});

it('should resurrect no processes if dump and backup are broken', function() {
fs.writeFileSync(cst.DUMP_FILE_PATH, '[{');
fs.writeFileSync(cst.DUMP_BACKUP_FILE_PATH, '[{');

should(pm2.resurrect()).be.false();
});

it('should delete broken dump and backup', function() {
should(fs.existsSync(cst.DUMP_FILE_PATH)).be.false();
should(fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)).be.false();
});

it('should resurrect no processes if dump and backup are missing', function() {
if (fs.existsSync(cst.DUMP_FILE_PATH)) {
fs.unlinkSync(cst.DUMP_FILE_PATH);
}

if (fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)) {
fs.unlinkSync(cst.DUMP_BACKUP_FILE_PATH);
}

should(pm2.resurrect()).be.false();
});

});

0 comments on commit de0f88e

Please sign in to comment.