Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ceb16c2
vmware: migration improvements
shwstppr Oct 1, 2020
1fa0c79
ui changes
shwstppr Oct 5, 2020
c41d5fb
null hypervisor check
shwstppr Oct 5, 2020
003af0e
review changes
shwstppr Oct 6, 2020
6aad7a7
review changes
shwstppr Oct 6, 2020
341a69f
fix
shwstppr Oct 6, 2020
503ae44
fixes
shwstppr Oct 7, 2020
d2a2ec5
Merge branch 'master' into vmware-migration-improvements
shwstppr Nov 3, 2020
45ad746
fix volume migration
shwstppr Nov 13, 2020
39683d8
fix
shwstppr Nov 13, 2020
74f85ba
fix datastore type getter
shwstppr Nov 13, 2020
9b1e0f6
fix
shwstppr Nov 17, 2020
d409b3b
log
shwstppr Nov 18, 2020
2039b55
get host hardware version
shwstppr Nov 18, 2020
aee302b
add newer version
shwstppr Nov 18, 2020
9824683
retrieve hardwareVersion from sdk
shwstppr Nov 18, 2020
4419ce6
revert to hardwareversion mapping
shwstppr Nov 19, 2020
4085a14
fix ui
shwstppr Nov 19, 2020
dd7825f
fix
shwstppr Nov 19, 2020
9ca75f0
changes for system vm
shwstppr Nov 20, 2020
919c5dd
fix
shwstppr Nov 20, 2020
8f6b1d1
fix npe on defaultnic
shwstppr Nov 20, 2020
c765b87
revert SDK configurationEx property changes
shwstppr Nov 20, 2020
d50e3ac
Merge branch 'master' into vmware-migration-improvements
shwstppr Nov 20, 2020
fa661f3
use static mapping for api version to hardware version
shwstppr Dec 7, 2020
0e07ff2
Merge branch 'master' into vmware-migration-improvements
shwstppr Dec 7, 2020
a67382f
Merge branch 'master' into vmware-migration-improvements
shwstppr Dec 29, 2020
131b5e0
fix systemvm migration with volume on zone-wide store
shwstppr Dec 29, 2020
102ceea
fix
shwstppr Dec 29, 2020
892cdeb
fixes
shwstppr Jan 4, 2021
391fcf2
Merge branch 'master' into vmware-migration-improvements
shwstppr Jan 12, 2021
da7de1f
fix post hypervisor storage migration cleanup
shwstppr Jan 12, 2021
6220a60
Merge branch 'master' into vmware-migration-improvements
shwstppr Jan 22, 2021
099d170
ui: moved over new ui changes from old repo
shwstppr Jan 22, 2021
a204e31
refactor
shwstppr Jan 27, 2021
6a03a7c
add missing file
shwstppr Feb 1, 2021
9f4fc90
Merge branch 'master' into vmware-migration-improvements
shwstppr Feb 3, 2021
e73fa08
remove tag matching for user provided mappings
shwstppr Feb 3, 2021
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
3 changes: 2 additions & 1 deletion api/src/main/java/com/cloud/hypervisor/HypervisorGuru.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.StoragePool;
import com.cloud.storage.Volume;
import com.cloud.utils.Pair;
import com.cloud.utils.component.Adapter;
import com.cloud.vm.NicProfile;
Expand Down Expand Up @@ -99,5 +100,5 @@ boolean attachRestoredVolumeToVirtualMachine(long zoneId, String location, Backu
* @param destination the primary storage pool to migrate to
* @return a list of commands to perform for a successful migration
*/
List<Command> finalizeMigrate(VirtualMachine vm, StoragePool destination);
List<Command> finalizeMigrate(VirtualMachine vm, Map<Volume, StoragePool> volumeToPool);
}
2 changes: 2 additions & 0 deletions api/src/main/java/com/cloud/vm/UserVmService.java
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,8 @@ UserVm moveVMToUser(AssignVMCmd moveUserVMCmd) throws ResourceAllocationExceptio

VirtualMachine vmStorageMigration(Long vmId, StoragePool destPool);

VirtualMachine vmStorageMigration(Long vmId, Map<String, String> volumeToPool);

UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException;

UserVm restoreVirtualMachine(Account caller, long vmId, Long newTemplateId) throws InsufficientCapacityException, ResourceUnavailableException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.admin.systemvm;

import org.apache.log4j.Logger;
import java.util.HashMap;

import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.ACL;
Expand All @@ -27,8 +27,10 @@
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.SystemVmResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;

import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
Expand All @@ -37,6 +39,7 @@
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.VirtualMachineMigrationException;
import com.cloud.host.Host;
import com.cloud.storage.StoragePool;
import com.cloud.user.Account;
import com.cloud.vm.VirtualMachine;

Expand All @@ -54,7 +57,6 @@ public class MigrateSystemVMCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.HOST_ID,
type = CommandType.UUID,
entityType = HostResponse.class,
required = true,
description = "destination Host ID to migrate VM to")
private Long hostId;

Expand All @@ -66,6 +68,13 @@ public class MigrateSystemVMCmd extends BaseAsyncCmd {
description = "the ID of the virtual machine")
private Long virtualMachineId;

@Parameter(name = ApiConstants.STORAGE_ID,
since = "4.16.0",
type = CommandType.UUID,
entityType = StoragePoolResponse.class,
description = "Destination storage pool ID to migrate VM volumes to. Required for migrating the root disk volume")
private Long storageId;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand All @@ -78,6 +87,10 @@ public Long getVirtualMachineId() {
return virtualMachineId;
}

public Long getStorageId() {
return storageId;
}

/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -109,15 +122,35 @@ public String getEventDescription() {

@Override
public void execute() {
if (getHostId() == null && getStorageId() == null) {
throw new InvalidParameterValueException("Either hostId or storageId must be specified");
}

Host destinationHost = _resourceService.getHost(getHostId());
if (destinationHost == null) {
throw new InvalidParameterValueException("Unable to find the host to migrate the VM, host id=" + getHostId());
if (getHostId() != null && getStorageId() != null) {
throw new InvalidParameterValueException("Only one of hostId and storageId can be specified");
}
try {
CallContext.current().setEventDetails("VM Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()) + " to host Id: " + this._uuidMgr.getUuid(Host.class, getHostId()));
//FIXME : Should not be calling UserVmService to migrate all types of VMs - need a generic VM layer
VirtualMachine migratedVm = _userVmService.migrateVirtualMachine(getVirtualMachineId(), destinationHost);
VirtualMachine migratedVm = null;
if (getHostId() != null) {
Host destinationHost = _resourceService.getHost(getHostId());
if (destinationHost == null) {
throw new InvalidParameterValueException("Unable to find the host to migrate the VM, host id=" + getHostId());
}
if (destinationHost.getType() != Host.Type.Routing) {
throw new InvalidParameterValueException("The specified host(" + destinationHost.getName() + ") is not suitable to migrate the VM, please specify another one");
}
CallContext.current().setEventDetails("VM Id: " + getVirtualMachineId() + " to host Id: " + getHostId());
migratedVm = _userVmService.migrateVirtualMachineWithVolume(getVirtualMachineId(), destinationHost, new HashMap<String, String>());
} else if (getStorageId() != null) {
// OfflineMigration performed when this parameter is specified
StoragePool destStoragePool = _storageService.getStoragePool(getStorageId());
if (destStoragePool == null) {
throw new InvalidParameterValueException("Unable to find the storage pool to migrate the VM");
}
CallContext.current().setEventDetails("VM Id: " + getVirtualMachineId() + " to storage pool Id: " + getStorageId());
migratedVm = _userVmService.vmStorageMigration(getVirtualMachineId(), destStoragePool);
Copy link
Contributor

Choose a reason for hiding this comment

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

@shwstppr possible to optimise multiple checks for getHostId() and getStorageId() not null here ?

}
if (migratedVm != null) {
// return the generic system VM instance response
SystemVmResponse response = _responseGenerator.createSystemVmResponse(migratedVm);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import java.util.Iterator;
import java.util.Map;

import org.apache.log4j.Logger;

import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
Expand All @@ -32,6 +30,8 @@
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.commons.collections.MapUtils;
import org.apache.log4j.Logger;

import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
Expand Down Expand Up @@ -61,7 +61,6 @@ public class MigrateVirtualMachineWithVolumeCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.HOST_ID,
type = CommandType.UUID,
entityType = HostResponse.class,
required = true,
description = "Destination Host ID to migrate VM to.")
private Long hostId;

Expand Down Expand Up @@ -97,7 +96,7 @@ public Long getVirtualMachineId() {

public Map<String, String> getVolumeToPool() {
Map<String, String> volumeToPoolMap = new HashMap<String, String>();
if (migrateVolumeTo != null && !migrateVolumeTo.isEmpty()) {
if (MapUtils.isNotEmpty(migrateVolumeTo)) {
Collection<?> allValues = migrateVolumeTo.values();
Iterator<?> iter = allValues.iterator();
while (iter.hasNext()) {
Expand Down Expand Up @@ -141,19 +140,35 @@ public String getEventDescription() {

@Override
public void execute() {
if (hostId == null && MapUtils.isEmpty(migrateVolumeTo)) {
throw new InvalidParameterValueException(String.format("Either %s or %s must be passed for migrating the VM", ApiConstants.HOST_ID, ApiConstants.MIGRATE_TO));
}

UserVm userVm = _userVmService.getUserVm(getVirtualMachineId());
if (userVm == null) {
throw new InvalidParameterValueException("Unable to find the VM by id=" + getVirtualMachineId());
}

Host destinationHost = _resourceService.getHost(getHostId());
// OfflineVmwareMigration: destination host would have to not be a required parameter for stopped VMs
if (destinationHost == null) {
throw new InvalidParameterValueException("Unable to find the host to migrate the VM, host id =" + getHostId());
if (!VirtualMachine.State.Running.equals(userVm.getState()) && hostId != null) {
throw new InvalidParameterValueException(String.format("VM ID: %s is not in Running state to migrate it to new host", userVm.getUuid()));
}

if (!VirtualMachine.State.Stopped.equals(userVm.getState()) && hostId == null) {
throw new InvalidParameterValueException(String.format("VM ID: %s is not in Stopped state to migrate, use %s parameter to migrate it to a new host", userVm.getUuid(), ApiConstants.HOST_ID));
}

try {
VirtualMachine migratedVm = _userVmService.migrateVirtualMachineWithVolume(getVirtualMachineId(), destinationHost, getVolumeToPool());
VirtualMachine migratedVm = null;
if (hostId != null) {
Host destinationHost = _resourceService.getHost(getHostId());
// OfflineVmwareMigration: destination host would have to not be a required parameter for stopped VMs
if (destinationHost == null) {
throw new InvalidParameterValueException("Unable to find the host to migrate the VM, host id =" + getHostId());
}
migratedVm = _userVmService.migrateVirtualMachineWithVolume(getVirtualMachineId(), destinationHost, getVolumeToPool());
} else if (MapUtils.isNotEmpty(migrateVolumeTo)) {
migratedVm = _userVmService.vmStorageMigration(getVirtualMachineId(), getVolumeToPool());
}
if (migratedVm != null) {
UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", (UserVm)migratedVm).get(0);
response.setResponseName(getCommandName());
Expand Down
33 changes: 18 additions & 15 deletions core/src/main/java/com/cloud/agent/api/MigrateVmToPoolCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,48 +18,51 @@
//
package com.cloud.agent.api;

import com.cloud.agent.api.to.VolumeTO;
import java.util.List;

import java.util.Collection;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.utils.Pair;

/**
* 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.
*
*/
public class MigrateVmToPoolCommand extends Command {
private Collection<VolumeTO> volumes;
private String vmName;
private String destinationPool;
private boolean executeInSequence = false;
private List<Pair<VolumeTO, StorageFilerTO>> volumeToFilerAsList;
private String hostGuidInTargetCluster;

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 volumeToFilerTo the volume to primary storage pool map 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, List<Pair<VolumeTO, StorageFilerTO>> volumeToFilerTo,
String hostGuidInTargetCluster, boolean executeInSequence) {
this.vmName = vmName;
this.volumes = volumes;
this.destinationPool = destinationPool;
this.hostGuidInTargetCluster = hostGuidInTargetCluster;
this.volumeToFilerAsList = volumeToFilerTo;
this.executeInSequence = executeInSequence;
}

public Collection<VolumeTO> getVolumes() {
return volumes;
public String getVmName() {
return vmName;
}

public String getDestinationPool() {
return destinationPool;
public List<Pair<VolumeTO, StorageFilerTO>> getVolumeToFilerAsList() {
return volumeToFilerAsList;
}

public String getVmName() {
return vmName;
public String getHostGuidInTargetCluster() {
return hostGuidInTargetCluster;
}

@Override
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;
String hostGuidInTargetCluster;

private DataTO srcData;
private DataTO destData;
Expand Down Expand Up @@ -68,6 +69,11 @@ public MigrateVolumeCommand(DataTO srcData, DataTO destData, Map<String, String>
setWait(timeout);
}

public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool sourcePool, StoragePool targetPool, String targetClusterHost) {
this(volumeId, volumePath, sourcePool, targetPool);
this.hostGuidInTargetCluster = targetClusterHost;
}

@Override
public boolean executeInSequence() {
return true;
Expand Down Expand Up @@ -125,7 +131,11 @@ public Map<String, String> getDestDetails() {
return destDetails;
}

public String getHostGuidInTargetCluster() {
return hostGuidInTargetCluster;
}

public int getWaitInMillSeconds() {
return getWait() * 1000;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@

package org.apache.cloudstack.storage.to;

import com.cloud.storage.MigrationOptions;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;

import com.cloud.agent.api.to.DataObjectType;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.offering.DiskOffering.DiskCacheMode;
import com.cloud.storage.MigrationOptions;
import com.cloud.storage.Storage;
import com.cloud.storage.Volume;

Expand Down Expand Up @@ -62,6 +62,7 @@ public class VolumeObjectTO implements DataTO {
private Hypervisor.HypervisorType hypervisorType;
private MigrationOptions migrationOptions;
private boolean directDownload;
private String dataStoreUuid;
private boolean deployAsIs;
private String updatedDataStoreUUID;
private String vSphereStoragePolicyId;
Expand Down Expand Up @@ -319,6 +320,14 @@ public boolean isDirectDownload() {
return directDownload;
}

public String getDataStoreUuid() {
return dataStoreUuid;
}

public void setDataStoreUuid(String dataStoreUuid) {
this.dataStoreUuid = dataStoreUuid;
}

public boolean isDeployAsIs() {
return deployAsIs;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import com.cloud.offering.DiskOffering;
import com.cloud.offering.DiskOfferingInfo;
import com.cloud.offering.ServiceOffering;
import com.cloud.storage.StoragePool;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.uservm.UserVm;
Expand Down Expand Up @@ -167,7 +166,7 @@ void advanceReboot(String vmUuid, Map<VirtualMachineProfile.Param, Object> param

VirtualMachine findById(long vmId);

void storageMigration(String vmUuid, StoragePool storagePoolId);
void storageMigration(String vmUuid, Map<Long, Long> volumeToPool);

/**
* @param vmInstance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Lon

void migrateVolumes(VirtualMachine vm, VirtualMachineTO vmTo, Host srcHost, Host destHost, Map<Volume, StoragePool> volumeToPool);

boolean storageMigration(VirtualMachineProfile vm, StoragePool destPool) throws StorageUnavailableException;
boolean storageMigration(VirtualMachineProfile vm, Map<Volume, StoragePool> volumeToPool) throws StorageUnavailableException;

void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest);

Expand Down
Loading