Skip to content

Commit

Permalink
buildx(history): improve child process termination and exit code hand…
Browse files Browse the repository at this point in the history
…ling

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
  • Loading branch information
crazy-max committed Jul 2, 2024
1 parent 200e43c commit ff35e30
Showing 1 changed file with 38 additions and 14 deletions.
52 changes: 38 additions & 14 deletions src/buildx/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
* limitations under the License.
*/

import {spawn} from 'child_process';
import {ChildProcessByStdio, spawn} from 'child_process';
import fs from 'fs';
import os from 'os';
import path from 'path';
import {Readable, Writable} from 'stream';
import * as core from '@actions/core';

import {Buildx} from './buildx';
Expand Down Expand Up @@ -91,22 +92,29 @@ export class History {
});
await Exec.exec('mkfifo', [buildxOutFifoPath]);

const buildxCmd = await this.buildx.getCommand(['--builder', builderName, 'dial-stdio']);

core.info(`[command]${buildxCmd.command} ${buildxCmd.args.join(' ')}`);
const buildxDialStdioProc = spawn(buildxCmd.command, buildxCmd.args, {
const buildxDialStdioCmd = await this.buildx.getCommand(['--builder', builderName, 'dial-stdio']);
core.info(`[command]${buildxDialStdioCmd.command} ${buildxDialStdioCmd.args.join(' ')}`);
const buildxDialStdioProc = spawn(buildxDialStdioCmd.command, buildxDialStdioCmd.args, {
stdio: ['pipe', 'pipe', 'inherit'],
detached: true
});
let buildxDialStdioKilled = false;
fs.createReadStream(buildxInFifoPath).pipe(buildxDialStdioProc.stdin);
buildxDialStdioProc.stdout.pipe(fs.createWriteStream(buildxOutFifoPath));
buildxDialStdioProc.on('exit', code => {
core.info(`Process "buildx dial-stdio" exited with code ${code}`);
buildxDialStdioProc.on('exit', (code, signal) => {
buildxDialStdioKilled = true;
if (signal) {
core.info(`Process "buildx dial-stdio" was killed with signal ${signal}`);
} else {
core.info(`Process "buildx dial-stdio" exited with code ${code}`);
}
});

const tmpDockerbuildFilename = path.join(outDir, 'rec.dockerbuild');
const summaryFilename = path.join(outDir, 'summary.json');

let dockerRunProc: ChildProcessByStdio<Writable, Readable, null> | undefined;
let dockerRunProcKilled = false;
await new Promise<void>((resolve, reject) => {
const ebargs: Array<string> = ['--ref-state-dir=/buildx-refs', `--node=${builderName}/${nodeName}`];
for (const ref of refs) {
Expand All @@ -127,7 +135,7 @@ export class History {
...ebargs
]
core.info(`[command]docker ${dockerRunArgs.join(' ')}`);
const dockerRunProc = spawn('docker', dockerRunArgs, {
dockerRunProc = spawn('docker', dockerRunArgs, {
stdio: ['pipe', 'pipe', 'inherit']
});
fs.createReadStream(buildxOutFifoPath).pipe(dockerRunProc.stdin);
Expand All @@ -140,19 +148,35 @@ export class History {
resolve();
}
} else {
reject(new Error(`Process "docker run" exited with code ${code}`));
reject(new Error(`Process "docker run" closed with code ${code}`));
}
});
dockerRunProc.on('error', err => {
core.error(`Error executing "docker run": ${err}`);
reject(err);
});
dockerRunProc.on('exit', code => {
core.info(`Process "docker run" exited with code ${code}`);
dockerRunProc.on('exit', (code, signal) => {
dockerRunProcKilled = true;
if (signal) {
core.info(`Process "docker run" was killed with signal ${signal}`);
} else {
core.info(`Process "docker run" exited with code ${code}`);
}
});
})
.catch(err => {
throw err;
})
.finally(() => {
if (buildxDialStdioProc && !buildxDialStdioKilled) {
core.debug('Force terminating "buildx dial-stdio" process');
buildxDialStdioProc.kill('SIGKILL');
}
if (dockerRunProc && !dockerRunProcKilled) {
core.debug('Force terminating "docker run" process');
dockerRunProc.kill('SIGKILL');
}
});
}).catch(err => {
throw err;
});

let dockerbuildFilename = `${GitHub.context.repo.owner}~${GitHub.context.repo.repo}~${refs[0].substring(0, 6).toUpperCase()}`;
if (refs.length > 1) {
Expand Down

0 comments on commit ff35e30

Please sign in to comment.