Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/src/com/cloud/template/TemplateApiService.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public interface TemplateApiService {

VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException;

VirtualMachineTemplate prepareTemplate(long templateId, long zoneId);
VirtualMachineTemplate prepareTemplate(long templateId, long zoneId, Long storageId);

boolean detachIso(long vmId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.cloudstack.api.response.ZoneResponse;

Expand Down Expand Up @@ -60,6 +61,15 @@ public class PrepareTemplateCmd extends BaseCmd {
description = "template ID of the template to be prepared in primary storage(s).")
private Long templateId;

@ACL(accessType = AccessType.OperateEntry)
@Parameter(name = ApiConstants.STORAGE_ID,
type = CommandType.UUID,
entityType = StoragePoolResponse.class,
required = false,
description = "storage pool ID of the primary storage pool to which the template should be prepared. If it is not provided the template" +
" is prepared on all the available primary storage pools.")
private Long storageId;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand All @@ -72,6 +82,10 @@ public Long getTemplateId() {
return templateId;
}

public Long getStorageId() {
return storageId;
}

/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
Expand All @@ -90,7 +104,7 @@ public long getEntityOwnerId() {
public void execute() {
ListResponse<TemplateResponse> response = new ListResponse<TemplateResponse>();

VirtualMachineTemplate vmTemplate = _templateService.prepareTemplate(templateId, zoneId);
VirtualMachineTemplate vmTemplate = _templateService.prepareTemplate(templateId, zoneId, storageId);
List<TemplateResponse> templateResponses = _responseGenerator.createTemplateResponses(ResponseView.Full, vmTemplate, zoneId, true);
response.setResponses(templateResponses);
response.setResponseName(getCommandName());
Expand Down
60 changes: 38 additions & 22 deletions server/src/com/cloud/template/TemplateManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
MessageBus _messageBus;

private boolean _disableExtraction = false;
private ExecutorService _preloadExecutor;

private List<TemplateAdapter> _adapters;

ExecutorService _preloadExecutor;

@Inject
private StorageCacheManager cacheMgr;
@Inject
Expand Down Expand Up @@ -436,7 +436,7 @@ public String extract(ExtractTemplateCmd cmd) {
}

@Override
public VirtualMachineTemplate prepareTemplate(long templateId, long zoneId) {
public VirtualMachineTemplate prepareTemplate(long templateId, long zoneId, Long storageId) {

VMTemplateVO vmTemplate = _tmpltDao.findById(templateId);
if (vmTemplate == null) {
Expand All @@ -445,7 +445,19 @@ public VirtualMachineTemplate prepareTemplate(long templateId, long zoneId) {

_accountMgr.checkAccess(CallContext.current().getCallingAccount(), AccessType.OperateEntry, true, vmTemplate);

prepareTemplateInAllStoragePools(vmTemplate, zoneId);
if (storageId != null) {
StoragePoolVO pool = _poolDao.findById(storageId);
if (pool != null) {
if (pool.getStatus() == StoragePoolStatus.Up && pool.getDataCenterId() == zoneId) {
prepareTemplateInOneStoragePool(vmTemplate, pool);
} else {
s_logger.warn("Skip loading template " + vmTemplate.getId() + " into primary storage " + pool.getId() + " as either the pool zone "
+ pool.getDataCenterId() + " is different from the requested zone " + zoneId + " or the pool is currently not available.");
}
}
} else {
prepareTemplateInAllStoragePools(vmTemplate, zoneId);
}
return vmTemplate;
}

Expand Down Expand Up @@ -556,28 +568,32 @@ public void prepareIsoForVmProfile(VirtualMachineProfile profile) {
}
}

private void prepareTemplateInOneStoragePool(final VMTemplateVO template, final StoragePoolVO pool) {
s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId());
_preloadExecutor.execute(new ManagedContextRunnable() {
@Override
protected void runInContext() {
try {
reallyRun();
} catch (Throwable e) {
s_logger.warn("Unexpected exception ", e);
}
}

private void reallyRun() {
s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId());
StoragePool pol = (StoragePool)_dataStoreMgr.getPrimaryDataStore(pool.getId());
prepareTemplateForCreate(template, pol);
s_logger.info("End of preloading template " + template.getId() + " into primary storage " + pool.getId());
}
});
}

public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) {
List<StoragePoolVO> pools = _poolDao.listByStatus(StoragePoolStatus.Up);
for (final StoragePoolVO pool : pools) {
if (pool.getDataCenterId() == zoneId) {
s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId());
_preloadExecutor.execute(new ManagedContextRunnable() {
@Override
protected void runInContext() {
try {
reallyRun();
} catch (Throwable e) {
s_logger.warn("Unexpected exception ", e);
}
}

private void reallyRun() {
s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId());
StoragePool pol = (StoragePool)_dataStoreMgr.getPrimaryDataStore(pool.getId());
prepareTemplateForCreate(template, pol);
s_logger.info("End of preloading template " + template.getId() + " into primary storage " + pool.getId());
}
});
prepareTemplateInOneStoragePool(template, pool);
} else {
s_logger.info("Skip loading template " + template.getId() + " into primary storage " + pool.getId() + " as pool zone " + pool.getDataCenterId() +
" is different from the requested zone " + zoneId);
Expand Down
Loading