Some fixes + cleanup of tmp directory.

This commit is contained in:
mike12345567 2022-10-11 19:28:13 +01:00
parent a41b362040
commit 2f5170f70c
3 changed files with 33 additions and 13 deletions

View File

@ -263,6 +263,7 @@ export const retrieveToTmp = async (bucketName: string, filepath: string) => {
export const retrieveDirectory = async (bucketName: string, path: string) => { export const retrieveDirectory = async (bucketName: string, path: string) => {
let writePath = join(budibaseTempDir(), v4()) let writePath = join(budibaseTempDir(), v4())
fs.mkdirSync(writePath)
const objects = await listAllObjects(bucketName, path) const objects = await listAllObjects(bucketName, path)
let fullObjects = await Promise.all( let fullObjects = await Promise.all(
objects.map(obj => retrieve(bucketName, obj.Key!)) objects.map(obj => retrieve(bucketName, obj.Key!))

View File

@ -7,7 +7,7 @@ export async function exportAppDump(ctx: any) {
let { appId, excludeRows } = ctx.query let { appId, excludeRows } = ctx.query
const appName = decodeURI(ctx.query.appname) const appName = decodeURI(ctx.query.appname)
excludeRows = isQsTrue(excludeRows) excludeRows = isQsTrue(excludeRows)
const backupIdentifier = `${appName}-export-${new Date().getTime()}.txt` const backupIdentifier = `${appName}-export-${new Date().getTime()}.tar.gz`
ctx.attachment(backupIdentifier) ctx.attachment(backupIdentifier)
ctx.body = await sdk.apps.exports.streamExportApp(appId, excludeRows) ctx.body = await sdk.apps.exports.streamExportApp(appId, excludeRows)

View File

@ -23,19 +23,19 @@ type ExportOpts = {
excludeRows?: boolean excludeRows?: boolean
} }
function tarFiles(cwd: string, files: string[], exportName?: string) { function tarFilesToTmp(tmpDir: string, files: string[]) {
exportName = exportName ? `${exportName}.tar.gz` : "export.tar.gz" const exportFile = join(budibaseTempDir(), `${uuid()}.tar.gz`)
tar.create( tar.create(
{ {
sync: true, sync: true,
gzip: true, gzip: true,
file: exportName, file: exportFile,
recursive: true, recursive: true,
cwd, cwd: tmpDir,
}, },
files files
) )
return join(cwd, exportName) return exportFile
} }
/** /**
@ -52,7 +52,7 @@ export async function exportDB(dbName: string, opts: ExportOpts = {}) {
const path = opts?.exportPath const path = opts?.exportPath
const writeStream = fs.createWriteStream(path) const writeStream = fs.createWriteStream(path)
await db.dump(writeStream, { filter: opts?.filter }) await db.dump(writeStream, { filter: opts?.filter })
return fs.createReadStream(path) return path
} else { } else {
// Stringify the dump in memory if required // Stringify the dump in memory if required
const memStream = new MemoryStream() const memStream = new MemoryStream()
@ -90,10 +90,16 @@ export async function exportApp(appId: string, config?: ExportOpts) {
ObjectStoreBuckets.APPS, ObjectStoreBuckets.APPS,
attachmentsPath attachmentsPath
) )
// move out of app directory, simplify structure const downloadedPath = join(tmpPath, attachmentsPath),
fs.renameSync(join(tmpPath, attachmentsPath), join(tmpPath, ATTACHMENT_PATH)) tmpAttachmentPath = join(tmpPath, ATTACHMENT_PATH)
// remove the old app directory created by object export if (fs.existsSync(downloadedPath)) {
fs.rmdirSync(join(tmpPath, prodAppId)) // move out of app directory, simplify structure
fs.renameSync(downloadedPath, tmpAttachmentPath)
// remove the old app directory created by object export
fs.rmdirSync(join(tmpPath, prodAppId))
} else {
fs.mkdirSync(tmpAttachmentPath)
}
// enforce an export of app DB to the tmp path // enforce an export of app DB to the tmp path
const dbPath = join(tmpPath, DB_EXPORT_FILE) const dbPath = join(tmpPath, DB_EXPORT_FILE)
await exportDB(appId, { await exportDB(appId, {
@ -104,7 +110,10 @@ export async function exportApp(appId: string, config?: ExportOpts) {
// if tar requested, return where the tarball is // if tar requested, return where the tarball is
if (config?.tar) { if (config?.tar) {
// now the tmpPath contains both the DB export and attachments, tar this // now the tmpPath contains both the DB export and attachments, tar this
return tarFiles(tmpPath, [ATTACHMENT_PATH, DB_EXPORT_FILE]) const tarPath = tarFilesToTmp(tmpPath, [ATTACHMENT_PATH, DB_EXPORT_FILE])
// cleanup the tmp export files as tarball returned
fs.rmSync(tmpPath, { recursive: true, force: true })
return tarPath
} }
// tar not requested, turn the directory where export is // tar not requested, turn the directory where export is
else { else {
@ -112,6 +121,13 @@ export async function exportApp(appId: string, config?: ExportOpts) {
} }
} }
/**
* Export all apps + global DB (if supplied) to a single tarball, this includes
* the attachments for each app as well.
* @param {string[]} appIds The IDs of the apps to be exported.
* @param {string} globalDbContents The contents of the global DB to export as well.
* @return {string} The path to the tarball.
*/
export async function exportMultipleApps( export async function exportMultipleApps(
appIds: string[], appIds: string[],
globalDbContents?: string globalDbContents?: string
@ -129,7 +145,10 @@ export async function exportMultipleApps(
if (globalDbContents) { if (globalDbContents) {
fs.writeFileSync(join(tmpPath, GLOBAL_DB_EXPORT_FILE), globalDbContents) fs.writeFileSync(join(tmpPath, GLOBAL_DB_EXPORT_FILE), globalDbContents)
} }
return tarFiles(tmpPath, [...appIds, GLOBAL_DB_EXPORT_FILE]) const tarPath = tarFilesToTmp(tmpPath, [...appIds, GLOBAL_DB_EXPORT_FILE])
// clear up the tmp path now tarball generated
fs.rmSync(tmpPath, { recursive: true, force: true })
return tarPath
} }
/** /**