Skip to content

Commit 17ecc5a

Browse files
committed
Handle create VM from backup for VMs created using ISO.
1 parent f8a20a4 commit 17ecc5a

File tree

6 files changed

+460
-112
lines changed

6 files changed

+460
-112
lines changed

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,7 @@ public class ApiConstants {
566566
public static final String ISOLATION_URI = "isolationuri";
567567
public static final String IS_ALLOCATED = "isallocated";
568568
public static final String IS_DEDICATED = "isdedicated";
569+
public static final String IS_ISO = "isiso";
569570
public static final String TAKEN = "taken";
570571
public static final String VM_AVAILABLE = "vmavailable";
571572
public static final String VM_DETAILS = "vmdetails";

engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupDaoImpl.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@
2525
import javax.annotation.PostConstruct;
2626
import javax.inject.Inject;
2727

28+
import com.cloud.storage.Storage;
29+
import com.cloud.storage.dao.VMTemplateDao;
30+
import com.cloud.template.VirtualMachineTemplate;
2831
import com.cloud.utils.db.GenericSearchBuilder;
32+
33+
import org.apache.cloudstack.api.ApiConstants;
2934
import org.apache.cloudstack.api.response.BackupResponse;
3035
import org.apache.cloudstack.backup.Backup;
3136
import org.apache.cloudstack.backup.BackupDetailVO;
@@ -63,6 +68,9 @@ public class BackupDaoImpl extends GenericDaoBase<BackupVO, Long> implements Bac
6368
@Inject
6469
VMInstanceDao vmInstanceDao;
6570

71+
@Inject
72+
private VMTemplateDao templateDao;
73+
6674
@Inject
6775
BackupOfferingDao backupOfferingDao;
6876

@@ -326,6 +334,10 @@ public BackupResponse newBackupResponse(Backup backup, Boolean listVmDetails) {
326334

327335
if (Boolean.TRUE.equals(listVmDetails)) {
328336
Map<String, String> details = backupDetailsDao.listDetailsKeyPairs(backup.getId(), true);
337+
details.put(ApiConstants.HYPERVISOR, vm.getHypervisorType().toString());
338+
VirtualMachineTemplate template = templateDao.findById(vm.getTemplateId());
339+
details.put(ApiConstants.TEMPLATE_ID, template.getUuid());
340+
details.put(ApiConstants.IS_ISO, String.valueOf(template.getFormat().equals(Storage.ImageFormat.ISO)));
329341
if (details != null) {
330342
response.setVmDetails(details);
331343
}

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 64 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4171,7 +4171,9 @@ private List<CheckedReservation> reserveStorageResourcesForVm(Account owner, Lon
41714171
CheckedReservation additionalPrimaryStorageReservation = diskOfferingId != null ? new CheckedReservation(owner, ResourceType.primary_storage, additionalResourceLimitStorageTags, size, reservationDao, resourceLimitService) : null;
41724172
checkedReservations.add(additionalPrimaryStorageReservation);
41734173

4174-
} else if (dataDiskOfferingsInfo != null) {
4174+
}
4175+
4176+
if (dataDiskOfferingsInfo != null) {
41754177
for (DiskOfferingInfo diskOfferingInfo : dataDiskOfferingsInfo) {
41764178
DiskOffering diskOffering = diskOfferingInfo.getDiskOffering();
41774179
List<String> additionalResourceLimitStorageTagsForDataDisk = getResourceLimitStorageTags(diskOfferingInfo.getDiskOffering().getId());
@@ -9024,6 +9026,16 @@ public boolean unmanageUserVM(Long vmId) {
90249026
return true;
90259027
}
90269028

9029+
private void updateDetailsWithRootDiskAttributes(Map<String, String> details, DiskOfferingInfo rootDiskOfferingInfo) {
9030+
details.put(VmDetailConstants.ROOT_DISK_SIZE, rootDiskOfferingInfo.getSize().toString());
9031+
if (rootDiskOfferingInfo.getMinIops() != null) {
9032+
details.put(MIN_IOPS, rootDiskOfferingInfo.getMinIops().toString());
9033+
}
9034+
if (rootDiskOfferingInfo.getMaxIops() != null) {
9035+
details.put(MAX_IOPS, rootDiskOfferingInfo.getMaxIops().toString());
9036+
}
9037+
}
9038+
90279039
@Override
90289040
public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws InsufficientCapacityException, ResourceAllocationException, ResourceUnavailableException {
90299041
//Verify that all objects exist before passing them to the service
@@ -9046,6 +9058,26 @@ public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws Insufficien
90469058

90479059
verifyDetails(cmd.getDetails());
90489060

9061+
VMInstanceVO backupVm = _vmInstanceDao.findByIdIncludingRemoved(backup.getVmId());
9062+
HypervisorType hypervisorType = backupVm.getHypervisorType();
9063+
9064+
Long templateId;
9065+
if (cmd.getTemplateId() != null) {
9066+
templateId = cmd.getTemplateId();
9067+
} else {
9068+
templateId = backupVm.getTemplateId();
9069+
}
9070+
9071+
VirtualMachineTemplate template = _templateDao.findById(templateId);
9072+
if (template == null) {
9073+
throw new InvalidParameterValueException("Unable to use template " + templateId);
9074+
}
9075+
Boolean isIso = template.getFormat().equals(ImageFormat.ISO);
9076+
9077+
if (template.isDeployAsIs()) {
9078+
throw new InvalidParameterValueException("Deploy as is template not supported");
9079+
}
9080+
90499081
Long serviceOfferingId = cmd.getServiceOfferingId();
90509082
ServiceOffering serviceOffering;
90519083
if (serviceOfferingId != null) {
@@ -9064,16 +9096,37 @@ public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws Insufficien
90649096
}
90659097
}
90669098

9099+
Long diskOfferingId = cmd.getDiskOfferingId();
9100+
if (diskOfferingId != null) {
9101+
if (!isIso) {
9102+
throw new InvalidParameterValueException(ApiConstants.DISK_OFFERING_ID + " parameter is supported for creating instance from backup only for ISO. For creating VMs with templates, please use the parameter " + ApiConstants.DATADISKS_DETAILS);
9103+
}
9104+
DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, diskOfferingId);
9105+
if (diskOffering == null) {
9106+
throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingId);
9107+
}
9108+
if (diskOffering.isComputeOnly()) {
9109+
throw new InvalidParameterValueException(String.format("The disk offering %s provided is directly mapped to a service offering, please provide an individual disk offering", diskOffering));
9110+
}
9111+
}
9112+
90679113
Long overrideDiskOfferingId = cmd.getOverrideDiskOfferingId();
9068-
if (overrideDiskOfferingId == null) {
9114+
9115+
if (isIso && diskOfferingId == null) {
9116+
DiskOfferingInfo rootDiskOfferingInfo = backupManager.getRootDiskOfferingInfoFromBackup(backup);
9117+
if (rootDiskOfferingInfo == null) {
9118+
throw new CloudRuntimeException("Unable to find root disk offering with the uuid stored in backup. Please specify a valid root disk offering id while creating instance");
9119+
}
9120+
diskOfferingId = rootDiskOfferingInfo.getDiskOffering().getId();
9121+
updateDetailsWithRootDiskAttributes(cmd.getDetails(), rootDiskOfferingInfo);
9122+
}
9123+
9124+
if (!isIso && overrideDiskOfferingId == null) {
90699125
DiskOfferingInfo rootDiskOfferingInfo = backupManager.getRootDiskOfferingInfoFromBackup(backup);
90709126
if (rootDiskOfferingInfo != null &&
90719127
serviceOffering.getDiskOfferingId() != rootDiskOfferingInfo.getDiskOffering().getId()) {
90729128
overrideDiskOfferingId = rootDiskOfferingInfo.getDiskOffering().getId();
9073-
Map<String, String> details = cmd.getDetails();
9074-
details.put(VmDetailConstants.ROOT_DISK_SIZE, rootDiskOfferingInfo.getSize().toString());
9075-
details.put(MIN_IOPS, rootDiskOfferingInfo.getSize().toString());
9076-
details.put(MAX_IOPS, rootDiskOfferingInfo.getSize().toString());
9129+
updateDetailsWithRootDiskAttributes(cmd.getDetails(), rootDiskOfferingInfo);
90779130
}
90789131
}
90799132

@@ -9093,32 +9146,6 @@ public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws Insufficien
90939146
}
90949147
}
90959148

9096-
Long templateId = cmd.getTemplateId();
9097-
VirtualMachineTemplate template;
9098-
if (templateId != null) {
9099-
template = _templateDao.findById(templateId);
9100-
if (template == null) {
9101-
throw new InvalidParameterValueException("Unable to use template " + templateId);
9102-
}
9103-
} else {
9104-
String templateUuid = backup.getDetail(ApiConstants.TEMPLATE_ID);
9105-
if (templateUuid == null) {
9106-
throw new CloudRuntimeException("Backup doesn't contain template uuid. Please specify a valid template id while creating instance");
9107-
}
9108-
template = _templateDao.findByUuid(templateUuid);
9109-
if (template == null) {
9110-
throw new CloudRuntimeException("Unable to find template with the uuid stored in backup. Please specify a valid template id while creating the instance");
9111-
}
9112-
}
9113-
9114-
if (template.isDeployAsIs()) {
9115-
throw new InvalidParameterValueException("Deploy as is template not supported");
9116-
}
9117-
9118-
if (cmd.getDiskOfferingId() != null) {
9119-
throw new InvalidParameterValueException(ApiConstants.DISK_OFFERING_ID + " parameter is not supported for creating instance from backup. Please use the parameter " + ApiConstants.DATADISKS_DETAILS);
9120-
}
9121-
91229149
List<DiskOfferingInfo> dataDiskOfferingsInfo = cmd.getDataDiskOfferingsInfo();
91239150
if (dataDiskOfferingsInfo != null) {
91249151
backupManager.updateDiskOfferingSizeFromBackup(dataDiskOfferingsInfo, backup);
@@ -9177,25 +9204,25 @@ public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws Insufficien
91779204
if (networkIds != null) {
91789205
throw new InvalidParameterValueException("Can't specify network Ids in Basic zone");
91799206
} else {
9180-
vm = createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(cmd, zone, template, owner), owner, name, displayName, null,
9181-
size , dataDiskOfferingsInfo, null , cmd.getHypervisor(), cmd.getHttpMethod(), null, null, null, sshKeyPairs, ipToNetworkMap, addrs, null , null , cmd.getAffinityGroupIdList(),
9207+
vm = createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(cmd, zone, template, owner), owner, name, displayName, diskOfferingId,
9208+
size , dataDiskOfferingsInfo, null , hypervisorType, cmd.getHttpMethod(), null, null, null, sshKeyPairs, ipToNetworkMap, addrs, null , null , cmd.getAffinityGroupIdList(),
91829209
cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(),
91839210
dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, false, overrideDiskOfferingId);
91849211
}
91859212
} else {
91869213
if (_networkModel.checkSecurityGroupSupportForNetwork(owner, zone, networkIds,
91879214
cmd.getSecurityGroupIdList())) {
91889215
vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, getSecurityGroupIdList(cmd, zone, template, owner), owner, name,
9189-
displayName, null, size, dataDiskOfferingsInfo, null, cmd.getHypervisor(), cmd.getHttpMethod(), null, null, null, sshKeyPairs, ipToNetworkMap, addrs, null, null,
9216+
displayName, diskOfferingId, size, dataDiskOfferingsInfo, null, hypervisorType, cmd.getHttpMethod(), null, null, null, sshKeyPairs, ipToNetworkMap, addrs, null, null,
91909217
cmd.getAffinityGroupIdList(), cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(),
91919218
dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, false, overrideDiskOfferingId, null);
91929219

91939220
} else {
91949221
if (cmd.getSecurityGroupIdList() != null && !cmd.getSecurityGroupIdList().isEmpty()) {
91959222
throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone");
91969223
}
9197-
vm = createAdvancedVirtualMachine(zone, serviceOffering, template, networkIds, owner, name, displayName, null, size, dataDiskOfferingsInfo, null,
9198-
cmd.getHypervisor(), cmd.getHttpMethod(), null, null, null, sshKeyPairs, ipToNetworkMap, addrs, null, null, cmd.getAffinityGroupIdList(), cmd.getDetails(),
9224+
vm = createAdvancedVirtualMachine(zone, serviceOffering, template, networkIds, owner, name, displayName, diskOfferingId, size, dataDiskOfferingsInfo, null,
9225+
hypervisorType, cmd.getHttpMethod(), null, null, null, sshKeyPairs, ipToNetworkMap, addrs, null, null, cmd.getAffinityGroupIdList(), cmd.getDetails(),
91999226
cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, false, null, overrideDiskOfferingId);
92009227
}
92019228
}

server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
import com.cloud.storage.DiskOfferingVO;
5050
import com.cloud.storage.VolumeApiService;
5151
import com.cloud.storage.dao.VMTemplateDao;
52-
import com.cloud.template.VirtualMachineTemplate;
5352
import com.cloud.user.DomainManager;
5453
import com.cloud.user.ResourceLimitService;
5554
import com.cloud.utils.fsm.NoTransitionException;
@@ -314,11 +313,8 @@ public boolean deleteBackupOffering(final Long offeringId) {
314313
@Override
315314
public Map<String, String> getVmDetailsForBackup(VirtualMachine vm) {
316315
HashMap<String, String> details = new HashMap<>();
317-
details.put(ApiConstants.HYPERVISOR, vm.getHypervisorType().toString());
318316
ServiceOffering serviceOffering = serviceOfferingDao.findById(vm.getServiceOfferingId());
319317
details.put(ApiConstants.SERVICE_OFFERING_ID, serviceOffering.getUuid());
320-
VirtualMachineTemplate template = vmTemplateDao.findById(vm.getTemplateId());
321-
details.put(ApiConstants.TEMPLATE_ID, template.getUuid());
322318
List<UserVmJoinVO> userVmJoinVOs = userVmJoinDao.searchByIds(vm.getId());
323319
if (userVmJoinVOs != null && !userVmJoinVOs.isEmpty()) {
324320
Set<String> networkIds = new HashSet<>();

0 commit comments

Comments
 (0)