diff --git a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java index e871bd8672f..5eca02f33d5 100644 --- a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java @@ -59,6 +59,8 @@ import com.cloud.utils.fsm.NoTransitionException; */ public interface VirtualMachineManager extends Manager { + String KVM_BLANK_VM_TEMPLATE_NAME = "kvm-blank-vm-template"; + ConfigKey ExecuteInSequence = new ConfigKey<>("Advanced", Boolean.class, "execute.in.sequence.hypervisor.commands", "false", "If set to true, start, stop, reboot, copy and migrate commands will be serialized on the agent side. If set to false the commands are executed in parallel. Default value is false.", false); @@ -312,4 +314,8 @@ public interface VirtualMachineManager extends Manager { ServiceOffering serviceOffering, Account systemAccount, DeploymentPlan plan) throws InsufficientServerCapacityException; + boolean isBlankInstanceDefaultTemplate(VirtualMachineTemplate template); + + boolean isBlankInstance(VirtualMachineTemplate template); + } diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index b96baf70b21..07f93837ba6 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -575,7 +575,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac logger.debug("Allocating disks for {}", persistedVm); - if (_userVmMgr.isBlankInstance(template)) { + if (isBlankInstance(template)) { logger.debug("Template is a dummy template for hypervisor {}, skipping volume allocation", hyperType); return; } else { @@ -6702,4 +6702,18 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac vmProfile), DataCenter.class, plan.getDataCenterId(), areAffinityGroupsAssociated(vmProfile)); } } + + @Override + public boolean isBlankInstanceDefaultTemplate(VirtualMachineTemplate template) { + return KVM_BLANK_VM_TEMPLATE_NAME.equals(template.getUniqueName()); + } + + @Override + public boolean isBlankInstance(VirtualMachineTemplate template) { + if (isBlankInstanceDefaultTemplate(template)) { + return true; + } + return Boolean.TRUE.equals( + MapUtils.getBoolean(CallContext.current().getContextParameters(), ApiConstants.BLANK_INSTANCE)); + } } diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java index 8639f006383..964265cb873 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.engine.orchestration; import com.cloud.storage.Snapshot; +import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate; import java.net.URL; @@ -292,9 +293,11 @@ public class CloudOrchestrator implements OrchestrationService { ServiceOfferingVO computeOffering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId()); + VMTemplateVO iso = _templateDao.findByIdIncludingRemoved(Long.valueOf(isoId)); + DiskOfferingInfo rootDiskOfferingInfo = new DiskOfferingInfo(); - if (diskOfferingId == null) { + if (diskOfferingId == null && !_itMgr.isBlankInstance(iso)) { throw new InvalidParameterValueException("Installing from ISO requires a disk offering to be specified for the root disk."); } DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId); @@ -345,7 +348,7 @@ public class CloudOrchestrator implements OrchestrationService { HypervisorType hypervisorType = HypervisorType.valueOf(hypervisor); - _itMgr.allocate(vm.getInstanceName(), _templateDao.findByIdIncludingRemoved(new Long(isoId)), computeOffering, rootDiskOfferingInfo, dataDiskOfferings, dataDiskDeviceIds, + _itMgr.allocate(vm.getInstanceName(), iso, computeOffering, rootDiskOfferingInfo, dataDiskOfferings, dataDiskDeviceIds, networkIpMap, plan, hypervisorType, extraDhcpOptionMap, null, volume, snapshot); return vmEntity; diff --git a/server/src/main/java/com/cloud/vm/UserVmManager.java b/server/src/main/java/com/cloud/vm/UserVmManager.java index f0985205040..4799a717295 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManager.java +++ b/server/src/main/java/com/cloud/vm/UserVmManager.java @@ -206,6 +206,4 @@ public interface UserVmManager extends UserVmService { * @return true if the VM is part of a CKS cluster, false otherwise. */ boolean isVMPartOfAnyCKSCluster(VMInstanceVO vm); - - boolean isBlankInstance(VirtualMachineTemplate template); } diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 1b1a5310e9b..210a671507f 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -426,8 +426,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir private static final long GiB_TO_BYTES = 1024 * 1024 * 1024; - private static final String KVM_BLANK_VM_TEMPLATE_NAME = "kvm-blank-vm-template"; - @Inject private EntityManager _entityMgr; @@ -3939,7 +3937,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir _accountMgr.checkAccess(owner, _diskOfferingDao.findById(diskOfferingId), zone); // If no network is specified, find system security group enabled network - if (isBlankInstance(template)) { + if (_itMgr.isBlankInstance(template)) { logger.debug("Blank instance for {} hypervisor, skipping network allocation in an advanced security group enabled zone", hypervisor); } else if (networkIdList == null || networkIdList.isEmpty()) { Network networkWithSecurityGroup = _networkModel.getNetworkWithSGWithFreeIPs(owner, zone.getId()); @@ -4054,7 +4052,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir _accountMgr.checkAccess(owner, diskOffering, zone); List vpcSupportedHTypes = _vpcMgr.getSupportedVpcHypervisors(); - if (isBlankInstance(template)) { + if (_itMgr.isBlankInstance(template)) { logger.debug("Template is a dummy template for hypervisor {}, skipping network allocation in an advanced zone", hypervisor); } else if (networkIdList == null || networkIdList.isEmpty()) { NetworkVO defaultNetwork = getDefaultNetwork(zone, owner, false); @@ -4290,7 +4288,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (isIso) { if (diskOfferingId == null) { DiskOfferingVO diskOffering = _diskOfferingDao.findById(rootDiskOfferingId); - if (diskOffering.isComputeOnly()) { + if (diskOffering.isComputeOnly() && !_itMgr.isBlankInstance(template)) { throw new InvalidParameterValueException("Installing from ISO requires a disk offering to be specified for the root disk."); } } else { @@ -4488,7 +4486,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } if (TemplateType.SYSTEM.equals(template.getTemplateType()) && !CKS_NODE.equals(vmType) && - !SHAREDFSVM.equals(vmType) && !isBlankInstanceDefaultTemplate(template)) { + !SHAREDFSVM.equals(vmType) && !_itMgr.isBlankInstanceDefaultTemplate(template)) { throw new InvalidParameterValueException(String.format("Unable to use system template %s to deploy a user vm", template)); } @@ -4501,7 +4499,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (CollectionUtils.isEmpty(snapshotsOnZone)) { throw new InvalidParameterValueException("The snapshot does not exist on zone " + zone.getId()); } - } else if (!isBlankInstanceDefaultTemplate(template)) { + } else if (!_itMgr.isBlankInstanceDefaultTemplate(template)) { List listZoneTemplate = _templateZoneDao.listByZoneTemplate(zone.getId(), template.getId()); if (listZoneTemplate == null || listZoneTemplate.isEmpty()) { throw new InvalidParameterValueException("The template " + template.getId() + " is not available for use"); @@ -4616,7 +4614,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // by Agent Manager in order to configure default // gateway for the vm if (defaultNetworkNumber == 0) { - if (isBlankInstance(template)) { + if (_itMgr.isBlankInstance(template)) { logger.debug("Template is a dummy template for hypervisor {}, vm can be created without a default network", hypervisorType); } else { throw new InvalidParameterValueException("At least 1 default network has to be specified for the vm"); @@ -6658,7 +6656,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir applyLeaseOnCreateInstance(vm, cmd.getLeaseDuration(), cmd.getLeaseExpiryAction(), svcOffering); } - if (isBlankInstance(template) && cmd instanceof DeployVMCmd && ((DeployVMCmd) cmd).isBlankInstance()) { + if (_itMgr.isBlankInstance(template) && cmd instanceof DeployVMCmd && ((DeployVMCmd) cmd).isBlankInstance()) { logger.info("Revoking launch permission for Dummy template"); launchPermissionDao.removePermissions(template.getId(), Collections.singletonList(owner.getId())); } @@ -10104,26 +10102,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } - protected boolean isBlankInstanceDefaultTemplate(VirtualMachineTemplate template) { - return KVM_BLANK_VM_TEMPLATE_NAME.equals(template.getUniqueName()); - } - - @Override - public boolean isBlankInstance(VirtualMachineTemplate template) { - if (isBlankInstanceDefaultTemplate(template)) { - return true; - } - return Boolean.TRUE.equals( - MapUtils.getBoolean(CallContext.current().getContextParameters(), ApiConstants.BLANK_INSTANCE)); - } - - VMTemplateVO getBlankInstanceTemplate() { - VMTemplateVO template = _templateDao.findByName(KVM_BLANK_VM_TEMPLATE_NAME); + protected VMTemplateVO getBlankInstanceTemplate() { + VMTemplateVO template = _templateDao.findByName(VirtualMachineManager.KVM_BLANK_VM_TEMPLATE_NAME); if (template != null) { return template; } template = VMTemplateVO.createSystemIso(_templateDao.getNextInSequence(Long.class, "id"), - KVM_BLANK_VM_TEMPLATE_NAME, KVM_BLANK_VM_TEMPLATE_NAME, true, + VirtualMachineManager.KVM_BLANK_VM_TEMPLATE_NAME, VirtualMachineManager.KVM_BLANK_VM_TEMPLATE_NAME, true, "", true, 64, Account.ACCOUNT_ID_SYSTEM, "", "Blank Template for KVM VM", false, 1); template.setState(VirtualMachineTemplate.State.Active);