split checkPrecondition so it can be used in cleaner as well

This commit is contained in:
Girish Ramakrishnan
2022-10-02 17:22:44 +02:00
parent 4f4a0ec289
commit c3793da5bb
7 changed files with 97 additions and 55 deletions

View File

@@ -2,7 +2,8 @@
exports = module.exports = {
getBackupRootPath,
checkBackupPreconditions,
getBackupProviderStatus,
getAvailableSize,
upload,
download,
@@ -33,7 +34,6 @@ const PROVIDER_EXT4 = 'ext4';
const assert = require('assert'),
BoxError = require('../boxerror.js'),
constants = require('../constants.js'),
DataLayout = require('../datalayout.js'),
debug = require('debug')('box:storage/filesystem'),
df = require('@sindresorhus/df'),
fs = require('fs'),
@@ -62,44 +62,26 @@ function getBackupRootPath(apiConfig) {
}
}
// binary units (non SI) 1024 based
function prettyBytes(bytes) {
assert.strictEqual(typeof bytes, 'number');
const i = Math.floor(Math.log(bytes) / Math.log(1024)),
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
return (bytes / Math.pow(1024, i)).toFixed(2) * 1 + '' + sizes[i];
}
// the du call in the function below requires root
async function checkBackupPreconditions(apiConfig, dataLayout) {
async function getBackupProviderStatus(apiConfig) {
assert.strictEqual(typeof apiConfig, 'object');
assert(dataLayout instanceof DataLayout, 'dataLayout must be a DataLayout');
// Check filesystem is mounted so we don't write into the actual folder on disk
if (mounts.isManagedProvider(apiConfig.provider) || apiConfig.provider === 'mountpoint') {
const hostPath = mounts.isManagedProvider(apiConfig.provider) ? paths.MANAGED_BACKUP_MOUNT_DIR : apiConfig.mountPoint;
const status = await mounts.getStatus(apiConfig.provider, hostPath); // { state, message }
debug(`clean: mount point status is ${JSON.stringify(status)}`);
if (status.state !== 'active') throw new BoxError(BoxError.MOUNT_ERROR, `Backup endpoint is not mounted: ${status.message}`);
return await mounts.getStatus(apiConfig.provider, hostPath); // { state, message }
}
return await mounts.getStatus(apiConfig.provider, apiConfig.backupFolder);
}
// the du call in the function below requires root
async function getAvailableSize(apiConfig) {
assert.strictEqual(typeof apiConfig, 'object');
const [error, dfResult] = await safe(df.file(getBackupRootPath(apiConfig)));
if (error) throw new BoxError(BoxError.FS_ERROR, `Error when checking for disk space: ${error.message}`);
let used = 0;
for (const localPath of dataLayout.localPaths()) {
debug(`checkBackupPreconditions: getting disk usage of ${localPath}`);
const result = safe.child_process.execSync(`du -Dsb ${localPath}`, { encoding: 'utf8' });
if (!result) throw new BoxError(BoxError.FS_ERROR, `du error: ${safe.error.message}`);
used += parseInt(result, 10);
}
debug(`checkBackupPreconditions: ${used} bytes`);
const needed = 0.6 * used + (1024 * 1024 * 1024); // check if there is atleast 1GB left afterwards. aim for 60% because rsync/tgz won't need full 100%
if (dfResult.available <= needed) throw new BoxError(BoxError.FS_ERROR, `Not enough disk space for backup. Needed: ${prettyBytes(needed)} Available: ${prettyBytes(dfResult.available)}`);
return dfResult.available;
}
function hasChownSupportSync(apiConfig) {