-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Mark VMs in error state when expunge fails during destroy operation #12749
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 | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2578,6 +2578,22 @@ public boolean expunge(UserVmVO vm) { | |||||
| } | ||||||
| } | ||||||
|
|
||||||
| private void transitionExpungingToError(long vmId) { | ||||||
| try { | ||||||
| UserVmVO vm = _vmDao.findById(vmId); | ||||||
| if (vm != null && vm.getState() == State.Expunging) { | ||||||
| boolean transitioned = _itMgr.stateTransitTo(vm, VirtualMachine.Event.OperationFailedToError, null); | ||||||
| if (transitioned) { | ||||||
| logger.info("Transitioned VM [{}] from Expunging to Error after failed expunge", vm.getUuid()); | ||||||
| } else { | ||||||
| logger.warn("Failed to persist transition of VM [{}] from Expunging to Error after failed expunge, possibly due to concurrent update", vm.getUuid()); | ||||||
| } | ||||||
| } | ||||||
| } catch (NoTransitionException e) { | ||||||
| logger.warn("Failed to transition VM to Error state: {}", e.getMessage()); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Release network resources, it was done on vm stop previously. | ||||||
| * @param id vm id | ||||||
|
|
@@ -3561,8 +3577,19 @@ public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, C | |||||
| detachVolumesFromVm(vm, dataVols); | ||||||
|
|
||||||
| UserVm destroyedVm = destroyVm(vmId, expunge); | ||||||
| if (expunge && !expunge(vm)) { | ||||||
| throw new CloudRuntimeException("Failed to expunge vm " + destroyedVm); | ||||||
| if (expunge) { | ||||||
| boolean expunged; | ||||||
| try { | ||||||
| expunged = expunge(vm); | ||||||
| } catch (RuntimeException e) { | ||||||
| logger.error("Failed to expunge VM [{}] due to: {}", vm, e.getMessage(), e); | ||||||
| transitionExpungingToError(vm.getId()); | ||||||
| throw new CloudRuntimeException("Failed to expunge VM " + vm.getUuid() + " due to: " + e.getMessage(), e); | ||||||
| } | ||||||
| if (!expunged) { | ||||||
| transitionExpungingToError(vm.getId()); | ||||||
| throw new CloudRuntimeException("Failed to expunge VM " + destroyedVm); | ||||||
|
||||||
| throw new CloudRuntimeException("Failed to expunge VM " + destroyedVm); | |
| throw new CloudRuntimeException("Failed to expunge VM " + vm.getUuid()); |
Copilot
AI
Mar 5, 2026
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.
The updated destroyVm(DestroyVMCmd) method now has two new failure paths: one where expunge(vm) returns false and one where it throws a RuntimeException. Both paths call transitionExpungingToError() and then throw a CloudRuntimeException. However, there are no tests in this PR covering these new code paths in destroyVm. The existing testDestroyVm test at line 3628 only covers the success case (where expunge returns true). Tests verifying that transitionExpungingToError is called and a CloudRuntimeException is thrown in both failure cases would improve reliability.
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.
The warning log message at line 2593 doesn't include the VM's UUID or ID to help identify which VM failed to transition. Since this code is inside a
tryblock that starts at line 2582 and thevmvariable is in scope when theNoTransitionExceptionis thrown (it can only be thrown from within theif (vm != null && ...)check on line 2584), the log message should includevm.getUuid()to make troubleshooting easier. However,vmis declared inside thetryblock and would be accessible in thecatchblock because the exception can only occur inside theifblock wherevm != null.