backuptask: save backupinfo in one place

This commit is contained in:
Girish Ramakrishnan
2025-08-15 14:33:31 +05:30
parent fd2705a49d
commit e7fb444bb3
3 changed files with 22 additions and 26 deletions

View File

@@ -28,9 +28,11 @@ const apps = require('./apps.js'),
locks = require('./locks.js'),
path = require('node:path'),
paths = require('./paths.js'),
{ Readable } = require('node:stream'),
safe = require('safetydance'),
services = require('./services.js'),
shell = require('./shell.js')('backuptask');
shell = require('./shell.js')('backuptask'),
stream = require('stream/promises');
const BACKUP_UPLOAD_CMD = path.join(__dirname, 'scripts/backupupload.js');
@@ -69,6 +71,17 @@ async function checkPreconditions(backupTarget, dataLayout) {
if (available <= needed) throw new BoxError(BoxError.FS_ERROR, `Not enough disk space for backup. Needed: ${df.prettyBytes(needed)} Available: ${df.prettyBytes(available)}`);
}
async function uploadBackupInfo(backupTarget, remotePath, integrityMap) {
const sortedIntegrityMap = [...integrityMap.entries()].sort(([a], [b]) => a < b); // for readability, order the entries
const integrityDataJsonString = JSON.stringify(Object.fromEntries(sortedIntegrityMap), null, 2);
const integrityDataStream = Readable.from(integrityDataJsonString);
const integrityUploader = await backupTargets.storageApi(backupTarget).upload(backupTarget.config, `${remotePath}.backupinfo`);
await stream.pipeline(integrityDataStream, integrityUploader.stream);
await integrityUploader.finish();
return await crypto.sign(null /* algorithm */, integrityDataJsonString, backupTarget.integrityKeyPair.privateKey);
}
// this function is called via backupupload (since it needs root to traverse app's directory)
async function upload(remotePath, targetId, dataLayoutString, progressCallback) {
assert.strictEqual(typeof remotePath, 'string');
@@ -85,7 +98,10 @@ async function upload(remotePath, targetId, dataLayoutString, progressCallback)
await checkPreconditions(backupTarget, dataLayout);
return await backupFormat.api(backupTarget.format).upload(backupTarget, remotePath, dataLayout, progressCallback);
const { stats, integrityMap } = await backupFormat.api(backupTarget.format).upload(backupTarget, remotePath, dataLayout, progressCallback);
const signature = await uploadBackupInfo(backupTarget, remotePath, integrityMap);
return { stats, integrity: { signature } };
}
async function download(backupTarget, remotePath, dataLayout, progressCallback) {