Skip to content

Commit 8171d19

Browse files
committed
improve check for already registered template
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 4bd5458 commit 8171d19

6 files changed

Lines changed: 253 additions & 46 deletions

File tree

engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDao.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<
9494

9595
List<VMTemplateVO> listByParentTemplatetId(long parentTemplatetId);
9696

97-
VMTemplateVO findLatestTemplateByName(String name, CPU.CPUArch arch);
97+
VMTemplateVO findLatestTemplateByName(String name, HypervisorType hypervisorType, CPU.CPUArch arch);
9898

9999
List<VMTemplateVO> findTemplatesLinkedToUserdata(long userdataId);
100100

@@ -103,4 +103,7 @@ public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<
103103
List<Long> listIdsByTemplateTag(String tag);
104104

105105
List<Long> listIdsByExtensionId(long extensionId);
106+
107+
VMTemplateVO findActiveSystemTemplateByHypervisorArchAndUrlPath(HypervisorType hypervisorType,
108+
CPU.CPUArch arch, String urlPathSuffix);
106109
}

engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDaoImpl.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,17 @@ public List<VMTemplateVO> listReadyTemplates() {
246246

247247

248248
@Override
249-
public VMTemplateVO findLatestTemplateByName(String name, CPU.CPUArch arch) {
249+
public VMTemplateVO findLatestTemplateByName(String name, HypervisorType hypervisorType, CPU.CPUArch arch) {
250250
SearchBuilder<VMTemplateVO> sb = createSearchBuilder();
251251
sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
252+
sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
252253
sb.and("arch", sb.entity().getArch(), SearchCriteria.Op.EQ);
253254
sb.done();
254255
SearchCriteria<VMTemplateVO> sc = sb.create();
255256
sc.setParameters("name", name);
257+
if (hypervisorType != null) {
258+
sc.setParameters("hypervisorType", hypervisorType);
259+
}
256260
if (arch != null) {
257261
sc.setParameters("arch", arch);
258262
}
@@ -857,6 +861,37 @@ public List<Long> listIdsByExtensionId(long extensionId) {
857861
return customSearch(sc, null);
858862
}
859863

864+
@Override
865+
public VMTemplateVO findActiveSystemTemplateByHypervisorArchAndUrlPath(HypervisorType hypervisorType,
866+
CPU.CPUArch arch, String urlPathSuffix) {
867+
if (StringUtils.isBlank(urlPathSuffix)) {
868+
return null;
869+
}
870+
SearchBuilder<VMTemplateVO> sb = createSearchBuilder();
871+
sb.and("templateType", sb.entity().getTemplateType(), SearchCriteria.Op.EQ);
872+
sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
873+
sb.and("arch", sb.entity().getArch(), SearchCriteria.Op.EQ);
874+
sb.and("urlPathSuffix", sb.entity().getUrl(), SearchCriteria.Op.LIKE);
875+
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
876+
sb.done();
877+
SearchCriteria<VMTemplateVO> sc = sb.create();
878+
sc.setParameters("templateType", TemplateType.SYSTEM);
879+
if (hypervisorType != null) {
880+
sc.setParameters("hypervisorType", hypervisorType);
881+
}
882+
if (arch != null) {
883+
sc.setParameters("arch", arch);
884+
}
885+
sc.setParameters("urlPathSuffix", "%" + urlPathSuffix);
886+
sc.setParameters("state", VirtualMachineTemplate.State.Active);
887+
Filter filter = new Filter(VMTemplateVO.class, "id", false, null, 1L);
888+
List<VMTemplateVO> templates = listBy(sc, filter);
889+
if (CollectionUtils.isNotEmpty(templates)) {
890+
return templates.get(0);
891+
}
892+
return null;
893+
}
894+
860895
@Override
861896
public boolean updateState(
862897
com.cloud.template.VirtualMachineTemplate.State currentState,

engine/schema/src/main/java/com/cloud/upgrade/SystemVmTemplateRegistration.java

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,15 @@ protected static MetadataTemplateDetails getMetadataTemplateDetails(Hypervisor.H
417417
return NewTemplateMap.get(getHypervisorArchKey(hypervisorType, arch));
418418
}
419419

420-
public VMTemplateVO getRegisteredTemplate(String templateName, CPU.CPUArch arch) {
421-
return vmTemplateDao.findLatestTemplateByName(templateName, arch);
420+
public VMTemplateVO getRegisteredTemplate(String templateName, Hypervisor.HypervisorType hypervisorType,
421+
CPU.CPUArch arch, String url) {
422+
VMTemplateVO registeredTemplate = vmTemplateDao.findLatestTemplateByName(templateName, hypervisorType, arch);
423+
if (registeredTemplate == null && StringUtils.isNotBlank(url)) {
424+
String urlPath = url.substring(url.lastIndexOf("/") + 1);
425+
registeredTemplate = vmTemplateDao.findActiveSystemTemplateByHypervisorArchAndUrlPath(hypervisorType, arch,
426+
urlPath);
427+
}
428+
return registeredTemplate;
422429
}
423430

424431
private static boolean isRunningInTest() {
@@ -940,7 +947,8 @@ protected void registerTemplatesForZone(long zoneId, String filePath) {
940947
if (templateDetails == null) {
941948
continue;
942949
}
943-
VMTemplateVO templateVO = getRegisteredTemplate(templateDetails.getName(), templateDetails.getArch());
950+
VMTemplateVO templateVO = getRegisteredTemplate(templateDetails.getName(),
951+
templateDetails.getHypervisorType(), templateDetails.getArch(), templateDetails.getUrl());
944952
if (templateVO != null) {
945953
TemplateDataStoreVO templateDataStoreVO =
946954
templateDataStoreDao.findByStoreTemplate(storeUrlAndId.second(), templateVO.getId());
@@ -999,7 +1007,7 @@ public void doInTransactionWithoutResult(final TransactionStatus status) {
9991007
}
10001008
}
10011009

1002-
private void updateRegisteredTemplateDetails(Long templateId, MetadataTemplateDetails templateDetails) {
1010+
protected void updateRegisteredTemplateDetails(Long templateId, MetadataTemplateDetails templateDetails) {
10031011
VMTemplateVO templateVO = vmTemplateDao.findById(templateId);
10041012
templateVO.setTemplateType(Storage.TemplateType.SYSTEM);
10051013
GuestOSVO guestOS = guestOSDao.findOneByDisplayName(templateDetails.getGuestOs());
@@ -1039,37 +1047,36 @@ private void updateTemplateUrlChecksumAndGuestOsId(VMTemplateVO templateVO, Meta
10391047
protected boolean registerOrUpdateSystemVmTemplate(MetadataTemplateDetails templateDetails,
10401048
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorsInUse) {
10411049
LOGGER.debug("Updating System VM template for {}", templateDetails.getHypervisorArchLog());
1042-
VMTemplateVO registeredTemplate = getRegisteredTemplate(templateDetails.getName(), templateDetails.getArch());
1043-
// change template type to SYSTEM
1050+
VMTemplateVO registeredTemplate = getRegisteredTemplate(templateDetails.getName(),
1051+
templateDetails.getHypervisorType(), templateDetails.getArch(), templateDetails.getUrl());
10441052
if (registeredTemplate != null) {
10451053
updateRegisteredTemplateDetails(registeredTemplate.getId(), templateDetails);
1046-
} else {
1047-
boolean isHypervisorArchMatchMetadata = hypervisorsInUse.stream()
1048-
.anyMatch(p -> p.first().equals(templateDetails.getHypervisorType())
1049-
&& Objects.equals(p.second(), templateDetails.getArch()));
1050-
if (isHypervisorArchMatchMetadata) {
1051-
try {
1052-
registerTemplates(hypervisorsInUse);
1053-
return true;
1054-
} catch (final Exception e) {
1055-
throw new CloudRuntimeException(String.format("Failed to register %s templates for hypervisors: [%s]. " +
1056-
"Cannot upgrade system VMs",
1057-
getSystemVmTemplateVersion(),
1058-
StringUtils.join(hypervisorsInUse.stream()
1059-
.map(x -> getHypervisorArchKey(x.first(), x.second()))
1060-
.collect(Collectors.toList()), ",")), e);
1061-
}
1062-
} else {
1063-
LOGGER.warn("Cannot upgrade {} system VM template for {} as it is not used, not failing upgrade",
1064-
getSystemVmTemplateVersion(), templateDetails.getHypervisorArchLog());
1065-
VMTemplateVO templateVO = vmTemplateDao.findLatestTemplateByTypeAndHypervisorAndArch(
1066-
templateDetails.getHypervisorType(), templateDetails.getArch(), Storage.TemplateType.SYSTEM);
1067-
if (templateVO != null) {
1068-
updateTemplateUrlChecksumAndGuestOsId(templateVO, templateDetails);
1069-
}
1054+
return false;
1055+
}
1056+
boolean isHypervisorArchMatchMetadata = hypervisorsInUse.stream()
1057+
.anyMatch(p -> p.first().equals(templateDetails.getHypervisorType())
1058+
&& Objects.equals(p.second(), templateDetails.getArch()));
1059+
if (!isHypervisorArchMatchMetadata) {
1060+
LOGGER.warn("Skipping upgrading {} system VM template for {} as it is not used, not failing upgrade",
1061+
getSystemVmTemplateVersion(), templateDetails.getHypervisorArchLog());
1062+
VMTemplateVO templateVO = vmTemplateDao.findLatestTemplateByTypeAndHypervisorAndArch(
1063+
templateDetails.getHypervisorType(), templateDetails.getArch(), Storage.TemplateType.SYSTEM);
1064+
if (templateVO != null) {
1065+
updateTemplateUrlChecksumAndGuestOsId(templateVO, templateDetails);
10701066
}
1067+
return false;
1068+
}
1069+
try {
1070+
registerTemplates(hypervisorsInUse);
1071+
return true;
1072+
} catch (final Exception e) {
1073+
throw new CloudRuntimeException(String.format("Failed to register %s templates for hypervisors: [%s]. " +
1074+
"Cannot upgrade system VMs",
1075+
getSystemVmTemplateVersion(),
1076+
StringUtils.join(hypervisorsInUse.stream()
1077+
.map(x -> getHypervisorArchKey(x.first(), x.second()))
1078+
.collect(Collectors.toList()), ",")), e);
10711079
}
1072-
return false;
10731080
}
10741081

10751082
public void updateSystemVmTemplates(final Connection conn) {

engine/schema/src/test/java/com/cloud/storage/dao/VMTemplateDaoImplTest.java

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ public void testFindLatestTemplateByName_ReturnsTemplate() {
7676
VMTemplateVO expectedTemplate = new VMTemplateVO();
7777
List<VMTemplateVO> returnedList = Collections.singletonList(expectedTemplate);
7878
doReturn(returnedList).when(templateDao).listBy(any(SearchCriteria.class), any(Filter.class));
79-
VMTemplateVO result = templateDao.findLatestTemplateByName("test", CPU.CPUArch.getDefault());
79+
VMTemplateVO result = templateDao.findLatestTemplateByName("test", Hypervisor.HypervisorType.KVM,
80+
CPU.CPUArch.getDefault());
8081
assertNotNull("Expected a non-null template", result);
8182
assertEquals("Expected the returned template to be the first element", expectedTemplate, result);
8283
}
@@ -85,7 +86,8 @@ public void testFindLatestTemplateByName_ReturnsTemplate() {
8586
public void testFindLatestTemplateByName_ReturnsNullWhenNoTemplateFound() {
8687
List<VMTemplateVO> emptyList = Collections.emptyList();
8788
doReturn(emptyList).when(templateDao).listBy(any(SearchCriteria.class), any(Filter.class));
88-
VMTemplateVO result = templateDao.findLatestTemplateByName("test", CPU.CPUArch.getDefault());
89+
VMTemplateVO result = templateDao.findLatestTemplateByName("test", Hypervisor.HypervisorType.VMware,
90+
CPU.CPUArch.getDefault());
8991
assertNull("Expected null when no templates are found", result);
9092
}
9193

@@ -94,7 +96,8 @@ public void testFindLatestTemplateByName_NullArch() {
9496
VMTemplateVO expectedTemplate = new VMTemplateVO();
9597
List<VMTemplateVO> returnedList = Collections.singletonList(expectedTemplate);
9698
doReturn(returnedList).when(templateDao).listBy(any(SearchCriteria.class), any(Filter.class));
97-
VMTemplateVO result = templateDao.findLatestTemplateByName("test", null);
99+
VMTemplateVO result = templateDao.findLatestTemplateByName("test", Hypervisor.HypervisorType.XenServer,
100+
null);
98101
assertNotNull("Expected a non-null template even if arch is null", result);
99102
assertEquals("Expected the returned template to be the first element", expectedTemplate, result);
100103
}
@@ -337,4 +340,82 @@ public void testFindSystemVMReadyTemplate() {
337340
VMTemplateVO readyTemplate = templateDao.findSystemVMReadyTemplate(zoneId, Hypervisor.HypervisorType.KVM, CPU.CPUArch.arm64.getType());
338341
Assert.assertEquals(CPU.CPUArch.arm64, readyTemplate.getArch());
339342
}
343+
344+
@Test
345+
public void findActiveSystemTemplateByHypervisorArchAndUrlPath_ReturnsTemplate() {
346+
VMTemplateVO expectedTemplate = mock(VMTemplateVO.class);
347+
SearchBuilder<VMTemplateVO> sb = mock(SearchBuilder.class);
348+
when(sb.entity()).thenReturn(expectedTemplate);
349+
SearchCriteria<VMTemplateVO>sc = mock(SearchCriteria.class);
350+
when(sb.create()).thenReturn(sc);
351+
when(templateDao.createSearchBuilder()).thenReturn(sb);
352+
List<VMTemplateVO> templates = Collections.singletonList(expectedTemplate);
353+
doReturn(templates).when(templateDao).listBy(any(SearchCriteria.class), any(Filter.class));
354+
355+
VMTemplateVO result = templateDao.findActiveSystemTemplateByHypervisorArchAndUrlPath(
356+
Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64, "testPath");
357+
358+
assertNotNull(result);
359+
assertEquals(expectedTemplate, result);
360+
}
361+
362+
@Test
363+
public void findActiveSystemTemplateByHypervisorArchAndUrlPath_ReturnsNullWhenNoTemplatesFound() {
364+
VMTemplateVO template = mock(VMTemplateVO.class);
365+
SearchBuilder<VMTemplateVO> sb = mock(SearchBuilder.class);
366+
when(sb.entity()).thenReturn(template);
367+
SearchCriteria<VMTemplateVO>sc = mock(SearchCriteria.class);
368+
when(sb.create()).thenReturn(sc);
369+
when(templateDao.createSearchBuilder()).thenReturn(sb);
370+
doReturn(Collections.emptyList()).when(templateDao).listBy(any(SearchCriteria.class), any(Filter.class));
371+
372+
VMTemplateVO result = templateDao.findActiveSystemTemplateByHypervisorArchAndUrlPath(
373+
Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64, "testPath");
374+
375+
assertNull(result);
376+
}
377+
378+
@Test
379+
public void findActiveSystemTemplateByHypervisorArchAndUrlPath_NullHypervisor() {
380+
VMTemplateVO expectedTemplate = mock(VMTemplateVO.class);
381+
SearchBuilder<VMTemplateVO> sb = mock(SearchBuilder.class);
382+
when(sb.entity()).thenReturn(expectedTemplate);
383+
SearchCriteria<VMTemplateVO>sc = mock(SearchCriteria.class);
384+
when(sb.create()).thenReturn(sc);
385+
when(templateDao.createSearchBuilder()).thenReturn(sb);
386+
List<VMTemplateVO> templates = Collections.singletonList(expectedTemplate);
387+
doReturn(templates).when(templateDao).listBy(any(SearchCriteria.class), any(Filter.class));
388+
389+
VMTemplateVO result = templateDao.findActiveSystemTemplateByHypervisorArchAndUrlPath(
390+
null, CPU.CPUArch.amd64, "testPath");
391+
392+
assertNotNull(result);
393+
assertEquals(expectedTemplate, result);
394+
}
395+
396+
@Test
397+
public void findActiveSystemTemplateByHypervisorArchAndUrlPath_NullArch() {
398+
VMTemplateVO expectedTemplate = mock(VMTemplateVO.class);
399+
SearchBuilder<VMTemplateVO> sb = mock(SearchBuilder.class);
400+
when(sb.entity()).thenReturn(expectedTemplate);
401+
SearchCriteria<VMTemplateVO>sc = mock(SearchCriteria.class);
402+
when(sb.create()).thenReturn(sc);
403+
when(templateDao.createSearchBuilder()).thenReturn(sb);
404+
List<VMTemplateVO> templates = Collections.singletonList(expectedTemplate);
405+
doReturn(templates).when(templateDao).listBy(any(SearchCriteria.class), any(Filter.class));
406+
407+
VMTemplateVO result = templateDao.findActiveSystemTemplateByHypervisorArchAndUrlPath(
408+
Hypervisor.HypervisorType.KVM, null, "testPath");
409+
410+
assertNotNull(result);
411+
assertEquals(expectedTemplate, result);
412+
}
413+
414+
@Test
415+
public void findActiveSystemTemplateByHypervisorArchAndUrlPath_EmptyUrlPathSuffix() {
416+
VMTemplateVO result = templateDao.findActiveSystemTemplateByHypervisorArchAndUrlPath(
417+
Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64, "");
418+
419+
assertNull(result);
420+
}
340421
}

0 commit comments

Comments
 (0)