Repository navigation
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## 4.22 #12898 +/- ##
============================================
+ Coverage 18.26% 18.28% +0.01%
- Complexity 16608 16643 +35
============================================
Files 5939 5940 +1
Lines 537697 537856 +159
Branches 65922 65943 +21
============================================
+ Hits 98210 98324 +114
- Misses 428299 428333 +34
- Partials 11188 11199 +11
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds optional, zone-scoped enhancements for KVM NAS backups (compression, LUKS encryption, bandwidth throttling, and post-backup integrity verification) by plumbing config from management server → TakeBackupCommand details → KVM agent wrapper → nasbackup.sh flags.
Changes:
- Add new CLI flags and implementation in
nasbackup.shfor compression (-c), encryption (-e), bandwidth throttling (-b), and verification (--verify). - Extend
TakeBackupCommandwith adetailsmap to carry optional settings to the agent. - Add zone-scoped NAS backup ConfigKeys and populate command details; update KVM wrapper to translate details into script args and manage a temporary passphrase file.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
scripts/vm/hypervisor/kvm/nasbackup.sh |
Implements compression/encryption/throttle/verify logic and argument parsing for NAS backup operations. |
core/src/main/java/org/apache/cloudstack/backup/TakeBackupCommand.java |
Adds a details map to carry optional backup feature settings from management to agent. |
plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupProvider.java |
Introduces zone-scoped ConfigKeys and passes enabled settings into TakeBackupCommand details. |
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtTakeBackupCommandWrapper.java |
Builds dynamic nasbackup.sh command args from TakeBackupCommand details and writes an encryption passphrase temp file. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- nasbackup.sh: Replace exit 1 with return 1 in encrypt_backup and verify_backup so callers can run cleanup before terminating - nasbackup.sh: Append (>>) instead of truncate (>) agent.log in qemu-img convert for stopped VM backups - nasbackup.sh: Add return 1 after cleanup on qemu-img convert failure to stop execution - nasbackup.sh: Callers of encrypt_backup/verify_backup now check return code and run cleanup on failure - LibvirtTakeBackupCommandWrapper: Fail with error when encryption is enabled but passphrase is missing instead of silently skipping - LibvirtTakeBackupCommandWrapper: Delete temp passphrase file in finally block, set 0600 permissions, use explicit UTF-8 charset - NASBackupProvider: Throw CloudRuntimeException when encryption is enabled but passphrase is null/empty - NASBackupProviderTest: Add tests for compression, bandwidth, integrity check, encryption+passphrase, and encryption-without- passphrase failure scenarios - TakeBackupCommand: Add @loglevel(Off) to details field to prevent passphrase leaking in debug logs - TakeBackupCommand: Normalize null to empty HashMap in setDetails
|
@blueorangutan package |
|
@sureshanaparti a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress. |
|
Packaging result [SF]: ✖️ el8 ✖️ el9 ✖️ debian ✖️ suse15. SL-JID 17323 |
|
@jmsperu can you check/fix the build failure. |
Address remaining Copilot review feedback on PR apache#12898: - Replace `2>&1 | tee -a` with `>> logFile 2>&1` in encrypt_backup, compress, and mount_operation to prevent tee from masking non-zero exit codes of qemu-img and mount commands - Add `return 1` after cleanup on virsh backup job failure to prevent continuing execution with broken state
|
@sureshanaparti Fixed. The test failures were caused by The fix also sets Also addressed in the previous commit: replaced Could you please retrigger the build? |
|
@jmsperu a [SL] Jenkins job has been kicked to build packages. It will be bundled with` SystemVM template(s). I'll keep you posted as I make progress. |
|
Packaging result [SF]: ✖️ el8 ✖️ el9 ✖️ debian ✖️ suse15. SL-JID 17346 |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
scripts/vm/hypervisor/kvm/nasbackup.sh:321
mount_operationruns underset -e, butmountis executed as a standalone command and then$?is checked. Withset -e, a mount failure will exit the script immediately and bypass the custom error message/handling. Consider rewriting this as a conditionalif ! mount ...; then ...; fiso failures are handled deterministically while still logging stderr.
mount -t ${NAS_TYPE} ${NAS_ADDRESS} ${mount_point} $([[ ! -z "${MOUNT_OPTS}" ]] && echo -o ${MOUNT_OPTS}) >> "$logFile" 2>&1
if [ $? -eq 0 ]; then
log -ne "Successfully mounted ${NAS_TYPE} store"
else
echo "Failed to mount ${NAS_TYPE} store"
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Synced with 4.22 after #13877 and #14006 landed (merge 2a9bbbb). Both sets of settings are kept and the enhancement flags now live in the new One behavioural point for review: compression and LUKS encryption rewrite each backup file with Local results (JDK 17): NASBackupProviderTest 28/28, Restore wrapper 22/22, Take wrapper 5/5. |
|
@abh1sar can you have another look? |
…he backup row exists, reject compression with encryption applyBackupEnhancementDetails now runs before createBackupObject, so encryption without a passphrase no longer leaves an orphaned BackupVO in BackingUp. qcow2 cannot compress and encrypt the same image, so enabling both settings for a zone fails the request up front with a message naming both settings, instead of building the backup and deleting it. The setting descriptions say so, and the passphrase description warns that restores use the current passphrase.
…ard, rate-limit probe, honest throttle logging, accept leaked clusters - refuse -c together with -e before mounting anything (qcow2 cannot do both) - qemu-img convert -r only exists since QEMU 5.2: probe it on a throwaway image and fall back to an unthrottled copy with a WARNING in the log - ionice -c 3 only when a bandwidth limit is set; build the convert arguments as arrays (the old command substitution passed '-r 50M' as one word under IFS=,) - running VMs: log per disk whether blockjob --bandwidth succeeded, and match disks with $2=="disk" so cdrom rows are skipped - --verify: qemu-img check exit 3 (leaked clusters) passes with a log line; 2 (corruption) and other codes still fail
…on state cannot be read isEncryptedImage() now throws when qemu-img info returns nothing usable, so a restore never falls back to rsync for a file that might be LUKS-encrypted. qemu-img check exit 3 (leaked clusters) is accepted on restore as well; 2 still reports the backup as corrupt. Tests cover both, and the existing tests now stub a real plain-qcow2 qemu-img info result instead of relying on a null.
|
@abh1sar thanks for the thorough review. All seven inline points are answered in their threads; the fixes are in f82d33f (management server), 1f596ed (nasbackup.sh) and d32f570 (restore wrapper). Local results: NASBackupProviderTest 29/29, LibvirtRestoreBackupCommandWrapperTest 24/24, LibvirtTakeBackupCommandWrapperTest 5/5, checkstyle clean. I also ran the script changes through a PATH-shimmed harness with real qemu-img, comparing old and new, for compression + encryption, On your question about rotating the passphrase: yes, today a restore only gets the zone's current |
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
d32f570 to
1d2eec1
Compare
… integrity check Rebased onto 4.22 as a single commit (the branch history had several merges of 4.22, which a commit-by-commit rebase cannot replay cleanly). Resolved against "Nasbackup quiesce fixes (apache#14305)": TakeBackupCommand and NASBackupProvider keep both the enhancement details and the new quiesce timeout and cleanup alert; nasbackup.sh keeps both option sets and takes the upstream 'exit 1' after a failed backup job; the PR's enhancement-flag tests move to LibvirtTakeBackupCommandWrapperEnhancementFlagsTest next to the upstream LibvirtTakeBackupCommandWrapperTest. Squashed from: - address review (apache#12898): restore fails closed when the encryption state cannot be read - address review (apache#12898): nasbackup.sh compression/encryption guard, rate-limit probe, honest throttle logging, accept leaked clusters - address review (apache#12898): validate enhancement settings before the backup row exists, reject compression with encryption - Restore wrapper tests: count only qemu-img calls - address review (apache#12898): restore LUKS-encrypted backups - address review (apache#12898): reorder java.io imports alphabetically; drop trailing '(Copilot review)' comment artifacts - refactor(backup): extract NAS backup enhancement logic into dedicated methods + tests - refactor(backup): consolidate detail keys in TakeBackupCommand - Fix build: use reflection for protected ConfigKey.valueOf() in test - Fix NASBackupProviderTest failures for zone-scoped ConfigKey values - Fix tee masking exit codes and missing return in nasbackup.sh - Address Copilot review feedback on NAS backup PR apache#12898 - NAS backup enhancements: compression, encryption, bandwidth throttle, integrity check Claude-Session: https://claude.ai/code/session_01BhiE1Abhs315m3n3UPy6V7
|
Rebased on the current 4.22 (1d2eec1). The branch history had several merges of 4.22, so it is now one commit on top of 4.22; the message lists the commits it replaces. The only upstream change that conflicted was "Nasbackup quiesce fixes" (#14305):
core, NAS plugin and KVM plugin build with checkstyle; NASBackupProviderTest 31/31, Libvirt take/restore backup wrapper tests 32/32; bash -n clean. Ready for review. |
|
A note on the rebase: the branch had picked up several merges of 4.22, so I rebased it as a single commit on top of 4.22 (its message lists the 13 commits it replaces) rather than replaying each one. Commit hashes quoted in earlier review threads are therefore no longer on the branch. If reviewers would rather see the separate commits again, let me know and I will restore them; otherwise I will keep it as one commit, since the PR would be squash-merged anyway. |
@jmsperu one commit is fine. checked the rebased commit against abhisars seven points and they look fixed except the running vm throttle test on a real host |
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
1d2eec1 to
3586cf2
Compare
… integrity check Rebased onto 4.22 as a single commit (the branch history had several merges of 4.22, which a commit-by-commit rebase cannot replay cleanly). Resolved against "Nasbackup quiesce fixes (apache#14305)": TakeBackupCommand and NASBackupProvider keep both the enhancement details and the new quiesce timeout and cleanup alert; nasbackup.sh keeps both option sets and takes the upstream 'exit 1' after a failed backup job; the PR's enhancement-flag tests move to LibvirtTakeBackupCommandWrapperEnhancementFlagsTest next to the upstream LibvirtTakeBackupCommandWrapperTest. Squashed from: - address review (apache#12898): restore fails closed when the encryption state cannot be read - address review (apache#12898): nasbackup.sh compression/encryption guard, rate-limit probe, honest throttle logging, accept leaked clusters - address review (apache#12898): validate enhancement settings before the backup row exists, reject compression with encryption - Restore wrapper tests: count only qemu-img calls - address review (apache#12898): restore LUKS-encrypted backups - address review (apache#12898): reorder java.io imports alphabetically; drop trailing '(Copilot review)' comment artifacts - refactor(backup): extract NAS backup enhancement logic into dedicated methods + tests - refactor(backup): consolidate detail keys in TakeBackupCommand - Fix build: use reflection for protected ConfigKey.valueOf() in test - Fix NASBackupProviderTest failures for zone-scoped ConfigKey values - Fix tee masking exit codes and missing return in nasbackup.sh - Address Copilot review feedback on NAS backup PR apache#12898 - NAS backup enhancements: compression, encryption, bandwidth throttle, integrity check Claude-Session: https://claude.ai/code/session_01BhiE1Abhs315m3n3UPy6V7
|
Rebased on 4.22 (90ef9b9) as 3586cf2, still one commit. Only the two test files conflicted; both now carry the upstream tests and this PR's tests. The upstream restore position test needed this PR's qemu-img info mock because the encryption check fails closed when the image cannot be read. nasbackup.sh had no upstream changes. |
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
… integrity check Rebased onto 4.22 as a single commit (the branch history had several merges of 4.22, which a commit-by-commit rebase cannot replay cleanly). Resolved against "Nasbackup quiesce fixes (apache#14305)": TakeBackupCommand and NASBackupProvider keep both the enhancement details and the new quiesce timeout and cleanup alert; nasbackup.sh keeps both option sets and takes the upstream 'exit 1' after a failed backup job; the PR's enhancement-flag tests move to LibvirtTakeBackupCommandWrapperEnhancementFlagsTest next to the upstream LibvirtTakeBackupCommandWrapperTest. Squashed from: - address review (apache#12898): restore fails closed when the encryption state cannot be read - address review (apache#12898): nasbackup.sh compression/encryption guard, rate-limit probe, honest throttle logging, accept leaked clusters - address review (apache#12898): validate enhancement settings before the backup row exists, reject compression with encryption - Restore wrapper tests: count only qemu-img calls - address review (apache#12898): restore LUKS-encrypted backups - address review (apache#12898): reorder java.io imports alphabetically; drop trailing '(Copilot review)' comment artifacts - refactor(backup): extract NAS backup enhancement logic into dedicated methods + tests - refactor(backup): consolidate detail keys in TakeBackupCommand - Fix build: use reflection for protected ConfigKey.valueOf() in test - Fix NASBackupProviderTest failures for zone-scoped ConfigKey values - Fix tee masking exit codes and missing return in nasbackup.sh - Address Copilot review feedback on NAS backup PR apache#12898 - NAS backup enhancements: compression, encryption, bandwidth throttle, integrity check Claude-Session: https://claude.ai/code/session_01BhiE1Abhs315m3n3UPy6V7
Lab run on libvirt 10.0.0 / QEMU 8.2.2 showed that a 4 GiB sparse disk with 172 MiB allocated still takes virtual size / limit when throttled with virsh blockjob --bandwidth, so the setting description now says so.
backup_running_vm and backup_stopped_vm returned 1 after a failed encrypt_backup or verify_backup, but the top-level dispatcher does not check the function's return value, so the script ended with status 0 and no size lines. The agent treats a non-zero exit status as the failure signal, so use exit 1 like every other failure path in both functions. Claude-Session: https://claude.ai/code/session_01EUU5skTaj95LfpkSbrWhPN
…backup The content-based pull path added for LINSTOR copies through libvirt's NBD export with qemu-img create and rebase, which have no rate option, so neither the convert -r limit nor the blockjob throttle reaches it. Log a warning instead of silently ignoring the setting. Claude-Session: https://claude.ai/code/session_01EUU5skTaj95LfpkSbrWhPN
…estore The LINSTOR restore tests look up replaceBlockDeviceWithBackup by reflection with the signature from before this change, and they let the qemu-img info probe fail. Pass the key file parameter (null, the backup is not encrypted there) and show the encryption probe a plain qcow2 header, as the other restore tests do. Claude-Session: https://claude.ai/code/session_01EUU5skTaj95LfpkSbrWhPN
d0984d7 to
34967c0
Compare
|
Rebased on 4.22 now that #14194 (LINSTOR incremental nasbackup) has landed; the conflicts were all in that change's footprint. How the overlap was resolved:
Three small fixes that came out of the rebase:
Tests (offline, |
Summary
Adds four optional, zone-scoped features to NAS backup operations on KVM, all disabled by default:
-c): Uses qcow2 internal compression (qemu-img convert -c) to reduce backup size-e): Encrypts backup files at rest using LUKS viaqemu-img convert --object secret-b): Limits backup I/O —virsh blockjob --bandwidthfor running VMs,qemu-img convert -r+ionicefor stopped VMs--verify): Runsqemu-img checkon each backup file after creationConfiguration Keys (Zone scope)
nas.backup.compression.enablednas.backup.encryption.enablednas.backup.encryption.passphrasenas.backup.bandwidth.limit.mbpsnas.backup.integrity.checkArchitecture
detailsmap onTakeBackupCommandnasbackup.shCLI flagsFiles Changed
scripts/vm/hypervisor/kvm/nasbackup.sh— new-c,-b,-e,--verifyflags withencrypt_backup()andverify_backup()functionscore/.../TakeBackupCommand.java— addeddetailsmap (HashMap) with getter/setter/addDetailplugins/backup/nas/.../NASBackupProvider.java— 5 new ConfigKeys, populate command details intakeBackup()plugins/hypervisors/kvm/.../LibvirtTakeBackupCommandWrapper.java— extract details, build dynamic CLI args, temp passphrase file lifecycleNotes
Test plan
nas.backup.compression.enabledat zone scope, take backup, verify qcow2 files are compressednas.backup.bandwidth.limit.mbps(e.g. 50), take backup of running VM, verifyvirsh blockjobbandwidth is appliednas.backup.bandwidth.limit.mbps, take backup of stopped VM, verifyqemu-img -rrate limit is appliednas.backup.encryption.enabledwith passphrase, take backup, verify files are LUKS encrypted (qemu-img infoshows encryption)nas.backup.integrity.check, take backup, verifyqemu-img checkruns and passes