backups: fix restore code path after backup id changes

This commit is contained in:
Girish Ramakrishnan
2022-04-05 09:28:30 -07:00
parent b4b999bd74
commit 709d4041b2
7 changed files with 38 additions and 34 deletions

View File

@@ -1113,10 +1113,12 @@ async function onTaskFinished(error, appId, installationState, taskId, auditSour
await eventlog.add(eventlog.ACTION_APP_UPDATE_FINISH, auditSource, { app, toManifest, fromManifest, success, errorMessage });
break;
}
case exports.ISTATE_PENDING_BACKUP:
await eventlog.add(eventlog.ACTION_APP_BACKUP_FINISH, auditSource, { app, success, errorMessage, backupId: task.result });
case exports.ISTATE_PENDING_BACKUP: {
const backup = await backups.get(task.result);
await eventlog.add(eventlog.ACTION_APP_BACKUP_FINISH, auditSource, { app, success, errorMessage, remotePath: backup?.remotePath, backupId: task.result });
break;
}
}
}
async function scheduleTask(appId, installationState, taskId, auditSource) {
@@ -2023,7 +2025,7 @@ async function restore(app, backupId, auditSource) {
values.mailboxDomain = app.domain;
}
const restoreConfig = { backupId, backupFormat: backupInfo.format };
const restoreConfig = { remotePath: backupInfo.remotePath, backupFormat: backupInfo.format };
const task = {
args: {
@@ -2037,7 +2039,7 @@ async function restore(app, backupId, auditSource) {
const taskId = await addTask(appId, exports.ISTATE_PENDING_RESTORE, task, auditSource);
await eventlog.add(eventlog.ACTION_APP_RESTORE, auditSource, { app: app, backupId: backupInfo.id, fromManifest: app.manifest, toManifest: backupInfo.manifest, taskId });
await eventlog.add(eventlog.ACTION_APP_RESTORE, auditSource, { app, backupId: backupInfo.id, remotePath: backupInfo.remotePath, fromManifest: app.manifest, toManifest: backupInfo.manifest, taskId });
return { taskId };
}
@@ -2050,10 +2052,10 @@ async function importApp(app, data, auditSource) {
const appId = app.id;
// all fields are optional
data.backupId = data.backupId || null;
data.remotePath = data.remotePath || null;
data.backupFormat = data.backupFormat || null;
data.backupConfig = data.backupConfig || null;
const { backupId, backupFormat, backupConfig } = data;
const { remotePath, backupFormat, backupConfig } = data;
let error = backupFormat ? validateBackupFormat(backupFormat) : null;
if (error) throw error;
@@ -2089,7 +2091,7 @@ async function importApp(app, data, auditSource) {
}
}
const restoreConfig = { backupId, backupFormat, backupConfig };
const restoreConfig = { remotePath, backupFormat, backupConfig };
const task = {
args: {
@@ -2102,7 +2104,7 @@ async function importApp(app, data, auditSource) {
};
const taskId = await addTask(appId, exports.ISTATE_PENDING_IMPORT, task, auditSource);
await eventlog.add(eventlog.ACTION_APP_IMPORT, auditSource, { app: app, backupId, fromManifest: app.manifest, toManifest: app.manifest, taskId });
await eventlog.add(eventlog.ACTION_APP_IMPORT, auditSource, { app: app, remotePath, fromManifest: app.manifest, toManifest: app.manifest, taskId });
return { taskId };
}
@@ -2158,6 +2160,7 @@ async function clone(app, data, user, auditSource) {
const backupInfo = await backups.get(backupId);
if (!backupInfo) throw new BoxError(BoxError.NOT_FOUND, 'Backup not found');
if (!backupInfo.manifest) throw new BoxError(BoxError.EXTERNAL_ERROR, 'Could not get restore config');
if (backupInfo.encryptionVersion === 1) throw new BoxError(BoxError.BAD_FIELD, 'This encrypted backup was created with an older Cloudron version and cannot be cloned');
@@ -2216,7 +2219,7 @@ async function clone(app, data, user, auditSource) {
await purchaseApp({ appId: newAppId, appstoreId: app.appStoreId, manifestId: manifest.id || 'customapp' });
const restoreConfig = { backupId, backupFormat: backupInfo.format };
const restoreConfig = { remotePath: backup.remotePath, backupFormat: backupInfo.format };
const task = {
args: { restoreConfig, overwriteDns, skipDnsSetup, oldManifest: null },
values: {},
@@ -2230,7 +2233,7 @@ async function clone(app, data, user, auditSource) {
newApp.redirectDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, domainObjectMap[ad.domain]); });
newApp.aliasDomains.forEach(function (ad) { ad.fqdn = dns.fqdn(ad.subdomain, domainObjectMap[ad.domain]); });
await eventlog.add(eventlog.ACTION_APP_CLONE, auditSource, { appId: newAppId, oldAppId: appId, backupId, oldApp: app, newApp, taskId });
await eventlog.add(eventlog.ACTION_APP_CLONE, auditSource, { appId: newAppId, oldAppId: appId, backupId, remotePath: backupInfo.remotePath, oldApp: app, newApp, taskId });
return { id: newAppId, taskId };
}
@@ -2474,11 +2477,11 @@ async function restoreInstalledApps(options, auditSource) {
apps = apps.filter(app => app.installationState !== exports.ISTATE_PENDING_RESTORE); // safeguard against tasks being created non-stop if we crash on startup
for (const app of apps) {
const [error, results] = await safe(backups.getByIdentifierAndStatePaged(app.id, backups.BACKUP_STATE_NORMAL, 1, 1));
const [error, backups] = await safe(backups.getByIdentifierAndStatePaged(app.id, backups.BACKUP_STATE_NORMAL, 1, 1));
let installationState, restoreConfig, oldManifest;
if (!error && results.length) {
if (!error && backups.length) {
installationState = exports.ISTATE_PENDING_RESTORE;
restoreConfig = { backupId: results[0].id, backupFormat: results[0].format };
restoreConfig = { remotePath: backups[0].remotePath, backupFormat: backups[0].format };
oldManifest = app.manifest;
} else {
installationState = exports.ISTATE_PENDING_INSTALL;