govmomi icon indicating copy to clipboard operation
govmomi copied to clipboard

Right way to replace/swap attached disk with another existing disk

Open rickatnight11 opened this issue 1 year ago • 8 comments

I'm trying to replace the root disk across a bunch of VMs by cloning the disk from a template, then swap the new disk in for the existing one. I'm having a heck of a time figuring out the right way to do this.

I have tried with DetachDisk and AttachDisk, but struggling to determine what disk ID AttachDisk is looking for (tried the UUID, but get The object or item referred to could not be found).

I have also tried a Reconfigure (similar to https://github.com/vmware/govmomi/issues/790, but I don't just want to add another disk, I want to swap one in (and keep the original one "detached" in the datastore), which looks like a better option (more atomic), but I can't quite figure out the way to construct the desired change.

I basically want the equivalent of this call:

https://developer.vmware.com/apis/vsphere-automation/latest/vcenter/api/vcenter/vm/vm/hardware/disk/disk/patch/

Would love some guidance on how to approach this!

rickatnight11 avatar Feb 21 '24 17:02 rickatnight11

Howdy 🖐   rickatnight11 ! Thank you for your interest in this project. We value your feedback and will respond soon.

If you want to contribute to this project, please make yourself familiar with the CONTRIBUTION guidelines.

github-actions[bot] avatar Feb 21 '24 17:02 github-actions[bot]

Digging more into the code, it looks like EditDevice is the helper function I'm looking for. Trying to figure out how to use it correctly.

rickatnight11 avatar Feb 21 '24 17:02 rickatnight11

So far I've tried swapping out the disk's backing with a bare-bones one that sets a different path:

// vm = object.VirtualMachine
// newdiskpath = "[datastore-name] vm-name/new-disk.vmdk"

vmdevices, err := vm.Device(ctx)
vmrootdisk := vmdevices.FindByKey(2000)

vmrootdisk.GetVirtualDevice().Backing = &types.VirtualDiskFlatVer2BackingInfo{
    VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{
        FileName:  newdiskpath,
        Datastore: vmrootdisk.GetVirtualDevice().Backing.(types.BaseVirtualDeviceFileBackingInfo).GetVirtualDeviceFileBackingInfo().Datastore,
    },
}

vm.EditDevice(ctx, vmrootdisk)

...but vCenter is returning:

"error": {
  "fault": {
    "property": "virtualDevice.backing",
    "deviceIndex": 0,
    "badFileOp": "replace"
  },
  "localizedMessage": "Invalid operation for device '0'.",
  "Description": {
    "key": "com.vmware.vim.vpxd.vpx.vmprov.ReconfigureVm",
    "message": "Reconfiguring Virtual Machine on destination host"
  }
}

I feel like I'm close.

rickatnight11 avatar Feb 21 '24 20:02 rickatnight11

I didn't manage to figure this out, but I did finally get RemoveDevice + AddDevice working, borrowing heavily from govc's device.remove and vm.disk.attach implementations. It's slightly annoying, because I end up needing to removing all disks and adding them back to maintain the original label order (i.e. "Hard disk 1", "Hard disk 2", etc), but it works! Would still love any feedback on cleaner/preferred ways to do this.

rickatnight11 avatar Feb 22 '24 16:02 rickatnight11

This issue is stale because it has been open for 90 days with no activity. It will automatically close after 30 more days of inactivity. Mark as fresh by adding the comment /remove-lifecycle stale.

github-actions[bot] avatar May 23 '24 01:05 github-actions[bot]

/remove-lifecycle stale

rickatnight11 avatar May 23 '24 19:05 rickatnight11

This issue is stale because it has been open for 90 days with no activity. It will automatically close after 30 more days of inactivity. Mark as fresh by adding the comment /remove-lifecycle stale.

github-actions[bot] avatar Aug 22 '24 01:08 github-actions[bot]

/remove-lifecycle stale

rickatnight11 avatar Aug 23 '24 20:08 rickatnight11