mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
server,engine-orchestration: allocate vm without transaction (#7695)
When deploying a VM is failed during the allocation process it may leave the resources that have been already allocated before the failure. They will get removed from the database as the whole code block is wrapped inside a transaction twice but the server would not inform the network or storage plugins to clean up the allocated resources. This PR removes Transactions during VM allocation which results in the allocated VM and its resource records being persisted in DB even during failures. When failure is encountered VM is moved to Error state. This helps VM and its resources to be properly deallocated when it is expunged either by a server task such as ExpungeTask or during manual expunge. Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
c733a23c90
commit
939ee9e153
@ -458,72 +458,79 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
throws InsufficientCapacityException {
|
throws InsufficientCapacityException {
|
||||||
|
|
||||||
s_logger.info(String.format("allocating virtual machine from template:%s with hostname:%s and %d networks", template.getUuid(), vmInstanceName, auxiliaryNetworks.size()));
|
s_logger.info(String.format("allocating virtual machine from template:%s with hostname:%s and %d networks", template.getUuid(), vmInstanceName, auxiliaryNetworks.size()));
|
||||||
|
VMInstanceVO persistedVm = null;
|
||||||
|
try {
|
||||||
|
final VMInstanceVO vm = _vmDao.findVMByInstanceName(vmInstanceName);
|
||||||
|
final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
|
||||||
|
|
||||||
final VMInstanceVO vm = _vmDao.findVMByInstanceName(vmInstanceName);
|
if (s_logger.isDebugEnabled()) {
|
||||||
final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
|
s_logger.debug("Allocating entries for VM: " + vm);
|
||||||
|
}
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
vm.setDataCenterId(plan.getDataCenterId());
|
||||||
s_logger.debug("Allocating entries for VM: " + vm);
|
if (plan.getPodId() != null) {
|
||||||
}
|
vm.setPodIdToDeployIn(plan.getPodId());
|
||||||
|
}
|
||||||
|
assert plan.getClusterId() == null && plan.getPoolId() == null : "We currently don't support cluster and pool preset yet";
|
||||||
|
persistedVm = _vmDao.persist(vm);
|
||||||
|
|
||||||
vm.setDataCenterId(plan.getDataCenterId());
|
final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(persistedVm, template, serviceOffering, null, null);
|
||||||
if (plan.getPodId() != null) {
|
|
||||||
vm.setPodIdToDeployIn(plan.getPodId());
|
|
||||||
}
|
|
||||||
assert plan.getClusterId() == null && plan.getPoolId() == null : "We currently don't support cluster and pool preset yet";
|
|
||||||
final VMInstanceVO vmFinal = _vmDao.persist(vm);
|
|
||||||
|
|
||||||
final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmFinal, template, serviceOffering, null, null);
|
Long rootDiskSize = rootDiskOfferingInfo.getSize();
|
||||||
|
if (vm.getType().isUsedBySystem() && SystemVmRootDiskSize.value() != null && SystemVmRootDiskSize.value() > 0L) {
|
||||||
|
rootDiskSize = SystemVmRootDiskSize.value();
|
||||||
|
}
|
||||||
|
final Long rootDiskSizeFinal = rootDiskSize;
|
||||||
|
|
||||||
Long rootDiskSize = rootDiskOfferingInfo.getSize();
|
if (s_logger.isDebugEnabled()) {
|
||||||
if (vm.getType().isUsedBySystem() && SystemVmRootDiskSize.value() != null && SystemVmRootDiskSize.value() > 0L) {
|
s_logger.debug("Allocating nics for " + persistedVm);
|
||||||
rootDiskSize = SystemVmRootDiskSize.value();
|
}
|
||||||
}
|
|
||||||
final Long rootDiskSizeFinal = rootDiskSize;
|
|
||||||
|
|
||||||
Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
|
try {
|
||||||
@Override
|
if (!vmProfile.getBootArgs().contains("ExternalLoadBalancerVm")) {
|
||||||
public void doInTransactionWithoutResult(final TransactionStatus status) throws InsufficientCapacityException {
|
_networkMgr.allocate(vmProfile, auxiliaryNetworks, extraDhcpOptions);
|
||||||
if (s_logger.isDebugEnabled()) {
|
|
||||||
s_logger.debug("Allocating nics for " + vmFinal);
|
|
||||||
}
|
}
|
||||||
|
} catch (final ConcurrentOperationException e) {
|
||||||
|
throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
if (s_logger.isDebugEnabled()) {
|
||||||
if (!vmProfile.getBootArgs().contains("ExternalLoadBalancerVm")) {
|
s_logger.debug("Allocating disks for " + persistedVm);
|
||||||
_networkMgr.allocate(vmProfile, auxiliaryNetworks, extraDhcpOptions);
|
}
|
||||||
}
|
|
||||||
} catch (final ConcurrentOperationException e) {
|
|
||||||
throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
allocateRootVolume(persistedVm, template, rootDiskOfferingInfo, owner, rootDiskSizeFinal);
|
||||||
s_logger.debug("Allocating disks for " + vmFinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
allocateRootVolume(vmFinal, template, rootDiskOfferingInfo, owner, rootDiskSizeFinal);
|
if (dataDiskOfferings != null) {
|
||||||
|
for (final DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings) {
|
||||||
if (dataDiskOfferings != null) {
|
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + persistedVm.getId(), dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(),
|
||||||
for (final DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings) {
|
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), persistedVm, template, owner, null);
|
||||||
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId(), dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(),
|
}
|
||||||
dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), vmFinal, template, owner, null);
|
}
|
||||||
}
|
if (datadiskTemplateToDiskOfferingMap != null && !datadiskTemplateToDiskOfferingMap.isEmpty()) {
|
||||||
}
|
int diskNumber = 1;
|
||||||
if (datadiskTemplateToDiskOfferingMap != null && !datadiskTemplateToDiskOfferingMap.isEmpty()) {
|
for (Entry<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap : datadiskTemplateToDiskOfferingMap.entrySet()) {
|
||||||
int diskNumber = 1;
|
DiskOffering diskOffering = dataDiskTemplateToDiskOfferingMap.getValue();
|
||||||
for (Entry<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap : datadiskTemplateToDiskOfferingMap.entrySet()) {
|
long diskOfferingSize = diskOffering.getDiskSize() / (1024 * 1024 * 1024);
|
||||||
DiskOffering diskOffering = dataDiskTemplateToDiskOfferingMap.getValue();
|
VMTemplateVO dataDiskTemplate = _templateDao.findById(dataDiskTemplateToDiskOfferingMap.getKey());
|
||||||
long diskOfferingSize = diskOffering.getDiskSize() / (1024 * 1024 * 1024);
|
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + persistedVm.getId() + "-" + String.valueOf(diskNumber), diskOffering, diskOfferingSize, null, null,
|
||||||
VMTemplateVO dataDiskTemplate = _templateDao.findById(dataDiskTemplateToDiskOfferingMap.getKey());
|
persistedVm, dataDiskTemplate, owner, Long.valueOf(diskNumber));
|
||||||
volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId() + "-" + String.valueOf(diskNumber), diskOffering, diskOfferingSize, null, null,
|
diskNumber++;
|
||||||
vmFinal, dataDiskTemplate, owner, Long.valueOf(diskNumber));
|
|
||||||
diskNumber++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Allocation completed for VM: " + vmFinal);
|
s_logger.debug("Allocation completed for VM: " + persistedVm);
|
||||||
|
}
|
||||||
|
} catch (InsufficientCapacityException | CloudRuntimeException e) {
|
||||||
|
// Failed VM will be in Stopped. Transition it to Error, so it can be expunged by ExpungeTask or similar
|
||||||
|
try {
|
||||||
|
if (persistedVm != null) {
|
||||||
|
stateTransitTo(persistedVm, VirtualMachine.Event.OperationFailedToError, null);
|
||||||
|
}
|
||||||
|
} catch (NoTransitionException nte) {
|
||||||
|
s_logger.error(String.format("Failed to transition %s in %s state to Error state", persistedVm, persistedVm.getState().toString()));
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -348,7 +348,6 @@ import com.cloud.utils.db.GlobalLock;
|
|||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
import com.cloud.utils.db.Transaction;
|
import com.cloud.utils.db.Transaction;
|
||||||
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
||||||
import com.cloud.utils.db.TransactionCallbackWithException;
|
|
||||||
import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
|
import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
|
||||||
import com.cloud.utils.db.TransactionStatus;
|
import com.cloud.utils.db.TransactionStatus;
|
||||||
import com.cloud.utils.db.UUIDManager;
|
import com.cloud.utils.db.UUIDManager;
|
||||||
@ -4366,161 +4365,156 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map<String, String> customParameters,
|
final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map<String, String> customParameters,
|
||||||
final Map<String, Map<Integer, String>> extraDhcpOptionMap, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
final Map<String, Map<Integer, String>> extraDhcpOptionMap, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
||||||
final Map<String, String> userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState, final boolean dynamicScalingEnabled, String vmType, final Long rootDiskOfferingId, String sshkeypairs) throws InsufficientCapacityException {
|
final Map<String, String> userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState, final boolean dynamicScalingEnabled, String vmType, final Long rootDiskOfferingId, String sshkeypairs) throws InsufficientCapacityException {
|
||||||
return Transaction.execute(new TransactionCallbackWithException<UserVmVO, InsufficientCapacityException>() {
|
UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, template.getGuestOSId(), offering.isOfferHA(),
|
||||||
@Override
|
offering.getLimitCpuUse(), owner.getDomainId(), owner.getId(), userId, offering.getId(), userData, userDataId, userDataDetails, hostName);
|
||||||
public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException {
|
vm.setUuid(uuidName);
|
||||||
UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, template.getGuestOSId(), offering.isOfferHA(),
|
vm.setDynamicallyScalable(dynamicScalingEnabled);
|
||||||
offering.getLimitCpuUse(), owner.getDomainId(), owner.getId(), userId, offering.getId(), userData, userDataId, userDataDetails, hostName);
|
|
||||||
vm.setUuid(uuidName);
|
|
||||||
vm.setDynamicallyScalable(dynamicScalingEnabled);
|
|
||||||
|
|
||||||
Map<String, String> details = template.getDetails();
|
Map<String, String> details = template.getDetails();
|
||||||
if (details != null && !details.isEmpty()) {
|
if (details != null && !details.isEmpty()) {
|
||||||
vm.details.putAll(details);
|
vm.details.putAll(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(sshPublicKeys)) {
|
if (StringUtils.isNotBlank(sshPublicKeys)) {
|
||||||
vm.setDetail(VmDetailConstants.SSH_PUBLIC_KEY, sshPublicKeys);
|
vm.setDetail(VmDetailConstants.SSH_PUBLIC_KEY, sshPublicKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(sshkeypairs)) {
|
if (StringUtils.isNotBlank(sshkeypairs)) {
|
||||||
vm.setDetail(VmDetailConstants.SSH_KEY_PAIR_NAMES, sshkeypairs);
|
vm.setDetail(VmDetailConstants.SSH_KEY_PAIR_NAMES, sshkeypairs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyboard != null && !keyboard.isEmpty()) {
|
if (keyboard != null && !keyboard.isEmpty()) {
|
||||||
vm.setDetail(VmDetailConstants.KEYBOARD, keyboard);
|
vm.setDetail(VmDetailConstants.KEYBOARD, keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isImport && isIso) {
|
if (!isImport && isIso) {
|
||||||
vm.setIsoId(template.getId());
|
vm.setIsoId(template.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
long guestOSId = template.getGuestOSId();
|
long guestOSId = template.getGuestOSId();
|
||||||
GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
|
GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
|
||||||
long guestOSCategoryId = guestOS.getCategoryId();
|
long guestOSCategoryId = guestOS.getCategoryId();
|
||||||
GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);
|
GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);
|
||||||
if (hypervisorType.equals(HypervisorType.VMware)) {
|
if (hypervisorType.equals(HypervisorType.VMware)) {
|
||||||
updateVMDiskController(vm, customParameters, guestOS);
|
updateVMDiskController(vm, customParameters, guestOS);
|
||||||
}
|
}
|
||||||
|
|
||||||
Long rootDiskSize = null;
|
Long rootDiskSize = null;
|
||||||
// custom root disk size, resizes base template to larger size
|
// custom root disk size, resizes base template to larger size
|
||||||
if (customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) {
|
if (customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) {
|
||||||
// already verified for positive number
|
// already verified for positive number
|
||||||
rootDiskSize = Long.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE));
|
rootDiskSize = Long.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE));
|
||||||
|
|
||||||
VMTemplateVO templateVO = _templateDao.findById(template.getId());
|
VMTemplateVO templateVO = _templateDao.findById(template.getId());
|
||||||
if (templateVO == null) {
|
if (templateVO == null) {
|
||||||
throw new InvalidParameterValueException("Unable to look up template by id " + template.getId());
|
throw new InvalidParameterValueException("Unable to look up template by id " + template.getId());
|
||||||
}
|
|
||||||
|
|
||||||
validateRootDiskResize(hypervisorType, rootDiskSize, templateVO, vm, customParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDisplayVm != null) {
|
|
||||||
vm.setDisplayVm(isDisplayVm);
|
|
||||||
} else {
|
|
||||||
vm.setDisplayVm(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isImport) {
|
|
||||||
vm.setDataCenterId(zone.getId());
|
|
||||||
vm.setHostId(host.getId());
|
|
||||||
if (lastHost != null) {
|
|
||||||
vm.setLastHostId(lastHost.getId());
|
|
||||||
}
|
|
||||||
vm.setPowerState(powerState);
|
|
||||||
if (powerState == VirtualMachine.PowerState.PowerOn) {
|
|
||||||
vm.setState(State.Running);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vm.setUserVmType(vmType);
|
|
||||||
_vmDao.persist(vm);
|
|
||||||
for (String key : customParameters.keySet()) {
|
|
||||||
// BIOS was explicitly passed as the boot type, so honour it
|
|
||||||
if (key.equalsIgnoreCase(ApiConstants.BootType.BIOS.toString())) {
|
|
||||||
vm.details.remove(ApiConstants.BootType.UEFI.toString());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deploy as is, Don't care about the boot type or template settings
|
|
||||||
if (key.equalsIgnoreCase(ApiConstants.BootType.UEFI.toString()) && template.isDeployAsIs()) {
|
|
||||||
vm.details.remove(ApiConstants.BootType.UEFI.toString());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hypervisorType.equals(HypervisorType.KVM)) {
|
|
||||||
if (key.equalsIgnoreCase(VmDetailConstants.IOTHREADS)) {
|
|
||||||
vm.details.remove(VmDetailConstants.IOTHREADS);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (key.equalsIgnoreCase(VmDetailConstants.IO_POLICY)) {
|
|
||||||
vm.details.remove(VmDetailConstants.IO_POLICY);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key.equalsIgnoreCase(VmDetailConstants.CPU_NUMBER) ||
|
|
||||||
key.equalsIgnoreCase(VmDetailConstants.CPU_SPEED) ||
|
|
||||||
key.equalsIgnoreCase(VmDetailConstants.MEMORY)) {
|
|
||||||
// handle double byte strings.
|
|
||||||
vm.setDetail(key, Integer.toString(Integer.parseInt(customParameters.get(key))));
|
|
||||||
} else {
|
|
||||||
vm.setDetail(key, customParameters.get(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vm.setDetail(VmDetailConstants.DEPLOY_VM, "true");
|
|
||||||
|
|
||||||
persistVMDeployAsIsProperties(vm, userVmOVFPropertiesMap);
|
|
||||||
|
|
||||||
List<String> hiddenDetails = new ArrayList<>();
|
|
||||||
if (customParameters.containsKey(VmDetailConstants.NAME_ON_HYPERVISOR)) {
|
|
||||||
hiddenDetails.add(VmDetailConstants.NAME_ON_HYPERVISOR);
|
|
||||||
}
|
|
||||||
_vmDao.saveDetails(vm, hiddenDetails);
|
|
||||||
if (!isImport) {
|
|
||||||
s_logger.debug("Allocating in the DB for vm");
|
|
||||||
DataCenterDeployment plan = new DataCenterDeployment(zone.getId());
|
|
||||||
|
|
||||||
List<String> computeTags = new ArrayList<String>();
|
|
||||||
computeTags.add(offering.getHostTag());
|
|
||||||
|
|
||||||
List<String> rootDiskTags = new ArrayList<String>();
|
|
||||||
DiskOfferingVO rootDiskOfferingVO = _diskOfferingDao.findById(rootDiskOfferingId);
|
|
||||||
rootDiskTags.add(rootDiskOfferingVO.getTags());
|
|
||||||
|
|
||||||
if (isIso) {
|
|
||||||
_orchSrvc.createVirtualMachineFromScratch(vm.getUuid(), Long.toString(owner.getAccountId()), vm.getIsoId().toString(), hostName, displayName,
|
|
||||||
hypervisorType.name(), guestOSCategory.getName(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags,
|
|
||||||
networkNicMap, plan, extraDhcpOptionMap, rootDiskOfferingId);
|
|
||||||
} else {
|
|
||||||
_orchSrvc.createVirtualMachine(vm.getUuid(), Long.toString(owner.getAccountId()), Long.toString(template.getId()), hostName, displayName, hypervisorType.name(),
|
|
||||||
offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan, rootDiskSize, extraDhcpOptionMap,
|
|
||||||
dataDiskTemplateToDiskOfferingMap, diskOfferingId, rootDiskOfferingId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
|
||||||
s_logger.debug("Successfully allocated DB entry for " + vm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CallContext.current().setEventDetails("Vm Id: " + vm.getUuid());
|
|
||||||
|
|
||||||
if (!isImport) {
|
|
||||||
if (!offering.isDynamic()) {
|
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(),
|
|
||||||
hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
|
|
||||||
} else {
|
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(),
|
|
||||||
hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters, vm.isDisplayVm());
|
|
||||||
}
|
|
||||||
|
|
||||||
//Update Resource Count for the given account
|
|
||||||
resourceCountIncrement(accountId, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
|
||||||
}
|
|
||||||
return vm;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
validateRootDiskResize(hypervisorType, rootDiskSize, templateVO, vm, customParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDisplayVm != null) {
|
||||||
|
vm.setDisplayVm(isDisplayVm);
|
||||||
|
} else {
|
||||||
|
vm.setDisplayVm(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isImport) {
|
||||||
|
vm.setDataCenterId(zone.getId());
|
||||||
|
vm.setHostId(host.getId());
|
||||||
|
if (lastHost != null) {
|
||||||
|
vm.setLastHostId(lastHost.getId());
|
||||||
|
}
|
||||||
|
vm.setPowerState(powerState);
|
||||||
|
if (powerState == VirtualMachine.PowerState.PowerOn) {
|
||||||
|
vm.setState(State.Running);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vm.setUserVmType(vmType);
|
||||||
|
_vmDao.persist(vm);
|
||||||
|
for (String key : customParameters.keySet()) {
|
||||||
|
// BIOS was explicitly passed as the boot type, so honour it
|
||||||
|
if (key.equalsIgnoreCase(ApiConstants.BootType.BIOS.toString())) {
|
||||||
|
vm.details.remove(ApiConstants.BootType.UEFI.toString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deploy as is, Don't care about the boot type or template settings
|
||||||
|
if (key.equalsIgnoreCase(ApiConstants.BootType.UEFI.toString()) && template.isDeployAsIs()) {
|
||||||
|
vm.details.remove(ApiConstants.BootType.UEFI.toString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hypervisorType.equals(HypervisorType.KVM)) {
|
||||||
|
if (key.equalsIgnoreCase(VmDetailConstants.IOTHREADS)) {
|
||||||
|
vm.details.remove(VmDetailConstants.IOTHREADS);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (key.equalsIgnoreCase(VmDetailConstants.IO_POLICY)) {
|
||||||
|
vm.details.remove(VmDetailConstants.IO_POLICY);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.equalsIgnoreCase(VmDetailConstants.CPU_NUMBER) ||
|
||||||
|
key.equalsIgnoreCase(VmDetailConstants.CPU_SPEED) ||
|
||||||
|
key.equalsIgnoreCase(VmDetailConstants.MEMORY)) {
|
||||||
|
// handle double byte strings.
|
||||||
|
vm.setDetail(key, Integer.toString(Integer.parseInt(customParameters.get(key))));
|
||||||
|
} else {
|
||||||
|
vm.setDetail(key, customParameters.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vm.setDetail(VmDetailConstants.DEPLOY_VM, "true");
|
||||||
|
|
||||||
|
persistVMDeployAsIsProperties(vm, userVmOVFPropertiesMap);
|
||||||
|
|
||||||
|
List<String> hiddenDetails = new ArrayList<>();
|
||||||
|
if (customParameters.containsKey(VmDetailConstants.NAME_ON_HYPERVISOR)) {
|
||||||
|
hiddenDetails.add(VmDetailConstants.NAME_ON_HYPERVISOR);
|
||||||
|
}
|
||||||
|
_vmDao.saveDetails(vm, hiddenDetails);
|
||||||
|
if (!isImport) {
|
||||||
|
s_logger.debug("Allocating in the DB for vm");
|
||||||
|
DataCenterDeployment plan = new DataCenterDeployment(zone.getId());
|
||||||
|
|
||||||
|
List<String> computeTags = new ArrayList<String>();
|
||||||
|
computeTags.add(offering.getHostTag());
|
||||||
|
|
||||||
|
List<String> rootDiskTags = new ArrayList<String>();
|
||||||
|
DiskOfferingVO rootDiskOfferingVO = _diskOfferingDao.findById(rootDiskOfferingId);
|
||||||
|
rootDiskTags.add(rootDiskOfferingVO.getTags());
|
||||||
|
|
||||||
|
if (isIso) {
|
||||||
|
_orchSrvc.createVirtualMachineFromScratch(vm.getUuid(), Long.toString(owner.getAccountId()), vm.getIsoId().toString(), hostName, displayName,
|
||||||
|
hypervisorType.name(), guestOSCategory.getName(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags,
|
||||||
|
networkNicMap, plan, extraDhcpOptionMap, rootDiskOfferingId);
|
||||||
|
} else {
|
||||||
|
_orchSrvc.createVirtualMachine(vm.getUuid(), Long.toString(owner.getAccountId()), Long.toString(template.getId()), hostName, displayName, hypervisorType.name(),
|
||||||
|
offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan, rootDiskSize, extraDhcpOptionMap,
|
||||||
|
dataDiskTemplateToDiskOfferingMap, diskOfferingId, rootDiskOfferingId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("Successfully allocated DB entry for " + vm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CallContext.current().setEventDetails("Vm Id: " + vm.getUuid());
|
||||||
|
|
||||||
|
if (!isImport) {
|
||||||
|
if (!offering.isDynamic()) {
|
||||||
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(),
|
||||||
|
hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
|
||||||
|
} else {
|
||||||
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(),
|
||||||
|
hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters, vm.isDisplayVm());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Update Resource Count for the given account
|
||||||
|
resourceCountIncrement(accountId, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
||||||
|
}
|
||||||
|
return vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateVMDiskController(UserVmVO vm, Map<String, String> customParameters, GuestOSVO guestOS) {
|
private void updateVMDiskController(UserVmVO vm, Map<String, String> customParameters, GuestOSVO guestOS) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user