diff --git a/src/addons.js b/src/addons.js index ea7a24df2..aebefce4b 100644 --- a/src/addons.js +++ b/src/addons.js @@ -36,6 +36,7 @@ var accesscontrol = require('./accesscontrol.js'), apps = require('./apps.js'), assert = require('assert'), async = require('async'), + BoxError = require('./boxerror.js'), clients = require('./clients.js'), constants = require('./constants.js'), ClientsError = clients.ClientsError, @@ -44,7 +45,6 @@ var accesscontrol = require('./accesscontrol.js'), debug = require('debug')('box:addons'), docker = require('./docker.js'), dockerConnection = docker.connection, - DockerError = docker.DockerError, fs = require('fs'), graphs = require('./graphs.js'), hat = require('./hat.js'), @@ -271,7 +271,7 @@ function restartContainer(serviceName, callback) { if (error) return callback(new AddonsError(AddonsError.INTERNAL_ERROR, error)); docker.startContainer(serviceName, function (error) { - if (error && error.reason === DockerError.NOT_FOUND) { + if (error && error.reason === BoxError.NOT_FOUND) { callback(null); // callback early since rebuilding takes long return rebuildService(serviceName, function (error) { if (error) console.error(`Unable to rebuild service ${serviceName}`, error); }); } @@ -306,7 +306,7 @@ function getServiceDetails(containerName, tokenEnvName, callback) { assert.strictEqual(typeof callback, 'function'); docker.inspect(containerName, function (error, result) { - if (error && error.reason === DockerError.NOT_FOUND) return callback(new AddonsError(AddonsError.NOT_ACTIVE, error)); + if (error && error.reason === BoxError.NOT_FOUND) return callback(new AddonsError(AddonsError.NOT_ACTIVE, error)); if (error) return callback(new AddonsError(AddonsError.INTERNAL_ERROR, error)); const ip = safe.query(result, 'NetworkSettings.Networks.cloudron.IPAddress', null); @@ -1803,7 +1803,7 @@ function statusSftp(callback) { assert.strictEqual(typeof callback, 'function'); docker.inspect('sftp', function (error, container) { - if (error && error.reason === DockerError.NOT_FOUND) return callback(null, { status: exports.SERVICE_STATUS_STOPPED }); + if (error && error.reason === BoxError.NOT_FOUND) return callback(null, { status: exports.SERVICE_STATUS_STOPPED }); if (error) return callback(new AddonsError(AddonsError.INTERNAL_ERROR, error)); docker.memoryUsage('sftp', function (error, result) { @@ -1824,7 +1824,7 @@ function statusGraphite(callback) { assert.strictEqual(typeof callback, 'function'); docker.inspect('graphite', function (error, container) { - if (error && error.reason === DockerError.NOT_FOUND) return callback(null, { status: exports.SERVICE_STATUS_STOPPED }); + if (error && error.reason === BoxError.NOT_FOUND) return callback(null, { status: exports.SERVICE_STATUS_STOPPED }); if (error) return callback(new AddonsError(AddonsError.INTERNAL_ERROR, error)); request.get('http://127.0.0.1:8417/graphite-web/dashboard', { timeout: 3000 }, function (error, response) { diff --git a/src/docker.js b/src/docker.js index dd221ca13..ef35f4fc0 100644 --- a/src/docker.js +++ b/src/docker.js @@ -1,8 +1,6 @@ 'use strict'; exports = module.exports = { - DockerError: DockerError, - connection: connectionInstance(), setRegistryConfig: setRegistryConfig, @@ -41,6 +39,7 @@ function connectionInstance(timeout) { var addons = require('./addons.js'), async = require('async'), assert = require('assert'), + BoxError = require('./boxerror.js'), child_process = require('child_process'), constants = require('./constants.js'), debug = require('debug')('box:docker.js'), @@ -56,30 +55,6 @@ var addons = require('./addons.js'), const CLEARVOLUME_CMD = path.join(__dirname, 'scripts/clearvolume.sh'), MKDIRVOLUME_CMD = path.join(__dirname, 'scripts/mkdirvolume.sh'); -function DockerError(reason, errorOrMessage) { - assert.strictEqual(typeof reason, 'string'); - assert(errorOrMessage instanceof Error || typeof errorOrMessage === 'string' || typeof errorOrMessage === 'undefined'); - - Error.call(this); - Error.captureStackTrace(this, this.constructor); - - this.name = this.constructor.name; - this.reason = reason; - if (typeof errorOrMessage === 'undefined') { - this.message = reason; - } else if (typeof errorOrMessage === 'string') { - this.message = errorOrMessage; - } else { - this.message = 'Internal error'; - this.nestedError = errorOrMessage; - } -} -util.inherits(DockerError, Error); -DockerError.INTERNAL_ERROR = 'Internal Error'; -DockerError.EXTERNAL_ERROR = 'External Error'; -DockerError.NOT_FOUND = 'Not found'; -DockerError.BAD_FIELD = 'Bad field'; - function debugApp(app) { assert(typeof app === 'object'); @@ -95,8 +70,8 @@ function setRegistryConfig(auth, callback) { // currently, auth info is not stashed in the db but maybe it should for restore to work? const cmd = isLogin ? `docker login ${auth.serveraddress} --username ${auth.username} --password ${auth.password}` : `docker logout ${auth.serveraddress}`; - child_process.exec(cmd, { }, function (error, stdout, stderr) { - if (error) return callback(new DockerError(DockerError.BAD_FIELD, stderr)); + child_process.exec(cmd, { }, function (error /*, stdout, stderr */) { + if (error) return callback(new BoxError(BoxError.ACCESS_DENIED, error.message)); callback(); }); @@ -109,8 +84,8 @@ function ping(callback) { var docker = connectionInstance(1000); docker.ping(function (error, result) { - if (error) return callback(new DockerError(DockerError.INTERNAL_ERROR, error)); - if (result !== 'OK') return callback(new DockerError(DockerError.INTERNAL_ERROR, 'Unable to ping the docker daemon')); + if (error) return callback(new BoxError(BoxError.INTERNAL_ERROR, error)); + if (result !== 'OK') return callback(new BoxError(BoxError.INTERNAL_ERROR, 'Unable to ping the docker daemon')); callback(null); }); @@ -122,7 +97,7 @@ function pullImage(manifest, callback) { // Use docker CLI here to support downloading of private repos. for dockerode, we have to use // https://github.com/apocas/dockerode#pull-from-private-repos docker.pull(manifest.dockerImage, function (error, stream) { - if (error) return callback(new DockerError(DockerError.EXTERNAL_ERROR, 'Unable to pull image. statusCode: ' + error.statusCode)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, 'Unable to pull image. statusCode: ' + error.statusCode)); // https://github.com/dotcloud/docker/issues/1074 says each status message // is emitted as a chunk @@ -145,7 +120,7 @@ function pullImage(manifest, callback) { stream.on('error', function (error) { debug('error pulling image %s of %s: %j', manifest.dockerImage, manifest.id, error); - callback(new DockerError(DockerError.EXTERNAL_ERROR, error.message)); + callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message)); }); }); } @@ -322,8 +297,8 @@ function startContainer(containerId, callback) { debug('Starting container %s', containerId); container.start(function (error) { - if (error && error.statusCode === 404) return callback(new DockerError(DockerError.NOT_FOUND)); - if (error && error.statusCode !== 304) return callback(new DockerError(DockerError.INTERNAL_ERROR, error)); + if (error && error.statusCode === 404) return callback(new BoxError(BoxError.NOT_FOUND)); + if (error && error.statusCode !== 304) return callback(new BoxError(BoxError.INTERNAL_ERROR, error)); return callback(null); }); @@ -482,8 +457,8 @@ function inspect(containerId, callback) { var container = exports.connection.getContainer(containerId); container.inspect(function (error, result) { - if (error && error.statusCode === 404) return callback(new DockerError(DockerError.NOT_FOUND)); - if (error) return callback(new DockerError(DockerError.INTERNAL_ERROR, error)); + if (error && error.statusCode === 404) return callback(new BoxError(BoxError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.INTERNAL_ERROR, error)); callback(null, result); }); @@ -496,7 +471,7 @@ function getEvents(options, callback) { let docker = exports.connection; docker.getEvents(options, function (error, stream) { - if (error) return callback(new DockerError(DockerError.INTERNAL_ERROR, error)); + if (error) return callback(new BoxError(BoxError.INTERNAL_ERROR, error)); callback(null, stream); }); @@ -509,8 +484,8 @@ function memoryUsage(containerId, callback) { var container = exports.connection.getContainer(containerId); container.stats({ stream: false }, function (error, result) { - if (error && error.statusCode === 404) return callback(new DockerError(DockerError.NOT_FOUND)); - if (error) return callback(new DockerError(DockerError.INTERNAL_ERROR, error)); + if (error && error.statusCode === 404) return callback(new BoxError(BoxError.NOT_FOUND)); + if (error) return callback(new BoxError(BoxError.INTERNAL_ERROR, error)); callback(null, result); }); @@ -620,7 +595,7 @@ function info(callback) { let docker = exports.connection; docker.info(function (error, result) { - if (error) return callback(new DockerError(DockerError.EXTERNAL_ERROR, 'Error connecting to docker. statusCode: ' + error.statusCode)); + if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, 'Error connecting to docker. statusCode: ' + error.statusCode)); callback(null, result); }); diff --git a/src/routes/settings.js b/src/routes/settings.js index f3eeb64f6..b2d34f23c 100644 --- a/src/routes/settings.js +++ b/src/routes/settings.js @@ -11,7 +11,7 @@ var assert = require('assert'), backups = require('../backups.js'), custom = require('../custom.js'), docker = require('../docker.js'), - DockerError = docker.DockerError, + BoxError = require('../boxerror.js'), HttpError = require('connect-lastmile').HttpError, HttpSuccess = require('connect-lastmile').HttpSuccess, safe = require('safetydance'), @@ -275,7 +275,7 @@ function setRegistryConfig(req, res, next) { if ('password' in req.body && typeof req.body.password !== 'string') return next(new HttpError(400, 'password is required')); docker.setRegistryConfig(req.body, function (error) { - if (error && error.reason === DockerError.BAD_FIELD) return next(new HttpError(400, error.message)); + if (error && error.reason === BoxError.ACCESS_DENIED) return next(new HttpError(400, error.message)); if (error) return next(new HttpError(500, error)); next(new HttpSuccess(200));