diff --git a/lib/support/processRunner.js b/lib/support/processRunner.js index 3068e19..e89ee91 100644 --- a/lib/support/processRunner.js +++ b/lib/support/processRunner.js @@ -25,7 +25,11 @@ var util = require('./util')() module.exports = function () { var isWin = /^win/.test(process.platform) - var run = function (mode, container, exitCb, cb) { + var commonRun = function (isPrerun, mode, container, exitCb, cb) { + if (isPrerun && container.process) { + container.process.flags.prerunning = true + } + var child = {} var cwd = container.path var called = false @@ -34,7 +38,8 @@ module.exports = function () { var env var toks - toks = util.tokenizeCommand(container.run) + var command = isPrerun ? container.prerun : container.run + toks = util.tokenizeCommand(command) if (container.type === 'node') { cmd = process.argv[0] @@ -63,11 +68,22 @@ module.exports = function () { options.stdio[3] = 'ipc' } + if (isPrerun) { + console.log('pre-run step: ' + container.name + ' [' + container.prerun + ']') + } + child = spawn(cmd, args, options) child.unref() child.on('error', function (err) { if (!called) { + if (isPrerun) { + console.log('pre-run step had errors') + if (container.process) { + container.process.flags.prerunning = false + } + } + called = true exitCb(err, container, child, -1) } @@ -75,6 +91,12 @@ module.exports = function () { child.on('exit', function (code) { if (!called) { + if (isPrerun) { + console.log('pre-run step completed successfully') + if (container.process) { + container.process.flags.prerunning = false + } + } called = true exitCb(null, container, child, code) } @@ -90,11 +112,33 @@ module.exports = function () { cb(null, child) } + var prerun = function (mode, container, exitCb, cb) { + var runModeIsPrerun = true + commonRun(runModeIsPrerun, mode, container, exitCb, cb) + } + var run = function (mode, container, exitCb, cb) { + var runModeIsPrerun = false + commonRun(runModeIsPrerun, mode, container, exitCb, cb) + } var start = function (system, mode, container, exitCb, cb) { if (container && container.run) { - run(mode, container, exitCb, cb) + if (container.type === 'process' && container.prerun) { + // if there's a prerun task then execute that before running + prerun(mode, container, function (err, child) { + // when the pre-run task has exited we can continue + if (err) { + cb("prerun step error: " + err) + } else { + run(mode, container, exitCb, cb) + } + }, function () { + // for the pre-run step we ignore standard callback + }) + } else { + run(mode, container, exitCb, cb) + } } else { console.log('warning: ' + container.name + ' not started, missing execute statement') cb(container.name + ' not started, missing execute statement') @@ -151,6 +195,7 @@ module.exports = function () { c.run = command c.name = c.name + '_' + commandName c.type = 'process' + c.prerun = undefined start(system, 'live', c, exitCb(cb), function (err, child) { process = {identifier: c.name, diff --git a/lib/support/util.js b/lib/support/util.js index 6ff52f4..50ec37d 100644 --- a/lib/support/util.js +++ b/lib/support/util.js @@ -67,13 +67,15 @@ module.exports = function () { if (hidePid) { return container.process.colour(line) + '\n' } else { - return container.process.colour('[' + container.name + ' - ' + container.process.child.pid + ']: ' + line) + '\n' + var pid = (container.process.child && container.process.child.pid) || 'unknown' + return container.process.colour('[' + container.name + ' - ' + pid + ']: ' + line) + '\n' } } }) var errorColorizer = split(function (line) { - return chalk.red('[' + container.name + ' - ' + container.process.child.pid + ']: ' + line) + '\n' + var pid = (container.process.child && container.process.child.pid) || 'unknown' + return chalk.red('[' + container.name + ' - ' + pid + ']: ' + line) + '\n' }) var logStream = fs.createWriteStream(logPath + '/' + container.name + '.log') diff --git a/lib/system.js b/lib/system.js index 5e156f6..8d8077a 100644 --- a/lib/system.js +++ b/lib/system.js @@ -72,9 +72,14 @@ module.exports = function () { return function (pth) { console.log('[' + container.name + '] file change: ' + path.basename(pth)) - if ((container.process && container.process.flags.running)) { + if (container.process && container.process.flags.running) { + var restartCausedByPrerun = container.process.flags.restarting && container.prerun; container.process.flags.restarting = true - stopContainer(container, function () {}) + if (!restartCausedByPrerun) { + stopContainer(container, function () {}) + } + } else if (container.process && container.process.flags.prerunning) { + // Do nothing } else { startContainer(container, function () {}) } @@ -148,7 +153,7 @@ module.exports = function () { var stopContainer = function (container, cb) { container.process.flags.stopping = true runner.stop(container, container.process.child.pid, function () { - if (container.process.monitor && !container.process.flags.restarting) { + if (container.process.monitor) { directoryWatcher.stop(container.process.monitor) container.process.monitor = null } diff --git a/test/fixture/system/fuge/prerun.yml b/test/fixture/system/fuge/prerun.yml new file mode 100644 index 0000000..e0d30b9 --- /dev/null +++ b/test/fixture/system/fuge/prerun.yml @@ -0,0 +1,14 @@ +prerun: + type: process + path: ../prerun + prerun: node prerunbuild.js + run: node prerun.js + ports: + - main=8002 +prerunfail: + type: process + path: ../prerun + prerun: xxxxxxxxxxxxxx + run: node prerun.js + ports: + - main=8002 diff --git a/test/fixture/system/prerun/prerun.js b/test/fixture/system/prerun/prerun.js new file mode 100644 index 0000000..6eb8fea --- /dev/null +++ b/test/fixture/system/prerun/prerun.js @@ -0,0 +1,11 @@ +'use strict' + +var http = require('http') +var resp = { resp: 'Hello World!\n' } + +var server = http.createServer(function (request, response) { + response.writeHead(200, {'Content-Type': 'text/plain'}) + response.end(resp.resp) +}) +server.listen(8002) +console.log('Server running at http://127.0.0.1:8002/') diff --git a/test/fixture/system/prerun/prerunbuild.js b/test/fixture/system/prerun/prerunbuild.js new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/fixture/system/prerun/prerunbuild.js @@ -0,0 +1 @@ + diff --git a/test/processRunner.test.js b/test/processRunner.test.js index 3ad4035..2f72090 100644 --- a/test/processRunner.test.js +++ b/test/processRunner.test.js @@ -193,3 +193,34 @@ test('process kill test', function (t) { }) }) + +test('prerun test 1', function (t) { + t.plan(4) + + config.load(path.join(__dirname, 'fixture', 'system', 'fuge', 'prerun.yml'), function (err, system) { + t.equal(err, null) + runner.start(system, 'live', system.topology.containers.prerun, exitCb, function (err, child) { + t.equal(null, err) + t.notEqual(undefined, child.pid) + + setTimeout(function () { + runner.stop(system.topology.containers.prerun, child.pid, function (err) { + t.equal(null, err) + }) + }, 100) + }) + }) +}) + +test('prerun test 2 (failure test)', function (t) { + t.plan(3) + + config.load(path.join(__dirname, 'fixture', 'system', 'fuge', 'prerun.yml'), function (err, system) { + t.equal(err, null) + + runner.start(system, 'live', system.topology.containers.prerunfail, exitCb, function (err, child) { + t.notEqual(null, err) + t.equal(undefined, child) + }) + }) +})