From 0cf5bf26a0c5be69fcd82c9791862209b5e0bce8 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Tue, 18 Oct 2022 19:43:19 +0100 Subject: [PATCH] Finishing import processor - download backup, delete dev DB and then import over the top of this. Also includes a rollback feature if the backup fails to restore for whatever reason. --- packages/server/src/sdk/app/backups/backup.ts | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/server/src/sdk/app/backups/backup.ts b/packages/server/src/sdk/app/backups/backup.ts index 92f70a5a84..cc2338e274 100644 --- a/packages/server/src/sdk/app/backups/backup.ts +++ b/packages/server/src/sdk/app/backups/backup.ts @@ -1,17 +1,48 @@ import { backups } from "@budibase/pro" -import { objectStore, tenancy } from "@budibase/backend-core" +import { objectStore, tenancy, db as dbCore } from "@budibase/backend-core" import { AppBackupQueueData } from "@budibase/types" import { exportApp } from "./exports" +import { importApp } from "./imports" import { Job } from "bull" import fs from "fs" import env from "../../../environment" +async function removeExistingApp(devId: string) { + const devDb = dbCore.dangerousGetDB(devId, { skip_setup: true }) + await devDb.destroy() +} + async function importProcessor(job: Job) { const data: AppBackupQueueData = job.data const appId = data.appId, backupId = data.import!.backupId - const { path, metadata } = await backups.downloadAppBackup(backupId) - // start by removing app database and contents of bucket - which will be updated + const tenantId = tenancy.getTenantIDFromAppID(appId) + tenancy.doInTenant(tenantId, async () => { + const devAppId = dbCore.getDevAppID(appId) + const performImport = async (path: string) => { + await importApp(devAppId, dbCore.dangerousGetDB(devAppId), { + file: { + type: "application/gzip", + path, + }, + key: path, + }) + } + // initially export the current state to disk - incase something goes wrong + const backupTarPath = await exportApp(devAppId, { tar: true }) + // get the backup ready on disk + const { path } = await backups.downloadAppBackup(backupId) + // start by removing app database and contents of bucket - which will be updated + await removeExistingApp(devAppId) + try { + await performImport(path) + } catch (err) { + // rollback - clear up failed import and re-import the pre-backup + await removeExistingApp(devAppId) + await performImport(backupTarPath) + } + fs.rmSync(backupTarPath) + }) } async function exportProcessor(job: Job) {