diff --git a/client/pages/config/backups.vue b/client/pages/config/backups.vue index f6adb3f2..aeffa96e 100644 --- a/client/pages/config/backups.vue +++ b/client/pages/config/backups.vue @@ -20,6 +20,14 @@

Number of backups to keep

+
+ + + +

Maximum backup size (in GB) info_outlined

+
+
+ @@ -32,6 +40,7 @@ export default { updatingServerSettings: false, dailyBackups: true, backupsToKeep: 2, + maxBackupSize: 1, newServerSettings: {} } }, @@ -47,19 +56,27 @@ export default { dailyBackupsTooltip() { return 'Runs at 1am every day (your server time). Saved in /metadata/backups.' }, + maxBackupSizeTooltip() { + return 'As a safeguard against misconfiguration, backups will fail if they exceed the configured size.' + }, serverSettings() { return this.$store.state.serverSettings } }, methods: { updateBackupsSettings() { + if (isNaN(this.maxBackupSize) || this.maxBackupSize <= 0) { + this.$toast.error('Invalid maximum backup size') + return + } if (isNaN(this.backupsToKeep) || this.backupsToKeep <= 0 || this.backupsToKeep > 99) { this.$toast.error('Invalid number of backups to keep') return } var updatePayload = { backupSchedule: this.dailyBackups ? '0 1 * * *' : false, - backupsToKeep: Number(this.backupsToKeep) + backupsToKeep: Number(this.backupsToKeep), + maxBackupSize: Number(this.maxBackupSize) } this.updateServerSettings(updatePayload) }, @@ -81,6 +98,7 @@ export default { this.backupsToKeep = this.newServerSettings.backupsToKeep || 2 this.dailyBackups = !!this.newServerSettings.backupSchedule + this.maxBackupSize = this.newServerSettings.maxBackupSize || 1 } }, mounted() { diff --git a/server/managers/BackupManager.js b/server/managers/BackupManager.js index 9c1002cd..f66d40cf 100644 --- a/server/managers/BackupManager.js +++ b/server/managers/BackupManager.js @@ -23,9 +23,6 @@ class BackupManager { this.scheduleTask = null this.backups = [] - - // If backup exceeds this value it will be aborted - this.MaxBytesBeforeAbort = 1000000000 // ~ 1GB } get serverSettings() { @@ -263,7 +260,8 @@ class BackupManager { reject(err) }) archive.on('progress', ({ fs: fsobj }) => { - if (fsobj.processedBytes > this.MaxBytesBeforeAbort) { + const maxBackupSizeInBytes = this.serverSettings.maxBackupSize * 1000 * 1000 * 1000 + if (fsobj.processedBytes > maxBackupSizeInBytes) { Logger.error(`[BackupManager] Archiver is too large - aborting to prevent endless loop, Bytes Processed: ${fsobj.processedBytes}`) archive.abort() setTimeout(() => { diff --git a/server/objects/settings/ServerSettings.js b/server/objects/settings/ServerSettings.js index 86cb33fb..7be8f9de 100644 --- a/server/objects/settings/ServerSettings.js +++ b/server/objects/settings/ServerSettings.js @@ -29,6 +29,7 @@ class ServerSettings { // this.backupSchedule = '0 1 * * *' // If false then auto-backups are disabled (default every day at 1am) this.backupSchedule = false this.backupsToKeep = 2 + this.maxBackupSize = 1 this.backupMetadataCovers = true // Logger @@ -78,6 +79,7 @@ class ServerSettings { this.backupSchedule = settings.backupSchedule || false this.backupsToKeep = settings.backupsToKeep || 2 + this.maxBackupSize = settings.maxBackupSize || 1 this.backupMetadataCovers = settings.backupMetadataCovers !== false this.loggerDailyLogsToKeep = settings.loggerDailyLogsToKeep || 7 @@ -114,6 +116,7 @@ class ServerSettings { rateLimitLoginWindow: this.rateLimitLoginWindow, backupSchedule: this.backupSchedule, backupsToKeep: this.backupsToKeep, + maxBackupSize: this.maxBackupSize, backupMetadataCovers: this.backupMetadataCovers, loggerDailyLogsToKeep: this.loggerDailyLogsToKeep, loggerScannerLogsToKeep: this.loggerScannerLogsToKeep,