Fix NPE on external/unmanaged instance import using custom offerings#12884
Fix NPE on external/unmanaged instance import using custom offerings#12884winterhazel wants to merge 2 commits intoapache:4.20from
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## 4.20 #12884 +/- ##
=========================================
Coverage 16.25% 16.25%
- Complexity 13415 13425 +10
=========================================
Files 5664 5664
Lines 500465 500507 +42
Branches 60780 60785 +5
=========================================
+ Hits 81338 81380 +42
Misses 410031 410031
Partials 9096 9096
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Fixes a regression where importing unmanaged/external instances with custom (dynamic) compute offerings can hit NPEs when CPU/RAM are not populated on the offering, by deriving CPU/RAM from the hypervisor (unmanaged) or from provided details (external/disk-based imports) and moving resource-limit reservations closer to the specific import paths.
Changes:
- Move VM (cpu/memory/vm count) resource-limit reservations out of top-level import methods and into specific import flows.
- Add pre-checks to determine CPU/RAM for unmanaged-instance imports (hypervisor vs offering) and for external KVM imports (offering vs
details). - Ensure reservations are closed via
ReservationHelper.closeAll(...)around import/conversion flows.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
Outdated
Show resolved
Hide resolved
| private void checkVmResourceLimitsForExternalKvmVmImport(Account owner, ServiceOfferingVO serviceOffering, VMTemplateVO template, Map<String, String> details, List<Reserver> reservations) throws ResourceAllocationException { | ||
| // When importing an external VM, the amount of CPUs and memory is always obtained from the compute offering, | ||
| // unlike the unmanaged instance import that obtains it from the hypervisor unless the VM is powered off and the offering is fixed | ||
| Integer cpu = serviceOffering.getCpu(); | ||
| Integer memory = serviceOffering.getRamSize(); | ||
|
|
||
| if (serviceOffering.isDynamic()) { | ||
| cpu = getDetailAsInteger(VmDetailConstants.CPU_NUMBER, details); | ||
| memory = getDetailAsInteger(VmDetailConstants.MEMORY, details); | ||
| } | ||
|
|
||
| List<String> resourceLimitHostTags = resourceLimitService.getResourceLimitHostTags(serviceOffering, template); | ||
|
|
||
| CheckedReservation vmReservation = new CheckedReservation(owner, Resource.ResourceType.user_vm, resourceLimitHostTags, 1L, reservationDao, resourceLimitService); | ||
| reservations.add(vmReservation); | ||
|
|
||
| CheckedReservation cpuReservation = new CheckedReservation(owner, Resource.ResourceType.cpu, resourceLimitHostTags, cpu.longValue(), reservationDao, resourceLimitService); | ||
| reservations.add(cpuReservation); | ||
|
|
||
| CheckedReservation memReservation = new CheckedReservation(owner, Resource.ResourceType.memory, resourceLimitHostTags, memory.longValue(), reservationDao, resourceLimitService); | ||
| reservations.add(memReservation); | ||
| } |
There was a problem hiding this comment.
New VM resource-limit selection logic (dynamic vs fixed offering, powered-off vs running unmanaged VM, and parsing CPU/memory from details) is not covered by unit tests in UnmanagedVMsManagerImplTest. Add focused tests for: (1) unmanaged import with null/unknown powerState, (2) external import with dynamic offering reading cpuNumber/memory, and (3) validation failures for missing/invalid values, to prevent regressions back to NPEs.
server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
Show resolved
Hide resolved
|
@blueorangutan package |
|
@abh1sar 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 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 17237 |
|
Tested the following test cases with custom and fixed service offerings and verified that the resource counts were being incremented accordingly
|
|
@blueorangutan test |
|
@abh1sar a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests |
|
[SF] Trillian Build Failed (tid-15736) |
|
@blueorangutan test |
|
@abh1sar a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests |
Description
This PR addresses a regression in the import of unmanaged/external VMs using a custom compute offering (reported in https://lists.apache.org/thread/1bvxjc197zhj61mtjxpm3tz1o27znjmv).
As both
serviceOffering.getCpu()andserviceOffering.getRamSize()return null when the offering is custom constrained/unconstrained, we need to check the amount of CPUs and memory returned by the hypervisor in case an unmanaged instance is being imported, or thecpuNumberandmemorydetails in case the instance belongs to a remote host/is being imported from its disk.Types of changes
Feature/Enhancement Scale or Bug Severity
Bug Severity
Screenshots (if appropriate):
How Has This Been Tested?
Tests are still pending. The following operations need to be validated with both fixed and custom offerings: