-
Notifications
You must be signed in to change notification settings - Fork 1.3k
NAS backup: compression, encryption, bandwidth throttle, integrity check #12898
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 4.22
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,6 +84,46 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co | |
| true, | ||
| BackupFrameworkEnabled.key()); | ||
|
|
||
| ConfigKey<Boolean> NASBackupCompressionEnabled = new ConfigKey<>("Advanced", Boolean.class, | ||
| "nas.backup.compression.enabled", | ||
| "false", | ||
| "Enable qcow2 compression for NAS backup files.", | ||
| true, | ||
| ConfigKey.Scope.Zone, | ||
| BackupFrameworkEnabled.key()); | ||
|
|
||
| ConfigKey<Boolean> NASBackupEncryptionEnabled = new ConfigKey<>("Advanced", Boolean.class, | ||
| "nas.backup.encryption.enabled", | ||
| "false", | ||
| "Enable LUKS encryption for NAS backup files.", | ||
| true, | ||
| ConfigKey.Scope.Zone, | ||
| BackupFrameworkEnabled.key()); | ||
|
|
||
| ConfigKey<String> NASBackupEncryptionPassphrase = new ConfigKey<>("Secure", String.class, | ||
| "nas.backup.encryption.passphrase", | ||
| "", | ||
| "Passphrase for LUKS encryption of NAS backup files. Required when encryption is enabled.", | ||
| true, | ||
| ConfigKey.Scope.Zone, | ||
| BackupFrameworkEnabled.key()); | ||
|
|
||
| ConfigKey<Integer> NASBackupBandwidthLimitMbps = new ConfigKey<>("Advanced", Integer.class, | ||
| "nas.backup.bandwidth.limit.mbps", | ||
| "0", | ||
| "Bandwidth limit in MiB/s for backup operations (0 = unlimited).", | ||
| true, | ||
| ConfigKey.Scope.Zone, | ||
| BackupFrameworkEnabled.key()); | ||
|
|
||
| ConfigKey<Boolean> NASBackupIntegrityCheckEnabled = new ConfigKey<>("Advanced", Boolean.class, | ||
| "nas.backup.integrity.check", | ||
| "false", | ||
| "Run qemu-img check on backup files after creation to verify integrity.", | ||
| true, | ||
| ConfigKey.Scope.Zone, | ||
| BackupFrameworkEnabled.key()); | ||
|
|
||
| @Inject | ||
| private BackupDao backupDao; | ||
|
|
||
|
|
@@ -205,6 +245,27 @@ public Pair<Boolean, Backup> takeBackup(final VirtualMachine vm, Boolean quiesce | |
| command.setMountOptions(backupRepository.getMountOptions()); | ||
| command.setQuiesce(quiesceVM); | ||
|
|
||
| // Pass optional backup enhancement settings from zone-scoped configs | ||
| Long zoneId = vm.getDataCenterId(); | ||
| if (Boolean.TRUE.equals(NASBackupCompressionEnabled.valueIn(zoneId))) { | ||
| command.addDetail("compression", "true"); | ||
| } | ||
| if (Boolean.TRUE.equals(NASBackupEncryptionEnabled.valueIn(zoneId))) { | ||
| String passphrase = NASBackupEncryptionPassphrase.valueIn(zoneId); | ||
| if (passphrase == null || passphrase.isEmpty()) { | ||
| throw new CloudRuntimeException("NAS backup encryption is enabled but no passphrase is configured (nas.backup.encryption.passphrase)"); | ||
| } | ||
| command.addDetail("encryption", "true"); | ||
| command.addDetail("encryption_passphrase", passphrase); | ||
| } | ||
| Integer bandwidthLimit = NASBackupBandwidthLimitMbps.valueIn(zoneId); | ||
| if (bandwidthLimit != null && bandwidthLimit > 0) { | ||
| command.addDetail("bandwidth_limit", String.valueOf(bandwidthLimit)); | ||
| } | ||
| if (Boolean.TRUE.equals(NASBackupIntegrityCheckEnabled.valueIn(zoneId))) { | ||
| command.addDetail("integrity_check", "true"); | ||
| } | ||
|
Comment on lines
+248
to
+267
|
||
|
|
||
| if (VirtualMachine.State.Stopped.equals(vm.getState())) { | ||
| List<VolumeVO> vmVolumes = volumeDao.findByInstance(vm.getId()); | ||
| vmVolumes.sort(Comparator.comparing(Volume::getDeviceId)); | ||
|
|
@@ -594,7 +655,12 @@ public Boolean crossZoneInstanceCreationEnabled(BackupOffering backupOffering) { | |
| @Override | ||
| public ConfigKey<?>[] getConfigKeys() { | ||
| return new ConfigKey[]{ | ||
| NASBackupRestoreMountTimeout | ||
| NASBackupRestoreMountTimeout, | ||
| NASBackupCompressionEnabled, | ||
| NASBackupEncryptionEnabled, | ||
| NASBackupEncryptionPassphrase, | ||
| NASBackupBandwidthLimitMbps, | ||
| NASBackupIntegrityCheckEnabled | ||
| }; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
detailsmay carry sensitive values (e.g., an encryption passphrase). CloudStack’s Gson logging usesLoggingExclusionStrategywith@LogLevelto exclude fields, so leaving this unannotated can leak secrets in debug logs. Annotatedetailswith@LogLevel(Off)(or avoid putting secrets in this map).