2015-07-20 00:09:47 -07:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
exports = module.exports = {
|
|
|
|
|
setupAddons: setupAddons,
|
|
|
|
|
teardownAddons: teardownAddons,
|
|
|
|
|
backupAddons: backupAddons,
|
|
|
|
|
restoreAddons: restoreAddons,
|
|
|
|
|
|
|
|
|
|
getEnvironment: getEnvironment,
|
|
|
|
|
getLinksSync: getLinksSync,
|
|
|
|
|
getBindsSync: getBindsSync,
|
2015-11-02 11:20:50 -08:00
|
|
|
getContainerNamesSync: getContainerNamesSync,
|
2015-07-20 00:09:47 -07:00
|
|
|
|
|
|
|
|
// exported for testing
|
2015-10-07 15:55:57 -07:00
|
|
|
_setupOauth: setupOauth,
|
|
|
|
|
_teardownOauth: teardownOauth
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var appdb = require('./appdb.js'),
|
|
|
|
|
assert = require('assert'),
|
|
|
|
|
async = require('async'),
|
2016-06-03 14:56:45 +02:00
|
|
|
clients = require('./clients.js'),
|
2015-07-20 00:09:47 -07:00
|
|
|
config = require('./config.js'),
|
2016-06-13 14:43:56 +02:00
|
|
|
ClientsError = clients.ClientsError,
|
2015-07-20 00:09:47 -07:00
|
|
|
debug = require('debug')('box:addons'),
|
2016-04-18 10:37:33 -07:00
|
|
|
docker = require('./docker.js'),
|
|
|
|
|
dockerConnection = docker.connection,
|
2015-07-20 00:09:47 -07:00
|
|
|
fs = require('fs'),
|
|
|
|
|
generatePassword = require('password-generator'),
|
|
|
|
|
hat = require('hat'),
|
2016-05-24 13:06:59 -07:00
|
|
|
infra = require('./infra_version.js'),
|
2015-07-20 00:09:47 -07:00
|
|
|
once = require('once'),
|
|
|
|
|
path = require('path'),
|
|
|
|
|
paths = require('./paths.js'),
|
|
|
|
|
safe = require('safetydance'),
|
|
|
|
|
shell = require('./shell.js'),
|
2016-06-03 14:56:45 +02:00
|
|
|
util = require('util');
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
var NOOP = function (app, options, callback) { return callback(); };
|
2015-07-20 00:09:47 -07:00
|
|
|
|
|
|
|
|
// setup can be called multiple times for the same app (configure crash restart) and existing data must not be lost
|
|
|
|
|
// teardown is destructive. app data stored with the addon is lost
|
|
|
|
|
var KNOWN_ADDONS = {
|
2016-05-12 08:54:59 -07:00
|
|
|
email: {
|
|
|
|
|
setup: setupEmail,
|
|
|
|
|
teardown: teardownEmail,
|
|
|
|
|
backup: NOOP,
|
2016-05-17 09:27:59 -07:00
|
|
|
restore: setupEmail
|
2016-05-12 08:54:59 -07:00
|
|
|
},
|
2015-07-20 00:09:47 -07:00
|
|
|
ldap: {
|
|
|
|
|
setup: setupLdap,
|
|
|
|
|
teardown: teardownLdap,
|
|
|
|
|
backup: NOOP,
|
|
|
|
|
restore: setupLdap
|
|
|
|
|
},
|
2015-10-18 09:52:37 -07:00
|
|
|
localstorage: {
|
|
|
|
|
setup: NOOP, // docker creates the directory for us
|
|
|
|
|
teardown: NOOP,
|
|
|
|
|
backup: NOOP, // no backup because it's already inside app data
|
|
|
|
|
restore: NOOP
|
|
|
|
|
},
|
|
|
|
|
mongodb: {
|
|
|
|
|
setup: setupMongoDb,
|
|
|
|
|
teardown: teardownMongoDb,
|
|
|
|
|
backup: backupMongoDb,
|
|
|
|
|
restore: restoreMongoDb
|
2015-07-20 00:09:47 -07:00
|
|
|
},
|
|
|
|
|
mysql: {
|
|
|
|
|
setup: setupMySql,
|
|
|
|
|
teardown: teardownMySql,
|
|
|
|
|
backup: backupMySql,
|
|
|
|
|
restore: restoreMySql,
|
|
|
|
|
},
|
2015-10-18 09:52:37 -07:00
|
|
|
oauth: {
|
|
|
|
|
setup: setupOauth,
|
|
|
|
|
teardown: teardownOauth,
|
|
|
|
|
backup: NOOP,
|
|
|
|
|
restore: setupOauth
|
|
|
|
|
},
|
2015-07-20 00:09:47 -07:00
|
|
|
postgresql: {
|
|
|
|
|
setup: setupPostgreSql,
|
|
|
|
|
teardown: teardownPostgreSql,
|
|
|
|
|
backup: backupPostgreSql,
|
|
|
|
|
restore: restorePostgreSql
|
|
|
|
|
},
|
2016-05-13 14:13:25 -07:00
|
|
|
recvmail: {
|
|
|
|
|
setup: setupRecvMail,
|
|
|
|
|
teardown: teardownRecvMail,
|
|
|
|
|
backup: NOOP,
|
2016-05-17 09:27:59 -07:00
|
|
|
restore: setupRecvMail
|
2016-05-13 14:13:25 -07:00
|
|
|
},
|
2015-07-20 00:09:47 -07:00
|
|
|
redis: {
|
|
|
|
|
setup: setupRedis,
|
|
|
|
|
teardown: teardownRedis,
|
2015-10-12 13:29:27 -07:00
|
|
|
backup: backupRedis,
|
2015-07-20 00:09:47 -07:00
|
|
|
restore: setupRedis // same thing
|
|
|
|
|
},
|
2015-10-18 09:52:37 -07:00
|
|
|
sendmail: {
|
|
|
|
|
setup: setupSendMail,
|
|
|
|
|
teardown: teardownSendMail,
|
|
|
|
|
backup: NOOP,
|
|
|
|
|
restore: setupSendMail
|
|
|
|
|
},
|
2015-10-18 08:40:24 -07:00
|
|
|
scheduler: {
|
|
|
|
|
setup: NOOP,
|
|
|
|
|
teardown: NOOP,
|
|
|
|
|
backup: NOOP,
|
|
|
|
|
restore: NOOP
|
|
|
|
|
},
|
2015-10-18 09:52:37 -07:00
|
|
|
simpleauth: {
|
|
|
|
|
setup: setupSimpleAuth,
|
|
|
|
|
teardown: teardownSimpleAuth,
|
|
|
|
|
backup: NOOP,
|
|
|
|
|
restore: setupSimpleAuth
|
2015-07-20 00:09:47 -07:00
|
|
|
},
|
|
|
|
|
_docker: {
|
|
|
|
|
setup: NOOP,
|
|
|
|
|
teardown: NOOP,
|
|
|
|
|
backup: NOOP,
|
|
|
|
|
restore: NOOP
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2016-05-24 09:40:26 -07:00
|
|
|
var RMAPPDIR_CMD = path.join(__dirname, 'scripts/rmappdir.sh');
|
2015-07-20 00:09:47 -07:00
|
|
|
|
|
|
|
|
function debugApp(app, args) {
|
|
|
|
|
assert(!app || typeof app === 'object');
|
|
|
|
|
|
|
|
|
|
var prefix = app ? (app.location || 'naked_domain') : '(no app)';
|
|
|
|
|
debug(prefix + ' ' + util.format.apply(util, Array.prototype.slice.call(arguments, 1)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function setupAddons(app, addons, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert(!addons || typeof addons === 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
if (!addons) return callback(null);
|
|
|
|
|
|
2015-07-20 11:03:11 -07:00
|
|
|
debugApp(app, 'setupAddons: Settings up %j', Object.keys(addons));
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
async.eachSeries(Object.keys(addons), function iterator(addon, iteratorCallback) {
|
|
|
|
|
if (!(addon in KNOWN_ADDONS)) return iteratorCallback(new Error('No such addon:' + addon));
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
debugApp(app, 'Setting up addon %s with options %j', addon, addons[addon]);
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
KNOWN_ADDONS[addon].setup(app, addons[addon], iteratorCallback);
|
2015-07-20 00:09:47 -07:00
|
|
|
}, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function teardownAddons(app, addons, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert(!addons || typeof addons === 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
if (!addons) return callback(null);
|
|
|
|
|
|
2015-07-20 11:03:11 -07:00
|
|
|
debugApp(app, 'teardownAddons: Tearing down %j', Object.keys(addons));
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
async.eachSeries(Object.keys(addons), function iterator(addon, iteratorCallback) {
|
|
|
|
|
if (!(addon in KNOWN_ADDONS)) return iteratorCallback(new Error('No such addon:' + addon));
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
debugApp(app, 'Tearing down addon %s with options %j', addon, addons[addon]);
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
KNOWN_ADDONS[addon].teardown(app, addons[addon], iteratorCallback);
|
2015-07-20 00:09:47 -07:00
|
|
|
}, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function backupAddons(app, addons, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert(!addons || typeof addons === 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'backupAddons');
|
|
|
|
|
|
|
|
|
|
if (!addons) return callback(null);
|
|
|
|
|
|
2015-07-20 11:03:11 -07:00
|
|
|
debugApp(app, 'backupAddons: Backing up %j', Object.keys(addons));
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
async.eachSeries(Object.keys(addons), function iterator (addon, iteratorCallback) {
|
|
|
|
|
if (!(addon in KNOWN_ADDONS)) return iteratorCallback(new Error('No such addon:' + addon));
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
KNOWN_ADDONS[addon].backup(app, addons[addon], iteratorCallback);
|
2015-07-20 00:09:47 -07:00
|
|
|
}, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function restoreAddons(app, addons, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert(!addons || typeof addons === 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'restoreAddons');
|
|
|
|
|
|
|
|
|
|
if (!addons) return callback(null);
|
|
|
|
|
|
2015-07-20 11:03:11 -07:00
|
|
|
debugApp(app, 'restoreAddons: restoring %j', Object.keys(addons));
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
async.eachSeries(Object.keys(addons), function iterator (addon, iteratorCallback) {
|
|
|
|
|
if (!(addon in KNOWN_ADDONS)) return iteratorCallback(new Error('No such addon:' + addon));
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
KNOWN_ADDONS[addon].restore(app, addons[addon], iteratorCallback);
|
2015-07-20 00:09:47 -07:00
|
|
|
}, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getEnvironment(app, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
appdb.getAddonConfigByAppId(app.id, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getLinksSync(app, addons) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert(!addons || typeof addons === 'object');
|
|
|
|
|
|
|
|
|
|
var links = [ ];
|
|
|
|
|
|
|
|
|
|
if (!addons) return links;
|
|
|
|
|
|
2016-05-15 21:18:43 -07:00
|
|
|
var addMail = false;
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
for (var addon in addons) {
|
|
|
|
|
switch (addon) {
|
|
|
|
|
case 'mysql': links.push('mysql:mysql'); break;
|
|
|
|
|
case 'postgresql': links.push('postgresql:postgresql'); break;
|
2016-05-15 21:18:43 -07:00
|
|
|
case 'sendmail': addMail = true; break;
|
|
|
|
|
case 'recvmail': addMail = true; break;
|
|
|
|
|
case 'email': addMail = true; break;
|
2015-07-20 00:09:47 -07:00
|
|
|
case 'redis': links.push('redis-' + app.id + ':redis-' + app.id); break;
|
|
|
|
|
case 'mongodb': links.push('mongodb:mongodb'); break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-15 21:18:43 -07:00
|
|
|
if (addMail) links.push('mail:mail');
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
return links;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getBindsSync(app, addons) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert(!addons || typeof addons === 'object');
|
|
|
|
|
|
|
|
|
|
var binds = [ ];
|
|
|
|
|
|
|
|
|
|
if (!addons) return binds;
|
|
|
|
|
|
|
|
|
|
for (var addon in addons) {
|
|
|
|
|
switch (addon) {
|
|
|
|
|
case '_docker': binds.push('/var/run/docker.sock:/var/run/docker.sock:rw'); break;
|
|
|
|
|
case 'localstorage': binds.push(path.join(paths.DATA_DIR, app.id, 'data') + ':/app/data:rw'); break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return binds;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-02 11:20:50 -08:00
|
|
|
function getContainerNamesSync(app, addons) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert(!addons || typeof addons === 'object');
|
|
|
|
|
|
|
|
|
|
var names = [ ];
|
|
|
|
|
|
|
|
|
|
if (!addons) return names;
|
|
|
|
|
|
|
|
|
|
for (var addon in addons) {
|
|
|
|
|
switch (addon) {
|
|
|
|
|
case 'scheduler':
|
|
|
|
|
// names here depend on how scheduler.js creates containers
|
|
|
|
|
names = names.concat(Object.keys(addons.scheduler).map(function (taskName) { return app.id + '-' + taskName; }));
|
|
|
|
|
break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return names;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function setupOauth(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof app, 'object');
|
2015-10-07 16:10:08 -07:00
|
|
|
assert.strictEqual(typeof options, 'object');
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
var appId = app.id;
|
|
|
|
|
var redirectURI = 'https://' + config.appFqdn(app.location);
|
2015-10-15 12:50:48 +02:00
|
|
|
var scope = 'profile';
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-06-03 15:05:00 +02:00
|
|
|
clients.delByAppIdAndType(appId, clients.TYPE_OAUTH, function (error) { // remove existing creds
|
2016-06-13 14:43:56 +02:00
|
|
|
if (error && error.reason !== ClientsError.NOT_FOUND) return callback(error);
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-06-03 15:11:08 +02:00
|
|
|
clients.add(appId, clients.TYPE_OAUTH, redirectURI, scope, function (error, result) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
var env = [
|
2016-06-03 14:56:45 +02:00
|
|
|
'OAUTH_CLIENT_ID=' + result.id,
|
2016-06-03 15:11:08 +02:00
|
|
|
'OAUTH_CLIENT_SECRET=' + result.clientSecret,
|
2015-07-20 00:09:47 -07:00
|
|
|
'OAUTH_ORIGIN=' + config.adminOrigin()
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Setting oauth addon config to %j', env);
|
|
|
|
|
|
|
|
|
|
appdb.setAddonConfig(appId, 'oauth', env, callback);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function teardownOauth(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof app, 'object');
|
2015-10-07 16:10:08 -07:00
|
|
|
assert.strictEqual(typeof options, 'object');
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2015-10-07 15:55:57 -07:00
|
|
|
debugApp(app, 'teardownOauth');
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-06-03 15:05:00 +02:00
|
|
|
clients.delByAppIdAndType(app.id, clients.TYPE_OAUTH, function (error) {
|
2016-06-13 14:43:56 +02:00
|
|
|
if (error && error.reason !== ClientsError.NOT_FOUND) console.error(error);
|
2015-07-20 00:09:47 -07:00
|
|
|
|
|
|
|
|
appdb.unsetAddonConfig(app.id, 'oauth', callback);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-09 11:44:32 +02:00
|
|
|
function setupSimpleAuth(app, options, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
var appId = app.id;
|
2015-10-15 12:50:48 +02:00
|
|
|
var scope = 'profile';
|
2015-10-09 11:44:32 +02:00
|
|
|
|
2016-06-03 15:05:00 +02:00
|
|
|
clients.delByAppIdAndType(app.id, clients.TYPE_SIMPLE_AUTH, function (error) { // remove existing creds
|
2016-06-13 14:43:56 +02:00
|
|
|
if (error && error.reason !== ClientsError.NOT_FOUND) return callback(error);
|
2015-10-09 11:44:32 +02:00
|
|
|
|
2016-06-03 15:11:08 +02:00
|
|
|
clients.add(appId, clients.TYPE_SIMPLE_AUTH, '', scope, function (error, result) {
|
2015-10-09 11:44:32 +02:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
var env = [
|
2015-11-19 16:32:03 +01:00
|
|
|
'SIMPLE_AUTH_SERVER=172.17.0.1',
|
2015-10-11 13:36:55 +02:00
|
|
|
'SIMPLE_AUTH_PORT=' + config.get('simpleAuthPort'),
|
2015-11-19 16:32:03 +01:00
|
|
|
'SIMPLE_AUTH_URL=http://172.17.0.1:' + config.get('simpleAuthPort'), // obsolete, remove
|
|
|
|
|
'SIMPLE_AUTH_ORIGIN=http://172.17.0.1:' + config.get('simpleAuthPort'),
|
2016-06-03 14:56:45 +02:00
|
|
|
'SIMPLE_AUTH_CLIENT_ID=' + result.id
|
2015-10-09 11:44:32 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Setting simple auth addon config to %j', env);
|
|
|
|
|
|
|
|
|
|
appdb.setAddonConfig(appId, 'simpleauth', env, callback);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function teardownSimpleAuth(app, options, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'teardownSimpleAuth');
|
|
|
|
|
|
2016-06-03 15:05:00 +02:00
|
|
|
clients.delByAppIdAndType(app.id, clients.TYPE_SIMPLE_AUTH, function (error) {
|
2016-06-13 14:43:56 +02:00
|
|
|
if (error && error.reason !== ClientsError.NOT_FOUND) console.error(error);
|
2015-10-09 11:44:32 +02:00
|
|
|
|
|
|
|
|
appdb.unsetAddonConfig(app.id, 'simpleauth', callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-12 08:54:59 -07:00
|
|
|
function setupEmail(app, options, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2016-05-16 12:52:36 -07:00
|
|
|
// note that "external" access info can be derived from MAIL_DOMAIN (since it's part of user documentation)
|
2016-05-12 08:54:59 -07:00
|
|
|
var env = [
|
2016-05-13 08:28:11 -07:00
|
|
|
'MAIL_SMTP_SERVER=mail',
|
2016-05-16 12:52:36 -07:00
|
|
|
'MAIL_SMTP_PORT=2525',
|
2016-05-15 21:18:43 -07:00
|
|
|
'MAIL_IMAP_SERVER=mail',
|
2016-05-13 08:28:11 -07:00
|
|
|
'MAIL_IMAP_PORT=9993',
|
2016-05-17 14:04:57 -07:00
|
|
|
'MAIL_SIEVE_SERVER=mail',
|
|
|
|
|
'MAIL_SIEVE_PORT=4190',
|
2016-05-12 23:34:35 -07:00
|
|
|
'MAIL_DOMAIN=' + config.fqdn()
|
2016-05-12 08:54:59 -07:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Setting up Email');
|
|
|
|
|
|
|
|
|
|
appdb.setAddonConfig(app.id, 'email', env, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function teardownEmail(app, options, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Tearing down Email');
|
|
|
|
|
|
|
|
|
|
appdb.unsetAddonConfig(app.id, 'email', callback);
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function setupLdap(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof app, 'object');
|
2015-10-07 16:10:08 -07:00
|
|
|
assert.strictEqual(typeof options, 'object');
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
var env = [
|
2015-11-19 16:32:03 +01:00
|
|
|
'LDAP_SERVER=172.17.0.1',
|
2015-10-11 13:37:53 +02:00
|
|
|
'LDAP_PORT=' + config.get('ldapPort'),
|
2015-11-19 16:32:03 +01:00
|
|
|
'LDAP_URL=ldap://172.17.0.1:' + config.get('ldapPort'),
|
2015-07-20 00:09:47 -07:00
|
|
|
'LDAP_USERS_BASE_DN=ou=users,dc=cloudron',
|
2015-09-25 21:17:48 -07:00
|
|
|
'LDAP_GROUPS_BASE_DN=ou=groups,dc=cloudron',
|
|
|
|
|
'LDAP_BIND_DN=cn='+ app.id + ',ou=apps,dc=cloudron',
|
|
|
|
|
'LDAP_BIND_PASSWORD=' + hat(256) // this is ignored
|
2015-07-20 00:09:47 -07:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Setting up LDAP');
|
|
|
|
|
|
|
|
|
|
appdb.setAddonConfig(app.id, 'ldap', env, callback);
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function teardownLdap(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof app, 'object');
|
2015-10-07 16:10:08 -07:00
|
|
|
assert.strictEqual(typeof options, 'object');
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Tearing down LDAP');
|
|
|
|
|
|
|
|
|
|
appdb.unsetAddonConfig(app.id, 'ldap', callback);
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function setupSendMail(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof app, 'object');
|
2015-10-07 16:10:08 -07:00
|
|
|
assert.strictEqual(typeof options, 'object');
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2016-05-26 10:57:39 -07:00
|
|
|
var from = (app.location ? app.location : app.manifest.title.replace(/[^a-zA-Z0-9]/, '')) + '.app';
|
2016-01-14 12:56:35 -08:00
|
|
|
|
2016-05-15 21:23:44 -07:00
|
|
|
var cmd = [ '/addons/mail/service.sh', 'add-send', from ];
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-05-15 21:23:44 -07:00
|
|
|
docker.execContainer('mail', cmd, { bufferStdout: true }, function (error, stdout) {
|
|
|
|
|
if (error) return callback(error);
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-05-15 21:23:44 -07:00
|
|
|
var env = stdout.toString('utf8').split('\n').slice(0, -1); // remove trailing newline
|
|
|
|
|
debugApp(app, 'Setting sendmail addon config to %j', env);
|
|
|
|
|
appdb.setAddonConfig(app.id, 'sendmail', env, callback);
|
|
|
|
|
});
|
2015-07-20 00:09:47 -07:00
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function teardownSendMail(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof app, 'object');
|
2015-10-07 16:10:08 -07:00
|
|
|
assert.strictEqual(typeof options, 'object');
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Tearing down sendmail');
|
|
|
|
|
|
2016-05-26 10:57:39 -07:00
|
|
|
var from = (app.location ? app.location : app.manifest.title.replace(/[^a-zA-Z0-9]/, '')) + '.app';
|
2016-05-15 21:23:44 -07:00
|
|
|
|
|
|
|
|
var cmd = [ '/addons/mail/service.sh', 'remove-send', from ];
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Tearing down sendmail');
|
|
|
|
|
|
|
|
|
|
docker.execContainer('mail', cmd, { }, function (error) {
|
|
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
appdb.unsetAddonConfig(app.id, 'sendmail', callback);
|
|
|
|
|
});
|
2015-07-20 00:09:47 -07:00
|
|
|
}
|
|
|
|
|
|
2016-05-13 14:13:25 -07:00
|
|
|
function setupRecvMail(app, options, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Setting up recvmail');
|
|
|
|
|
|
2016-05-26 10:57:39 -07:00
|
|
|
var to = (app.location ? app.location : app.manifest.title.replace(/[^a-zA-Z0-9]/, '')) + '.app';
|
2016-05-13 14:13:25 -07:00
|
|
|
|
2016-05-15 21:23:44 -07:00
|
|
|
var cmd = [ '/addons/mail/service.sh', 'add-recv', to ];
|
2016-05-13 14:13:25 -07:00
|
|
|
|
2016-05-15 21:23:44 -07:00
|
|
|
docker.execContainer('mail', cmd, { bufferStdout: true }, function (error, stdout) {
|
2016-05-13 14:13:25 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
var env = stdout.toString('utf8').split('\n').slice(0, -1); // remove trailing newline
|
|
|
|
|
debugApp(app, 'Setting recvmail addon config to %j', env);
|
|
|
|
|
appdb.setAddonConfig(app.id, 'recvmail', env, callback);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function teardownRecvMail(app, options, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2016-05-26 10:57:39 -07:00
|
|
|
var to = (app.location ? app.location : app.manifest.title.replace(/[^a-zA-Z0-9]/, '')) + '.app';
|
2016-05-13 14:13:25 -07:00
|
|
|
|
2016-05-15 21:23:44 -07:00
|
|
|
var cmd = [ '/addons/mail/service.sh', 'remove-recv', to ];
|
2016-05-13 14:13:25 -07:00
|
|
|
|
|
|
|
|
debugApp(app, 'Tearing down recvmail');
|
|
|
|
|
|
2016-05-15 21:23:44 -07:00
|
|
|
docker.execContainer('mail', cmd, { }, function (error) {
|
2016-05-13 14:13:25 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
appdb.unsetAddonConfig(app.id, 'recvmail', callback);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function setupMySql(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof app, 'object');
|
2015-10-07 16:10:08 -07:00
|
|
|
assert.strictEqual(typeof options, 'object');
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Setting up mysql');
|
|
|
|
|
|
2016-02-02 08:37:48 -08:00
|
|
|
var cmd = [ '/addons/mysql/service.sh', options.multipleDatabases ? 'add-prefix' : 'add', app.id ];
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-04-18 15:02:31 -07:00
|
|
|
docker.execContainer('mysql', cmd, { bufferStdout: true }, function (error, stdout) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
2016-04-18 11:02:02 -07:00
|
|
|
var env = stdout.toString('utf8').split('\n').slice(0, -1); // remove trailing newline
|
|
|
|
|
debugApp(app, 'Setting mysql addon config to %j', env);
|
|
|
|
|
appdb.setAddonConfig(app.id, 'mysql', env, callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function teardownMySql(app, options, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2016-02-02 08:37:48 -08:00
|
|
|
var cmd = [ '/addons/mysql/service.sh', options.multipleDatabases ? 'remove-prefix' : 'remove', app.id ];
|
2015-07-20 00:09:47 -07:00
|
|
|
|
|
|
|
|
debugApp(app, 'Tearing down mysql');
|
|
|
|
|
|
2016-04-18 15:02:31 -07:00
|
|
|
docker.execContainer('mysql', cmd, { }, function (error) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
2016-04-18 11:02:02 -07:00
|
|
|
appdb.unsetAddonConfig(app.id, 'mysql', callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function backupMySql(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
debugApp(app, 'Backing up mysql');
|
|
|
|
|
|
|
|
|
|
callback = once(callback); // ChildProcess exit may or may not be called after error
|
|
|
|
|
|
|
|
|
|
var output = fs.createWriteStream(path.join(paths.DATA_DIR, app.id, 'mysqldump'));
|
|
|
|
|
output.on('error', callback);
|
|
|
|
|
|
2016-04-18 14:50:09 -07:00
|
|
|
var cmd = [ '/addons/mysql/service.sh', options.multipleDatabases ? 'backup-prefix' : 'backup', app.id ];
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-04-18 14:50:09 -07:00
|
|
|
docker.execContainer('mysql', cmd, { stdout: output }, callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function restoreMySql(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
callback = once(callback); // ChildProcess exit may or may not be called after error
|
|
|
|
|
|
2015-10-08 02:08:27 -07:00
|
|
|
setupMySql(app, options, function (error) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'restoreMySql');
|
|
|
|
|
|
|
|
|
|
var input = fs.createReadStream(path.join(paths.DATA_DIR, app.id, 'mysqldump'));
|
|
|
|
|
input.on('error', callback);
|
|
|
|
|
|
2016-04-18 14:50:09 -07:00
|
|
|
var cmd = [ '/addons/mysql/service.sh', options.multipleDatabases ? 'restore-prefix' : 'restore', app.id ];
|
|
|
|
|
docker.execContainer('mysql', cmd, { stdin: input }, callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function setupPostgreSql(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof app, 'object');
|
2015-10-07 16:10:08 -07:00
|
|
|
assert.strictEqual(typeof options, 'object');
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Setting up postgresql');
|
|
|
|
|
|
|
|
|
|
var cmd = [ '/addons/postgresql/service.sh', 'add', app.id ];
|
|
|
|
|
|
2016-04-18 15:02:31 -07:00
|
|
|
docker.execContainer('postgresql', cmd, { bufferStdout: true }, function (error, stdout) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
2016-04-18 11:15:21 -07:00
|
|
|
var env = stdout.toString('utf8').split('\n').slice(0, -1); // remove trailing newline
|
|
|
|
|
debugApp(app, 'Setting postgresql addon config to %j', env);
|
|
|
|
|
appdb.setAddonConfig(app.id, 'postgresql', env, callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function teardownPostgreSql(app, options, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
var cmd = [ '/addons/postgresql/service.sh', 'remove', app.id ];
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Tearing down postgresql');
|
|
|
|
|
|
2016-04-18 15:02:31 -07:00
|
|
|
docker.execContainer('postgresql', cmd, { }, function (error) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
2016-04-18 11:22:23 -07:00
|
|
|
appdb.unsetAddonConfig(app.id, 'postgresql', callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function backupPostgreSql(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
debugApp(app, 'Backing up postgresql');
|
|
|
|
|
|
|
|
|
|
callback = once(callback); // ChildProcess exit may or may not be called after error
|
|
|
|
|
|
|
|
|
|
var output = fs.createWriteStream(path.join(paths.DATA_DIR, app.id, 'postgresqldump'));
|
|
|
|
|
output.on('error', callback);
|
|
|
|
|
|
2016-04-18 14:50:09 -07:00
|
|
|
var cmd = [ '/addons/postgresql/service.sh', 'backup', app.id ];
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-04-18 14:50:09 -07:00
|
|
|
docker.execContainer('postgresql', cmd, { stdout: output }, callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function restorePostgreSql(app, options, callback) {
|
2016-04-18 14:50:09 -07:00
|
|
|
callback = once(callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2015-10-08 02:08:27 -07:00
|
|
|
setupPostgreSql(app, options, function (error) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'restorePostgreSql');
|
|
|
|
|
|
|
|
|
|
var input = fs.createReadStream(path.join(paths.DATA_DIR, app.id, 'postgresqldump'));
|
|
|
|
|
input.on('error', callback);
|
|
|
|
|
|
2016-04-18 14:50:09 -07:00
|
|
|
var cmd = [ '/addons/postgresql/service.sh', 'restore', app.id ];
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-04-18 14:50:09 -07:00
|
|
|
docker.execContainer('postgresql', cmd, { stdin: input }, callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function setupMongoDb(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof app, 'object');
|
2015-10-07 16:10:08 -07:00
|
|
|
assert.strictEqual(typeof options, 'object');
|
2015-07-20 00:09:47 -07:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Setting up mongodb');
|
|
|
|
|
|
|
|
|
|
var cmd = [ '/addons/mongodb/service.sh', 'add', app.id ];
|
|
|
|
|
|
2016-04-18 18:05:23 -07:00
|
|
|
docker.execContainer('mongodb', cmd, { bufferStdout: true }, function (error, stdout) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
2016-04-18 18:05:23 -07:00
|
|
|
var env = stdout.toString('utf8').split('\n').slice(0, -1); // remove trailing newline
|
|
|
|
|
debugApp(app, 'Setting mongodb addon config to %j', env);
|
|
|
|
|
appdb.setAddonConfig(app.id, 'mongodb', env, callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function teardownMongoDb(app, options, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
var cmd = [ '/addons/mongodb/service.sh', 'remove', app.id ];
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'Tearing down mongodb');
|
|
|
|
|
|
2016-04-18 15:02:31 -07:00
|
|
|
docker.execContainer('mongodb', cmd, { }, function (error) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
2016-04-18 11:29:11 -07:00
|
|
|
appdb.unsetAddonConfig(app.id, 'mongodb', callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function backupMongoDb(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
debugApp(app, 'Backing up mongodb');
|
|
|
|
|
|
|
|
|
|
callback = once(callback); // ChildProcess exit may or may not be called after error
|
|
|
|
|
|
|
|
|
|
var output = fs.createWriteStream(path.join(paths.DATA_DIR, app.id, 'mongodbdump'));
|
|
|
|
|
output.on('error', callback);
|
|
|
|
|
|
2016-04-18 14:50:09 -07:00
|
|
|
var cmd = [ '/addons/mongodb/service.sh', 'backup', app.id ];
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-04-18 14:50:09 -07:00
|
|
|
docker.execContainer('mongodb', cmd, { stdout: output }, callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function restoreMongoDb(app, options, callback) {
|
2015-07-20 00:09:47 -07:00
|
|
|
callback = once(callback); // ChildProcess exit may or may not be called after error
|
|
|
|
|
|
2015-10-08 02:08:27 -07:00
|
|
|
setupMongoDb(app, options, function (error) {
|
2015-07-20 00:09:47 -07:00
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
debugApp(app, 'restoreMongoDb');
|
|
|
|
|
|
|
|
|
|
var input = fs.createReadStream(path.join(paths.DATA_DIR, app.id, 'mongodbdump'));
|
|
|
|
|
input.on('error', callback);
|
|
|
|
|
|
2016-04-18 14:50:09 -07:00
|
|
|
var cmd = [ '/addons/mongodb/service.sh', 'restore', app.id ];
|
2016-04-18 18:57:29 -07:00
|
|
|
docker.execContainer('mongodb', cmd, { stdin: input }, callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ensures that app's addon redis container is running. Can be called when named container already exists/running
|
2015-10-07 16:10:08 -07:00
|
|
|
function setupRedis(app, options, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2016-01-13 19:08:04 -08:00
|
|
|
var redisPassword = generatePassword(64, false /* memorable */, /[\w\d_]/); // ensure no / in password for being sed friendly (and be uri friendly)
|
2015-07-20 00:09:47 -07:00
|
|
|
var redisVarsFile = path.join(paths.ADDON_CONFIG_DIR, 'redis-' + app.id + '_vars.sh');
|
|
|
|
|
var redisDataDir = path.join(paths.DATA_DIR, app.id + '/redis');
|
|
|
|
|
|
|
|
|
|
if (!safe.fs.writeFileSync(redisVarsFile, 'REDIS_PASSWORD=' + redisPassword)) {
|
|
|
|
|
return callback(new Error('Error writing redis config'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!safe.fs.mkdirSync(redisDataDir) && safe.error.code !== 'EEXIST') return callback(new Error('Error creating redis data dir:' + safe.error));
|
|
|
|
|
|
|
|
|
|
var createOptions = {
|
|
|
|
|
name: 'redis-' + app.id,
|
2015-10-23 19:24:22 -07:00
|
|
|
Hostname: 'redis-' + app.location,
|
2015-07-20 00:09:47 -07:00
|
|
|
Tty: true,
|
2016-05-24 13:06:59 -07:00
|
|
|
Image: infra.images.redis.tag,
|
2015-07-20 00:09:47 -07:00
|
|
|
Cmd: null,
|
2015-10-08 08:46:19 -07:00
|
|
|
Volumes: {
|
|
|
|
|
'/tmp': {},
|
2015-10-15 11:00:39 -07:00
|
|
|
'/run': {}
|
2015-10-08 08:46:19 -07:00
|
|
|
},
|
2015-10-19 21:35:02 -07:00
|
|
|
VolumesFrom: [],
|
|
|
|
|
HostConfig: {
|
|
|
|
|
Binds: [
|
|
|
|
|
redisVarsFile + ':/etc/redis/redis_vars.sh:ro',
|
|
|
|
|
redisDataDir + ':/var/lib/redis:rw'
|
|
|
|
|
],
|
|
|
|
|
Memory: 1024 * 1024 * 75, // 100mb
|
|
|
|
|
MemorySwap: 1024 * 1024 * 75 * 2, // 150mb
|
|
|
|
|
PortBindings: {
|
|
|
|
|
'6379/tcp': [{ HostPort: '0', HostIp: '127.0.0.1' }]
|
|
|
|
|
},
|
|
|
|
|
ReadonlyRootfs: true,
|
|
|
|
|
RestartPolicy: {
|
|
|
|
|
'Name': 'always',
|
|
|
|
|
'MaximumRetryCount': 0
|
|
|
|
|
}
|
2015-07-20 00:09:47 -07:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var env = [
|
|
|
|
|
'REDIS_URL=redis://redisuser:' + redisPassword + '@redis-' + app.id,
|
|
|
|
|
'REDIS_PASSWORD=' + redisPassword,
|
|
|
|
|
'REDIS_HOST=redis-' + app.id,
|
|
|
|
|
'REDIS_PORT=6379'
|
|
|
|
|
];
|
|
|
|
|
|
2016-04-18 10:37:33 -07:00
|
|
|
var redisContainer = dockerConnection.getContainer(createOptions.name);
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-06-16 15:41:50 -05:00
|
|
|
try {
|
|
|
|
|
shell.execSync('stopRedis', 'docker stop --time=10 ' + createOptions.name + ' 2>/dev/null || true');
|
|
|
|
|
shell.execSync('stopRedis', 'docker rm --volumes ' + createOptions.name + ' 2>/dev/null || true');
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log('IGNORE EXCEPTIOn', e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dockerConnection.createContainer(createOptions, function (error) {
|
|
|
|
|
if (error && error.statusCode !== 409) return callback(error); // if not already created
|
|
|
|
|
|
|
|
|
|
redisContainer.start(function (error) {
|
|
|
|
|
if (error && error.statusCode !== 304) return callback(error); // if not already running
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2016-06-16 17:24:38 -05:00
|
|
|
appdb.setAddonConfig(app.id, 'redis', env, callback);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 16:10:08 -07:00
|
|
|
function teardownRedis(app, options, callback) {
|
|
|
|
|
assert.strictEqual(typeof app, 'object');
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2016-04-18 10:37:33 -07:00
|
|
|
var container = dockerConnection.getContainer('redis-' + app.id);
|
2015-07-20 00:09:47 -07:00
|
|
|
|
|
|
|
|
var removeOptions = {
|
|
|
|
|
force: true, // kill container if it's running
|
2015-10-11 11:37:05 -07:00
|
|
|
v: true // removes volumes associated with the container
|
2015-07-20 00:09:47 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
container.remove(removeOptions, function (error) {
|
|
|
|
|
if (error && error.statusCode !== 404) return callback(new Error('Error removing container:' + error));
|
|
|
|
|
|
|
|
|
|
safe.fs.unlinkSync(paths.ADDON_CONFIG_DIR, 'redis-' + app.id + '_vars.sh');
|
|
|
|
|
|
|
|
|
|
shell.sudo('teardownRedis', [ RMAPPDIR_CMD, app.id + '/redis' ], function (error, stdout, stderr) {
|
|
|
|
|
if (error) return callback(new Error('Error removing redis data:' + error));
|
|
|
|
|
|
|
|
|
|
appdb.unsetAddonConfig(app.id, 'redis', callback);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
2015-10-12 13:29:27 -07:00
|
|
|
|
|
|
|
|
function backupRedis(app, options, callback) {
|
|
|
|
|
debugApp(app, 'Backing up redis');
|
|
|
|
|
|
2016-04-18 14:50:09 -07:00
|
|
|
var cmd = [ '/addons/redis/service.sh', 'backup' ]; // the redis dir is volume mounted
|
2015-10-12 13:29:27 -07:00
|
|
|
|
2016-04-18 15:02:31 -07:00
|
|
|
docker.execContainer('redis-' + app.id, cmd, { }, callback);
|
2015-10-12 13:29:27 -07:00
|
|
|
}
|