docker: better error message when out of disk space

This commit is contained in:
Girish Ramakrishnan
2023-03-09 21:06:54 +01:00
parent c2b1350fa0
commit 5e606c50a4

View File

@@ -40,6 +40,7 @@ const apps = require('./apps.js'),
delay = require('./delay.js'),
Docker = require('dockerode'),
paths = require('./paths.js'),
promiseRetry = require('./promise-retry.js'),
services = require('./services.js'),
settings = require('./settings.js'),
shell = require('./shell.js'),
@@ -113,24 +114,28 @@ async function pullImage(manifest) {
if (error) throw new BoxError(BoxError.DOCKER_ERROR, `Unable to pull image ${manifest.dockerImage}. Please check the network or if the image needs authentication. statusCode: ${error.statusCode}`);
return new Promise((resolve, reject) => {
// https://github.com/dotcloud/docker/issues/1074 says each status message
// is emitted as a chunk
// https://github.com/dotcloud/docker/issues/1074 says each status message is emitted as a chunk
let layerError = null;
stream.on('data', function (chunk) {
const data = safe.JSON.parse(chunk) || { };
debug('pullImage: %j', data);
// The data.status here is useless because this is per layer as opposed to per image
if (!data.status && data.error) {
debug('pullImage error %s: %s', manifest.dockerImage, data.errorDetail.message);
if (!data.status && data.error) { // data is { errorDetail: { message: xx } , error: xx }
debug(`pullImage error ${manifest.dockerImage}: ${data.errorDetail.message}`);
layerError = data.errorDetail;
}
});
stream.on('end', function () {
debug('downloaded image %s', manifest.dockerImage);
resolve();
debug(`downloaded image ${manifest.dockerImage} . error: ${!!layerError}`);
if (!layerError) return resolve();
reject(new BoxError(layerError.includes('no space') ? BoxError.FS_ERROR : BoxError.DOCKER_ERROR, layerError.message));
});
stream.on('error', function (error) {
stream.on('error', function (error) { // this is only hit for stream error and not for some download error
debug('error pulling image %s: %j', manifest.dockerImage, error);
reject(new BoxError(BoxError.DOCKER_ERROR, error.message));
});
@@ -147,14 +152,9 @@ async function downloadImage(manifest) {
const [error, result] = await safe(image.inspect());
if (!error && result) return; // image is already present locally
for (let times = 0; times < 10; times++) {
debug(`downloadImage: pulling image. attempt ${times+1}`);
const [pullError] = await safe(pullImage(manifest));
if (pullError && pullError.reason === BoxError.NOT_FOUND) throw pullError;
if (!pullError) break;
await delay(5000);
}
await promiseRetry({ times: 10, interval: 5000, retry: (pullError) => pullError.reason !== BoxError.NOT_FOUND && pullError.reason !== BoxError.FS_ERROR }, async () => {
await pullImage(manifest);
});
}
async function getVolumeMounts(app) {