diff --git a/lib/utils/device/live.ts b/lib/utils/device/live.ts index 3cd4d7d4..a310320d 100644 --- a/lib/utils/device/live.ts +++ b/lib/utils/device/live.ts @@ -221,21 +221,14 @@ export class LivepushManager { } // Setup cleanup handlers for the device - - // This is necessary because the `exit-hook` module is used by several - // dependencies, and will exit without calling the following handler. - // Once https://github.com/balena-io/balena-cli/issues/867 has been solved, - // we are free to (and definitely should) remove the below line - process.removeAllListeners('SIGINT'); - process.on('SIGINT', async () => { + process.once('SIGINT', async () => { this.logger.logLivepush('Cleaning up device...'); await Promise.all( _.map(this.containers, (container) => { container.livepush.cleanupIntermediateContainers(); }), ); - - process.exit(0); + this.logger.logDebug('Cleaning up done.'); }); } diff --git a/lib/utils/device/logs.ts b/lib/utils/device/logs.ts index be8fab4d..828551ed 100644 --- a/lib/utils/device/logs.ts +++ b/lib/utils/device/logs.ts @@ -42,12 +42,13 @@ export function displayDeviceLogs( logs.on('data', (log) => { displayLogLine(log, logger, system, filterServices); }); - - logs.on('error', reject); - logs.on('end', () => { - logger.logError('Connection to device lost'); + logs.once('error', reject); + logs.once('end', () => { + logger.logWarn('Connection to device lost'); resolve(); }); + process.once('SIGINT', () => logs.emit('close')); + process.once('SIGTERM', () => logs.emit('close')); }); } diff --git a/lib/utils/remote-build.ts b/lib/utils/remote-build.ts index 0e080abf..39951f14 100644 --- a/lib/utils/remote-build.ts +++ b/lib/utils/remote-build.ts @@ -123,32 +123,7 @@ export async function startRemoteBuild(build: RemoteBuild): Promise { } if (!build.opts.headless) { - return new Promise((resolve, reject) => { - // Setup interrupt handlers so we can cancel the build if the user presses - // ctrl+c - - // This is necessary because the `exit-hook` module is used by several - // dependencies, and will exit without calling the following handler. - // Once https://github.com/balena-io/balena-cli/issues/867 has been solved, - // we are free to (and definitely should) remove the below line - process.removeAllListeners('SIGINT'); - process.on('SIGINT', () => { - process.stderr.write('Received SIGINT, cleaning up. Please wait.\n'); - cancelBuildIfNecessary(build).then(() => { - stream.end(); - process.exit(130); - }); - }); - - stream.on('data', getBuilderMessageHandler(build)); - stream.on('end', resolve); - stream.on('error', reject); - }).then(() => { - globalLogger.outputDeferredMessages(); - if (build.hadError) { - throw new RemoteBuildFailedError(); - } - }); + return awaitRemoteBuildStream(build, stream); } // We're running a headless build, which means we'll @@ -166,6 +141,42 @@ export async function startRemoteBuild(build: RemoteBuild): Promise { handleHeadlessBuildMessage(result); } +async function awaitRemoteBuildStream( + build: RemoteBuild, + stream: NodeJS.ReadWriteStream, +) { + let sigintHandler: (() => Promise) | null = null; + try { + await new Promise((resolve, reject) => { + // Setup interrupt handlers so we can cancel the build if the user presses + // ctrl+c + sigintHandler = async () => { + process.exitCode = 130; + console.error('Received SIGINT, cleaning up. Please wait.'); + try { + await cancelBuildIfNecessary(build); + } catch (err) { + console.error(err.message); + } finally { + stream.end(); + } + }; + process.once('SIGINT', sigintHandler); + stream.on('data', getBuilderMessageHandler(build)); + stream.on('end', resolve); + stream.on('error', reject); + }); + } finally { + if (sigintHandler) { + process.removeListener('SIGINT', sigintHandler); + } + globalLogger.outputDeferredMessages(); + } + if (build.hadError) { + throw new RemoteBuildFailedError(); + } +} + function handleHeadlessBuildMessage(message: HeadlessBuilderMessage) { if (!process.stdout.isTTY) { process.stdout.write(JSON.stringify(message)); diff --git a/patches/all/exit-hook+1.1.1.patch b/patches/all/exit-hook+1.1.1.patch new file mode 100644 index 00000000..72745300 --- /dev/null +++ b/patches/all/exit-hook+1.1.1.patch @@ -0,0 +1,17 @@ +diff --git a/node_modules/exit-hook/index.js b/node_modules/exit-hook/index.js +index e18013f..3366356 100644 +--- a/node_modules/exit-hook/index.js ++++ b/node_modules/exit-hook/index.js +@@ -14,9 +14,9 @@ function exit(exit, signal) { + el(); + }); + +- if (exit === true) { +- process.exit(128 + signal); +- } ++ // if (exit === true) { ++ // process.exit(128 + signal); ++ // } + }; + + module.exports = function (cb) {