diff --git a/src/docker.js b/src/docker.js index b516f0ca0..c3f2e6b88 100644 --- a/src/docker.js +++ b/src/docker.js @@ -2,6 +2,8 @@ exports = module.exports = { connection: connectionInstance(), + setRegistryConfig: setRegistryConfig, + downloadImage: downloadImage, createContainer: createContainer, startContainer: startContainer, @@ -58,12 +60,50 @@ var addons = require('./addons.js'), const RMVOLUME_CMD = path.join(__dirname, 'scripts/rmvolume.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.BAD_FIELD = 'Bad field'; + function debugApp(app, args) { assert(typeof app === 'object'); debug(app.fqdn + ' ' + util.format.apply(util, Array.prototype.slice.call(arguments, 1))); } +function setRegistryConfig(auth, callback) { + assert.strictEqual(typeof auth, 'object'); + assert.strictEqual(typeof callback, 'function'); + + const isLogin = !!auth.password; + + // 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)); + + callback(); + }); +} + function pullImage(manifest, callback) { var docker = exports.connection; diff --git a/src/routes/settings.js b/src/routes/settings.js index c1fd342e4..5c8185094 100644 --- a/src/routes/settings.js +++ b/src/routes/settings.js @@ -23,10 +23,14 @@ exports = module.exports = { setAppstoreConfig: setAppstoreConfig, getPlatformConfig: getPlatformConfig, - setPlatformConfig: setPlatformConfig + setPlatformConfig: setPlatformConfig, + + setRegistryConfig: setRegistryConfig }; var assert = require('assert'), + docker = require('../docker.js'), + DockerError = docker.DockerError, HttpError = require('connect-lastmile').HttpError, HttpSuccess = require('connect-lastmile').HttpSuccess, safe = require('safetydance'), @@ -235,3 +239,18 @@ function setAppstoreConfig(req, res, next) { }); }); } + +function setRegistryConfig(req, res, next) { + assert.strictEqual(typeof req.body, 'object'); + + if (typeof req.body.serveraddress !== 'string') return next(new HttpError(400, 'serveraddress is required')); + if ('username' in req.body && typeof req.body.username !== 'string') return next(new HttpError(400, 'username is required')); + 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) return next(new HttpError(500, error)); + + next(new HttpSuccess(200)); + }); +} diff --git a/src/server.js b/src/server.js index 9c68a0f7d..028539213 100644 --- a/src/server.js +++ b/src/server.js @@ -237,6 +237,8 @@ function initializeExpressSync() { router.get ('/api/v1/settings/appstore_config', appstoreScope, verifyOperator, routes.settings.getAppstoreConfig); router.post('/api/v1/settings/appstore_config', appstoreScope, verifyOperator, routes.settings.setAppstoreConfig); + router.post('/api/v1/settings/registry_config', appstoreScope, verifyOperator, routes.settings.setRegistryConfig); + // email routes router.get ('/api/v1/mail/:domain', mailScope, routes.mail.getDomain); router.post('/api/v1/mail', mailScope, routes.mail.addDomain);