diff --git a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index d32a5240e20..141b094f512 100644 --- a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -665,6 +665,11 @@ public class TemplateServiceImpl implements TemplateService { continue; } + Map templates = listTemplate(store); + if (templates == null || !templates.containsKey(tmplt.getUniqueName())) { + continue; + } + if (tmpl.getInstallPath() == null) { logger.debug("Template [{}] found in image store [{}] but install path is null. Skipping.", tmplt.getUniqueName(), store.getName()); @@ -678,24 +683,14 @@ public class TemplateServiceImpl implements TemplateService { private boolean searchAndCopyWithinZone(VMTemplateVO tmplt, DataStore destStore) { Long destZoneId = destStore.getScope().getScopeId(); List storesInSameZone = _storeMgr.getImageStoresByZoneIds(destZoneId); - for (DataStore sourceStore : storesInSameZone) { - Map existingTemplatesInSourceStore = listTemplate(sourceStore); - if (existingTemplatesInSourceStore == null || - !existingTemplatesInSourceStore.containsKey(tmplt.getUniqueName())) { - logger.debug("Template [{}] does not exist on image store [{}]; searching another.", tmplt.getUniqueName(), sourceStore.getName()); - continue; - } - TemplateObject sourceTmpl = (TemplateObject) _templateFactory.getTemplate(tmplt.getId(), sourceStore); - if (sourceTmpl.getInstallPath() == null) { - logger.warn("Cannot copy template [{}] from image store [{}]; install path is null.", tmplt.getUniqueName(), sourceStore.getName()); - continue; - } - - storageOrchestrator.orchestrateTemplateCopyToImageStore(sourceTmpl, destStore); - return true; + TemplateObject sourceTmpl = findUsableTemplate(tmplt, storesInSameZone); + if (sourceTmpl == null) { + return false; } - return false; + + storageOrchestrator.orchestrateTemplateCopyToImageStore(sourceTmpl, destStore); + return true; } private boolean copyTemplateAcrossZones(DataStore destStore, TemplateObject sourceTmpl) { diff --git a/engine/storage/image/src/test/java/org/apache/cloudstack/storage/image/TemplateServiceImplTest.java b/engine/storage/image/src/test/java/org/apache/cloudstack/storage/image/TemplateServiceImplTest.java index faf08de0061..2ce219bca1e 100644 --- a/engine/storage/image/src/test/java/org/apache/cloudstack/storage/image/TemplateServiceImplTest.java +++ b/engine/storage/image/src/test/java/org/apache/cloudstack/storage/image/TemplateServiceImplTest.java @@ -302,6 +302,8 @@ public class TemplateServiceImplTest { Mockito.when(storeWithNullPath.getName()).thenReturn("store-null"); DataStore storeWithValidPath = Mockito.mock(DataStore.class); + Mockito.when(storeWithValidPath.getName()).thenReturn("store-valid"); + TemplateObject tmplWithNullPath = Mockito.mock(TemplateObject.class); Mockito.when(tmplWithNullPath.getInstallPath()).thenReturn(null); @@ -311,6 +313,12 @@ public class TemplateServiceImplTest { Mockito.doReturn(tmplWithNullPath).when(templateDataFactoryMock).getTemplate(10L, storeWithNullPath); Mockito.doReturn(tmplWithValidPath).when(templateDataFactoryMock).getTemplate(10L, storeWithValidPath); + Map templates = new HashMap<>(); + templates.put("test-template", Mockito.mock(TemplateProp.class)); + + Mockito.doReturn(templates).when(templateService).listTemplate(storeWithNullPath); + Mockito.doReturn(templates).when(templateService).listTemplate(storeWithValidPath); + List imageStores = List.of(storeWithNullPath, storeWithValidPath); TemplateObject result = templateService.findUsableTemplate(template, imageStores);