Allow installing from a backup

This commit is contained in:
Girish Ramakrishnan
2017-04-11 12:49:21 -07:00
parent aa0e820605
commit a01dea3932
4 changed files with 21 additions and 3 deletions
+3
View File
@@ -117,6 +117,7 @@ Request:
cert: <string>, // pem encoded TLS cert
key: <string>, // pem encoded TLS key
memoryLimit: <number>, // memory constraint in bytes
backupId: <string>, // initialize the app from this backup
altDomain: <string>, // alternate domain from which this app can be reached
xFrameOptions: <string> // set X-Frame-Options header, to control which websites can embed this app
}
@@ -153,6 +154,8 @@ If `altDomain` is set, the app can be accessed from `https://<altDomain>`.
`memoryLimit` is the maximum memory this app can use (in bytes) including swap. If set to 0, the app uses the `memoryLimit` value set in the manifest. If set to -1, the app gets unlimited memory.
If `backupId` is provided the app will be initialized with the data from the backup.
Read more about the options at [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options).
Response (200):
+5 -3
View File
@@ -494,7 +494,8 @@ function install(data, auditSource, callback) {
altDomain = data.altDomain || null,
xFrameOptions = data.xFrameOptions || 'SAMEORIGIN',
sso = 'sso' in data ? data.sso : null,
debugMode = data.debugMode || null;
debugMode = data.debugMode || null,
backupId = data.backupId || null;
assert(data.appStoreId || data.manifest); // atleast one of them is required
@@ -556,7 +557,8 @@ function install(data, auditSource, callback) {
xFrameOptions: xFrameOptions,
sso: sso,
debugMode: debugMode,
mailboxName: (location ? location : manifest.title.toLowerCase().replace(/[^a-zA-Z0-9]/g, '')) + '.app'
mailboxName: (location ? location : manifest.title.toLowerCase().replace(/[^a-zA-Z0-9]/g, '')) + '.app',
lastBackupId: backupId
};
appdb.add(appId, appStoreId, manifest, location, portBindings, data, function (error) {
@@ -571,7 +573,7 @@ function install(data, auditSource, callback) {
taskmanager.restartAppTask(appId);
eventlog.add(eventlog.ACTION_APP_INSTALL, auditSource, { appId: appId, location: location, manifest: manifest });
eventlog.add(eventlog.ACTION_APP_INSTALL, auditSource, { appId: appId, location: location, manifest: manifest, backupId: backupId });
callback(null, { id : appId });
});
+11
View File
@@ -343,6 +343,8 @@ function install(app, callback) {
assert.strictEqual(typeof app, 'object');
assert.strictEqual(typeof callback, 'function');
var backupId = app.lastBackupId;
async.series([
verifyManifest.bind(null, app),
@@ -373,6 +375,15 @@ function install(app, callback) {
updateApp.bind(null, app, { installationProgress: '60, Setting up addons' }),
addons.setupAddons.bind(null, app, app.manifest.addons),
function restoreFromBackup(next) {
if (!backupId) return next();
async.series([
updateApp.bind(null, app, { installationProgress: '65, Download backup and restore addons' }),
backups.restoreApp.bind(null, app, app.manifest.addons, backupId),
], next);
},
updateApp.bind(null, app, { installationProgress: '70, Creating container' }),
createContainer.bind(null, app),
+2
View File
@@ -113,6 +113,8 @@ function installApp(req, res, next) {
if (('portBindings' in data) && typeof data.portBindings !== 'object') return next(new HttpError(400, 'portBindings must be an object'));
if ('icon' in data && typeof data.icon !== 'string') return next(new HttpError(400, 'icon is not a string'));
if (data.backupId && typeof data.backupId !== 'string') return next(new HttpError(400, 'backupId must be string or null'));
// falsy values in cert and key unset the cert
if (data.key && typeof data.cert !== 'string') return next(new HttpError(400, 'cert must be a string'));
if (data.cert && typeof data.key !== 'string') return next(new HttpError(400, 'key must be a string'));