Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions core/src/main/java/com/cloud/agent/api/MigrateVmToPoolCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
//
package com.cloud.agent.api;

import com.cloud.agent.api.to.VolumeTO;

import java.util.Collection;

import com.cloud.agent.api.to.VolumeTO;

/**
* used to tell the agent to migrate a vm to a different primary storage pool.
* It is for now only implemented on Vmware and is supposed to work irrespective of whether the VM is started or not.
Expand All @@ -32,6 +32,7 @@ public class MigrateVmToPoolCommand extends Command {
private String vmName;
private String destinationPool;
private boolean executeInSequence = false;
private String hostGuidInTargetCluster;

protected MigrateVmToPoolCommand() {
}
Expand All @@ -41,15 +42,22 @@ protected MigrateVmToPoolCommand() {
* @param vmName the name of the VM to migrate
* @param volumes used to supply feedback on vmware generated names
* @param destinationPool the primary storage pool to migrate the VM to
* @param hostGuidInTargetCluster GUID of host in target cluster when migrating across clusters
* @param executeInSequence
*/
public MigrateVmToPoolCommand(String vmName, Collection<VolumeTO> volumes, String destinationPool, boolean executeInSequence) {
public MigrateVmToPoolCommand(String vmName, Collection<VolumeTO> volumes, String destinationPool,
String hostGuidInTargetCluster, boolean executeInSequence) {
this.vmName = vmName;
this.volumes = volumes;
this.destinationPool = destinationPool;
this.hostGuidInTargetCluster = hostGuidInTargetCluster;
this.executeInSequence = executeInSequence;
}

public MigrateVmToPoolCommand(String vmName, Collection<VolumeTO> volumes, String destinationPool, boolean executeInSequence) {
this(vmName, volumes, destinationPool, null, executeInSequence);
}

public Collection<VolumeTO> getVolumes() {
return volumes;
}
Expand All @@ -62,6 +70,10 @@ public String getVmName() {
return vmName;
}

public String getHostGuidInTargetCluster() {
return hostGuidInTargetCluster;
}

@Override
public boolean executeInSequence() {
return executeInSequence;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class MigrateVolumeCommand extends Command {
StorageFilerTO sourcePool;
String attachedVmName;
Volume.Type volumeType;
private String hostGuidInTargetCluster;

private DataTO srcData;
private DataTO destData;
Expand All @@ -54,9 +55,10 @@ public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool,
this.setWait(timeout);
}

public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool sourcePool, StoragePool targetPool) {
public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool sourcePool, StoragePool targetPool, String hostGuidInTargetCluster) {
this(volumeId,volumePath,targetPool, null, Volume.Type.UNKNOWN, -1);
this.sourcePool = new StorageFilerTO(sourcePool);
this.hostGuidInTargetCluster = hostGuidInTargetCluster;
}

public MigrateVolumeCommand(DataTO srcData, DataTO destData, Map<String, String> srcDetails, Map<String, String> destDetails, int timeout) {
Expand Down Expand Up @@ -101,6 +103,10 @@ public Volume.Type getVolumeType() {
return volumeType;
}

public String getHostGuidInTargetCluster() {
return hostGuidInTargetCluster;
}

public DataTO getSrcData() {
return srcData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
// under the License.
package com.cloud.hypervisor.guru;

import static com.cloud.utils.NumbersUtil.toHumanReadableSize;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
Expand Down Expand Up @@ -149,8 +151,6 @@
import com.vmware.vim25.VirtualMachineConfigSummary;
import com.vmware.vim25.VirtualMachineRuntimeInfo;

import static com.cloud.utils.NumbersUtil.toHumanReadableSize;

public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Configurable {
private static final Logger s_logger = Logger.getLogger(VMwareGuru.class);

Expand Down Expand Up @@ -209,16 +209,35 @@ protected VMwareGuru() {
return vmwareVmImplementer.implement(vm, toVirtualMachineTO(vm), getClusterId(vm.getId()));
}

long getClusterId(long vmId) {
long clusterId;
Long hostId;

hostId = _vmDao.findById(vmId).getHostId();
if (hostId == null) {
Long getClusterId(long vmId) {
Long clusterId = null;
Long hostId = null;
VMInstanceVO vm = _vmDao.findById(vmId);
if (vm != null) {
hostId = _vmDao.findById(vmId).getHostId();
}
if (vm != null && hostId == null) {
// If VM is in stopped state then hostId would be undefined. Hence read last host's Id instead.
hostId = _vmDao.findById(vmId).getLastHostId();
}
clusterId = _hostDao.findById(hostId).getClusterId();
HostVO host = null;
if (hostId != null) {
host = _hostDao.findById(hostId);
}
if (host != null) {
clusterId = host.getClusterId();
} else {
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();
}
}
}

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.

please extract into a separate method. i.e. Long getPoolFromRootVolume(...)

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.

}

return clusterId;
}
Expand Down Expand Up @@ -418,9 +437,11 @@ private static String resolveNameInGuid(String guid) {

@Override public Map<String, String> getClusterSettings(long vmId) {
Map<String, String> details = new HashMap<String, String>();
long clusterId = getClusterId(vmId);
details.put(VmwareReserveCpu.key(), VmwareReserveCpu.valueIn(clusterId).toString());
details.put(VmwareReserveMemory.key(), VmwareReserveMemory.valueIn(clusterId).toString());
Long clusterId = getClusterId(vmId);
if (clusterId != null) {
details.put(VmwareReserveCpu.key(), VmwareReserveCpu.valueIn(clusterId).toString());
details.put(VmwareReserveMemory.key(), VmwareReserveMemory.valueIn(clusterId).toString());
}
return details;
}

Expand Down Expand Up @@ -1066,14 +1087,29 @@ private VirtualDisk getAttachedDisk(VirtualMachineMO vmMo, String diskPath) thro
VolumeTO vol = new VolumeTO(volume, destination);
vols.add(vol);
}
MigrateVmToPoolCommand migrateVmToPoolCommand = new MigrateVmToPoolCommand(vm.getInstanceName(), vols, destination.getUuid(), true);
commands.add(migrateVmToPoolCommand);

// OfflineVmwareMigration: cleanup if needed
final Long destClusterId = destination.getClusterId();
final Long srcClusterId = getClusterId(vm.getId());
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);

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.

please restructure this in smaller methods

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.


if (srcClusterId != null && destClusterId != null && !srcClusterId.equals(destClusterId)) {
// OfflineVmwareMigration: cleanup if needed
if (isInterClusterMigration) {
final String srcDcName = _clusterDetailsDao.getVmwareDcName(srcClusterId);
final String destDcName = _clusterDetailsDao.getVmwareDcName(destClusterId);
if (srcDcName != null && destDcName != null && !srcDcName.equals(destDcName)) {
Expand Down
Loading