Skip to content

Fix incorrect disk sizes during VMware VM import#138

Merged
votdev merged 2 commits into
harvester:mainfrom
susesamu:10167
Mar 11, 2026
Merged

Fix incorrect disk sizes during VMware VM import#138
votdev merged 2 commits into
harvester:mainfrom
susesamu:10167

Conversation

@susesamu
Copy link
Copy Markdown
Contributor

Problem:
When importing virtual machines from VMware vCenter, the vm-import-controller determines disk sizes using nfc.LeaseItem.Size. In some VMware environments this value represents the total provisioned capacity of the VM, not the size of the individual disk.

As a result, each imported disk may incorrectly receive the aggregate VM size, causing PVCs to be over-provisioned and migrations to fail due to insufficient storage.

Solution:
Disk capacities are now determined using the VM hardware configuration retrieved from: mo.VirtualMachine.Config.Hardware.Device For each VirtualDisk, the code reads: VirtualDisk.CapacityInKB and maps disks to lease items using the VMDK filename basename.

Related Issue:
harvester/harvester#10167

Test plan:

  1. Create a VM with multiple disks with different sizes.
  2. Create a VirtualMachineImport resource
  3. Check the disk sizes created in Harvester
  4. Disk sizes should now match the original VMware disk capacities.

Copilot AI review requested due to automatic review settings March 10, 2026 17:12
Signed-off-by: Samuel Vasconcelos <samuel.vasconcelos@suse.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes incorrect per-disk sizing during VMware vCenter VM import by deriving disk capacities from the VM’s hardware device configuration rather than relying on nfc.LeaseItem.Size, which can represent aggregate VM capacity in some environments.

Changes:

  • Fetches config.hardware.device from vCenter and builds a VMDK filename → capacity map using VirtualDisk.CapacityInKB.
  • Uses the mapped per-disk capacity when exporting/downloading VMDKs, with a warning + fallback to lease item size when mapping fails.
  • Updates logged/exported DiskImportStatus sizes to reflect the corrected per-disk value.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/source/vmware/client.go Outdated
Comment thread pkg/source/vmware/client.go Outdated
Comment thread pkg/source/vmware/client.go Outdated
Comment thread pkg/source/vmware/client.go Outdated
Signed-off-by: Samuel Vasconcelos <samuel.vasconcelos@suse.com>
Copy link
Copy Markdown
Collaborator

@ibrokethecloud ibrokethecloud left a comment

Choose a reason for hiding this comment

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

thanks for the quick fix.

Copy link
Copy Markdown
Member

@votdev votdev left a comment

Choose a reason for hiding this comment

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

LGTM, thx

@votdev votdev merged commit 4c2cc09 into harvester:main Mar 11, 2026
6 checks passed
// ignore iso and nvram disks
if strings.HasSuffix(i.Path, ".vmdk") {
baseItem := strings.ToLower(filepath.Base(i.Path))
diskSize := sizeByVmdk[baseItem]
Copy link
Copy Markdown
Member

@votdev votdev Mar 11, 2026

Choose a reason for hiding this comment

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

How does the mapping happen here? Based on the support bundle i've extracted this info:

LeaseInfo

{
  "deviceId": "/1/ParaVirtualSCSIController0:1",
  "path": "SLES16-2.vmdk",
  "size": 80530636800,
  "cimType": 0,
  "create": false,
  "URL": {
    "Scheme": "https",
    "Opaque": "",
    "User": null,
    "Host": "vmware.conteudoquestionavel.org",
    "Path": "/ha-nfc/52c91da8-6923-7676-f5a4-cbb19194098f/SLES16-2.vmdk",
    "RawPath": "",
    "OmitHost": false,
    "ForceQuery": false,
    "RawQuery": "",
    "Fragment": "",
    "RawFragment": ""
  },
  "Thumbprint": ""
},

VM spec

{
  "key": 2002,
  "deviceInfo": {
    "label": "Hard disk 3",
    "summary": "26,214,400 KB"
  },
  "backing": {
    "fileName": "[local-datastore] SLES 16/SLES 16_2.vmdk",
    "datastore": {
      "type": "Datastore",
      "value": "6985f8ec-3425f1d4-aece-a2e6808d17b3"
    },
    "diskMode": "persistent",
    "split": false,
    "writeThrough": false,
    "thinProvisioned": false,
    "eagerlyScrub": false,
    "uuid": "6000C29e-a273-0689-b75a-b2f33d9b102c",
    "contentId": "f0a5eff0d78b173514823721fffffffe",
    "digestEnabled": false,
    "sharing": "sharingNone"
  },
  "controllerKey": 1000,
  "unitNumber": 2,
  "capacityInKB": 26214400,
  "capacityInBytes": 26843545600,
  "shares": {
    "shares": 1000,
    "level": "normal"
  },
  "storageIOAllocation": {
    "limit": -1,
    "shares": {
      "shares": 1000,
      "level": "normal"
    },
    "reservation": 0
  },
  "diskObjectId": "1-2002",
  "vDiskVersion": 1,
  "nativeUnmanagedLinkedClone": false,
  "guestReadOnly": false
},

The base names that are used as the key in the dictionary do not match:

"[local-datastore] SLES 16/SLES 16_2.vmdk" vs. "SLES16-2.vmdk"

which becomes

"SLES 16_2.vmdk" vs. "SLES16-2.vmdk"

I think there needs to be done some processing or transformation to do a valid matching.

Or do i miss something here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

that's correct, in most VMware exports the LeaseItem.Path corresponds to the original backing filename, vmware probably sanitized the filename during the NFC export process, the comparison will fail, we need something more robust to compare

}, []string{"spec"})).Info("Origin spec of the volumes to be imported")

var vmMo mo.VirtualMachine
err = vmObj.Properties(c.ctx, vmObj.Reference(),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You can use the govmomi helper function

func (v VirtualMachine) Device(ctx context.Context) (VirtualDeviceList, error)
vdl, err := vmObj.Device(c.ctx)

votdev added a commit to votdev/vm-import-controller that referenced this pull request Mar 11, 2026
…)"

This reverts commit 4c2cc09.

Signed-off-by: Volker Theile <vtheile@suse.com>
votdev added a commit that referenced this pull request Mar 11, 2026
This reverts commit 4c2cc09.

Signed-off-by: Volker Theile <vtheile@suse.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants