Skip to content

Commit 0bdd37e

Browse files
committed
fix size check logic and deleted template
1 parent 759579c commit 0bdd37e

File tree

5 files changed

+82
-50
lines changed

5 files changed

+82
-50
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,10 @@ public BackupResponse newBackupResponse(Backup backup, Boolean listVmDetails) {
336336
Map<String, String> details = backupDetailsDao.listDetailsKeyPairs(backup.getId(), true);
337337
details.put(ApiConstants.HYPERVISOR, vm.getHypervisorType().toString());
338338
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)));
339+
if (template != null) {
340+
details.put(ApiConstants.TEMPLATE_ID, template.getUuid());
341+
details.put(ApiConstants.IS_ISO, String.valueOf(template.getFormat().equals(Storage.ImageFormat.ISO)));
342+
}
341343
if (details != null) {
342344
response.setVmDetails(details);
343345
}

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

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6158,10 +6158,6 @@ public String finalizeUserData(String userData, Long userDataId, VirtualMachineT
61586158
}
61596159

61606160
private void verifyServiceOffering(BaseDeployVMCmd cmd, ServiceOffering serviceOffering) {
6161-
if (serviceOffering == null) {
6162-
throw new InvalidParameterValueException("Unable to find service offering: " + serviceOffering.getId());
6163-
}
6164-
61656161
if (ServiceOffering.State.Inactive.equals(serviceOffering.getState())) {
61666162
throw new InvalidParameterValueException(String.format("Service offering is inactive: [%s].", serviceOffering.getUuid()));
61676163
}
@@ -6181,10 +6177,6 @@ private void verifyServiceOffering(BaseDeployVMCmd cmd, ServiceOffering serviceO
61816177
}
61826178

61836179
private void verifyTemplate(BaseDeployVMCmd cmd, VirtualMachineTemplate template, Long serviceOfferingId) {
6184-
// Make sure a valid template ID was specified
6185-
if (template == null) {
6186-
throw new InvalidParameterValueException("Unable to use template " + template.getId());
6187-
}
61886180
if (TemplateType.VNF.equals(template.getTemplateType())) {
61896181
vnfTemplateManager.validateVnfApplianceNics(template, cmd.getNetworkIds());
61906182
} else if (cmd instanceof DeployVnfApplianceCmd) {
@@ -6231,6 +6223,9 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE
62316223
Long overrideDiskOfferingId = cmd.getOverrideDiskOfferingId();
62326224

62336225
ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
6226+
if (serviceOffering == null) {
6227+
throw new InvalidParameterValueException("Unable to find service offering: " + serviceOffering.getId());
6228+
}
62346229
verifyServiceOffering(cmd, serviceOffering);
62356230

62366231
Account caller = CallContext.current().getCallingAccount();
@@ -6269,6 +6264,10 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE
62696264
(!(HypervisorType.KVM.equals(template.getHypervisorType()) || HypervisorType.KVM.equals(cmd.getHypervisor())))) {
62706265
throw new InvalidParameterValueException("Deploying a virtual machine with existing volume/snapshot is supported only from KVM hypervisors");
62716266
}
6267+
// Make sure a valid template ID was specified
6268+
if (template == null) {
6269+
throw new InvalidParameterValueException("Unable to use template " + templateId);
6270+
}
62726271
verifyTemplate(cmd, template, serviceOfferingId);
62736272

62746273
Long diskOfferingId = cmd.getDiskOfferingId();
@@ -9401,6 +9400,15 @@ private void updateDetailsWithRootDiskAttributes(Map<String, String> details, Di
94019400
}
94029401
}
94039402

9403+
private void checkRootDiskSizeAgainstBackup(Long instanceVolumeSize,DiskOffering rootDiskOffering, Long backupVolumeSize) {
9404+
Long instanceRootDiskSize = rootDiskOffering.isCustomized() ? instanceVolumeSize : rootDiskOffering.getDiskSize() / GiB_TO_BYTES;
9405+
if (instanceRootDiskSize < backupVolumeSize) {
9406+
throw new InvalidParameterValueException(
9407+
String.format("Instance volume root disk size %d[GiB] cannot be less than the backed-up volume size %d[GiB].",
9408+
instanceVolumeSize, backupVolumeSize));
9409+
}
9410+
}
9411+
94049412
@Override
94059413
public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws InsufficientCapacityException, ResourceAllocationException, ResourceUnavailableException {
94069414
//Verify that all objects exist before passing them to the service
@@ -9430,6 +9438,9 @@ public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws Insufficien
94309438
ServiceOffering serviceOffering;
94319439
if (serviceOfferingId != null) {
94329440
serviceOffering = serviceOfferingDao.findById(serviceOfferingId);
9441+
if (serviceOffering == null) {
9442+
throw new InvalidParameterValueException("Unable to find service offering: " + serviceOffering.getId());
9443+
}
94339444
} else {
94349445
String serviceOfferingUuid = backup.getDetail(ApiConstants.SERVICE_OFFERING_ID);
94359446
if (serviceOfferingUuid == null) {
@@ -9443,12 +9454,20 @@ public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws Insufficien
94439454
verifyServiceOffering(cmd, serviceOffering);
94449455

94459456
Long templateId;
9457+
VirtualMachineTemplate template;
94469458
if (cmd.getTemplateId() != null) {
94479459
templateId = cmd.getTemplateId();
9460+
template = _templateDao.findById(templateId);
9461+
if (template == null) {
9462+
throw new InvalidParameterValueException("Unable to use template " + templateId);
9463+
}
94489464
} else {
94499465
templateId = backupVm.getTemplateId();
9466+
template = _templateDao.findById(templateId);
9467+
if (template == null) {
9468+
throw new CloudRuntimeException("Unable to find template associated with the backup. Please specify a valid template while creating instance");
9469+
}
94509470
}
9451-
VirtualMachineTemplate template = _templateDao.findById(templateId);
94529471
verifyTemplate(cmd, template, serviceOffering.getId());
94539472

94549473
Long size = cmd.getSize();
@@ -9470,38 +9489,28 @@ public UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws Insufficien
94709489

94719490
Long overrideDiskOfferingId = cmd.getOverrideDiskOfferingId();
94729491

9473-
DiskOfferingInfo rootDiskOfferingInfo = backupManager.getRootDiskOfferingInfoFromBackup(backup);
9492+
DiskOfferingInfo rootDiskOfferingInfoFromBackup = backupManager.getRootDiskOfferingInfoFromBackup(backup);
9493+
94749494
if (isIso) {
94759495
if (diskOfferingId == null) {
9476-
if (rootDiskOfferingInfo == null) {
9477-
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");
9478-
}
9479-
diskOfferingId = rootDiskOfferingInfo.getDiskOffering().getId();
9480-
updateDetailsWithRootDiskAttributes(cmd.getDetails(), rootDiskOfferingInfo);
9481-
size = rootDiskOfferingInfo.getSize();
9496+
diskOfferingId = rootDiskOfferingInfoFromBackup.getDiskOffering().getId();
9497+
updateDetailsWithRootDiskAttributes(cmd.getDetails(), rootDiskOfferingInfoFromBackup);
9498+
size = rootDiskOfferingInfoFromBackup.getSize();
94829499
} else {
94839500
DiskOffering rootDiskOffering = _diskOfferingDao.findById(diskOfferingId);
9484-
Long rootDiskSize = rootDiskOffering.isCustomized() ? size : rootDiskOffering.getDiskSize() / GiB_TO_BYTES;
9485-
if (rootDiskOfferingInfo != null && rootDiskSize < rootDiskOfferingInfo.getSize()) {
9486-
throw new InvalidParameterValueException(
9487-
String.format("Instance volume size %d[GiB] cannot be less than the backed-up volume size %d[GiB].",
9488-
rootDiskSize, rootDiskOfferingInfo.getSize()));
9489-
}
9501+
checkRootDiskSizeAgainstBackup(size, rootDiskOffering, rootDiskOfferingInfoFromBackup.getSize());
94909502
}
94919503
} else {
94929504
if (overrideDiskOfferingId == null) {
9493-
if (rootDiskOfferingInfo != null && serviceOffering.getDiskOfferingId() != rootDiskOfferingInfo.getDiskOffering().getId()) {
9494-
overrideDiskOfferingId = rootDiskOfferingInfo.getDiskOffering().getId();
9495-
updateDetailsWithRootDiskAttributes(cmd.getDetails(), rootDiskOfferingInfo);
9496-
}
9505+
overrideDiskOfferingId = serviceOffering.getDiskOfferingId();
9506+
updateDetailsWithRootDiskAttributes(cmd.getDetails(), rootDiskOfferingInfoFromBackup);
94979507
} else {
94989508
DiskOffering overrideDiskOffering = _diskOfferingDao.findById(overrideDiskOfferingId);
9499-
String diskSizeDetail = cmd.getDetails().get(VmDetailConstants.ROOT_DISK_SIZE);
9500-
Long diskSize = diskSizeDetail != null ? Long.parseLong(diskSizeDetail) : overrideDiskOffering.getDiskSize() / GiB_TO_BYTES;
9501-
if (rootDiskOfferingInfo != null && diskSize < rootDiskOfferingInfo.getSize()) {
9502-
throw new InvalidParameterValueException(
9503-
String.format("Instance volume size %d[GiB] cannot be less than the backed-up volume size %d[GiB].",
9504-
diskSize, rootDiskOfferingInfo.getSize()));
9509+
if (overrideDiskOffering.isComputeOnly()) {
9510+
updateDetailsWithRootDiskAttributes(cmd.getDetails(), rootDiskOfferingInfoFromBackup);
9511+
} else {
9512+
Long rootDiskSize = Long.parseLong(cmd.getDetails().getOrDefault(VmDetailConstants.ROOT_DISK_SIZE, null));
9513+
checkRootDiskSizeAgainstBackup(rootDiskSize, overrideDiskOffering, rootDiskOfferingInfoFromBackup.getSize());
95059514
}
95069515
}
95079516
}

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

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,10 +1017,11 @@ private Backup.VolumeInfo getVolumeInfo(List<Backup.VolumeInfo> backedUpVolumes,
10171017
@Override
10181018
public void checkDiskOfferingSizeAgainstBackup(List<DiskOfferingInfo> dataDiskOfferingsInfo, Backup backup) {
10191019
List<DiskOfferingInfo> dataDiskOfferingsInfoFromBackup = getDataDiskOfferingListFromBackup(backup);
1020-
if (dataDiskOfferingsInfoFromBackup == null) {
1021-
return;
1022-
}
10231020
int index = 0;
1021+
if (dataDiskOfferingsInfo.size() != dataDiskOfferingsInfoFromBackup.size()) {
1022+
throw new InvalidParameterValueException("Unable to restore VM with the current backup " +
1023+
"as the backup has different number of disks as the VM");
1024+
}
10241025
for (DiskOfferingInfo diskOfferingInfo : dataDiskOfferingsInfo) {
10251026
if (index < dataDiskOfferingsInfoFromBackup.size()) {
10261027
if (diskOfferingInfo.getSize() < dataDiskOfferingsInfoFromBackup.get(index).getSize()) {
@@ -1036,27 +1037,34 @@ public void checkDiskOfferingSizeAgainstBackup(List<DiskOfferingInfo> dataDiskOf
10361037
@Override
10371038
public DiskOfferingInfo getRootDiskOfferingInfoFromBackup(Backup backup) {
10381039
List<Backup.VolumeInfo> volumes = backup.getBackedUpVolumes();
1039-
if (volumes != null && !volumes.isEmpty()) {
1040-
for (Backup.VolumeInfo volume : volumes) {
1041-
if (volume.getType() == Volume.Type.ROOT) {
1042-
DiskOfferingVO diskOffering = diskOfferingDao.findByUuid(volume.getDiskOfferingId());
1043-
if (diskOffering == null) {
1044-
throw new CloudRuntimeException("Unable to find the root disk offering with uuid (" + volume.getDiskOfferingId() + ") stored in backup. Please specify a valid root disk offering id while creating the instance");
1045-
}
1046-
Long size = volume.getSize() / (1024 * 1024 * 1024);
1047-
return new DiskOfferingInfo(diskOffering, size, volume.getMinIops(), volume.getMaxIops());
1040+
DiskOfferingInfo rootDiskOffering = null;
1041+
if (volumes == null || volumes.isEmpty()) {
1042+
throw new CloudRuntimeException("Failed to get backed-up volumes info from backup");
1043+
}
1044+
for (Backup.VolumeInfo volume : volumes) {
1045+
if (volume.getType() == Volume.Type.ROOT) {
1046+
DiskOfferingVO diskOffering = diskOfferingDao.findByUuid(volume.getDiskOfferingId());
1047+
if (diskOffering == null) {
1048+
throw new CloudRuntimeException(String.format("Unable to find the root disk offering with uuid (%s) " +
1049+
"stored in backup. Please specify a valid root disk offering id while creating the instance",
1050+
volume.getDiskOfferingId()));
10481051
}
1052+
Long size = volume.getSize() / (1024 * 1024 * 1024);
1053+
rootDiskOffering = new DiskOfferingInfo(diskOffering, size, volume.getMinIops(), volume.getMaxIops());
10491054
}
10501055
}
1051-
return null;
1056+
if (rootDiskOffering == null) {
1057+
throw new CloudRuntimeException("Failed to get the root disk in backed-up volumes info from backup");
1058+
}
1059+
return rootDiskOffering;
10521060
}
10531061

10541062
@Override
10551063
public List<DiskOfferingInfo> getDataDiskOfferingListFromBackup(Backup backup) {
10561064
List<DiskOfferingInfo> diskOfferingInfoList = new ArrayList<>();
10571065
List<Backup.VolumeInfo> volumes = backup.getBackedUpVolumes();
1058-
if (volumes == null) {
1059-
return diskOfferingInfoList;
1066+
if (volumes == null || volumes.isEmpty()) {
1067+
throw new CloudRuntimeException("Failed to get backed-up Volumes info from backup");
10601068
}
10611069
for (Backup.VolumeInfo volume : volumes) {
10621070
if (volume.getType() == Volume.Type.DATADISK) {
@@ -1160,6 +1168,17 @@ public boolean restoreBackupToVM(final Long backupId, final Long vmId) throws Re
11601168
throw new CloudRuntimeException("Unable to restore VM with the current backup as the backup has different number of disks as the VM");
11611169
}
11621170

1171+
int index = 0;
1172+
for (VolumeVO vmVolume: vmVolumes) {
1173+
Backup.VolumeInfo backupVolume = backupVolumes.get(index);
1174+
if (vmVolume.getSize() < backupVolume.getSize()) {
1175+
throw new CloudRuntimeException(String.format(
1176+
"Instance volume size %d[GiB] for volume (%s) is less than the backed-up volume size %d[GiB] for backed-up volume (%s).",
1177+
vmVolume.getSize(), vmVolume.getUuid(), backupVolume.getSize(), backupVolume.getUuid()));
1178+
}
1179+
index++;
1180+
}
1181+
11631182
BackupOffering offering = backupOfferingDao.findByIdIncludingRemoved(backup.getBackupOfferingId());
11641183
if (offering == null) {
11651184
throw new CloudRuntimeException("Failed to find backup offering of the VM backup.");

server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3374,6 +3374,8 @@ public void testAllocateVMFromBackupUsingBackupValues() throws InsufficientCapac
33743374
DiskOfferingVO diskOffering = mock(DiskOfferingVO.class);
33753375
when(backup.getDetail(ApiConstants.SERVICE_OFFERING_ID)).thenReturn("service-offering-uuid");
33763376
when(_serviceOfferingDao.findByUuid("service-offering-uuid")).thenReturn(serviceOffering);
3377+
DiskOfferingInfo rootDiskOfferingInfo = new DiskOfferingInfo(diskOffering, 10L, 1000L, 2000L);
3378+
when(backupManager.getRootDiskOfferingInfoFromBackup(backup)).thenReturn(rootDiskOfferingInfo);
33773379

33783380
NetworkVO network1 = mock(NetworkVO.class);
33793381
NetworkVO network2 = mock(NetworkVO.class);

ui/src/components/view/DeployVMFromBackup.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@
370370
</a-step>
371371
<a-step
372372
:title="$t('label.data.disk')"
373-
v-if="!(!template.deployasis && template.childtemplates && template.childtemplates.length > 0)"
373+
v-if="!(!template.deployasis && template.childtemplates && template.childtemplates.length > 0) && dataPreFill.datadisksdetails && dataPreFill.datadisksdetails.length > 0"
374374
:status="zoneSelected ? 'process' : 'wait'">
375375
<template #description>
376376
<div v-if="zoneSelected">

0 commit comments

Comments
 (0)