Skip to content

Commit df1ad66

Browse files
committed
Implement template replication up to capacity after upload and during template creation
1 parent cb36bef commit df1ad66

4 files changed

Lines changed: 57 additions & 1 deletion

File tree

engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ public TemplateInfo getTemplate() {
7171

7272
boolean canCopyTemplateToImageStore(long templateId, long zoneId);
7373

74+
void replicateTemplateUpToCap(long templateId, long zoneId);
75+
7476
void downloadBootstrapSysTemplate(DataStore store);
7577

7678
void addSystemVMTemplatesToSecondary(DataStore store);

engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateServiceImpl.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,48 @@ private boolean hasReachedSecStorageCopyLimit(VMTemplateVO template, long zoneId
351351
return !canCopyTemplateToImageStore(template.getId(), zoneId);
352352
}
353353

354+
@Override
355+
public void replicateTemplateUpToCap(long templateId, long zoneId) {
356+
VMTemplateVO template = _templateDao.findById(templateId);
357+
if (template == null) {
358+
return;
359+
}
360+
List<DataStore> stores = _storeMgr.getImageStoresByScope(new ZoneScope(zoneId));
361+
if (stores == null || stores.isEmpty()) {
362+
return;
363+
}
364+
for (DataStore store : stores) {
365+
if (hasActiveTemplateCopyOnStore(templateId, store.getId())) {
366+
continue;
367+
}
368+
if (!canCopyTemplateToImageStore(templateId, zoneId)) {
369+
break;
370+
}
371+
try {
372+
storageOrchestrator.orchestrateTemplateCopyFromSecondaryStores(templateId, store);
373+
} catch (Exception e) {
374+
logger.warn("Failed to proactively replicate template [{}] to image store [{}] in zone [{}]: {}",
375+
template.getUniqueName(), store.getName(), zoneId, e.getMessage());
376+
}
377+
}
378+
}
379+
380+
private boolean hasActiveTemplateCopyOnStore(long templateId, long storeId) {
381+
List<TemplateDataStoreVO> rows = _vmTemplateStoreDao.listByTemplateStore(templateId, storeId);
382+
if (rows == null) {
383+
return false;
384+
}
385+
for (TemplateDataStoreVO row : rows) {
386+
State st = row.getState();
387+
Status ds = row.getDownloadState();
388+
if (st != State.Failed && st != State.Destroyed
389+
&& ds != Status.ABANDONED && ds != Status.DOWNLOAD_ERROR) {
390+
return true;
391+
}
392+
}
393+
return false;
394+
}
395+
354396
@Override
355397
public void enforceSecStorageCopyLimit(long templateId, long zoneId) {
356398
VMTemplateVO template = _templateDao.findById(templateId);

server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,12 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
451451
if (logger.isDebugEnabled()) {
452452
logger.debug("Template {} uploaded successfully", tmpTemplate);
453453
}
454+
try {
455+
templateService.replicateTemplateUpToCap(tmpTemplate.getId(), vo.getDataCenterId());
456+
} catch (Exception e) {
457+
logger.warn("Failed to schedule additional copies for uploaded template [{}] in zone [{}]: {}",
458+
tmpTemplate.getUuid(), vo.getDataCenterId(), e.getMessage());
459+
}
454460
break;
455461
case IN_PROGRESS:
456462
if (tmpTemplate.getState() == VirtualMachineTemplate.State.NotUploaded) {

server/src/main/java/com/cloud/template/TemplateManagerImpl.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1722,10 +1722,10 @@ public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) t
17221722
Account caller = CallContext.current().getCallingAccount();
17231723
boolean kvmSnapshotOnlyInPrimaryStorage = false;
17241724
SnapshotInfo snapInfo = null;
1725+
long zoneId = 0;
17251726

17261727
try {
17271728
TemplateInfo tmplInfo = _tmplFactory.getTemplate(templateId, DataStoreRole.Image);
1728-
long zoneId = 0;
17291729
if (snapshotId != null) {
17301730
snapshot = _snapshotDao.findById(snapshotId);
17311731
if (command.getZoneId() == null) {
@@ -1865,6 +1865,12 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
18651865
}
18661866

18671867
if (privateTemplate != null) {
1868+
try {
1869+
_tmpltSvr.replicateTemplateUpToCap(privateTemplate.getId(), zoneId);
1870+
} catch (Exception e) {
1871+
logger.warn("Failed to schedule additional copies for template [{}] in zone [{}]: {}",
1872+
privateTemplate.getUniqueName(), zoneId, e.getMessage());
1873+
}
18681874
return privateTemplate;
18691875
} else {
18701876
throw new CloudRuntimeException("Failed to create a Template");

0 commit comments

Comments
 (0)