clone: save app config
clone also clones the tags, labels and icon. this is not done for restore or import since it's not clear if this is a good idea or not. for example, if user had some custom tags and label set and then restores to some old backup, is it expected to reset the labels and tags?
This commit is contained in:
98
src/apps.js
98
src/apps.js
@@ -70,6 +70,8 @@ exports = module.exports = {
|
||||
downloadFile,
|
||||
uploadFile,
|
||||
|
||||
backupConfig,
|
||||
|
||||
PORT_TYPE_TCP: 'tcp',
|
||||
PORT_TYPE_UDP: 'udp',
|
||||
|
||||
@@ -856,7 +858,7 @@ function setAccessRestriction(app, accessRestriction, auditSource, callback) {
|
||||
let error = validateAccessRestriction(accessRestriction);
|
||||
if (error) return callback(error);
|
||||
|
||||
appdb.update(appId, { accessRestriction: accessRestriction }, function (error) {
|
||||
appdb.update(appId, { accessRestriction }, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId, app, accessRestriction });
|
||||
@@ -875,7 +877,7 @@ function setLabel(app, label, auditSource, callback) {
|
||||
let error = validateLabel(label);
|
||||
if (error) return callback(error);
|
||||
|
||||
appdb.update(appId, { label: label }, function (error) {
|
||||
appdb.update(appId, { label }, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId, app, label });
|
||||
@@ -894,7 +896,7 @@ function setTags(app, tags, auditSource, callback) {
|
||||
let error = validateTags(tags);
|
||||
if (error) return callback(error);
|
||||
|
||||
appdb.update(appId, { tags: tags }, function (error) {
|
||||
appdb.update(appId, { tags }, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId, app, tags });
|
||||
@@ -1632,7 +1634,7 @@ function clone(app, data, user, auditSource, callback) {
|
||||
assert.strictEqual(typeof auditSource, 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
var location = data.location.toLowerCase(),
|
||||
const location = data.location.toLowerCase(),
|
||||
domain = data.domain.toLowerCase(),
|
||||
portBindings = data.portBindings || null,
|
||||
backupId = data.backupId,
|
||||
@@ -1670,46 +1672,55 @@ function clone(app, data, user, auditSource, callback) {
|
||||
|
||||
const newAppId = uuid.v4();
|
||||
|
||||
const data = {
|
||||
installationState: exports.ISTATE_PENDING_CLONE,
|
||||
runState: exports.RSTATE_RUNNING,
|
||||
memoryLimit: app.memoryLimit,
|
||||
accessRestriction: app.accessRestriction,
|
||||
sso: !!app.sso,
|
||||
mailboxName: mailboxName,
|
||||
mailboxDomain: mailboxDomain,
|
||||
enableBackup: app.enableBackup,
|
||||
reverseProxyConfig: app.reverseProxyConfig,
|
||||
env: app.env,
|
||||
alternateDomains: [],
|
||||
aliasDomains: [],
|
||||
servicesConfig: app.servicesConfig
|
||||
};
|
||||
|
||||
appdb.add(newAppId, appStoreId, manifest, location, domain, translatePortBindings(portBindings, manifest), data, function (error) {
|
||||
if (error && error.reason === BoxError.ALREADY_EXISTS) return callback(getDuplicateErrorDetails(error.message, locations, domainObjectMap, portBindings));
|
||||
appdb.getIcons(app.id, function (error, icons) {
|
||||
if (error) return callback(error);
|
||||
|
||||
purchaseApp({ appId: newAppId, appstoreId: app.appStoreId, manifestId: manifest.id || 'customapp' }, function (error) {
|
||||
const data = {
|
||||
installationState: exports.ISTATE_PENDING_CLONE,
|
||||
runState: exports.RSTATE_RUNNING,
|
||||
memoryLimit: app.memoryLimit,
|
||||
cpuShares: app.cpuShares,
|
||||
accessRestriction: app.accessRestriction,
|
||||
sso: !!app.sso,
|
||||
mailboxName: mailboxName,
|
||||
mailboxDomain: mailboxDomain,
|
||||
enableBackup: app.enableBackup,
|
||||
reverseProxyConfig: app.reverseProxyConfig,
|
||||
env: app.env,
|
||||
alternateDomains: [],
|
||||
aliasDomains: [],
|
||||
servicesConfig: app.servicesConfig,
|
||||
label: app.label ? `${app.label}-clone` : '',
|
||||
tags: app.tags,
|
||||
enableAutomaticUpdate: app.enableAutomaticUpdate,
|
||||
icons: icons.icon
|
||||
};
|
||||
|
||||
appdb.add(newAppId, appStoreId, manifest, location, domain, translatePortBindings(portBindings, manifest), data, function (error) {
|
||||
if (error && error.reason === BoxError.ALREADY_EXISTS) return callback(getDuplicateErrorDetails(error.message, locations, domainObjectMap, portBindings));
|
||||
if (error) return callback(error);
|
||||
|
||||
const restoreConfig = { backupId: backupId, backupFormat: backupInfo.format };
|
||||
const task = {
|
||||
args: { restoreConfig, overwriteDns, skipDnsSetup, oldManifest: null },
|
||||
values: {},
|
||||
requiredState: exports.ISTATE_PENDING_CLONE
|
||||
};
|
||||
addTask(newAppId, exports.ISTATE_PENDING_CLONE, task, function (error, result) {
|
||||
purchaseApp({ appId: newAppId, appstoreId: app.appStoreId, manifestId: manifest.id || 'customapp' }, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
const newApp = _.extend({}, data, { appStoreId, manifest, location, domain, portBindings });
|
||||
newApp.fqdn = domains.fqdn(newApp.location, domainObjectMap[newApp.domain]);
|
||||
newApp.alternateDomains.forEach(function (ad) { ad.fqdn = domains.fqdn(ad.subdomain, domainObjectMap[ad.domain]); });
|
||||
newApp.aliasDomains.forEach(function (ad) { ad.fqdn = domains.fqdn(ad.subdomain, domainObjectMap[ad.domain]); });
|
||||
const restoreConfig = { backupId: backupId, backupFormat: backupInfo.format };
|
||||
const task = {
|
||||
args: { restoreConfig, overwriteDns, skipDnsSetup, oldManifest: null },
|
||||
values: {},
|
||||
requiredState: exports.ISTATE_PENDING_CLONE
|
||||
};
|
||||
addTask(newAppId, exports.ISTATE_PENDING_CLONE, task, function (error, result) {
|
||||
if (error) return callback(error);
|
||||
|
||||
eventlog.add(eventlog.ACTION_APP_CLONE, auditSource, { appId: newAppId, oldAppId: appId, backupId: backupId, oldApp: app, newApp: newApp, taskId: result.taskId });
|
||||
const newApp = _.extend({}, data, { appStoreId, manifest, location, domain, portBindings });
|
||||
newApp.fqdn = domains.fqdn(newApp.location, domainObjectMap[newApp.domain]);
|
||||
newApp.alternateDomains.forEach(function (ad) { ad.fqdn = domains.fqdn(ad.subdomain, domainObjectMap[ad.domain]); });
|
||||
newApp.aliasDomains.forEach(function (ad) { ad.fqdn = domains.fqdn(ad.subdomain, domainObjectMap[ad.domain]); });
|
||||
|
||||
callback(null, { id: newAppId, taskId: result.taskId });
|
||||
eventlog.add(eventlog.ACTION_APP_CLONE, auditSource, { appId: newAppId, oldAppId: appId, backupId: backupId, oldApp: app, newApp: newApp, taskId: result.taskId });
|
||||
|
||||
callback(null, { id: newAppId, taskId: result.taskId });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -2189,3 +2200,18 @@ function uploadFile(app, sourceFilePath, destFilePath, callback) {
|
||||
readFile.pipe(stream);
|
||||
});
|
||||
}
|
||||
|
||||
function backupConfig(app, callback) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
if (!safe.fs.writeFileSync(path.join(paths.APPS_DATA_DIR, app.id + '/config.json'), JSON.stringify(app))) {
|
||||
return callback(new BoxError(BoxError.FS_ERROR, 'Error creating config.json: ' + safe.error.message));
|
||||
}
|
||||
|
||||
appdb.getIcons(app.id, function (error, icons) {
|
||||
if (!error && icons.icon) safe.fs.writeFileSync(path.join(paths.APPS_DATA_DIR, app.id + '/icon.png'), icons.icon);
|
||||
|
||||
callback(null);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user