mirror of https://github.com/apache/cloudstack.git
Boot into hardware setup menu on Vmware (#4021)
This commit is contained in:
parent
fbfab5b5eb
commit
0795cd430b
|
|
@ -65,6 +65,7 @@ public class VirtualMachineTO {
|
|||
String uuid;
|
||||
String bootType;
|
||||
String bootMode;
|
||||
boolean enterHardwareSetup;
|
||||
|
||||
DiskTO[] disks;
|
||||
NicTO[] nics;
|
||||
|
|
@ -393,4 +394,12 @@ public class VirtualMachineTO {
|
|||
public String getBootMode() { return bootMode; }
|
||||
|
||||
public void setBootMode(String bootMode) { this.bootMode = bootMode; }
|
||||
|
||||
public boolean isEnterHardwareSetup() {
|
||||
return enterHardwareSetup;
|
||||
}
|
||||
|
||||
public void setEnterHardwareSetup(boolean enterHardwareSetup) {
|
||||
this.enterHardwareSetup = enterHardwareSetup;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ public interface VirtualMachineProfile {
|
|||
public static final Param UefiFlag = new Param("UefiFlag");
|
||||
public static final Param BootMode = new Param("BootMode");
|
||||
public static final Param BootType = new Param("BootType");
|
||||
public static final Param BootIntoSetup = new Param("enterHardwareSetup");
|
||||
|
||||
private String name;
|
||||
|
||||
|
|
|
|||
|
|
@ -805,8 +805,9 @@ public class ApiConstants {
|
|||
public static final String NODE_ROOT_DISK_SIZE = "noderootdisksize";
|
||||
public static final String SUPPORTS_HA = "supportsha";
|
||||
|
||||
public static final String BOOT_TYPE ="boottype";
|
||||
public static final String BOOT_MODE ="bootmode";
|
||||
public static final String BOOT_TYPE = "boottype";
|
||||
public static final String BOOT_MODE = "bootmode";
|
||||
public static final String BOOT_INTO_SETUP = "bootintosetup";
|
||||
|
||||
public enum BootType {
|
||||
UEFI, BIOS;
|
||||
|
|
|
|||
|
|
@ -113,12 +113,15 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
|
|||
@Parameter(name = ApiConstants.NETWORK_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = NetworkResponse.class, description = "list of network ids used by virtual machine. Can't be specified with ipToNetworkList parameter")
|
||||
private List<Long> networkIds;
|
||||
|
||||
@Parameter(name = ApiConstants.BOOT_TYPE, type = CommandType.STRING, required = false, description = "Guest VM Boot option either custom[UEFI] or default boot [BIOS]")
|
||||
@Parameter(name = ApiConstants.BOOT_TYPE, type = CommandType.STRING, required = false, description = "Guest VM Boot option either custom[UEFI] or default boot [BIOS]", since = "4.14.0.0")
|
||||
private String bootType;
|
||||
|
||||
@Parameter(name = ApiConstants.BOOT_MODE, type = CommandType.STRING, required = false, description = "Boot Mode [Legacy] or [Secure] Applicable when Boot Type Selected is UEFI, otherwise Legacy By default for BIOS")
|
||||
@Parameter(name = ApiConstants.BOOT_MODE, type = CommandType.STRING, required = false, description = "Boot Mode [Legacy] or [Secure] Applicable when Boot Type Selected is UEFI, otherwise Legacy By default for BIOS", since = "4.14.0.0")
|
||||
private String bootMode;
|
||||
|
||||
@Parameter(name = ApiConstants.BOOT_INTO_SETUP, type = CommandType.BOOLEAN, required = false, description = "Boot into hardware setup or not (ignored if startVm = false, only valid for vmware)", since = "4.15.0.0")
|
||||
private Boolean bootIntoSetup;
|
||||
|
||||
//DataDisk information
|
||||
@ACL
|
||||
@Parameter(name = ApiConstants.DISK_OFFERING_ID, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "the ID of the disk offering for the virtual machine. If the template is of ISO format,"
|
||||
|
|
@ -281,15 +284,14 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
|
|||
}
|
||||
}
|
||||
}
|
||||
if(getBootType() != null){ // export to get
|
||||
if(getBootType() == ApiConstants.BootType.UEFI) {
|
||||
customparameterMap.put(getBootType().toString(), getBootMode().toString());
|
||||
}
|
||||
if (ApiConstants.BootType.UEFI.equals(getBootType())) {
|
||||
customparameterMap.put(getBootType().toString(), getBootMode().toString());
|
||||
}
|
||||
|
||||
if (rootdisksize != null && !customparameterMap.containsKey("rootdisksize")) {
|
||||
customparameterMap.put("rootdisksize", rootdisksize.toString());
|
||||
}
|
||||
|
||||
return customparameterMap;
|
||||
}
|
||||
|
||||
|
|
@ -577,6 +579,10 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
|
|||
return copyImageTags == null ? false : copyImageTags;
|
||||
}
|
||||
|
||||
public Boolean getBootIntoSetup() {
|
||||
return bootIntoSetup;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ public class RebootVMCmd extends BaseAsyncCmd implements UserCmd {
|
|||
required=true, description="The ID of the virtual machine")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.BOOT_INTO_SETUP, type = CommandType.BOOLEAN, required = false, description = "Boot into hardware setup menu or not", since = "4.15.0.0")
|
||||
private Boolean bootIntoSetup;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -61,6 +64,10 @@ public class RebootVMCmd extends BaseAsyncCmd implements UserCmd {
|
|||
return id;
|
||||
}
|
||||
|
||||
public Boolean getBootIntoSetup() {
|
||||
return bootIntoSetup;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ public class StartVMCmd extends BaseAsyncCmd implements UserCmd {
|
|||
@Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "Deployment planner to use for vm allocation. Available to ROOT admin only", since = "4.4", authorized = { RoleType.Admin })
|
||||
private String deploymentPlanner;
|
||||
|
||||
@Parameter(name = ApiConstants.BOOT_INTO_SETUP, type = CommandType.BOOLEAN, required = false, description = "Boot into hardware setup menu or not", since = "4.15.0.0")
|
||||
private Boolean bootIntoSetup;
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////////// Accessors ///////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
|
@ -105,6 +108,10 @@ public class StartVMCmd extends BaseAsyncCmd implements UserCmd {
|
|||
return clusterId;
|
||||
}
|
||||
|
||||
public Boolean getBootIntoSetup() {
|
||||
return bootIntoSetup;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////// API Implementation///////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -503,14 +503,13 @@ public class HostResponse extends BaseResponse {
|
|||
detailsCopy.remove("username");
|
||||
detailsCopy.remove("password");
|
||||
|
||||
if(detailsCopy.containsKey(Host.HOST_UEFI_ENABLE)) {
|
||||
if (detailsCopy.containsKey(Host.HOST_UEFI_ENABLE)) {
|
||||
this.setUefiCapabilty(Boolean.parseBoolean((String) detailsCopy.get(Host.HOST_UEFI_ENABLE)));
|
||||
detailsCopy.remove(Host.HOST_UEFI_ENABLE);
|
||||
} else {
|
||||
this.setUefiCapabilty(new Boolean(false)); // in case of existing host which is not scanned for UEFI capability
|
||||
}
|
||||
|
||||
|
||||
this.details = detailsCopy;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -889,6 +889,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
||||
if ( jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("start parameter value of %s == %s during dispatching",
|
||||
VirtualMachineProfile.Param.BootIntoSetup.getName(),
|
||||
(params == null?"<very null>":params.get(VirtualMachineProfile.Param.BootIntoSetup))));
|
||||
}
|
||||
// avoid re-entrance
|
||||
VmWorkJobVO placeHolder = null;
|
||||
final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
|
||||
|
|
@ -901,6 +906,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("start parameter value of %s == %s during processing of queued job",
|
||||
VirtualMachineProfile.Param.BootIntoSetup.getName(),
|
||||
(params == null?"<very null>":params.get(VirtualMachineProfile.Param.BootIntoSetup))));
|
||||
}
|
||||
final Outcome<VirtualMachine> outcome = startVmThroughJobQueue(vmUuid, params, planToDeploy, planner);
|
||||
|
||||
try {
|
||||
|
|
@ -1064,10 +1074,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
|
||||
final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, owner, params);
|
||||
s_logger.info(" Uefi params " + "UefiFlag: " + params.get(VirtualMachineProfile.Param.UefiFlag)
|
||||
+ " Boot Type: " + params.get(VirtualMachineProfile.Param.BootType)
|
||||
+ " Boot Mode: " + params.get(VirtualMachineProfile.Param.BootMode)
|
||||
);
|
||||
logBootModeParameters(params);
|
||||
DeployDestination dest = null;
|
||||
try {
|
||||
dest = _dpMgr.planDeployment(vmProfile, plan, avoids, planner);
|
||||
|
|
@ -1137,6 +1144,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
final VirtualMachineTO vmTO = hvGuru.implement(vmProfile);
|
||||
|
||||
checkAndSetEnterSetupMode(vmTO, params);
|
||||
|
||||
handlePath(vmTO.getDisks(), vm.getHypervisorType());
|
||||
|
||||
cmds = new Commands(Command.OnError.Stop);
|
||||
|
|
@ -1315,6 +1324,30 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
}
|
||||
|
||||
private void logBootModeParameters(Map<VirtualMachineProfile.Param, Object> params) {
|
||||
StringBuffer msgBuf = new StringBuffer("Uefi params ");
|
||||
boolean log = false;
|
||||
if (params.get(VirtualMachineProfile.Param.UefiFlag) != null) {
|
||||
msgBuf.append(String.format("UefiFlag: %s ", params.get(VirtualMachineProfile.Param.UefiFlag)));
|
||||
log = true;
|
||||
}
|
||||
if (params.get(VirtualMachineProfile.Param.BootType) != null) {
|
||||
msgBuf.append(String.format("Boot Type: %s ", params.get(VirtualMachineProfile.Param.BootType)));
|
||||
log = true;
|
||||
}
|
||||
if (params.get(VirtualMachineProfile.Param.BootMode) != null) {
|
||||
msgBuf.append(String.format("Boot Mode: %s ", params.get(VirtualMachineProfile.Param.BootMode)));
|
||||
log = true;
|
||||
}
|
||||
if (params.get(VirtualMachineProfile.Param.BootIntoSetup) != null) {
|
||||
msgBuf.append(String.format("Boot into Setup: %s ", params.get(VirtualMachineProfile.Param.BootIntoSetup)));
|
||||
log = true;
|
||||
}
|
||||
if (log) {
|
||||
s_logger.info(msgBuf.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Add extra config data to the vmTO as a Map
|
||||
private void addExtraConfig(VirtualMachineTO vmTO) {
|
||||
Map<String, String> details = vmTO.getDetails();
|
||||
|
|
@ -3094,6 +3127,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
|
||||
placeHolder = createPlaceHolderWork(vm.getId());
|
||||
try {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("reboot parameter value of %s == %s at orchestration", VirtualMachineProfile.Param.BootIntoSetup.getName(),
|
||||
(params == null? "<very null>":params.get(VirtualMachineProfile.Param.BootIntoSetup))));
|
||||
}
|
||||
orchestrateReboot(vmUuid, params);
|
||||
} finally {
|
||||
if (placeHolder != null) {
|
||||
|
|
@ -3101,6 +3138,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("reboot parameter value of %s == %s through job-queue", VirtualMachineProfile.Param.BootIntoSetup.getName(),
|
||||
(params == null? "<very null>":params.get(VirtualMachineProfile.Param.BootIntoSetup))));
|
||||
}
|
||||
final Outcome<VirtualMachine> outcome = rebootVmThroughJobQueue(vmUuid, params);
|
||||
|
||||
try {
|
||||
|
|
@ -3150,7 +3191,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
final Commands cmds = new Commands(Command.OnError.Stop);
|
||||
RebootCommand rebootCmd = new RebootCommand(vm.getInstanceName(), getExecuteInSequence(vm.getHypervisorType()));
|
||||
rebootCmd.setVirtualMachine(getVmTO(vm.getId()));
|
||||
VirtualMachineTO vmTo = getVmTO(vm.getId());
|
||||
checkAndSetEnterSetupMode(vmTo, params);
|
||||
rebootCmd.setVirtualMachine(vmTo);
|
||||
cmds.addCommand(rebootCmd);
|
||||
_agentMgr.send(host.getId(), cmds);
|
||||
|
||||
|
|
@ -3170,6 +3213,14 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
}
|
||||
|
||||
private void checkAndSetEnterSetupMode(VirtualMachineTO vmTo, Map<VirtualMachineProfile.Param, Object> params) {
|
||||
Boolean enterSetup = (Boolean)params.get(VirtualMachineProfile.Param.BootIntoSetup);
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("orchestrating VM reboot for '%s' %s set to %s", vmTo.getName(), VirtualMachineProfile.Param.BootIntoSetup, enterSetup));
|
||||
}
|
||||
vmTo.setEnterHardwareSetup(enterSetup == null ? false : enterSetup);
|
||||
}
|
||||
|
||||
protected VirtualMachineTO getVmTO(Long vmId) {
|
||||
final VMInstanceVO vm = _vmDao.findById(vmId);
|
||||
final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
|
||||
|
|
@ -5223,6 +5274,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
assert vm != null;
|
||||
|
||||
Boolean enterSetup = (Boolean)work.getParams().get(VirtualMachineProfile.Param.BootIntoSetup);
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("orchestrating VM start for '%s' %s set to %s", vm.getInstanceName(), VirtualMachineProfile.Param.BootIntoSetup, enterSetup));
|
||||
}
|
||||
|
||||
try{
|
||||
orchestrateStart(vm.getUuid(), work.getParams(), work.getPlan(), _dpMgr.getDeploymentPlannerByName(work.getDeploymentPlanner()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,19 +17,15 @@
|
|||
package com.cloud.hypervisor.guru;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
|
||||
|
|
@ -61,13 +57,11 @@ import com.cloud.agent.api.UnregisterVMCommand;
|
|||
import com.cloud.agent.api.storage.CopyVolumeCommand;
|
||||
import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
|
||||
import com.cloud.agent.api.storage.CreateVolumeOVACommand;
|
||||
import com.cloud.agent.api.storage.OVFPropertyTO;
|
||||
import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
|
||||
import com.cloud.agent.api.to.DataObjectType;
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.agent.api.to.DataTO;
|
||||
import com.cloud.agent.api.to.DiskTO;
|
||||
import com.cloud.agent.api.to.NicTO;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
import com.cloud.cluster.ClusterManager;
|
||||
|
|
@ -75,7 +69,6 @@ import com.cloud.configuration.Resource;
|
|||
import com.cloud.dc.ClusterDetailsDao;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.event.UsageEventUtils;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
|
|
@ -90,18 +83,13 @@ import com.cloud.hypervisor.vmware.dao.VmwareDatacenterDao;
|
|||
import com.cloud.hypervisor.vmware.dao.VmwareDatacenterZoneMapDao;
|
||||
import com.cloud.hypervisor.vmware.manager.VmwareManager;
|
||||
import com.cloud.hypervisor.vmware.mo.DatacenterMO;
|
||||
import com.cloud.hypervisor.vmware.mo.DiskControllerType;
|
||||
import com.cloud.hypervisor.vmware.mo.NetworkMO;
|
||||
import com.cloud.hypervisor.vmware.mo.VirtualDiskManagerMO;
|
||||
import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
|
||||
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder;
|
||||
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
|
||||
import com.cloud.hypervisor.vmware.resource.VmwareContextFactory;
|
||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.Networks;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
|
|
@ -117,11 +105,9 @@ import com.cloud.service.ServiceOfferingVO;
|
|||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.DataStoreRole;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.GuestOSHypervisorVO;
|
||||
import com.cloud.storage.GuestOSVO;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.TemplateOVFPropertyVO;
|
||||
import com.cloud.storage.VMTemplateStoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
|
|
@ -129,20 +115,16 @@ import com.cloud.storage.Volume;
|
|||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.GuestOSDao;
|
||||
import com.cloud.storage.dao.GuestOSHypervisorDao;
|
||||
import com.cloud.storage.dao.TemplateOVFPropertiesDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.secondary.SecondaryStorageVmManager;
|
||||
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.UuidUtils;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.SecondaryStorageVmVO;
|
||||
|
|
@ -152,8 +134,6 @@ import com.cloud.vm.VirtualMachine;
|
|||
import com.cloud.vm.VirtualMachine.Type;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
|
@ -172,373 +152,62 @@ import com.vmware.vim25.VirtualMachineRuntimeInfo;
|
|||
public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Configurable {
|
||||
private static final Logger s_logger = Logger.getLogger(VMwareGuru.class);
|
||||
|
||||
@Inject
|
||||
private NetworkDao _networkDao;
|
||||
@Inject
|
||||
private GuestOSDao _guestOsDao;
|
||||
@Inject
|
||||
private GuestOSHypervisorDao _guestOsHypervisorDao;
|
||||
@Inject
|
||||
private HostDao _hostDao;
|
||||
@Inject
|
||||
private HostDetailsDao _hostDetailsDao;
|
||||
@Inject
|
||||
private ClusterDetailsDao _clusterDetailsDao;
|
||||
@Inject
|
||||
private CommandExecLogDao _cmdExecLogDao;
|
||||
@Inject
|
||||
private VmwareManager _vmwareMgr;
|
||||
@Inject
|
||||
private SecondaryStorageVmManager _secStorageMgr;
|
||||
@Inject
|
||||
private NetworkModel _networkMgr;
|
||||
@Inject
|
||||
private NicDao _nicDao;
|
||||
@Inject
|
||||
private DomainRouterDao _domainRouterDao;
|
||||
@Inject
|
||||
private PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
|
||||
@Inject
|
||||
private VMInstanceDao _vmDao;
|
||||
@Inject
|
||||
private VirtualMachineManager vmManager;
|
||||
@Inject
|
||||
private ClusterManager _clusterMgr;
|
||||
@Inject
|
||||
VolumeDao _volumeDao;
|
||||
@Inject
|
||||
ResourceLimitService _resourceLimitService;
|
||||
@Inject
|
||||
PrimaryDataStoreDao _storagePoolDao;
|
||||
@Inject
|
||||
VolumeDataFactory _volFactory;
|
||||
@Inject
|
||||
private VmwareDatacenterDao vmwareDatacenterDao;
|
||||
@Inject
|
||||
private VmwareDatacenterZoneMapDao vmwareDatacenterZoneMapDao;
|
||||
@Inject
|
||||
private ServiceOfferingDao serviceOfferingDao;
|
||||
@Inject
|
||||
private VMTemplatePoolDao templateStoragePoolDao;
|
||||
@Inject
|
||||
private VMTemplateDao vmTemplateDao;
|
||||
@Inject
|
||||
private UserVmDao userVmDao;
|
||||
@Inject
|
||||
private DiskOfferingDao diskOfferingDao;
|
||||
@Inject
|
||||
private PhysicalNetworkDao physicalNetworkDao;
|
||||
@Inject
|
||||
private TemplateOVFPropertiesDao templateOVFPropertiesDao;
|
||||
|
||||
@Inject VmwareVmImplementer vmwareVmImplementer;
|
||||
|
||||
@Inject NetworkDao _networkDao;
|
||||
@Inject GuestOSDao _guestOsDao;
|
||||
@Inject HostDao _hostDao;
|
||||
@Inject HostDetailsDao _hostDetailsDao;
|
||||
@Inject ClusterDetailsDao _clusterDetailsDao;
|
||||
@Inject CommandExecLogDao _cmdExecLogDao;
|
||||
@Inject VmwareManager _vmwareMgr;
|
||||
@Inject SecondaryStorageVmManager _secStorageMgr;
|
||||
@Inject NicDao _nicDao;
|
||||
@Inject PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
|
||||
@Inject VMInstanceDao _vmDao;
|
||||
@Inject VirtualMachineManager vmManager;
|
||||
@Inject ClusterManager _clusterMgr;
|
||||
@Inject VolumeDao _volumeDao;
|
||||
@Inject ResourceLimitService _resourceLimitService;
|
||||
@Inject PrimaryDataStoreDao _storagePoolDao;
|
||||
@Inject VolumeDataFactory _volFactory;
|
||||
@Inject VmwareDatacenterDao vmwareDatacenterDao;
|
||||
@Inject VmwareDatacenterZoneMapDao vmwareDatacenterZoneMapDao;
|
||||
@Inject ServiceOfferingDao serviceOfferingDao;
|
||||
@Inject VMTemplatePoolDao templateStoragePoolDao;
|
||||
@Inject VMTemplateDao vmTemplateDao;
|
||||
@Inject UserVmDao userVmDao;
|
||||
@Inject DiskOfferingDao diskOfferingDao;
|
||||
@Inject PhysicalNetworkDao physicalNetworkDao;
|
||||
|
||||
protected VMwareGuru() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static final ConfigKey<Boolean> VmwareReserveCpu = new ConfigKey<Boolean>(Boolean.class, "vmware.reserve.cpu", "Advanced", "false",
|
||||
"Specify whether or not to reserve CPU when deploying an instance.", true, ConfigKey.Scope.Cluster,
|
||||
null);
|
||||
"Specify whether or not to reserve CPU when deploying an instance.", true, ConfigKey.Scope.Cluster, null);
|
||||
|
||||
public static final ConfigKey<Boolean> VmwareReserveMemory = new ConfigKey<Boolean>(Boolean.class, "vmware.reserve.mem", "Advanced", "false",
|
||||
"Specify whether or not to reserve memory when deploying an instance.", true,
|
||||
ConfigKey.Scope.Cluster, null);
|
||||
"Specify whether or not to reserve memory when deploying an instance.", true, ConfigKey.Scope.Cluster, null);
|
||||
|
||||
protected ConfigKey<Boolean> VmwareEnableNestedVirtualization = new ConfigKey<Boolean>(Boolean.class, "vmware.nested.virtualization", "Advanced", "false",
|
||||
public static final ConfigKey<Boolean> VmwareEnableNestedVirtualization = new ConfigKey<Boolean>(Boolean.class, "vmware.nested.virtualization", "Advanced", "false",
|
||||
"When set to true this will enable nested virtualization when this is supported by the hypervisor", true, ConfigKey.Scope.Global, null);
|
||||
|
||||
protected ConfigKey<Boolean> VmwareEnableNestedVirtualizationPerVM = new ConfigKey<Boolean>(Boolean.class, "vmware.nested.virtualization.perVM", "Advanced", "false",
|
||||
public static final ConfigKey<Boolean> VmwareEnableNestedVirtualizationPerVM = new ConfigKey<Boolean>(Boolean.class, "vmware.nested.virtualization.perVM", "Advanced", "false",
|
||||
"When set to true this will enable nested virtualization per vm", true, ConfigKey.Scope.Global, null);
|
||||
|
||||
@Override
|
||||
public HypervisorType getHypervisorType() {
|
||||
@Override public HypervisorType getHypervisorType() {
|
||||
return HypervisorType.VMware;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualMachineTO implement(VirtualMachineProfile vm) {
|
||||
VirtualMachineTO to = toVirtualMachineTO(vm);
|
||||
to.setBootloader(BootloaderType.HVM);
|
||||
|
||||
Map<String, String> details = to.getDetails();
|
||||
if (details == null)
|
||||
details = new HashMap<String, String>();
|
||||
|
||||
Type vmType = vm.getType();
|
||||
boolean userVm = !(vmType.equals(VirtualMachine.Type.DomainRouter) || vmType.equals(VirtualMachine.Type.ConsoleProxy)
|
||||
|| vmType.equals(VirtualMachine.Type.SecondaryStorageVm));
|
||||
|
||||
String nicDeviceType = details.get(VmDetailConstants.NIC_ADAPTER);
|
||||
if (!userVm) {
|
||||
|
||||
if (nicDeviceType == null) {
|
||||
details.put(VmDetailConstants.NIC_ADAPTER, _vmwareMgr.getSystemVMDefaultNicAdapterType());
|
||||
} else {
|
||||
try {
|
||||
VirtualEthernetCardType.valueOf(nicDeviceType);
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
|
||||
details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// for user-VM, use E1000 as default
|
||||
if (nicDeviceType == null) {
|
||||
details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
|
||||
} else {
|
||||
try {
|
||||
VirtualEthernetCardType.valueOf(nicDeviceType);
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
|
||||
details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
details.put(VmDetailConstants.BOOT_MODE, to.getBootMode());
|
||||
String diskDeviceType = details.get(VmDetailConstants.ROOT_DISK_CONTROLLER);
|
||||
if (userVm) {
|
||||
if (diskDeviceType == null) {
|
||||
details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, _vmwareMgr.getRootDiskController());
|
||||
}
|
||||
}
|
||||
String diskController = details.get(VmDetailConstants.DATA_DISK_CONTROLLER);
|
||||
if (userVm) {
|
||||
if (diskController == null) {
|
||||
details.put(VmDetailConstants.DATA_DISK_CONTROLLER, DiskControllerType.lsilogic.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (vm.getType() == VirtualMachine.Type.NetScalerVm) {
|
||||
details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, "scsi");
|
||||
}
|
||||
|
||||
List<NicProfile> nicProfiles = vm.getNics();
|
||||
|
||||
for (NicProfile nicProfile : nicProfiles) {
|
||||
if (nicProfile.getTrafficType() == TrafficType.Guest) {
|
||||
if (_networkMgr.isProviderSupportServiceInNetwork(nicProfile.getNetworkId(), Service.Firewall, Provider.CiscoVnmc)) {
|
||||
details.put("ConfigureVServiceInNexus", Boolean.TRUE.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
long clusterId = getClusterId(vm.getId());
|
||||
details.put(VmwareReserveCpu.key(), VmwareReserveCpu.valueIn(clusterId).toString());
|
||||
details.put(VmwareReserveMemory.key(), VmwareReserveMemory.valueIn(clusterId).toString());
|
||||
to.setDetails(details);
|
||||
|
||||
if (vmType.equals(VirtualMachine.Type.DomainRouter)) {
|
||||
|
||||
NicProfile publicNicProfile = null;
|
||||
for (NicProfile nicProfile : nicProfiles) {
|
||||
if (nicProfile.getTrafficType() == TrafficType.Public) {
|
||||
publicNicProfile = nicProfile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (publicNicProfile != null) {
|
||||
NicTO[] nics = to.getNics();
|
||||
|
||||
// reserve extra NICs
|
||||
NicTO[] expandedNics = new NicTO[nics.length + _vmwareMgr.getRouterExtraPublicNics()];
|
||||
int i = 0;
|
||||
int deviceId = -1;
|
||||
for (i = 0; i < nics.length; i++) {
|
||||
expandedNics[i] = nics[i];
|
||||
if (nics[i].getDeviceId() > deviceId)
|
||||
deviceId = nics[i].getDeviceId();
|
||||
}
|
||||
deviceId++;
|
||||
|
||||
long networkId = publicNicProfile.getNetworkId();
|
||||
NetworkVO network = _networkDao.findById(networkId);
|
||||
|
||||
for (; i < nics.length + _vmwareMgr.getRouterExtraPublicNics(); i++) {
|
||||
NicTO nicTo = new NicTO();
|
||||
|
||||
nicTo.setDeviceId(deviceId++);
|
||||
nicTo.setBroadcastType(publicNicProfile.getBroadcastType());
|
||||
nicTo.setType(publicNicProfile.getTrafficType());
|
||||
nicTo.setIp("0.0.0.0");
|
||||
nicTo.setNetmask("255.255.255.255");
|
||||
|
||||
try {
|
||||
String mac = _networkMgr.getNextAvailableMacAddressInNetwork(networkId);
|
||||
nicTo.setMac(mac);
|
||||
} catch (InsufficientAddressCapacityException e) {
|
||||
throw new CloudRuntimeException("unable to allocate mac address on network: " + networkId);
|
||||
}
|
||||
nicTo.setDns1(publicNicProfile.getIPv4Dns1());
|
||||
nicTo.setDns2(publicNicProfile.getIPv4Dns2());
|
||||
if (publicNicProfile.getIPv4Gateway() != null) {
|
||||
nicTo.setGateway(publicNicProfile.getIPv4Gateway());
|
||||
} else {
|
||||
nicTo.setGateway(network.getGateway());
|
||||
}
|
||||
nicTo.setDefaultNic(false);
|
||||
nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri());
|
||||
nicTo.setIsolationuri(publicNicProfile.getIsolationUri());
|
||||
|
||||
Integer networkRate = _networkMgr.getNetworkRate(network.getId(), null);
|
||||
nicTo.setNetworkRateMbps(networkRate);
|
||||
|
||||
expandedNics[i] = nicTo;
|
||||
}
|
||||
|
||||
to.setNics(expandedNics);
|
||||
|
||||
VirtualMachine router = vm.getVirtualMachine();
|
||||
DomainRouterVO routerVO = _domainRouterDao.findById(router.getId());
|
||||
if (routerVO != null && routerVO.getIsRedundantRouter()) {
|
||||
Long peerRouterId = _nicDao.getPeerRouterId(publicNicProfile.getMacAddress(), router.getId());
|
||||
DomainRouterVO peerRouterVO = null;
|
||||
if (peerRouterId != null) {
|
||||
peerRouterVO = _domainRouterDao.findById(peerRouterId);
|
||||
if (peerRouterVO != null) {
|
||||
details.put("PeerRouterInstanceName", peerRouterVO.getInstanceName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringBuffer sbMacSequence = new StringBuffer();
|
||||
for (NicTO nicTo : sortNicsByDeviceId(to.getNics())) {
|
||||
sbMacSequence.append(nicTo.getMac()).append("|");
|
||||
}
|
||||
if (!sbMacSequence.toString().isEmpty()) {
|
||||
sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
|
||||
String bootArgs = to.getBootArgs();
|
||||
to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Don't do this if the virtual machine is one of the special types
|
||||
// Should only be done on user machines
|
||||
if (userVm) {
|
||||
configureNestedVirtualization(details, to);
|
||||
}
|
||||
// Determine the VM's OS description
|
||||
GuestOSVO guestOS = _guestOsDao.findByIdIncludingRemoved(vm.getVirtualMachine().getGuestOSId());
|
||||
to.setOs(guestOS.getDisplayName());
|
||||
to.setHostName(vm.getHostName());
|
||||
HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId());
|
||||
GuestOSHypervisorVO guestOsMapping = null;
|
||||
if (host != null) {
|
||||
guestOsMapping = _guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), getHypervisorType().toString(), host.getHypervisorVersion());
|
||||
}
|
||||
if (guestOsMapping == null || host == null) {
|
||||
to.setPlatformEmulator(null);
|
||||
} else {
|
||||
to.setPlatformEmulator(guestOsMapping.getGuestOsName());
|
||||
}
|
||||
|
||||
List<OVFPropertyTO> ovfProperties = new ArrayList<>();
|
||||
for (String detailKey : details.keySet()) {
|
||||
if (detailKey.startsWith(ApiConstants.OVF_PROPERTIES)) {
|
||||
String ovfPropKey = detailKey.replace(ApiConstants.OVF_PROPERTIES + "-", "");
|
||||
TemplateOVFPropertyVO templateOVFPropertyVO = templateOVFPropertiesDao.findByTemplateAndKey(vm.getTemplateId(), ovfPropKey);
|
||||
if (templateOVFPropertyVO == null) {
|
||||
s_logger.warn(String.format("OVF property %s not found on template, discarding", ovfPropKey));
|
||||
continue;
|
||||
}
|
||||
String ovfValue = details.get(detailKey);
|
||||
boolean isPassword = templateOVFPropertyVO.isPassword();
|
||||
OVFPropertyTO propertyTO = new OVFPropertyTO(ovfPropKey, ovfValue, isPassword);
|
||||
ovfProperties.add(propertyTO);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(ovfProperties)) {
|
||||
removeOvfPropertiesFromDetails(ovfProperties, details);
|
||||
String templateInstallPath = null;
|
||||
List<DiskTO> rootDiskList = vm.getDisks().stream().filter(x -> x.getType() == Volume.Type.ROOT).collect(Collectors.toList());
|
||||
if (rootDiskList.size() != 1) {
|
||||
throw new CloudRuntimeException("Did not find only one root disk for VM " + vm.getHostName());
|
||||
}
|
||||
|
||||
DiskTO rootDiskTO = rootDiskList.get(0);
|
||||
DataStoreTO dataStore = rootDiskTO.getData().getDataStore();
|
||||
StoragePoolVO storagePoolVO = _storagePoolDao.findByUuid(dataStore.getUuid());
|
||||
long dataCenterId = storagePoolVO.getDataCenterId();
|
||||
List<StoragePoolVO> pools = _storagePoolDao.listByDataCenterId(dataCenterId);
|
||||
for (StoragePoolVO pool : pools) {
|
||||
VMTemplateStoragePoolVO ref = templateStoragePoolDao.findByPoolTemplate(pool.getId(), vm.getTemplateId());
|
||||
if (ref != null && ref.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
|
||||
templateInstallPath = ref.getInstallPath();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (templateInstallPath == null) {
|
||||
throw new CloudRuntimeException("Did not find the template install path for template " +
|
||||
vm.getTemplateId() + " on zone " + dataCenterId);
|
||||
}
|
||||
|
||||
Pair<String, List<OVFPropertyTO>> pair = new Pair<>(templateInstallPath, ovfProperties);
|
||||
to.setOvfProperties(pair);
|
||||
}
|
||||
|
||||
return to;
|
||||
@Override public VirtualMachineTO implement(VirtualMachineProfile vm) {
|
||||
vmwareVmImplementer.setGlobalNestedVirtualisationEnabled(VmwareEnableNestedVirtualization.value());
|
||||
vmwareVmImplementer.setGlobalNestedVPerVMEnabled(VmwareEnableNestedVirtualizationPerVM.value());
|
||||
return vmwareVmImplementer.implement(vm, toVirtualMachineTO(vm), getClusterId(vm.getId()));
|
||||
}
|
||||
|
||||
/*
|
||||
Remove OVF properties from details to be sent to hypervisor (avoid duplicate data)
|
||||
*/
|
||||
private void removeOvfPropertiesFromDetails(List<OVFPropertyTO> ovfProperties, Map<String, String> details) {
|
||||
for (OVFPropertyTO propertyTO : ovfProperties) {
|
||||
String key = propertyTO.getKey();
|
||||
details.remove(ApiConstants.OVF_PROPERTIES + "-" + key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide in which cases nested virtualization should be enabled based on (1){@code globalNestedV}, (2){@code globalNestedVPerVM}, (3){@code localNestedV}<br/>
|
||||
* Nested virtualization should be enabled when one of this cases:
|
||||
* <ul>
|
||||
* <li>(1)=TRUE, (2)=TRUE, (3) is NULL (missing)</li>
|
||||
* <li>(1)=TRUE, (2)=TRUE, (3)=TRUE</li>
|
||||
* <li>(1)=TRUE, (2)=FALSE</li>
|
||||
* <li>(1)=FALSE, (2)=TRUE, (3)=TRUE</li>
|
||||
* </ul>
|
||||
* In any other case, it shouldn't be enabled
|
||||
* @param globalNestedV value of {@code 'vmware.nested.virtualization'} global config
|
||||
* @param globalNestedVPerVM value of {@code 'vmware.nested.virtualization.perVM'} global config
|
||||
* @param localNestedV value of {@code 'nestedVirtualizationFlag'} key in vm details if present, null if not present
|
||||
* @return "true" for cases in which nested virtualization is enabled, "false" if not
|
||||
*/
|
||||
protected Boolean shouldEnableNestedVirtualization(Boolean globalNestedV, Boolean globalNestedVPerVM, String localNestedV){
|
||||
if (globalNestedV == null || globalNestedVPerVM == null) {
|
||||
return false;
|
||||
}
|
||||
boolean globalNV = globalNestedV.booleanValue();
|
||||
boolean globalNVPVM = globalNestedVPerVM.booleanValue();
|
||||
|
||||
if (globalNVPVM){
|
||||
return (localNestedV == null && globalNV) || BooleanUtils.toBoolean(localNestedV);
|
||||
}
|
||||
return globalNV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds {@code 'nestedVirtualizationFlag'} value to {@code details} due to if it should be enabled or not
|
||||
* @param details vm details
|
||||
* @param to vm to
|
||||
*/
|
||||
protected void configureNestedVirtualization(Map<String, String> details, VirtualMachineTO to) {
|
||||
Boolean globalNestedV = VmwareEnableNestedVirtualization.value();
|
||||
Boolean globalNestedVPerVM = VmwareEnableNestedVirtualizationPerVM.value();
|
||||
String localNestedV = details.get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG);
|
||||
|
||||
Boolean shouldEnableNestedVirtualization = shouldEnableNestedVirtualization(globalNestedV, globalNestedVPerVM, localNestedV);
|
||||
s_logger.debug("Nested virtualization requested, adding flag to vm configuration");
|
||||
details.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, Boolean.toString(shouldEnableNestedVirtualization));
|
||||
to.setDetails(details);
|
||||
}
|
||||
|
||||
private long getClusterId(long vmId) {
|
||||
long getClusterId(long vmId) {
|
||||
long clusterId;
|
||||
Long hostId;
|
||||
|
||||
|
|
@ -552,32 +221,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
return clusterId;
|
||||
}
|
||||
|
||||
private NicTO[] sortNicsByDeviceId(NicTO[] nics) {
|
||||
|
||||
List<NicTO> listForSort = new ArrayList<NicTO>();
|
||||
for (NicTO nic : nics) {
|
||||
listForSort.add(nic);
|
||||
}
|
||||
Collections.sort(listForSort, new Comparator<NicTO>() {
|
||||
|
||||
@Override
|
||||
public int compare(NicTO arg0, NicTO arg1) {
|
||||
if (arg0.getDeviceId() < arg1.getDeviceId()) {
|
||||
return -1;
|
||||
} else if (arg0.getDeviceId() == arg1.getDeviceId()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
return listForSort.toArray(new NicTO[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
|
||||
@Override @DB public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
|
||||
boolean needDelegation = false;
|
||||
if (cmd instanceof StorageSubSystemCommand) {
|
||||
Boolean fullCloneEnabled = VmwareFullClone.value();
|
||||
|
|
@ -585,12 +229,12 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
c.setExecuteInSequence(fullCloneEnabled);
|
||||
}
|
||||
if (cmd instanceof DownloadCommand) {
|
||||
cmd.setContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key(), String.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.value()));
|
||||
cmd.setContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key(), String.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.value()));
|
||||
}
|
||||
//NOTE: the hostid can be a hypervisor host, or a ssvm agent. For copycommand, if it's for volume upload, the hypervisor
|
||||
//type is empty, so we need to check the format of volume at first.
|
||||
if (cmd instanceof CopyCommand) {
|
||||
CopyCommand cpyCommand = (CopyCommand) cmd;
|
||||
CopyCommand cpyCommand = (CopyCommand)cmd;
|
||||
DataTO srcData = cpyCommand.getSrcTO();
|
||||
DataStoreTO srcStoreTO = srcData.getDataStore();
|
||||
DataTO destData = cpyCommand.getDestTO();
|
||||
|
|
@ -617,8 +261,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
|
||||
}
|
||||
|
||||
if (destData.getObjectType() == DataObjectType.VOLUME && destStoreTO.getRole() == DataStoreRole.Primary &&
|
||||
srcData.getObjectType() == DataObjectType.TEMPLATE && srcStoreTO.getRole() == DataStoreRole.Primary) {
|
||||
if (destData.getObjectType() == DataObjectType.VOLUME && destStoreTO.getRole() == DataStoreRole.Primary && srcData.getObjectType() == DataObjectType.TEMPLATE
|
||||
&& srcStoreTO.getRole() == DataStoreRole.Primary) {
|
||||
needDelegation = false;
|
||||
} else {
|
||||
needDelegation = true;
|
||||
|
|
@ -662,9 +306,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
cmd.setContextParam("vCenterSessionTimeout", String.valueOf(_vmwareMgr.getVcenterSessionTimeout()));
|
||||
cmd.setContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key(), String.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.value()));
|
||||
|
||||
if (cmd instanceof BackupSnapshotCommand || cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
|
||||
cmd instanceof CreatePrivateTemplateFromSnapshotCommand || cmd instanceof CopyVolumeCommand || cmd instanceof CopyCommand ||
|
||||
cmd instanceof CreateVolumeOVACommand || cmd instanceof PrepareOVAPackingCommand || cmd instanceof CreateVolumeFromSnapshotCommand) {
|
||||
if (cmd instanceof BackupSnapshotCommand || cmd instanceof CreatePrivateTemplateFromVolumeCommand || cmd instanceof CreatePrivateTemplateFromSnapshotCommand || cmd instanceof CopyVolumeCommand || cmd instanceof CopyCommand || cmd instanceof CreateVolumeOVACommand || cmd instanceof PrepareOVAPackingCommand
|
||||
|| cmd instanceof CreateVolumeFromSnapshotCommand) {
|
||||
String workerName = _vmwareMgr.composeWorkerName();
|
||||
long checkPointId = 1;
|
||||
// FIXME: Fix long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName));
|
||||
|
|
@ -707,8 +350,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
return tokens[0] + "@" + vCenterIp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics) {
|
||||
@Override public List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics) {
|
||||
List<Command> commands = new ArrayList<Command>();
|
||||
List<NicVO> nicVOs = _nicDao.listByVmId(vm.getId());
|
||||
for (NicVO nic : nicVOs) {
|
||||
|
|
@ -719,26 +361,22 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
// We need the traffic label to figure out which vSwitch has the
|
||||
// portgroup
|
||||
PhysicalNetworkTrafficTypeVO trafficTypeVO = _physicalNetworkTrafficTypeDao.findBy(networkVO.getPhysicalNetworkId(), networkVO.getTrafficType());
|
||||
UnregisterNicCommand unregisterNicCommand =
|
||||
new UnregisterNicCommand(vm.getInstanceName(), trafficTypeVO.getVmwareNetworkLabel(), UUID.fromString(nic.getUuid()));
|
||||
UnregisterNicCommand unregisterNicCommand = new UnregisterNicCommand(vm.getInstanceName(), trafficTypeVO.getVmwareNetworkLabel(), UUID.fromString(nic.getUuid()));
|
||||
commands.add(unregisterNicCommand);
|
||||
}
|
||||
}
|
||||
return commands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigComponentName() {
|
||||
@Override public String getConfigComponentName() {
|
||||
return VMwareGuru.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
@Override public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[] {VmwareReserveCpu, VmwareReserveMemory, VmwareEnableNestedVirtualization, VmwareEnableNestedVirtualizationPerVM};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Command> finalizeExpungeVolumes(VirtualMachine vm) {
|
||||
@Override public List<Command> finalizeExpungeVolumes(VirtualMachine vm) {
|
||||
List<Command> commands = new ArrayList<Command>();
|
||||
|
||||
List<VolumeVO> volumes = _volumeDao.findByInstance(vm.getId());
|
||||
|
|
@ -776,8 +414,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
return commands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getClusterSettings(long vmId) {
|
||||
@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());
|
||||
|
|
@ -799,8 +436,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
*/
|
||||
private DatacenterMO getDatacenterMO(long zoneId) throws Exception {
|
||||
VmwareDatacenterVO vmwareDatacenter = getVmwareDatacenter(zoneId);
|
||||
VmwareContext context = VmwareContextFactory.getContext(vmwareDatacenter.getVcenterHost(),
|
||||
vmwareDatacenter.getUser(), vmwareDatacenter.getPassword());
|
||||
VmwareContext context = VmwareContextFactory.getContext(vmwareDatacenter.getVcenterHost(), vmwareDatacenter.getUser(), vmwareDatacenter.getPassword());
|
||||
DatacenterMO dcMo = new DatacenterMO(context, vmwareDatacenter.getVmwareDatacenterName());
|
||||
ManagedObjectReference dcMor = dcMo.getMor();
|
||||
if (dcMor == null) {
|
||||
|
|
@ -826,9 +462,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
*/
|
||||
private ServiceOfferingVO createServiceOfferingForVMImporting(Integer cpus, Integer memory, Integer maxCpuUsage) {
|
||||
String name = "Imported-" + cpus + "-" + memory;
|
||||
ServiceOfferingVO vo = new ServiceOfferingVO(name, cpus, memory, maxCpuUsage, null, null,
|
||||
false, name, Storage.ProvisioningType.THIN, false, false,
|
||||
null, false, Type.User, false);
|
||||
ServiceOfferingVO vo = new ServiceOfferingVO(name, cpus, memory, maxCpuUsage, null, null, false, name, Storage.ProvisioningType.THIN, false, false, null, false, Type.User,
|
||||
false);
|
||||
return serviceOfferingDao.persist(vo);
|
||||
}
|
||||
|
||||
|
|
@ -836,15 +471,12 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
* Get service offering ID for VM being imported.
|
||||
* If it cannot be found it creates one and returns its ID
|
||||
*/
|
||||
private Long getImportingVMServiceOffering(VirtualMachineConfigSummary configSummary,
|
||||
VirtualMachineRuntimeInfo runtimeInfo) {
|
||||
private Long getImportingVMServiceOffering(VirtualMachineConfigSummary configSummary, VirtualMachineRuntimeInfo runtimeInfo) {
|
||||
Integer numCpu = configSummary.getNumCpu();
|
||||
Integer memorySizeMB = configSummary.getMemorySizeMB();
|
||||
Integer maxCpuUsage = runtimeInfo.getMaxCpuUsage();
|
||||
List<ServiceOfferingVO> offerings = serviceOfferingDao.listPublicByCpuAndMemory(numCpu, memorySizeMB);
|
||||
return CollectionUtils.isEmpty(offerings) ?
|
||||
createServiceOfferingForVMImporting(numCpu, memorySizeMB, maxCpuUsage).getId() :
|
||||
offerings.get(0).getId();
|
||||
return CollectionUtils.isEmpty(offerings) ? createServiceOfferingForVMImporting(numCpu, memorySizeMB, maxCpuUsage).getId() : offerings.get(0).getId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -876,7 +508,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
* Check backing info
|
||||
*/
|
||||
private void checkBackingInfo(VirtualDeviceBackingInfo backingInfo) {
|
||||
if (! (backingInfo instanceof VirtualDiskFlatVer2BackingInfo)) {
|
||||
if (!(backingInfo instanceof VirtualDiskFlatVer2BackingInfo)) {
|
||||
throw new CloudRuntimeException("Unsopported backing, expected " + VirtualDiskFlatVer2BackingInfo.class.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
|
@ -899,7 +531,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
private Long getPoolId(VirtualDisk disk) {
|
||||
VirtualDeviceBackingInfo backing = disk.getBacking();
|
||||
checkBackingInfo(backing);
|
||||
VirtualDiskFlatVer2BackingInfo info = (VirtualDiskFlatVer2BackingInfo) backing;
|
||||
VirtualDiskFlatVer2BackingInfo info = (VirtualDiskFlatVer2BackingInfo)backing;
|
||||
String[] fileNameParts = info.getFileName().split(" ");
|
||||
String datastoreUuid = StringUtils.substringBetween(fileNameParts[0], "[", "]");
|
||||
return getPoolIdFromDatastoreUuid(datastoreUuid);
|
||||
|
|
@ -920,7 +552,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
private String getRootDiskTemplatePath(VirtualDisk rootDisk) {
|
||||
VirtualDeviceBackingInfo backing = rootDisk.getBacking();
|
||||
checkBackingInfo(backing);
|
||||
VirtualDiskFlatVer2BackingInfo info = (VirtualDiskFlatVer2BackingInfo) backing;
|
||||
VirtualDiskFlatVer2BackingInfo info = (VirtualDiskFlatVer2BackingInfo)backing;
|
||||
VirtualDiskFlatVer2BackingInfo parent = info.getParent();
|
||||
return (parent != null) ? getVolumeNameFromFileName(parent.getFileName()) : getVolumeNameFromFileName(info.getFileName());
|
||||
}
|
||||
|
|
@ -950,8 +582,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
/**
|
||||
* Get template size
|
||||
*/
|
||||
private Long getTemplateSize(VirtualMachineMO template, String vmInternalName,
|
||||
Map<VirtualDisk, VolumeVO> disksMapping, Backup backup) throws Exception {
|
||||
private Long getTemplateSize(VirtualMachineMO template, String vmInternalName, Map<VirtualDisk, VolumeVO> disksMapping, Backup backup) throws Exception {
|
||||
List<VirtualDisk> disks = template.getVirtualDisks();
|
||||
if (CollectionUtils.isEmpty(disks)) {
|
||||
throw new CloudRuntimeException("Couldn't find VM template size");
|
||||
|
|
@ -964,11 +595,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
*/
|
||||
private VMTemplateVO createVMTemplateRecord(String vmInternalName, long guestOsId, long accountId) {
|
||||
Long nextTemplateId = vmTemplateDao.getNextInSequence(Long.class, "id");
|
||||
VMTemplateVO templateVO = new VMTemplateVO(nextTemplateId, "Imported-from-" + vmInternalName,
|
||||
Storage.ImageFormat.OVA,false, false, false, Storage.TemplateType.USER,
|
||||
null, false, 64, accountId, null, "Template imported from VM " + vmInternalName,
|
||||
false, guestOsId, false, HypervisorType.VMware, null, null,
|
||||
false, false, false);
|
||||
VMTemplateVO templateVO = new VMTemplateVO(nextTemplateId, "Imported-from-" + vmInternalName, Storage.ImageFormat.OVA, false, false, false, Storage.TemplateType.USER, null,
|
||||
false, 64, accountId, null, "Template imported from VM " + vmInternalName, false, guestOsId, false, HypervisorType.VMware, null, null, false, false, false);
|
||||
return vmTemplateDao.persist(templateVO);
|
||||
}
|
||||
|
||||
|
|
@ -979,9 +607,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
*/
|
||||
private long getTemplateId(String templatePath, String vmInternalName, Long guestOsId, long accountId) {
|
||||
List<VMTemplateStoragePoolVO> poolRefs = templateStoragePoolDao.listByTemplatePath(templatePath);
|
||||
return CollectionUtils.isNotEmpty(poolRefs) ?
|
||||
poolRefs.get(0).getTemplateId() :
|
||||
createVMTemplateRecord(vmInternalName, guestOsId, accountId).getId();
|
||||
return CollectionUtils.isNotEmpty(poolRefs) ? poolRefs.get(0).getTemplateId() : createVMTemplateRecord(vmInternalName, guestOsId, accountId).getId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -990,9 +616,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
private void updateTemplateRef(long templateId, Long poolId, String templatePath, Long templateSize) {
|
||||
VMTemplateStoragePoolVO templateRef = templateStoragePoolDao.findByPoolPath(poolId, templatePath);
|
||||
if (templateRef == null) {
|
||||
templateRef = new VMTemplateStoragePoolVO(poolId, templateId, null, 100,
|
||||
VMTemplateStorageResourceAssoc.Status.DOWNLOADED, templatePath, null,
|
||||
null, templatePath, templateSize);
|
||||
templateRef = new VMTemplateStoragePoolVO(poolId, templateId, null, 100, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, templatePath, null, null, templatePath,
|
||||
templateSize);
|
||||
templateRef.setState(ObjectInDataStoreStateMachine.State.Ready);
|
||||
templateStoragePoolDao.persist(templateRef);
|
||||
}
|
||||
|
|
@ -1001,8 +626,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
/**
|
||||
* Get template ID for VM being imported. If it is not found, it is created
|
||||
*/
|
||||
private Long getImportingVMTemplate(List<VirtualDisk> virtualDisks, DatacenterMO dcMo, String vmInternalName,
|
||||
Long guestOsId, long accountId, Map<VirtualDisk, VolumeVO> disksMapping, Backup backup) throws Exception {
|
||||
private Long getImportingVMTemplate(List<VirtualDisk> virtualDisks, DatacenterMO dcMo, String vmInternalName, Long guestOsId, long accountId, Map<VirtualDisk, VolumeVO> disksMapping, Backup backup) throws Exception {
|
||||
for (VirtualDisk disk : virtualDisks) {
|
||||
if (isRootDisk(disk, disksMapping, backup)) {
|
||||
VolumeVO volumeVO = disksMapping.get(disk);
|
||||
|
|
@ -1026,9 +650,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
* If VM does not exist: create and persist VM
|
||||
* If VM exists: update VM
|
||||
*/
|
||||
private VMInstanceVO getVM(String vmInternalName, long templateId, long guestOsId,
|
||||
long serviceOfferingId, long zoneId, long accountId, long userId,
|
||||
long domainId) {
|
||||
private VMInstanceVO getVM(String vmInternalName, long templateId, long guestOsId, long serviceOfferingId, long zoneId, long accountId, long userId, long domainId) {
|
||||
VMInstanceVO vm = _vmDao.findVMByInstanceNameIncludingRemoved(vmInternalName);
|
||||
if (vm != null) {
|
||||
vm.setState(VirtualMachine.State.Stopped);
|
||||
|
|
@ -1036,16 +658,14 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
_vmDao.update(vm.getId(), vm);
|
||||
if (vm.getRemoved() != null) {
|
||||
_vmDao.unremove(vm.getId());
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, vm.getDataCenterId(), vm.getId(),
|
||||
vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(),
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(),
|
||||
vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
|
||||
}
|
||||
return _vmDao.findById(vm.getId());
|
||||
} else {
|
||||
long id = userVmDao.getNextInSequence(Long.class, "id");
|
||||
UserVmVO vmInstanceVO = new UserVmVO(id, vmInternalName, vmInternalName, templateId, HypervisorType.VMware,
|
||||
guestOsId, false, false, domainId, accountId, userId, serviceOfferingId,
|
||||
null, vmInternalName, null);
|
||||
UserVmVO vmInstanceVO = new UserVmVO(id, vmInternalName, vmInternalName, templateId, HypervisorType.VMware, guestOsId, false, false, domainId, accountId, userId,
|
||||
serviceOfferingId, null, vmInternalName, null);
|
||||
vmInstanceVO.setDataCenterId(zoneId);
|
||||
return userVmDao.persist(vmInstanceVO);
|
||||
}
|
||||
|
|
@ -1054,11 +674,9 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
/**
|
||||
* Create and persist volume
|
||||
*/
|
||||
private VolumeVO createVolumeRecord(Volume.Type type, String volumeName, long zoneId, long domainId,
|
||||
long accountId, long diskOfferingId, Storage.ProvisioningType provisioningType,
|
||||
Long size, long instanceId, Long poolId, long templateId, Integer unitNumber, VirtualMachineDiskInfo diskInfo) {
|
||||
VolumeVO volumeVO = new VolumeVO(type, volumeName, zoneId, domainId, accountId, diskOfferingId,
|
||||
provisioningType, size, null, null, null);
|
||||
private VolumeVO createVolumeRecord(Volume.Type type, String volumeName, long zoneId, long domainId, long accountId, long diskOfferingId, Storage.ProvisioningType provisioningType,
|
||||
Long size, long instanceId, Long poolId, long templateId, Integer unitNumber, VirtualMachineDiskInfo diskInfo) {
|
||||
VolumeVO volumeVO = new VolumeVO(type, volumeName, zoneId, domainId, accountId, diskOfferingId, provisioningType, size, null, null, null);
|
||||
volumeVO.setFormat(Storage.ImageFormat.OVA);
|
||||
volumeVO.setPath(volumeName);
|
||||
volumeVO.setState(Volume.State.Ready);
|
||||
|
|
@ -1097,9 +715,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
*/
|
||||
private long getDiskOfferingId(long size, Storage.ProvisioningType provisioningType) {
|
||||
List<DiskOfferingVO> offerings = diskOfferingDao.listAllBySizeAndProvisioningType(size, provisioningType);
|
||||
return CollectionUtils.isNotEmpty(offerings) ?
|
||||
offerings.get(0).getId() :
|
||||
diskOfferingDao.findByUniqueName("Cloud.Com-Custom").getId();
|
||||
return CollectionUtils.isNotEmpty(offerings) ? offerings.get(0).getId() : diskOfferingDao.findByUniqueName("Cloud.Com-Custom").getId();
|
||||
}
|
||||
|
||||
protected VolumeVO updateVolume(VirtualDisk disk, Map<VirtualDisk, VolumeVO> disksMapping, VirtualMachineMO vmToImport, Long poolId, VirtualMachine vm) throws Exception {
|
||||
|
|
@ -1116,8 +732,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
if (volume.getRemoved() != null) {
|
||||
_volumeDao.unremove(volume.getId());
|
||||
if (vm.getType() == Type.User) {
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(),
|
||||
volume.getId(), volume.getName(), volume.getDiskOfferingId(), null, volume.getSize(),
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), volume.getDiskOfferingId(), null, volume.getSize(),
|
||||
Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
|
||||
_resourceLimitService.incrementResourceCount(vm.getAccountId(), Resource.ResourceType.volume, volume.isDisplayVolume());
|
||||
_resourceLimitService.incrementResourceCount(vm.getAccountId(), Resource.ResourceType.primary_storage, volume.isDisplayVolume(), volume.getSize());
|
||||
|
|
@ -1129,8 +744,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
/**
|
||||
* Get volumes for VM being imported
|
||||
*/
|
||||
private void syncVMVolumes(VMInstanceVO vmInstanceVO, List<VirtualDisk> virtualDisks,
|
||||
Map<VirtualDisk, VolumeVO> disksMapping, VirtualMachineMO vmToImport, Backup backup) throws Exception {
|
||||
private void syncVMVolumes(VMInstanceVO vmInstanceVO, List<VirtualDisk> virtualDisks, Map<VirtualDisk, VolumeVO> disksMapping, VirtualMachineMO vmToImport, Backup backup)
|
||||
throws Exception {
|
||||
long zoneId = vmInstanceVO.getDataCenterId();
|
||||
long accountId = vmInstanceVO.getAccountId();
|
||||
long domainId = vmInstanceVO.getDomainId();
|
||||
|
|
@ -1155,8 +770,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
return diskInfoBuilder.getDiskInfoByBackingFileBaseName(volumeName, poolName);
|
||||
}
|
||||
|
||||
private VolumeVO createVolume(VirtualDisk disk, VirtualMachineMO vmToImport, long domainId, long zoneId,
|
||||
long accountId, long instanceId, Long poolId, long templateId, Backup backup, boolean isImport) throws Exception {
|
||||
private VolumeVO createVolume(VirtualDisk disk, VirtualMachineMO vmToImport, long domainId, long zoneId, long accountId, long instanceId, Long poolId, long templateId, Backup backup, boolean isImport) throws Exception {
|
||||
VMInstanceVO vm = _vmDao.findByIdIncludingRemoved(backup.getVmId());
|
||||
if (vm == null) {
|
||||
throw new CloudRuntimeException("Failed to find the backup volume information from the VM backup");
|
||||
|
|
@ -1173,14 +787,13 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
}
|
||||
VirtualDeviceBackingInfo backing = disk.getBacking();
|
||||
checkBackingInfo(backing);
|
||||
VirtualDiskFlatVer2BackingInfo info = (VirtualDiskFlatVer2BackingInfo) backing;
|
||||
VirtualDiskFlatVer2BackingInfo info = (VirtualDiskFlatVer2BackingInfo)backing;
|
||||
String volumeName = getVolumeName(disk, vmToImport);
|
||||
Storage.ProvisioningType provisioningType = getProvisioningType(info);
|
||||
long diskOfferingId = getDiskOfferingId(size, provisioningType);
|
||||
Integer unitNumber = disk.getUnitNumber();
|
||||
VirtualMachineDiskInfo diskInfo = getDiskInfo(vmToImport, poolId, volumeName);
|
||||
return createVolumeRecord(type, volumeName, zoneId, domainId, accountId, diskOfferingId,
|
||||
provisioningType, size, instanceId, poolId, templateId, unitNumber, diskInfo);
|
||||
return createVolumeRecord(type, volumeName, zoneId, domainId, accountId, diskOfferingId, provisioningType, size, instanceId, poolId, templateId, unitNumber, diskInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1208,9 +821,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
private NetworkVO createNetworkRecord(Long zoneId, String tag, String vlan, long accountId, long domainId) {
|
||||
Long physicalNetworkId = getPhysicalNetworkId(zoneId, tag);
|
||||
final long id = _networkDao.getNextInSequence(Long.class, "id");
|
||||
NetworkVO networkVO = new NetworkVO(id, TrafficType.Guest, Networks.Mode.Dhcp, BroadcastDomainType.Vlan, 9L,
|
||||
domainId, accountId, id, "Imported-network-" + id, "Imported-network-" + id, null, Network.GuestType.Isolated,
|
||||
zoneId, physicalNetworkId, ControlledEntity.ACLType.Account, false, null, false);
|
||||
NetworkVO networkVO = new NetworkVO(id, TrafficType.Guest, Networks.Mode.Dhcp, BroadcastDomainType.Vlan, 9L, domainId, accountId, id, "Imported-network-" + id,
|
||||
"Imported-network-" + id, null, Network.GuestType.Isolated, zoneId, physicalNetworkId, ControlledEntity.ACLType.Account, false, null, false);
|
||||
networkVO.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlan));
|
||||
networkVO.setGuruName("ExternalGuestNetworkGuru");
|
||||
networkVO.setState(Network.State.Implemented);
|
||||
|
|
@ -1252,7 +864,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
*/
|
||||
private NetworkMO getNetworkMO(VirtualE1000 nic, VmwareContext context) {
|
||||
VirtualDeviceConnectInfo connectable = nic.getConnectable();
|
||||
VirtualEthernetCardNetworkBackingInfo info = (VirtualEthernetCardNetworkBackingInfo) nic.getBacking();
|
||||
VirtualEthernetCardNetworkBackingInfo info = (VirtualEthernetCardNetworkBackingInfo)nic.getBacking();
|
||||
ManagedObjectReference networkMor = info.getNetwork();
|
||||
if (networkMor == null) {
|
||||
throw new CloudRuntimeException("Could not find network for NIC on: " + nic.getMacAddress());
|
||||
|
|
@ -1261,15 +873,14 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
}
|
||||
|
||||
private Pair<String, String> getNicMacAddressAndNetworkName(VirtualDevice nicDevice, VmwareContext context) throws Exception {
|
||||
VirtualE1000 nic = (VirtualE1000) nicDevice;
|
||||
VirtualE1000 nic = (VirtualE1000)nicDevice;
|
||||
String macAddress = nic.getMacAddress();
|
||||
NetworkMO networkMO = getNetworkMO(nic, context);
|
||||
String networkName = networkMO.getName();
|
||||
return new Pair<>(macAddress, networkName);
|
||||
}
|
||||
|
||||
private void syncVMNics(VirtualDevice[] nicDevices, DatacenterMO dcMo, Map<String, NetworkVO> networksMapping,
|
||||
VMInstanceVO vm) throws Exception {
|
||||
private void syncVMNics(VirtualDevice[] nicDevices, DatacenterMO dcMo, Map<String, NetworkVO> networksMapping, VMInstanceVO vm) throws Exception {
|
||||
VmwareContext context = dcMo.getContext();
|
||||
List<NicVO> allNics = _nicDao.listByVmId(vm.getId());
|
||||
for (VirtualDevice nicDevice : nicDevices) {
|
||||
|
|
@ -1298,14 +909,12 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
|
||||
for (Backup.VolumeInfo backedUpVol : backedUpVolumes) {
|
||||
for (VirtualDisk disk : virtualDisks) {
|
||||
if (!map.containsKey(disk) && backedUpVol.getSize().equals(disk.getCapacityInBytes())
|
||||
&& !usedVols.containsKey(backedUpVol.getUuid())) {
|
||||
if (!map.containsKey(disk) && backedUpVol.getSize().equals(disk.getCapacityInBytes()) && !usedVols.containsKey(backedUpVol.getUuid())) {
|
||||
String volId = backedUpVol.getUuid();
|
||||
VolumeVO vol = _volumeDao.findByUuidIncludingRemoved(volId);
|
||||
usedVols.put(backedUpVol.getUuid(), true);
|
||||
map.put(disk, vol);
|
||||
s_logger.debug("VM restore mapping for disk " + disk.getBacking() +
|
||||
" (capacity: " + disk.getCapacityInBytes() + ") with volume ID" + vol.getId());
|
||||
s_logger.debug("VM restore mapping for disk " + disk.getBacking() + " (capacity: " + disk.getCapacityInBytes() + ") with volume ID" + vol.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1328,7 +937,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
*/
|
||||
private VirtualDisk findRestoredVolume(Backup.VolumeInfo volumeInfo, VirtualMachineMO vm) throws Exception {
|
||||
List<VirtualDisk> virtualDisks = vm.getVirtualDisks();
|
||||
for (VirtualDisk disk: virtualDisks) {
|
||||
for (VirtualDisk disk : virtualDisks) {
|
||||
if (disk.getCapacityInBytes().equals(volumeInfo.getSize())) {
|
||||
return disk;
|
||||
}
|
||||
|
|
@ -1342,15 +951,14 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
private String getVolumeFullPath(VirtualDisk disk) {
|
||||
VirtualDeviceBackingInfo backing = disk.getBacking();
|
||||
checkBackingInfo(backing);
|
||||
VirtualDiskFlatVer2BackingInfo info = (VirtualDiskFlatVer2BackingInfo) backing;
|
||||
VirtualDiskFlatVer2BackingInfo info = (VirtualDiskFlatVer2BackingInfo)backing;
|
||||
return info.getFileName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dest volume full path
|
||||
*/
|
||||
private String getDestVolumeFullPath(VirtualDisk restoredDisk, VirtualMachineMO restoredVm,
|
||||
VirtualMachineMO vmMo) throws Exception {
|
||||
private String getDestVolumeFullPath(VirtualDisk restoredDisk, VirtualMachineMO restoredVm, VirtualMachineMO vmMo) throws Exception {
|
||||
VirtualDisk vmDisk = vmMo.getVirtualDisks().get(0);
|
||||
String vmDiskPath = vmMo.getVmdkFileBaseName(vmDisk);
|
||||
String vmDiskFullPath = getVolumeFullPath(vmMo.getVirtualDisks().get(0));
|
||||
|
|
@ -1365,13 +973,11 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
VirtualDisk vmDisk = vmMo.getVirtualDisks().get(0);
|
||||
VirtualDeviceBackingInfo backing = vmDisk.getBacking();
|
||||
checkBackingInfo(backing);
|
||||
VirtualDiskFlatVer2BackingInfo info = (VirtualDiskFlatVer2BackingInfo) backing;
|
||||
VirtualDiskFlatVer2BackingInfo info = (VirtualDiskFlatVer2BackingInfo)backing;
|
||||
return info.getDatastore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualMachine importVirtualMachineFromBackup(long zoneId, long domainId, long accountId, long userId,
|
||||
String vmInternalName, Backup backup) throws Exception {
|
||||
@Override public VirtualMachine importVirtualMachineFromBackup(long zoneId, long domainId, long accountId, long userId, String vmInternalName, Backup backup) throws Exception {
|
||||
DatacenterMO dcMo = getDatacenterMO(zoneId);
|
||||
VirtualMachineMO vmToImport = dcMo.findVm(vmInternalName);
|
||||
if (vmToImport == null) {
|
||||
|
|
@ -1397,9 +1003,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
return vm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attachRestoredVolumeToVirtualMachine(long zoneId, String location, Backup.VolumeInfo volumeInfo,
|
||||
VirtualMachine vm, long poolId, Backup backup) throws Exception {
|
||||
@Override public boolean attachRestoredVolumeToVirtualMachine(long zoneId, String location, Backup.VolumeInfo volumeInfo, VirtualMachine vm, long poolId, Backup backup)
|
||||
throws Exception {
|
||||
DatacenterMO dcMo = getDatacenterMO(zoneId);
|
||||
VirtualMachineMO vmRestored = findVM(dcMo, location);
|
||||
VirtualMachineMO vmMo = findVM(dcMo, vm.getInstanceName());
|
||||
|
|
@ -1435,8 +1040,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
s_logger.error("Failed to get the attached the (restored) volume " + diskPath);
|
||||
return false;
|
||||
}
|
||||
createVolume(attachedDisk, vmMo, vm.getDomainId(), vm.getDataCenterId(), vm.getAccountId(), vm.getId(),
|
||||
poolId, vm.getTemplateId(), backup, false);
|
||||
createVolume(attachedDisk, vmMo, vm.getDomainId(), vm.getDataCenterId(), vm.getAccountId(), vm.getId(), poolId, vm.getTemplateId(), backup, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1450,15 +1054,14 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Command> finalizeMigrate(VirtualMachine vm, StoragePool destination) {
|
||||
@Override public List<Command> finalizeMigrate(VirtualMachine vm, StoragePool destination) {
|
||||
List<Command> commands = new ArrayList<Command>();
|
||||
|
||||
// OfflineVmwareMigration: specialised migration command
|
||||
List<VolumeVO> volumes = _volumeDao.findByInstance(vm.getId());
|
||||
List<VolumeTO> vols = new ArrayList<>();
|
||||
for (Volume volume : volumes) {
|
||||
VolumeTO vol = new VolumeTO(volume,destination);
|
||||
VolumeTO vol = new VolumeTO(volume, destination);
|
||||
vols.add(vol);
|
||||
}
|
||||
MigrateVmToPoolCommand migrateVmToPoolCommand = new MigrateVmToPoolCommand(vm.getInstanceName(), vols, destination.getUuid(), true);
|
||||
|
|
@ -1468,7 +1071,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
final Long destClusterId = destination.getClusterId();
|
||||
final Long srcClusterId = getClusterId(vm.getId());
|
||||
|
||||
if (srcClusterId != null && destClusterId != null && ! srcClusterId.equals(destClusterId)) {
|
||||
if (srcClusterId != null && destClusterId != null && !srcClusterId.equals(destClusterId)) {
|
||||
final String srcDcName = _clusterDetailsDao.getVmwareDcName(srcClusterId);
|
||||
final String destDcName = _clusterDetailsDao.getVmwareDcName(destClusterId);
|
||||
if (srcDcName != null && destDcName != null && !srcDcName.equals(destDcName)) {
|
||||
|
|
@ -1480,4 +1083,9 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||
}
|
||||
return commands;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) {
|
||||
return super.toVirtualMachineTO(vmProfile);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,468 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.hypervisor.guru;
|
||||
|
||||
import com.cloud.agent.api.storage.OVFPropertyTO;
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.agent.api.to.DiskTO;
|
||||
import com.cloud.agent.api.to.NicTO;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.hypervisor.vmware.manager.VmwareManager;
|
||||
import com.cloud.hypervisor.vmware.mo.DiskControllerType;
|
||||
import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.Networks;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.storage.GuestOSHypervisorVO;
|
||||
import com.cloud.storage.GuestOSVO;
|
||||
import com.cloud.storage.TemplateOVFPropertyVO;
|
||||
import com.cloud.storage.VMTemplateStoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.dao.GuestOSDao;
|
||||
import com.cloud.storage.dao.GuestOSHypervisorDao;
|
||||
import com.cloud.storage.dao.TemplateOVFPropertiesDao;
|
||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||
import com.cloud.template.VirtualMachineTemplate;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class VmwareVmImplementer {
|
||||
private static final Logger LOG = Logger.getLogger(VmwareVmImplementer.class);
|
||||
|
||||
@Inject
|
||||
DomainRouterDao domainRouterDao;
|
||||
@Inject
|
||||
GuestOSDao guestOsDao;
|
||||
@Inject
|
||||
GuestOSHypervisorDao guestOsHypervisorDao;
|
||||
@Inject
|
||||
HostDao hostDao;
|
||||
@Inject
|
||||
NetworkDao networkDao;
|
||||
@Inject
|
||||
NetworkModel networkMgr;
|
||||
@Inject
|
||||
NicDao nicDao;
|
||||
@Inject
|
||||
PrimaryDataStoreDao storagePoolDao;
|
||||
@Inject
|
||||
TemplateOVFPropertiesDao templateOVFPropertiesDao;
|
||||
@Inject
|
||||
VMTemplatePoolDao templateStoragePoolDao;
|
||||
@Inject
|
||||
VmwareManager vmwareMgr;
|
||||
|
||||
private Boolean globalNestedVirtualisationEnabled;
|
||||
private Boolean globalNestedVPerVMEnabled;
|
||||
|
||||
Boolean getGlobalNestedVirtualisationEnabled() {
|
||||
return globalNestedVirtualisationEnabled != null ? globalNestedVirtualisationEnabled : false;
|
||||
}
|
||||
|
||||
void setGlobalNestedVirtualisationEnabled(Boolean globalNestedVirtualisationEnabled) {
|
||||
this.globalNestedVirtualisationEnabled = globalNestedVirtualisationEnabled;
|
||||
}
|
||||
|
||||
Boolean getGlobalNestedVPerVMEnabled() {
|
||||
return globalNestedVPerVMEnabled != null ? globalNestedVPerVMEnabled : false;
|
||||
}
|
||||
|
||||
void setGlobalNestedVPerVMEnabled(Boolean globalNestedVPerVMEnabled) {
|
||||
this.globalNestedVPerVMEnabled = globalNestedVPerVMEnabled;
|
||||
}
|
||||
|
||||
VirtualMachineTO implement(VirtualMachineProfile vm, VirtualMachineTO to, long clusterId) {
|
||||
to.setBootloader(VirtualMachineTemplate.BootloaderType.HVM);
|
||||
|
||||
Map<String, String> details = to.getDetails();
|
||||
if (details == null)
|
||||
details = new HashMap<String, String>();
|
||||
|
||||
VirtualMachine.Type vmType = vm.getType();
|
||||
boolean userVm = !(vmType.equals(VirtualMachine.Type.DomainRouter) || vmType.equals(VirtualMachine.Type.ConsoleProxy) || vmType.equals(VirtualMachine.Type.SecondaryStorageVm));
|
||||
|
||||
String nicDeviceType = details.get(VmDetailConstants.NIC_ADAPTER);
|
||||
if (!userVm) {
|
||||
|
||||
if (nicDeviceType == null) {
|
||||
details.put(VmDetailConstants.NIC_ADAPTER, vmwareMgr.getSystemVMDefaultNicAdapterType());
|
||||
} else {
|
||||
try {
|
||||
VirtualEthernetCardType.valueOf(nicDeviceType);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
|
||||
details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// for user-VM, use E1000 as default
|
||||
if (nicDeviceType == null) {
|
||||
details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
|
||||
} else {
|
||||
try {
|
||||
VirtualEthernetCardType.valueOf(nicDeviceType);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
|
||||
details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setBootParameters(vm, to, details);
|
||||
|
||||
setDiskControllers(vm, details, userVm);
|
||||
|
||||
List<NicProfile> nicProfiles = getNicProfiles(vm, details);
|
||||
|
||||
addReservationDetails(clusterId, details);
|
||||
|
||||
if (vmType.equals(VirtualMachine.Type.DomainRouter)) {
|
||||
configureDomainRouterNicsAndDetails(vm, to, details, nicProfiles);
|
||||
}
|
||||
|
||||
// Don't do this if the virtual machine is one of the special types
|
||||
// Should only be done on user machines
|
||||
if (userVm) {
|
||||
configureNestedVirtualization(details, to);
|
||||
}
|
||||
// Determine the VM's OS description
|
||||
GuestOSVO guestOS = guestOsDao.findByIdIncludingRemoved(vm.getVirtualMachine().getGuestOSId());
|
||||
to.setOs(guestOS.getDisplayName());
|
||||
to.setHostName(vm.getHostName());
|
||||
HostVO host = hostDao.findById(vm.getVirtualMachine().getHostId());
|
||||
GuestOSHypervisorVO guestOsMapping = null;
|
||||
if (host != null) {
|
||||
guestOsMapping = guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), Hypervisor.HypervisorType.VMware.toString(), host.getHypervisorVersion());
|
||||
}
|
||||
if (guestOsMapping == null || host == null) {
|
||||
to.setPlatformEmulator(null);
|
||||
} else {
|
||||
to.setPlatformEmulator(guestOsMapping.getGuestOsName());
|
||||
}
|
||||
|
||||
List<OVFPropertyTO> ovfProperties = getOvfPropertyList(vm, details);
|
||||
|
||||
handleOvfProperties(vm, to, details, ovfProperties);
|
||||
|
||||
setDetails(to, details);
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
private void setDetails(VirtualMachineTO to, Map<String, String> details) {
|
||||
if (LOG.isTraceEnabled()) {
|
||||
for (String key: details.keySet()) {
|
||||
LOG.trace(String.format("Detail for VM %s: %s => %s",to.getName(), key, details.get(key)));
|
||||
}
|
||||
}
|
||||
to.setDetails(details);
|
||||
}
|
||||
|
||||
private void configureDomainRouterNicsAndDetails(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details, List<NicProfile> nicProfiles) {
|
||||
NicProfile publicNicProfile = null;
|
||||
for (NicProfile nicProfile : nicProfiles) {
|
||||
if (nicProfile.getTrafficType() == Networks.TrafficType.Public) {
|
||||
publicNicProfile = nicProfile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (publicNicProfile != null) {
|
||||
NicTO[] nics = to.getNics();
|
||||
|
||||
// reserve extra NICs
|
||||
NicTO[] expandedNics = new NicTO[nics.length + vmwareMgr.getRouterExtraPublicNics()];
|
||||
int i = 0;
|
||||
int deviceId = -1;
|
||||
for (i = 0; i < nics.length; i++) {
|
||||
expandedNics[i] = nics[i];
|
||||
if (nics[i].getDeviceId() > deviceId)
|
||||
deviceId = nics[i].getDeviceId();
|
||||
}
|
||||
deviceId++;
|
||||
|
||||
long networkId = publicNicProfile.getNetworkId();
|
||||
NetworkVO network = networkDao.findById(networkId);
|
||||
|
||||
for (; i < nics.length + vmwareMgr.getRouterExtraPublicNics(); i++) {
|
||||
NicTO nicTo = new NicTO();
|
||||
|
||||
nicTo.setDeviceId(deviceId++);
|
||||
nicTo.setBroadcastType(publicNicProfile.getBroadcastType());
|
||||
nicTo.setType(publicNicProfile.getTrafficType());
|
||||
nicTo.setIp("0.0.0.0");
|
||||
nicTo.setNetmask("255.255.255.255");
|
||||
|
||||
try {
|
||||
String mac = networkMgr.getNextAvailableMacAddressInNetwork(networkId);
|
||||
nicTo.setMac(mac);
|
||||
} catch (InsufficientAddressCapacityException e) {
|
||||
throw new CloudRuntimeException("unable to allocate mac address on network: " + networkId);
|
||||
}
|
||||
nicTo.setDns1(publicNicProfile.getIPv4Dns1());
|
||||
nicTo.setDns2(publicNicProfile.getIPv4Dns2());
|
||||
if (publicNicProfile.getIPv4Gateway() != null) {
|
||||
nicTo.setGateway(publicNicProfile.getIPv4Gateway());
|
||||
} else {
|
||||
nicTo.setGateway(network.getGateway());
|
||||
}
|
||||
nicTo.setDefaultNic(false);
|
||||
nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri());
|
||||
nicTo.setIsolationuri(publicNicProfile.getIsolationUri());
|
||||
|
||||
Integer networkRate = networkMgr.getNetworkRate(network.getId(), null);
|
||||
nicTo.setNetworkRateMbps(networkRate);
|
||||
|
||||
expandedNics[i] = nicTo;
|
||||
}
|
||||
|
||||
to.setNics(expandedNics);
|
||||
|
||||
VirtualMachine router = vm.getVirtualMachine();
|
||||
DomainRouterVO routerVO = domainRouterDao.findById(router.getId());
|
||||
if (routerVO != null && routerVO.getIsRedundantRouter()) {
|
||||
Long peerRouterId = nicDao.getPeerRouterId(publicNicProfile.getMacAddress(), router.getId());
|
||||
DomainRouterVO peerRouterVO = null;
|
||||
if (peerRouterId != null) {
|
||||
peerRouterVO = domainRouterDao.findById(peerRouterId);
|
||||
if (peerRouterVO != null) {
|
||||
details.put("PeerRouterInstanceName", peerRouterVO.getInstanceName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringBuffer sbMacSequence = new StringBuffer();
|
||||
for (NicTO nicTo : sortNicsByDeviceId(to.getNics())) {
|
||||
sbMacSequence.append(nicTo.getMac()).append("|");
|
||||
}
|
||||
if (!sbMacSequence.toString().isEmpty()) {
|
||||
sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
|
||||
String bootArgs = to.getBootArgs();
|
||||
to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleOvfProperties(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details, List<OVFPropertyTO> ovfProperties) {
|
||||
if (CollectionUtils.isNotEmpty(ovfProperties)) {
|
||||
removeOvfPropertiesFromDetails(ovfProperties, details);
|
||||
String templateInstallPath = null;
|
||||
List<DiskTO> rootDiskList = vm.getDisks().stream().filter(x -> x.getType() == Volume.Type.ROOT).collect(Collectors.toList());
|
||||
if (rootDiskList.size() != 1) {
|
||||
throw new CloudRuntimeException("Did not find only one root disk for VM " + vm.getHostName());
|
||||
}
|
||||
|
||||
DiskTO rootDiskTO = rootDiskList.get(0);
|
||||
DataStoreTO dataStore = rootDiskTO.getData().getDataStore();
|
||||
StoragePoolVO storagePoolVO = storagePoolDao.findByUuid(dataStore.getUuid());
|
||||
long dataCenterId = storagePoolVO.getDataCenterId();
|
||||
List<StoragePoolVO> pools = storagePoolDao.listByDataCenterId(dataCenterId);
|
||||
for (StoragePoolVO pool : pools) {
|
||||
VMTemplateStoragePoolVO ref = templateStoragePoolDao.findByPoolTemplate(pool.getId(), vm.getTemplateId());
|
||||
if (ref != null && ref.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
|
||||
templateInstallPath = ref.getInstallPath();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (templateInstallPath == null) {
|
||||
throw new CloudRuntimeException("Did not find the template install path for template " + vm.getTemplateId() + " on zone " + dataCenterId);
|
||||
}
|
||||
|
||||
Pair<String, List<OVFPropertyTO>> pair = new Pair<String, List<OVFPropertyTO>>(templateInstallPath, ovfProperties);
|
||||
to.setOvfProperties(pair);
|
||||
}
|
||||
}
|
||||
|
||||
private List<OVFPropertyTO> getOvfPropertyList(VirtualMachineProfile vm, Map<String, String> details) {
|
||||
List<OVFPropertyTO> ovfProperties = new ArrayList<OVFPropertyTO>();
|
||||
for (String detailKey : details.keySet()) {
|
||||
if (detailKey.startsWith(ApiConstants.OVF_PROPERTIES)) {
|
||||
String ovfPropKey = detailKey.replace(ApiConstants.OVF_PROPERTIES + "-", "");
|
||||
TemplateOVFPropertyVO templateOVFPropertyVO = templateOVFPropertiesDao.findByTemplateAndKey(vm.getTemplateId(), ovfPropKey);
|
||||
if (templateOVFPropertyVO == null) {
|
||||
LOG.warn(String.format("OVF property %s not found on template, discarding", ovfPropKey));
|
||||
continue;
|
||||
}
|
||||
String ovfValue = details.get(detailKey);
|
||||
boolean isPassword = templateOVFPropertyVO.isPassword();
|
||||
OVFPropertyTO propertyTO = new OVFPropertyTO(ovfPropKey, ovfValue, isPassword);
|
||||
ovfProperties.add(propertyTO);
|
||||
}
|
||||
}
|
||||
return ovfProperties;
|
||||
}
|
||||
|
||||
private void addReservationDetails(long clusterId, Map<String, String> details) {
|
||||
details.put(VMwareGuru.VmwareReserveCpu.key(), VMwareGuru.VmwareReserveCpu.valueIn(clusterId).toString());
|
||||
details.put(VMwareGuru.VmwareReserveMemory.key(), VMwareGuru.VmwareReserveMemory.valueIn(clusterId).toString());
|
||||
}
|
||||
|
||||
private List<NicProfile> getNicProfiles(VirtualMachineProfile vm, Map<String, String> details) {
|
||||
List<NicProfile> nicProfiles = vm.getNics();
|
||||
|
||||
for (NicProfile nicProfile : nicProfiles) {
|
||||
if (nicProfile.getTrafficType() == Networks.TrafficType.Guest) {
|
||||
if (networkMgr.isProviderSupportServiceInNetwork(nicProfile.getNetworkId(), Network.Service.Firewall, Network.Provider.CiscoVnmc)) {
|
||||
details.put("ConfigureVServiceInNexus", Boolean.TRUE.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nicProfiles;
|
||||
}
|
||||
|
||||
private void setDiskControllers(VirtualMachineProfile vm, Map<String, String> details, boolean userVm) {
|
||||
String diskDeviceType = details.get(VmDetailConstants.ROOT_DISK_CONTROLLER);
|
||||
if (userVm) {
|
||||
if (diskDeviceType == null) {
|
||||
details.put(VmDetailConstants.ROOT_DISK_CONTROLLER,vmwareMgr.getRootDiskController());
|
||||
}
|
||||
}
|
||||
String diskController = details.get(VmDetailConstants.DATA_DISK_CONTROLLER);
|
||||
if (userVm) {
|
||||
if (diskController == null) {
|
||||
details.put(VmDetailConstants.DATA_DISK_CONTROLLER, DiskControllerType.lsilogic.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (vm.getType() == VirtualMachine.Type.NetScalerVm) {
|
||||
details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, "scsi");
|
||||
}
|
||||
}
|
||||
|
||||
private void setBootParameters(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details) {
|
||||
details.put(VmDetailConstants.BOOT_MODE, to.getBootMode());
|
||||
if (vm.getParameter(VirtualMachineProfile.Param.BootIntoSetup) != null && (Boolean)vm.getParameter(VirtualMachineProfile.Param.BootIntoSetup) == true) {
|
||||
to.setEnterHardwareSetup(true);
|
||||
}
|
||||
// there should also be
|
||||
// details.put(VmDetailConstants.BOOT_TYPE, to.getBootType());
|
||||
}
|
||||
|
||||
/*
|
||||
Remove OVF properties from details to be sent to hypervisor (avoid duplicate data)
|
||||
*/
|
||||
private void removeOvfPropertiesFromDetails(List<OVFPropertyTO> ovfProperties, Map<String, String> details) {
|
||||
for (OVFPropertyTO propertyTO : ovfProperties) {
|
||||
String key = propertyTO.getKey();
|
||||
details.remove(ApiConstants.OVF_PROPERTIES + "-" + key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds {@code 'nestedVirtualizationFlag'} value to {@code details} due to if it should be enabled or not
|
||||
* @param details vm details should not be null
|
||||
* @param to vm to
|
||||
*/
|
||||
protected void configureNestedVirtualization(Map<String, String> details, VirtualMachineTO to) {
|
||||
String localNestedV = details.get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG);
|
||||
|
||||
Boolean globalNestedVirtualisationEnabled = getGlobalNestedVirtualisationEnabled();
|
||||
Boolean globalNestedVPerVMEnabled = getGlobalNestedVPerVMEnabled();
|
||||
|
||||
Boolean shouldEnableNestedVirtualization = shouldEnableNestedVirtualization(globalNestedVirtualisationEnabled, globalNestedVPerVMEnabled, localNestedV);
|
||||
if(LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format(
|
||||
"Due to '%B'(globalNestedVirtualisationEnabled) and '%B'(globalNestedVPerVMEnabled) I'm adding a flag with value %B to the vm configuration for Nested Virtualisation.",
|
||||
globalNestedVirtualisationEnabled,
|
||||
globalNestedVPerVMEnabled,
|
||||
shouldEnableNestedVirtualization)
|
||||
);
|
||||
}
|
||||
details.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, Boolean.toString(shouldEnableNestedVirtualization));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide in which cases nested virtualization should be enabled based on (1){@code globalNestedV}, (2){@code globalNestedVPerVM}, (3){@code localNestedV}<br/>
|
||||
* Nested virtualization should be enabled when one of this cases:
|
||||
* <ul>
|
||||
* <li>(1)=TRUE, (2)=TRUE, (3) is NULL (missing)</li>
|
||||
* <li>(1)=TRUE, (2)=TRUE, (3)=TRUE</li>
|
||||
* <li>(1)=TRUE, (2)=FALSE</li>
|
||||
* <li>(1)=FALSE, (2)=TRUE, (3)=TRUE</li>
|
||||
* </ul>
|
||||
* In any other case, it shouldn't be enabled
|
||||
* @param globalNestedV value of {@code 'vmware.nested.virtualization'} global config
|
||||
* @param globalNestedVPerVM value of {@code 'vmware.nested.virtualization.perVM'} global config
|
||||
* @param localNestedV value of {@code 'nestedVirtualizationFlag'} key in vm details if present, null if not present
|
||||
* @return "true" for cases in which nested virtualization is enabled, "false" if not
|
||||
*/
|
||||
Boolean shouldEnableNestedVirtualization(Boolean globalNestedV, Boolean globalNestedVPerVM, String localNestedV) {
|
||||
if (globalNestedV == null || globalNestedVPerVM == null) {
|
||||
return false;
|
||||
}
|
||||
boolean globalNV = globalNestedV.booleanValue();
|
||||
boolean globalNVPVM = globalNestedVPerVM.booleanValue();
|
||||
|
||||
if (globalNVPVM) {
|
||||
return (localNestedV == null && globalNV) || BooleanUtils.toBoolean(localNestedV);
|
||||
}
|
||||
return globalNV;
|
||||
}
|
||||
|
||||
private NicTO[] sortNicsByDeviceId(NicTO[] nics) {
|
||||
|
||||
List<NicTO> listForSort = new ArrayList<NicTO>();
|
||||
for (NicTO nic : nics) {
|
||||
listForSort.add(nic);
|
||||
}
|
||||
Collections.sort(listForSort, new Comparator<NicTO>() {
|
||||
|
||||
@Override public int compare(NicTO arg0, NicTO arg1) {
|
||||
if (arg0.getDeviceId() < arg1.getDeviceId()) {
|
||||
return -1;
|
||||
} else if (arg0.getDeviceId() == arg1.getDeviceId()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
return listForSort.toArray(new NicTO[0]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1723,10 +1723,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
String dataDiskController = vmSpec.getDetails().get(VmDetailConstants.DATA_DISK_CONTROLLER);
|
||||
String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER);
|
||||
DiskTO rootDiskTO = null;
|
||||
String bootMode = "bios";
|
||||
String bootMode = null;
|
||||
if (vmSpec.getDetails().containsKey(VmDetailConstants.BOOT_MODE)) {
|
||||
bootMode = vmSpec.getDetails().get(VmDetailConstants.BOOT_MODE);
|
||||
}
|
||||
if (null == bootMode) {
|
||||
bootMode = ApiConstants.BootType.BIOS.toString();
|
||||
}
|
||||
|
||||
// If root disk controller is scsi, then data disk controller would also be scsi instead of using 'osdefault'
|
||||
// This helps avoid mix of different scsi subtype controllers in instance.
|
||||
|
|
@ -2285,15 +2288,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(bootMode) && !bootMode.equalsIgnoreCase("bios")) {
|
||||
vmConfigSpec.setFirmware("efi");
|
||||
if (vmSpec.getDetails().containsKey(ApiConstants.BootType.UEFI.toString()) && "secure".equalsIgnoreCase(vmSpec.getDetails().get(ApiConstants.BootType.UEFI.toString()))) {
|
||||
VirtualMachineBootOptions bootOptions = new VirtualMachineBootOptions();
|
||||
bootOptions.setEfiSecureBootEnabled(true);
|
||||
vmConfigSpec.setBootOptions(bootOptions);
|
||||
}
|
||||
}
|
||||
|
||||
setBootOptions(vmSpec, bootMode, vmConfigSpec);
|
||||
|
||||
//
|
||||
// Configure VM
|
||||
|
|
@ -2382,6 +2377,30 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
}
|
||||
}
|
||||
|
||||
private void setBootOptions(VirtualMachineTO vmSpec, String bootMode, VirtualMachineConfigSpec vmConfigSpec) {
|
||||
VirtualMachineBootOptions bootOptions = null;
|
||||
if (StringUtils.isNotBlank(bootMode) && !bootMode.equalsIgnoreCase("bios")) {
|
||||
vmConfigSpec.setFirmware("efi");
|
||||
if (vmSpec.getDetails().containsKey(ApiConstants.BootType.UEFI.toString()) && "secure".equalsIgnoreCase(vmSpec.getDetails().get(ApiConstants.BootType.UEFI.toString()))) {
|
||||
if (bootOptions == null) {
|
||||
bootOptions = new VirtualMachineBootOptions();
|
||||
}
|
||||
bootOptions.setEfiSecureBootEnabled(true);
|
||||
}
|
||||
}
|
||||
if (vmSpec.isEnterHardwareSetup()) {
|
||||
if (bootOptions == null) {
|
||||
bootOptions = new VirtualMachineBootOptions();
|
||||
}
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(String.format("configuring VM '%s' to enter hardware setup",vmSpec.getName()));
|
||||
}
|
||||
bootOptions.setEnterBIOSSetup(vmSpec.isEnterHardwareSetup());
|
||||
}
|
||||
if (bootOptions != null) {
|
||||
vmConfigSpec.setBootOptions(bootOptions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ovf section spec from existing vApp configuration
|
||||
|
|
@ -3908,8 +3927,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
s_logger.trace("Detected mounted vmware tools installer for :[" + cmd.getVmName() + "]");
|
||||
}
|
||||
try {
|
||||
vmMo.rebootGuest();
|
||||
return new RebootAnswer(cmd, "reboot succeeded", true);
|
||||
if (canSetEnableSetupConfig(vmMo,cmd.getVirtualMachine())) {
|
||||
vmMo.rebootGuest();
|
||||
return new RebootAnswer(cmd, "reboot succeeded", true);
|
||||
} else {
|
||||
return new RebootAnswer(cmd, "Failed to configure VM to boot into hardware setup menu: " + vmMo.getName(), false);
|
||||
}
|
||||
} catch (ToolsUnavailableFaultMsg e) {
|
||||
s_logger.warn("VMware tools is not installed at guest OS, we will perform hard reset for reboot");
|
||||
} catch (Exception e) {
|
||||
|
|
@ -3950,6 +3973,33 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set the boot into setup option if possible
|
||||
* @param vmMo vmware view on the vm
|
||||
* @param virtualMachine orchestration spec for the vm
|
||||
* @return true unless reboot into setup is requested and vmware is unable to comply
|
||||
*/
|
||||
private boolean canSetEnableSetupConfig(VirtualMachineMO vmMo, VirtualMachineTO virtualMachine) {
|
||||
if (virtualMachine.isEnterHardwareSetup()) {
|
||||
VirtualMachineBootOptions bootOptions = new VirtualMachineBootOptions();
|
||||
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(String.format("configuring VM '%s' to reboot into hardware setup menu.",virtualMachine.getName()));
|
||||
}
|
||||
bootOptions.setEnterBIOSSetup(virtualMachine.isEnterHardwareSetup());
|
||||
vmConfigSpec.setBootOptions(bootOptions);
|
||||
try {
|
||||
if (!vmMo.configureVm(vmConfigSpec)) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.error(String.format("failed to reconfigure VM '%s' to boot into hardware setup menu",virtualMachine.getName()),e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected Answer execute(CheckVirtualMachineCommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource CheckVirtualMachineCommand: " + _gson.toJson(cmd));
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
<property name="name" value="VMwareGuru" />
|
||||
</bean>
|
||||
|
||||
<bean id="VmwareVmImplementer" class="com.cloud.hypervisor.guru.VmwareVmImplementer"/>
|
||||
|
||||
<bean id="VmwareInvestigator" class="com.cloud.ha.VmwareInvestigator">
|
||||
<property name="name" value="VMwareInvestigator" />
|
||||
</bean>
|
||||
|
|
|
|||
|
|
@ -16,11 +16,9 @@
|
|||
// under the License.
|
||||
package com.cloud.hypervisor.guru;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
|
@ -29,9 +27,9 @@ import org.apache.cloudstack.framework.config.ConfigKey;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
|
|
@ -43,19 +41,13 @@ import com.cloud.agent.api.to.VirtualMachineTO;
|
|||
import com.cloud.vm.VmDetailConstants;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ConfigKey.class, VMwareGuru.class})
|
||||
@PrepareForTest({ConfigKey.class, VmwareVmImplementer.class})
|
||||
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
|
||||
public class VMwareGuruTest {
|
||||
|
||||
@Mock(name="VmwareEnableNestedVirtualization")
|
||||
private ConfigKey<Boolean> vmwareNestedVirtualizationConfig;
|
||||
|
||||
@Mock(name="VmwareEnableNestedVirtualizationPerVM")
|
||||
private ConfigKey<Boolean> vmwareNestedVirtualizationPerVmConfig;
|
||||
public class VmwareVmImplementerTest {
|
||||
|
||||
@Spy
|
||||
@InjectMocks
|
||||
private VMwareGuru _guru = new VMwareGuru();
|
||||
private VmwareVmImplementer implementer = new VmwareVmImplementer();
|
||||
|
||||
@Mock
|
||||
VirtualMachineTO vmTO;
|
||||
|
|
@ -68,26 +60,25 @@ public class VMwareGuruTest {
|
|||
}
|
||||
|
||||
private void setConfigValues(Boolean globalNV, Boolean globalNVPVM, String localNV){
|
||||
when(vmwareNestedVirtualizationConfig.value()).thenReturn(globalNV);
|
||||
when(vmwareNestedVirtualizationPerVmConfig.value()).thenReturn(globalNVPVM);
|
||||
implementer.setGlobalNestedVirtualisationEnabled(globalNV.booleanValue());
|
||||
implementer.setGlobalNestedVPerVMEnabled(globalNVPVM.booleanValue());
|
||||
if (localNV != null) {
|
||||
vmDetails.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, localNV);
|
||||
}
|
||||
}
|
||||
|
||||
private void executeAndVerifyTest(Boolean globalNV, Boolean globalNVPVM, String localNV, Boolean expectedResult){
|
||||
Boolean result = _guru.shouldEnableNestedVirtualization(globalNV, globalNVPVM, localNV);
|
||||
Boolean result = implementer.shouldEnableNestedVirtualization(globalNV, globalNVPVM, localNV);
|
||||
assertEquals(expectedResult, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigureNestedVirtualization(){
|
||||
setConfigValues(true, true, null);
|
||||
_guru.configureNestedVirtualization(vmDetails, vmTO);
|
||||
implementer.configureNestedVirtualization(vmDetails, vmTO);
|
||||
Map<String,String> spyDetails = Mockito.spy(vmDetails);
|
||||
|
||||
InOrder inOrder = inOrder(_guru, vmTO);
|
||||
inOrder.verify(_guru).shouldEnableNestedVirtualization(true, true, null);
|
||||
inOrder.verify(vmTO).setDetails(vmDetails);
|
||||
verify(implementer).shouldEnableNestedVirtualization(true, true, null);
|
||||
|
||||
assertTrue(vmDetails.containsKey(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG));
|
||||
assertEquals(Boolean.toString(true), vmDetails.get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG));
|
||||
|
|
@ -786,7 +786,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
return true;
|
||||
}
|
||||
|
||||
if (rebootVirtualMachine(userId, vmId) == null) {
|
||||
if (rebootVirtualMachine(userId, vmId, false) == null) {
|
||||
s_logger.warn("Failed to reboot the vm " + vmInstance);
|
||||
return false;
|
||||
} else {
|
||||
|
|
@ -897,7 +897,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
s_logger.debug("Vm " + vmInstance + " is stopped, not rebooting it as a part of SSH Key reset");
|
||||
return true;
|
||||
}
|
||||
if (rebootVirtualMachine(userId, vmId) == null) {
|
||||
if (rebootVirtualMachine(userId, vmId, false) == null) {
|
||||
s_logger.warn("Failed to reboot the vm " + vmInstance);
|
||||
return false;
|
||||
} else {
|
||||
|
|
@ -934,9 +934,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
return status;
|
||||
}
|
||||
|
||||
private UserVm rebootVirtualMachine(long userId, long vmId) throws InsufficientCapacityException, ResourceUnavailableException {
|
||||
private UserVm rebootVirtualMachine(long userId, long vmId, boolean enterSetup) throws InsufficientCapacityException, ResourceUnavailableException {
|
||||
UserVmVO vm = _vmDao.findById(vmId);
|
||||
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("reboot %s with enterSetup set to %s", vm.getInstanceName(), Boolean.toString(enterSetup)));
|
||||
}
|
||||
|
||||
if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) {
|
||||
s_logger.warn("Vm id=" + vmId + " doesn't exist");
|
||||
return null;
|
||||
|
|
@ -969,8 +973,18 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
} catch (Exception ex){
|
||||
throw new CloudRuntimeException("Router start failed due to" + ex);
|
||||
}finally {
|
||||
s_logger.info("Rebooting vm " + vm.getInstanceName());
|
||||
_itMgr.reboot(vm.getUuid(), null);
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info(String.format("Rebooting vm %s%s.", vm.getInstanceName(), enterSetup? " entering hardware setup menu" : " as is"));
|
||||
}
|
||||
Map<VirtualMachineProfile.Param,Object> params = null;
|
||||
if (enterSetup) {
|
||||
params = new HashMap();
|
||||
params.put(VirtualMachineProfile.Param.BootIntoSetup, Boolean.TRUE);
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("Adding %s to paramlist", VirtualMachineProfile.Param.BootIntoSetup));
|
||||
}
|
||||
}
|
||||
_itMgr.reboot(vm.getUuid(), params);
|
||||
}
|
||||
return _vmDao.findById(vmId);
|
||||
} else {
|
||||
|
|
@ -2836,7 +2850,19 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VM_START, eventDescription = "starting Vm", async = true)
|
||||
public UserVm startVirtualMachine(StartVMCmd cmd) throws ExecutionException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
|
||||
return startVirtualMachine(cmd.getId(), cmd.getPodId(), cmd.getClusterId(), cmd.getHostId(), null, cmd.getDeploymentPlanner()).first();
|
||||
Map<VirtualMachineProfile.Param, Object> additonalParams = null;
|
||||
if (cmd.getBootIntoSetup() != null) {
|
||||
if (additonalParams == null) {
|
||||
additonalParams = new HashMap<>();
|
||||
}
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("Adding %s into the param map", VirtualMachineProfile.Param.BootIntoSetup.getName()));
|
||||
}
|
||||
|
||||
additonalParams.put(VirtualMachineProfile.Param.BootIntoSetup, cmd.getBootIntoSetup());
|
||||
}
|
||||
|
||||
return startVirtualMachine(cmd.getId(), cmd.getPodId(), cmd.getClusterId(), cmd.getHostId(), additonalParams, cmd.getDeploymentPlanner()).first();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2866,7 +2892,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId + " corresponding to the vm");
|
||||
}
|
||||
|
||||
UserVm userVm = rebootVirtualMachine(CallContext.current().getCallingUserId(), vmId);
|
||||
Boolean enterSetup = cmd.getBootIntoSetup();
|
||||
if (enterSetup != null && !HypervisorType.VMware.equals(vmInstance.getHypervisorType())) {
|
||||
throw new InvalidParameterValueException("booting into a hardware setup menu does not make sense on " + vmInstance.getHypervisorType());
|
||||
}
|
||||
UserVm userVm = rebootVirtualMachine(CallContext.current().getCallingUserId(), vmId, enterSetup == null ? false : cmd.getBootIntoSetup());
|
||||
if (userVm != null ) {
|
||||
// update the vmIdCountMap if the vm is in advanced shared network with out services
|
||||
final List<NicVO> nics = _nicDao.listByVmId(vmId);
|
||||
|
|
@ -4288,7 +4318,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
Long podId = null;
|
||||
Long clusterId = null;
|
||||
Long hostId = cmd.getHostId();
|
||||
Map<VirtualMachineProfile.Param, Object> additonalParams = null;
|
||||
Map<VirtualMachineProfile.Param, Object> additonalParams = new HashMap<>();
|
||||
Map<Long, DiskOffering> diskOfferingMap = cmd.getDataDiskTemplateToDiskOfferingMap();
|
||||
if (cmd instanceof DeployVMCmdByAdmin) {
|
||||
DeployVMCmdByAdmin adminCmd = (DeployVMCmdByAdmin)cmd;
|
||||
|
|
@ -4296,16 +4326,19 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
clusterId = adminCmd.getClusterId();
|
||||
}
|
||||
if (MapUtils.isNotEmpty(cmd.getDetails()) && cmd.getDetails().containsKey(ApiConstants.BootType.UEFI.toString())) {
|
||||
additonalParams = new HashMap<VirtualMachineProfile.Param, Object>();
|
||||
Map<String, String> map = cmd.getDetails();
|
||||
additonalParams.put(VirtualMachineProfile.Param.UefiFlag, "Yes");
|
||||
additonalParams.put(VirtualMachineProfile.Param.BootType, ApiConstants.BootType.UEFI.toString());
|
||||
additonalParams.put(VirtualMachineProfile.Param.BootMode, map.get(ApiConstants.BootType.UEFI.toString()));
|
||||
}
|
||||
if (cmd.getBootIntoSetup() != null) {
|
||||
additonalParams.put(VirtualMachineProfile.Param.BootIntoSetup, cmd.getBootIntoSetup());
|
||||
}
|
||||
return startVirtualMachine(vmId, podId, clusterId, hostId, diskOfferingMap, additonalParams, cmd.getDeploymentPlanner());
|
||||
}
|
||||
|
||||
private UserVm startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, Map<Long, DiskOffering> diskOfferingMap, Map<VirtualMachineProfile.Param, Object> additonalParams, String deploymentPlannerToUse)
|
||||
private UserVm startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, Map<Long, DiskOffering> diskOfferingMap
|
||||
, Map<VirtualMachineProfile.Param, Object> additonalParams, String deploymentPlannerToUse)
|
||||
throws ResourceUnavailableException,
|
||||
InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException {
|
||||
UserVmVO vm = _vmDao.findById(vmId);
|
||||
|
|
@ -4640,7 +4673,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
}
|
||||
|
||||
@Override
|
||||
public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse)
|
||||
public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId,
|
||||
Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse)
|
||||
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
|
||||
// Input validation
|
||||
final Account callerAccount = CallContext.current().getCallingAccount();
|
||||
|
|
@ -4743,11 +4777,18 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
// use it to encrypt & save the vm password
|
||||
encryptAndStorePassword(vm, password);
|
||||
|
||||
params = new HashMap<VirtualMachineProfile.Param, Object>();
|
||||
if (additionalParams != null) {
|
||||
params.putAll(additionalParams);
|
||||
params = createParameterInParameterMap(params, additionalParams, VirtualMachineProfile.Param.VmPassword, password);
|
||||
}
|
||||
|
||||
if(null != additionalParams && additionalParams.containsKey(VirtualMachineProfile.Param.BootIntoSetup)) {
|
||||
if (! HypervisorType.VMware.equals(vm.getHypervisorType())) {
|
||||
throw new InvalidParameterValueException(ApiConstants.BOOT_INTO_SETUP + " makes no sense for " + vm.getHypervisorType());
|
||||
}
|
||||
params.put(VirtualMachineProfile.Param.VmPassword, password);
|
||||
Object paramValue = additionalParams.get(VirtualMachineProfile.Param.BootIntoSetup);
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("It was specified whether to enter setup mode: " + paramValue.toString());
|
||||
}
|
||||
params = createParameterInParameterMap(params, additionalParams, VirtualMachineProfile.Param.BootIntoSetup, paramValue);
|
||||
}
|
||||
|
||||
VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
|
||||
|
|
@ -4782,6 +4823,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
return vmParamPair;
|
||||
}
|
||||
|
||||
private Map<VirtualMachineProfile.Param, Object> createParameterInParameterMap(Map<VirtualMachineProfile.Param, Object> params, Map<VirtualMachineProfile.Param, Object> parameterMap, VirtualMachineProfile.Param parameter,
|
||||
Object parameterValue) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("createParameterInParameterMap(%s, %s)", parameter, parameterValue));
|
||||
}
|
||||
if (params == null) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("creating new Parameter map");
|
||||
}
|
||||
params = new HashMap<>();
|
||||
if (parameterMap != null) {
|
||||
params.putAll(parameterMap);
|
||||
}
|
||||
}
|
||||
params.put(parameter, parameterValue);
|
||||
return params;
|
||||
}
|
||||
|
||||
private Pod getDestinationPod(Long podId, boolean isRootAdmin) {
|
||||
Pod destinationPod = null;
|
||||
if (podId != null) {
|
||||
|
|
@ -7114,4 +7173,4 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
id, instanceName, uuidName, hypervisorType, customParameters,
|
||||
null, null, null, powerState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -504,6 +504,12 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="select-area">
|
||||
<div class="value">
|
||||
<input type="checkbox" name="bootintosetup" id="bootintosetup" />
|
||||
<label><translate key="label.vm.enterhardwaresetup" /></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Zone -->
|
||||
<div class="select">
|
||||
|
|
|
|||
|
|
@ -789,6 +789,7 @@ var dictionary = {
|
|||
"label.end.vxlan":"End VXLAN",
|
||||
"label.endpoint":"Endpoint",
|
||||
"label.endpoint.or.operation":"Endpoint or Operation",
|
||||
"label.enter.hardware.setup":"Enter the hardware setup menu",
|
||||
"label.enter.token":"Enter token",
|
||||
"label.error":"Error",
|
||||
"label.error.code":"Error Code",
|
||||
|
|
@ -994,6 +995,7 @@ var dictionary = {
|
|||
"label.keyboard.language":"Keyboard language",
|
||||
"label.vm.boottype":"Boot Type",
|
||||
"label.vm.bootmode":"Boot Mode",
|
||||
"label.vm.enterhardwaresetup":"Enter hardware setup after boot",
|
||||
"label.keyboard.type":"Keyboard type",
|
||||
"label.kubernetes.cluster":"Kubernetes cluster",
|
||||
"label.kubernetes.cluster.details":"Kubernetes cluster details",
|
||||
|
|
|
|||
|
|
@ -1413,6 +1413,12 @@
|
|||
bootmode : bootmode
|
||||
});
|
||||
}
|
||||
var bootintosetup = (args.data.bootintosetup == "on");
|
||||
if (bootintosetup) {
|
||||
$.extend(deployVmData, {
|
||||
bootintosetup : bootintosetup
|
||||
});
|
||||
}
|
||||
|
||||
if (g_hostid != null) {
|
||||
$.extend(deployVmData, {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,16 @@
|
|||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
bootintosetup: {
|
||||
label: 'label.enter.hardware.setup',
|
||||
isBoolean: true,
|
||||
isHidden: function(args) {
|
||||
if (args.context.instances[0].hypervisor !== 'VMware') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1049,7 +1059,18 @@
|
|||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
bootintosetup: {
|
||||
label: 'label.enter.hardware.setup',
|
||||
isBoolean: true,
|
||||
isHidden: function(args) {
|
||||
if (args.context.instances[0].hypervisor !== 'VMware') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
action: function(args) {
|
||||
|
|
@ -1071,6 +1092,12 @@
|
|||
hostid: args.data.hostId
|
||||
});
|
||||
}
|
||||
var bootintosetup = (args.data.bootintosetup == "on");
|
||||
if (bootintosetup) {
|
||||
$.extend(data, {
|
||||
bootintosetup : bootintosetup
|
||||
});
|
||||
}
|
||||
$.ajax({
|
||||
url: createURL("startVirtualMachine"),
|
||||
data: data,
|
||||
|
|
@ -1115,10 +1142,34 @@
|
|||
restart: {
|
||||
label: 'label.action.reboot.instance',
|
||||
compactLabel: 'label.reboot',
|
||||
createForm: {
|
||||
title: 'label.action.reboot.instance',
|
||||
desc: 'message.action.reboot.instance',
|
||||
preFilter: function(args) {
|
||||
args.$form.find('.form-item[rel=bootintosetup]').find('input').attr('checked', 'checked'); //checked
|
||||
args.$form.find('.form-item[rel=bootintosetup]').css('display', 'inline-block'); //shown
|
||||
},
|
||||
fields: {
|
||||
bootintosetup: {
|
||||
label: 'label.enter.hardware.setup',
|
||||
isBoolean: true,
|
||||
isHidden: function(args) {
|
||||
if (args.context.instances[0].hypervisor !== 'VMware') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
action: function(args) {
|
||||
$.ajax({
|
||||
url: createURL("rebootVirtualMachine&id=" + args.context.instances[0].id),
|
||||
url: createURL("rebootVirtualMachine"),
|
||||
dataType: "json",
|
||||
data: {
|
||||
id: args.context.instances[0].id,
|
||||
bootintosetup: (args.data.bootintosetup == "on")
|
||||
},
|
||||
async: true,
|
||||
success: function(json) {
|
||||
var jid = json.rebootvirtualmachineresponse.jobid;
|
||||
|
|
|
|||
Loading…
Reference in New Issue