Skip to content

MORPH-1029: Gen2 hot disk resize support#168

Open
dgaharwar12 wants to merge 3 commits into
mainfrom
deepti/morph-1029/fix-gen2-hot-disk-resize
Open

MORPH-1029: Gen2 hot disk resize support#168
dgaharwar12 wants to merge 3 commits into
mainfrom
deepti/morph-1029/fix-gen2-hot-disk-resize

Conversation

@dgaharwar12

Copy link
Copy Markdown

Issue description (MORPH-1029 / Case 5393638946)

Summary

When adding or expanding disks on SCVMM VMs through Morpheus, the VM was stopped and started even though the same operations in the SCVMM console left the VM running. The disk change succeeded, but customers saw an unnecessary restart (downtime).


Root cause

Morpheus SCVMM resize logic always treated disk changes as requiring a powered-off VM.

  1. getResizeConfig always set hotResize = false
    For every resize, including disk-only changes with no memory or CPU change, Morpheus decided a stop was required.

  2. resizeWorkloadAndServer stops the VM when hotResize is false
    It calls stopWorkload / stopServer before disk work, then starts the VM again afterward. Customer logs showed shutdown → resize → startup (~40s downtime) even for disk-only reconfigure.

  3. This was not required by SCVMM
    The plugin already uses Expand-SCVirtualDiskDrive and New-SCVirtualDiskDrive, which SCVMM can run on running Generation 2 VMs. The restart was imposed by Morpheus, not by SCVMM.

  4. VM generation was not used
    Gen 1 VMs often need a power-off for disk changes; Gen 2 VMs support online disk add/expand. The plugin did not distinguish them:

    • hotResize was hard-coded to false in resize config
    • Cloud sync did not populate Generation from SCVMM or set hotResize on discovered VMs

What was fixed

Plugin-only (morpheus-scvmm-plugin):

Area | Change -- | -- ScvmmGenerationUtil | Maps SCVMM VM generation to generation1 / generation2 and ComputeServer.hotResize ScvmmApiService.listVirtualMachines | Syncs Generation from SCVMM with each VM VirtualMachineSync | On add/update, sets generation config and hotResize (Gen 2 → true) ScvmmProvisionProvider.getResizeConfig | Gen 2 + disk-only resize/add → hotResize = true (no stop/start). Memory/CPU changes or disk delete → still hotResize = false validateResizeWorkload | Returns correct hotResize so the UI reflects online vs offline resize Provision | Sets hotResize / generation from template generation when a VM is provisioned

Expected behavior after fix

  • Gen 2 VM, disk expand or add only → VM stays running; no Morpheus shutdown/startup
  • Gen 1 VM → unchanged (stop/start still used where required)
  • Memory, CPU, or disk delete → VM still stopped as before

Note: Run a cloud sync after upgrading the plugin so existing Gen 2 VMs get hotResize and generation from SCVMM.

@dgaharwar12 dgaharwar12 requested a review from cpdtaylor June 4, 2026 13:50
@dgaharwar12 dgaharwar12 self-assigned this Jun 4, 2026
@dgaharwar12 dgaharwar12 added the bug Something isn't working label Jun 4, 2026
updated minVersion from 8.0.3 to 9.0.2

if (masterItem.Generation != null) {
def generation = ScvmmGenerationUtil.toGenerationConfig(masterItem.Generation)
def hotResize = ScvmmGenerationUtil.isGeneration2(generation)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

potential improvement here. The logic to determine hotResize is defined here, but also in the ScvvmGenerationUtil. It could be kept in one place.

Address PR review: move generation/hotResize sync out of VirtualMachineSync
into syncGenerationFromCloudItem so hotResize is determined in one place.

class ScvmmGenerationUtil {

static String toGenerationConfig(Object generation) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename teh function to getGenerationConfig() ?
Again config also does not sound the right word.

But the point is the function should be a get function.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this is a beneficial minor improvement.

return generationConfig == 'generation2'
}

static boolean hotResizeFromCloudItem(Map cloudItem) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to hotResizeEnabled ?

if (!server) {
return false
}
if (server.hotResize == true) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we checking if (server.hotResize == true) {

We should only do
return isGeneration2(server.getConfigProperty('generation'))

applyGenerationConfig(server, scvmmGeneration)
}

private static void applyGenerationConfig(ComputeServer server, String generation) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to setGenerationConfig ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess all functions starting with apply should be renamed to set ?

rtn.hotResize = false
} else if (opts.volumes && hasDiskResizeOrAdd(resizeRequest)) {
rtn.hotResize = supportsHotDisk
} else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which cases will land in this else case ?

@panigrap

panigrap commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

@dgaharwar12 We generally follow the practice of attaching screenshots / screen recoding video/ logs to prove that the fix works and that gives more confidence to the reviewers.
Could you please upload your test details.

@dgaharwar12

Copy link
Copy Markdown
Author

Sure, I can share them tomorrow.


class ScvmmGenerationUtil {

static String toGenerationConfig(Object generation) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this is a beneficial minor improvement.

* @param opts additional options
* @return Response from API
*/
@Override

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function header above line 2196 used to be the function header for the resizeWorkload function below it. I don't think that was intentional. Correct and add a function header for the new method?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change is looking similar to embedded fix merged here: https://github.com/HPE-EMU/morpheus-ui/pull/4387/changes

@panigrap panigrap Jun 11, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The embedded PR decides on hot resize based on generation and Dynamic Memory status

And the current PR decides on hot resize based on only generation.

I feel the table given in the embedded PR makes more sense to me.

Hot-Add Capability Matrix

Operation Gen 2 Gen 1
Memory (Dynamic) Yes Yes
Memory (Static) No No
CPU add Yes No
CPU remove No No
Disk (SCSI) Yes Yes

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dgaharwar12 was the hot resize problem occured after the embedded PR merge too ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But looks like the embedded PR was well tested for all the scenarios listed in the table.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants