exec: rework API to get exit code
This commit is contained in:
+37
-7
@@ -66,7 +66,9 @@ exports = module.exports = {
|
||||
stop,
|
||||
restart,
|
||||
|
||||
exec,
|
||||
createExec,
|
||||
startExec,
|
||||
getExec,
|
||||
|
||||
checkManifestConstraints,
|
||||
downloadManifest,
|
||||
@@ -2335,7 +2337,7 @@ function checkManifestConstraints(manifest) {
|
||||
return null;
|
||||
}
|
||||
|
||||
async function exec(app, options) {
|
||||
async function createExec(app, options) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert(options && typeof options === 'object');
|
||||
|
||||
@@ -2346,7 +2348,7 @@ async function exec(app, options) {
|
||||
throw new BoxError(BoxError.BAD_STATE, 'App not installed or running');
|
||||
}
|
||||
|
||||
const execOptions = {
|
||||
const createOptions = {
|
||||
AttachStdin: true,
|
||||
AttachStdout: true,
|
||||
AttachStderr: true,
|
||||
@@ -2358,6 +2360,18 @@ async function exec(app, options) {
|
||||
Cmd: cmd
|
||||
};
|
||||
|
||||
return await docker.createExec(app.containerId, createOptions);
|
||||
}
|
||||
|
||||
async function startExec(app, execId, options) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert.strictEqual(typeof execId, 'string');
|
||||
assert(options && typeof options === 'object');
|
||||
|
||||
if (app.installationState !== exports.ISTATE_INSTALLED || app.runState !== exports.RSTATE_RUNNING) {
|
||||
throw new BoxError(BoxError.BAD_STATE, 'App not installed or running');
|
||||
}
|
||||
|
||||
const startOptions = {
|
||||
Detach: false,
|
||||
Tty: options.tty,
|
||||
@@ -2373,10 +2387,26 @@ async function exec(app, options) {
|
||||
stderr: true
|
||||
};
|
||||
|
||||
const stream = await docker.execContainer(app.containerId, { execOptions, startOptions, rows: options.rows, columns: options.columns });
|
||||
const stream = await docker.startExec(execId, startOptions);
|
||||
|
||||
if (options.rows && options.columns) {
|
||||
// there is a race where resizing too early results in a 404 "no such exec"
|
||||
// https://git.cloudron.io/cloudron/box/issues/549
|
||||
setTimeout(async function () {
|
||||
await safe(docker.resizeExec(execId, { h: options.rows, w: options.columns }, { debug }));
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
async function getExec(app, execId) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert.strictEqual(typeof execId, 'string');
|
||||
|
||||
return await docker.getExec(execId);
|
||||
}
|
||||
|
||||
function canAutoupdateApp(app, updateInfo) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert.strictEqual(typeof updateInfo, 'object');
|
||||
@@ -2601,7 +2631,7 @@ async function downloadFile(app, filePath) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert.strictEqual(typeof filePath, 'string');
|
||||
|
||||
const statStream = await exec(app, { cmd: [ 'stat', '--printf=%F-%s', filePath ], tty: true });
|
||||
const statStream = await startExec(app, { cmd: [ 'stat', '--printf=%F-%s', filePath ], tty: true });
|
||||
const data = await drainStream(statStream);
|
||||
|
||||
const parts = data.split('-');
|
||||
@@ -2622,7 +2652,7 @@ async function downloadFile(app, filePath) {
|
||||
throw new BoxError(BoxError.NOT_FOUND, 'only files or dirs can be downloaded');
|
||||
}
|
||||
|
||||
const inputStream = await exec(app, { cmd, tty: false });
|
||||
const inputStream = await startExec(app, { cmd, tty: false });
|
||||
|
||||
// transforms the docker stream into a normal stream
|
||||
const stdoutStream = new TransformStream({
|
||||
@@ -2663,7 +2693,7 @@ async function uploadFile(app, sourceFilePath, destFilePath) {
|
||||
const escapedDestFilePath = safe.child_process.execSync(`printf %q '${destFilePath.replace(/'/g, '\'\\\'\'')}'`, { shell: '/bin/bash', encoding: 'utf8' });
|
||||
debug(`uploadFile: ${sourceFilePath} -> ${escapedDestFilePath}`);
|
||||
|
||||
const destStream = await exec(app, { cmd: [ 'bash', '-c', `cat - > ${escapedDestFilePath}` ], tty: false });
|
||||
const destStream = await startExec(app, { cmd: [ 'bash', '-c', `cat - > ${escapedDestFilePath}` ], tty: false });
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const done = once(error => reject(new BoxError(BoxError.FS_ERROR, error.message)));
|
||||
|
||||
Reference in New Issue
Block a user