vmware: fix inter-cluster stopped vm and volume migration#4895
vmware: fix inter-cluster stopped vm and volume migration#4895yadvr merged 7 commits intoapache:4.15from
Conversation
Fixes apache#4838 For inter-cluster migration without shared storage, VMware needs a host to be specified. Fix is to specify an appropriate host in the target cluster. Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
|
@blueorangutan package |
|
@shwstppr a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress. |
|
Packaging result: ✔️ centos7 ✔️ centos8 ✔️ debian. SL-JID 336 |
|
@blueorangutan test centos7 vmware-67u3 |
|
@shwstppr a Trillian-Jenkins test job (centos7 mgmt + vmware-67u3) has been kicked to run smoke tests |
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
DaanHoogland
left a comment
There was a problem hiding this comment.
mostly structural change requests so far.
| List<VolumeVO> volumes = _volumeDao.findByInstanceAndType(vmId, Volume.Type.ROOT); | ||
| if (CollectionUtils.isNotEmpty(volumes)) { | ||
| VolumeVO rootVolume = volumes.get(0); | ||
| if (rootVolume.getPoolId() != null) { | ||
| StoragePoolVO pool = _storagePoolDao.findById(rootVolume.getPoolId()); | ||
| if (pool != null && pool.getClusterId() != null) { | ||
| clusterId = pool.getClusterId(); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
please extract into a separate method. i.e. Long getPoolFromRootVolume(...)
| final boolean isInterClusterMigration = srcClusterId != null && destClusterId != null && ! srcClusterId.equals(destClusterId); | ||
| Host hostInTargetCluster = null; | ||
| if (isInterClusterMigration) { | ||
| // Without host vMotion might fail between non-shared storages with error similar to, | ||
| // https://kb.vmware.com/s/article/1003795 | ||
| // As this is offline migration VM won't be started on this host | ||
| List<HostVO> hosts = _hostDao.findHypervisorHostInCluster(destClusterId); | ||
| if (CollectionUtils.isNotEmpty(hosts)) { | ||
| hostInTargetCluster = hosts.get(0); | ||
| } | ||
| if (hostInTargetCluster == null) { | ||
| throw new CloudRuntimeException("Migration failed, unable to find suitable target host for VM placement while migrating between storage pools of different clusters without shared storages"); | ||
| } | ||
| } | ||
| MigrateVmToPoolCommand migrateVmToPoolCommand = new MigrateVmToPoolCommand(vm.getInstanceName(), | ||
| vols, destination.getUuid(), hostInTargetCluster == null ? null : hostInTargetCluster.getGuid(), true); | ||
| commands.add(migrateVmToPoolCommand); |
There was a problem hiding this comment.
please restructure this in smaller methods
| private Answer migrateAndAnswer(VirtualMachineMO vmMo, String poolUuid, VmwareHypervisorHost hyperHost, Command cmd) throws Exception { | ||
| ManagedObjectReference morDs = getTargetDatastoreMOReference(poolUuid, hyperHost); | ||
|
|
||
| private Answer migrateAndAnswer(VirtualMachineMO vmMo, String poolUuid, VmwareHypervisorHost sourceHyperHost, |
There was a problem hiding this comment.
please restructure this method (at least extract the new pieces)
| morDcOfTargetHost = tgtHyperHost.getHyperHostDatacenter(); | ||
| if (!morDc.getValue().equalsIgnoreCase(morDcOfTargetHost.getValue())) { | ||
| String msg = "Source host & target host are in different datacentesr"; | ||
| String msg = "Source host & target host are in different datacenter"; |
| VmwareHypervisorHost hyperHostInTargetCluster = null; | ||
| if (cmd.getHostGuidInTargetCluster() != null) { | ||
| hyperHostInTargetCluster = VmwareHelper.getHostMOFromHostName(getServiceContext(), cmd.getHostGuidInTargetCluster()); | ||
| } | ||
| VmwareHypervisorHost targetDSHost = hyperHostInTargetCluster != null ? hyperHostInTargetCluster : hyperHost; |
There was a problem hiding this comment.
this merrits a call to a specific method
There was a problem hiding this comment.
@DaanHoogland which specific method? I didn't get you
There was a problem hiding this comment.
something like
| VmwareHypervisorHost hyperHostInTargetCluster = null; | |
| if (cmd.getHostGuidInTargetCluster() != null) { | |
| hyperHostInTargetCluster = VmwareHelper.getHostMOFromHostName(getServiceContext(), cmd.getHostGuidInTargetCluster()); | |
| } | |
| VmwareHypervisorHost targetDSHost = hyperHostInTargetCluster != null ? hyperHostInTargetCluster : hyperHost; | |
| VmwareHypervisorHost targetDSHost = getTargetHostFromTargetCluster(cmd); |
and
| VmwareHypervisorHost hyperHostInTargetCluster = null; | |
| if (cmd.getHostGuidInTargetCluster() != null) { | |
| hyperHostInTargetCluster = VmwareHelper.getHostMOFromHostName(getServiceContext(), cmd.getHostGuidInTargetCluster()); | |
| } | |
| VmwareHypervisorHost targetDSHost = hyperHostInTargetCluster != null ? hyperHostInTargetCluster : hyperHost; | |
| private VmwareHypervisorHost getTargetHostFromTargetCluster(MigrateVolumeCmd cmd) { | |
| VmwareHypervisorHost hyperHostInTargetCluster = null; | |
| if (cmd.getHostGuidInTargetCluster() != null) { | |
| hyperHostInTargetCluster = VmwareHelper.getHostMOFromHostName(getServiceContext(), cmd.getHostGuidInTargetCluster()); | |
| } | |
| return hyperHostInTargetCluster != null ? hyperHostInTargetCluster : hyperHost; | |
| } |
There was a problem hiding this comment.
@DaanHoogland both hyperHostInTargetCluster and targetDSHost are used in the method later multiple times. I used two different variables to prevent using if..else multiple times.
| String hardwareVersion = null; | ||
| if (hyperHostInTargetCluster != null) { | ||
| Integer sourceHardwareVersion = HypervisorHostHelper.getHostHardwareVersion(hyperHost); | ||
| Integer destinationHardwareVersion = HypervisorHostHelper.getHostHardwareVersion(hyperHostInTargetCluster); | ||
| if (sourceHardwareVersion != null && destinationHardwareVersion != null && !sourceHardwareVersion.equals(destinationHardwareVersion)) { | ||
| hardwareVersion = String.valueOf(Math.min(sourceHardwareVersion, destinationHardwareVersion)); | ||
| } | ||
| } |
| ScopeType targetScopeType = destData.getDataStore().getScope().getScopeType(); | ||
| Long hostId = null; | ||
| String hostGuidInTargetCluster = null; | ||
| if (ScopeType.CLUSTER.equals(sourceScopeType)) { | ||
| // Find Volume source cluster and select any Vmware hypervisor host to attach worker VM | ||
| hostId = findSuitableHostIdForWorkerVmPlacement(sourcePool.getClusterId()); | ||
| if (hostId == null) { | ||
| throw new CloudRuntimeException("Offline Migration failed, unable to find suitable host for worker VM placement in the cluster of storage pool: " + sourcePool.getName()); | ||
| } | ||
| if (ScopeType.CLUSTER.equals(targetScopeType) && !sourcePool.getClusterId().equals(targetPool.getClusterId())) { | ||
| // Without host vMotion might fail between non-shared storages with error similar to, | ||
| // https://kb.vmware.com/s/article/1003795 | ||
| List<HostVO> hosts = hostDao.findHypervisorHostInCluster(targetPool.getClusterId()); | ||
| if (CollectionUtils.isNotEmpty(hosts)) { | ||
| hostGuidInTargetCluster = hosts.get(0).getGuid(); | ||
| } | ||
| if (hostGuidInTargetCluster == null) { | ||
| throw new CloudRuntimeException("Offline Migration failed, unable to find suitable target host for worker VM placement while migrating between storage pools of different cluster without shared storages"); | ||
| } | ||
| } | ||
| } else if (ScopeType.CLUSTER.equals(targetScopeType)) { | ||
| hostId = findSuitableHostIdForWorkerVmPlacement(targetPool.getClusterId()); | ||
| if (hostId == null) { | ||
| throw new CloudRuntimeException("Offline Migration failed, unable to find suitable host for worker VM placement in the cluster of storage pool: " + targetPool.getName()); | ||
| } | ||
| } |
There was a problem hiding this comment.
please extract getTargetScopeType(..) and possibly more methods from that.
|
Trillian test result (tid-357)
|
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
|
@blueorangutan package |
|
@shwstppr a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress. |
|
Packaging result: ✔️ centos7 ✔️ centos8 ✔️ debian. SL-JID 342 |
|
@blueorangutan test centos7 vmware-67u3 |
|
@shwstppr a Trillian-Jenkins test job (centos7 mgmt + vmware-67u3) has been kicked to run smoke tests |
|
Trillian test result (tid-370)
|
plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java
Outdated
Show resolved
Hide resolved
vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
Show resolved
Hide resolved
vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
Show resolved
Hide resolved
VM can have multiple ROOT volumes and some can be on zone-wide store therefore iterate over all of them till a cluster ID is found. Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
|
@blueorangutan package |
|
@shwstppr a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress. |
|
Packaging result: ✔️ centos7 ✔️ centos8 ✔️ debian. SL-JID 358 |
|
@blueorangutan test centos7 vmware-67u3 |
|
@borisstoyanov a Trillian-Jenkins test job (centos7 mgmt + vmware-67u3) has been kicked to run smoke tests |
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
|
@blueorangutan package |
|
@shwstppr a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress. |
|
Packaging result: ✔️ centos7 ✔️ centos8 ✔️ debian. SL-JID 361 |
|
@blueorangutan test centos7 vmware-67u3 |
|
@borisstoyanov a Trillian-Jenkins test job (centos7 mgmt + vmware-67u3) has been kicked to run smoke tests |
|
Trillian test result (tid-385)
|
borisstoyanov
left a comment
There was a problem hiding this comment.
LGTM, tested on VMware with single and successive migration of VM
|
@nvazquez are you lgtm on the PR? Will hold merging until your confirmation. |
|
Merged based on Bobby, Nicolas's review and testing, and smoketests. |
Description
Fixes #4838
For inter-cluster migration without shared storage, VMware needs a host to be specified. Fix is to specify an appropriate host in the target cluster during a stopped VM migration. Also, find target datastore using the host in the target cluster.
Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Bug Severity
Screenshots (if appropriate):
How Has This Been Tested?