use of org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult in project cloudstack by apache.
the class TemplateManagerImpl method copy.
@Override
@DB
public boolean copy(long userId, VMTemplateVO template, DataStore srcSecStore, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException {
long tmpltId = template.getId();
long dstZoneId = dstZone.getId();
// find all eligible image stores for the destination zone
List<DataStore> dstSecStores = _dataStoreMgr.getImageStoresByScopeExcludingReadOnly(new ZoneScope(dstZoneId));
if (dstSecStores == null || dstSecStores.isEmpty()) {
throw new StorageUnavailableException("Destination zone is not ready, no image store associated", DataCenter.class, dstZone.getId());
}
AccountVO account = _accountDao.findById(template.getAccountId());
// find the size of the template to be copied
TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(srcSecStore.getId(), tmpltId);
_resourceLimitMgr.checkResourceLimit(account, ResourceType.template);
_resourceLimitMgr.checkResourceLimit(account, ResourceType.secondary_storage, new Long(srcTmpltStore.getSize()).longValue());
// Event details
String copyEventType;
if (template.getFormat().equals(ImageFormat.ISO)) {
copyEventType = EventTypes.EVENT_ISO_COPY;
} else {
copyEventType = EventTypes.EVENT_TEMPLATE_COPY;
}
TemplateInfo srcTemplate = _tmplFactory.getTemplate(template.getId(), srcSecStore);
// for that zone
for (DataStore dstSecStore : dstSecStores) {
TemplateDataStoreVO dstTmpltStore = _tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId);
if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) {
// already downloaded on this image store
return true;
}
if (dstTmpltStore != null && dstTmpltStore.getDownloadState() != Status.DOWNLOAD_IN_PROGRESS) {
_tmplStoreDao.removeByTemplateStore(tmpltId, dstSecStore.getId());
}
AsyncCallFuture<TemplateApiResult> future = _tmpltSvr.copyTemplate(srcTemplate, dstSecStore);
try {
TemplateApiResult result = future.get();
if (result.isFailed()) {
s_logger.debug("copy template failed for image store " + dstSecStore.getName() + ":" + result.getResult());
// try next image store
continue;
}
_tmpltDao.addTemplateToZone(template, dstZoneId);
if (account.getId() != Account.ACCOUNT_ID_SYSTEM) {
UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltStore.getPhysicalSize(), srcTmpltStore.getSize(), template.getClass().getName(), template.getUuid());
}
// Copy every Datadisk template that belongs to the template to Destination zone
List<VMTemplateVO> dataDiskTemplates = _tmpltDao.listByParentTemplatetId(template.getId());
if (dataDiskTemplates != null && !dataDiskTemplates.isEmpty()) {
for (VMTemplateVO dataDiskTemplate : dataDiskTemplates) {
s_logger.debug("Copying " + dataDiskTemplates.size() + " for source template " + template.getId() + ". Copy all Datadisk templates to destination datastore " + dstSecStore.getName());
TemplateInfo srcDataDiskTemplate = _tmplFactory.getTemplate(dataDiskTemplate.getId(), srcSecStore);
AsyncCallFuture<TemplateApiResult> dataDiskCopyFuture = _tmpltSvr.copyTemplate(srcDataDiskTemplate, dstSecStore);
try {
TemplateApiResult dataDiskCopyResult = dataDiskCopyFuture.get();
if (dataDiskCopyResult.isFailed()) {
s_logger.error("Copy of datadisk template: " + srcDataDiskTemplate.getId() + " to image store: " + dstSecStore.getName() + " failed with error: " + dataDiskCopyResult.getResult() + " , will try copying the next one");
// Continue to copy next Datadisk template
continue;
}
_tmpltDao.addTemplateToZone(dataDiskTemplate, dstZoneId);
_resourceLimitMgr.incrementResourceCount(dataDiskTemplate.getAccountId(), ResourceType.secondary_storage, dataDiskTemplate.getSize());
} catch (Exception ex) {
s_logger.error("Failed to copy datadisk template: " + srcDataDiskTemplate.getId() + " to image store: " + dstSecStore.getName() + " , will try copying the next one");
}
}
}
} catch (Exception ex) {
s_logger.debug("failed to copy template to image store:" + dstSecStore.getName() + " ,will try next one");
}
}
return true;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult in project cloudstack by apache.
the class TemplateManagerImpl method prepareTemplateForCreate.
@Override
@DB
public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO templ, StoragePool pool) {
VMTemplateVO template = _tmpltDao.findById(templ.getId(), true);
long poolId = pool.getId();
long templateId = template.getId();
VMTemplateStoragePoolVO templateStoragePoolRef = null;
TemplateDataStoreVO templateStoreRef = null;
templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId, null);
if (templateStoragePoolRef != null) {
templateStoragePoolRef.setMarkedForGC(false);
_tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef);
if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Template " + templateId + " has already been downloaded to pool " + poolId);
}
return templateStoragePoolRef;
}
}
templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, pool.getDataCenterId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
if (templateStoreRef == null) {
s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
return null;
}
List<StoragePoolHostVO> vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up);
if (vos == null || vos.isEmpty()) {
throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool");
}
if (templateStoragePoolRef == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Downloading template " + templateId + " to pool " + poolId);
}
DataStore srcSecStore = _dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image);
TemplateInfo srcTemplate = _tmplFactory.getTemplate(templateId, srcSecStore);
AsyncCallFuture<TemplateApiResult> future = _tmpltSvr.prepareTemplateOnPrimary(srcTemplate, pool);
try {
TemplateApiResult result = future.get();
if (result.isFailed()) {
s_logger.debug("prepare template failed:" + result.getResult());
return null;
}
return _tmpltPoolDao.findByPoolTemplate(poolId, templateId, null);
} catch (Exception ex) {
s_logger.debug("failed to copy template from image store:" + srcSecStore.getName() + " to primary storage");
}
}
return null;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult in project cloudstack by apache.
the class HypervisorTemplateAdapter method createTemplateWithinZone.
private void createTemplateWithinZone(Long zId, TemplateProfile profile, VMTemplateVO template) {
// find all eligible image stores for this zone scope
List<DataStore> imageStores = storeMgr.getImageStoresByScopeExcludingReadOnly(new ZoneScope(zId));
if (imageStores == null || imageStores.size() == 0) {
throw new CloudRuntimeException("Unable to find image store to download template " + profile.getTemplate());
}
Set<Long> zoneSet = new HashSet<Long>();
Collections.shuffle(imageStores);
// For private templates choose a random store. TODO - Have a better algorithm based on size, no. of objects, load etc.
for (DataStore imageStore : imageStores) {
// skip data stores for a disabled zone
Long zoneId = imageStore.getScope().getScopeId();
if (zoneId != null) {
DataCenterVO zone = _dcDao.findById(zoneId);
if (zone == null) {
s_logger.warn("Unable to find zone by id " + zoneId + ", so skip downloading template to its image store " + imageStore.getId());
continue;
}
// Check if zone is disabled
if (Grouping.AllocationState.Disabled == zone.getAllocationState()) {
s_logger.info("Zone " + zoneId + " is disabled. Skip downloading template to its image store " + imageStore.getId());
continue;
}
// Check if image store has enough capacity for template
if (!_statsCollector.imageStoreHasEnoughCapacity(imageStore)) {
s_logger.info("Image store doesn't have enough capacity. Skip downloading template to this image store " + imageStore.getId());
continue;
}
// We want to download private template to one of the image store in a zone
if (isPrivateTemplate(template) && zoneSet.contains(zoneId)) {
continue;
} else {
zoneSet.add(zoneId);
}
}
TemplateInfo tmpl = imageFactory.getTemplate(template.getId(), imageStore);
CreateTemplateContext<TemplateApiResult> context = new CreateTemplateContext<TemplateApiResult>(null, tmpl);
AsyncCallbackDispatcher<HypervisorTemplateAdapter, TemplateApiResult> caller = AsyncCallbackDispatcher.create(this);
caller.setCallback(caller.getTarget().createTemplateAsyncCallBack(null, null));
caller.setContext(context);
imageService.createTemplateAsync(tmpl, imageStore, caller);
}
}
use of org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult in project cloudstack by apache.
the class StorageManagerImpl method cleanupStorage.
@Override
public void cleanupStorage(boolean recurring) {
GlobalLock scanLock = GlobalLock.getInternLock("storagemgr.cleanup");
try {
if (scanLock.lock(3)) {
try {
// Cleanup primary storage pools
if (TemplateCleanupEnabled.value()) {
List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
for (StoragePoolVO pool : storagePools) {
try {
List<VMTemplateStoragePoolVO> unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool);
s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " + pool.getName());
for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
s_logger.debug("Storage pool garbage collector is skipping template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId() + " because it is not completely downloaded.");
continue;
}
if (!templatePoolVO.getMarkedForGC()) {
templatePoolVO.setMarkedForGC(true);
_vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO);
s_logger.debug("Storage pool garbage collector has marked template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId() + " for garbage collection.");
continue;
}
_tmpltMgr.evictTemplateFromStoragePool(templatePoolVO);
}
} catch (Exception e) {
s_logger.warn("Problem cleaning up primary storage pool " + pool, e);
}
}
}
// destroy snapshots in destroying state in snapshot_store_ref
List<SnapshotDataStoreVO> ssSnapshots = _snapshotStoreDao.listByState(ObjectInDataStoreStateMachine.State.Destroying);
for (SnapshotDataStoreVO ssSnapshotVO : ssSnapshots) {
try {
_snapshotService.deleteSnapshot(snapshotFactory.getSnapshot(ssSnapshotVO.getSnapshotId(), DataStoreRole.Image));
} catch (Exception e) {
s_logger.debug("Failed to delete snapshot: " + ssSnapshotVO.getId() + " from storage");
}
}
cleanupSecondaryStorage(recurring);
List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed(new Date(System.currentTimeMillis() - ((long) StorageCleanupDelay.value() << 10)));
for (VolumeVO vol : vols) {
try {
// If this fails, just log a warning. It's ideal if we clean up the host-side clustered file
// system, but not necessary.
handleManagedStorage(vol);
} catch (Exception e) {
s_logger.warn("Unable to destroy host-side clustered file system " + vol.getUuid(), e);
}
try {
VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
if (volumeInfo != null) {
volService.ensureVolumeIsExpungeReady(vol.getId());
volService.expungeVolumeAsync(volumeInfo);
} else {
s_logger.debug("Volume " + vol.getUuid() + " is already destroyed");
}
} catch (Exception e) {
s_logger.warn("Unable to destroy volume " + vol.getUuid(), e);
}
}
// remove snapshots in Error state
List<SnapshotVO> snapshots = _snapshotDao.listAllByStatus(Snapshot.State.Error);
for (SnapshotVO snapshotVO : snapshots) {
try {
List<SnapshotDataStoreVO> storeRefs = _snapshotStoreDao.findBySnapshotId(snapshotVO.getId());
for (SnapshotDataStoreVO ref : storeRefs) {
_snapshotStoreDao.expunge(ref.getId());
}
_snapshotDao.expunge(snapshotVO.getId());
} catch (Exception e) {
s_logger.warn("Unable to destroy snapshot " + snapshotVO.getUuid(), e);
}
}
// destroy uploaded volumes in abandoned/error state
List<VolumeDataStoreVO> volumeDataStores = _volumeDataStoreDao.listByVolumeState(Volume.State.UploadError, Volume.State.UploadAbandoned);
for (VolumeDataStoreVO volumeDataStore : volumeDataStores) {
VolumeVO volume = _volumeDao.findById(volumeDataStore.getVolumeId());
if (volume == null) {
s_logger.warn("Uploaded volume with id " + volumeDataStore.getVolumeId() + " not found, so cannot be destroyed");
continue;
}
try {
DataStore dataStore = _dataStoreMgr.getDataStore(volumeDataStore.getDataStoreId(), DataStoreRole.Image);
EndPoint ep = _epSelector.select(dataStore, volumeDataStore.getExtractUrl());
if (ep == null) {
s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded volume " + volume.getUuid());
continue;
}
Host host = _hostDao.findById(ep.getId());
if (host != null && host.getManagementServerId() != null) {
if (_serverId == host.getManagementServerId().longValue()) {
volService.destroyVolume(volume.getId());
// decrement volume resource count
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
// expunge volume from secondary if volume is on image store
VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
if (volOnSecondary != null) {
s_logger.info("Expunging volume " + volume.getUuid() + " uploaded using HTTP POST from secondary data store");
AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnSecondary);
VolumeApiResult result = future.get();
if (!result.isSuccess()) {
s_logger.warn("Failed to expunge volume " + volume.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
}
}
}
}
} catch (Throwable th) {
s_logger.warn("Unable to destroy uploaded volume " + volume.getUuid() + ". Error details: " + th.getMessage());
}
}
// destroy uploaded templates in abandoned/error state
List<TemplateDataStoreVO> templateDataStores = _templateStoreDao.listByTemplateState(VirtualMachineTemplate.State.UploadError, VirtualMachineTemplate.State.UploadAbandoned);
for (TemplateDataStoreVO templateDataStore : templateDataStores) {
VMTemplateVO template = _templateDao.findById(templateDataStore.getTemplateId());
if (template == null) {
s_logger.warn("Uploaded template with id " + templateDataStore.getTemplateId() + " not found, so cannot be destroyed");
continue;
}
try {
DataStore dataStore = _dataStoreMgr.getDataStore(templateDataStore.getDataStoreId(), DataStoreRole.Image);
EndPoint ep = _epSelector.select(dataStore, templateDataStore.getExtractUrl());
if (ep == null) {
s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded template " + template.getUuid());
continue;
}
Host host = _hostDao.findById(ep.getId());
if (host != null && host.getManagementServerId() != null) {
if (_serverId == host.getManagementServerId().longValue()) {
AsyncCallFuture<TemplateApiResult> future = _imageSrv.deleteTemplateAsync(tmplFactory.getTemplate(template.getId(), dataStore));
TemplateApiResult result = future.get();
if (!result.isSuccess()) {
s_logger.warn("Failed to delete template " + template.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
continue;
}
// remove from template_zone_ref
List<VMTemplateZoneVO> templateZones = _vmTemplateZoneDao.listByZoneTemplate(((ImageStoreEntity) dataStore).getDataCenterId(), template.getId());
if (templateZones != null) {
for (VMTemplateZoneVO templateZone : templateZones) {
_vmTemplateZoneDao.remove(templateZone.getId());
}
}
// mark all the occurrences of this template in the given store as destroyed
_templateStoreDao.removeByTemplateStore(template.getId(), dataStore.getId());
// find all eligible image stores for this template
List<DataStore> imageStores = _tmpltMgr.getImageStoreByTemplate(template.getId(), null);
if (imageStores == null || imageStores.size() == 0) {
template.setState(VirtualMachineTemplate.State.Inactive);
_templateDao.update(template.getId(), template);
// decrement template resource count
_resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template);
}
}
}
} catch (Throwable th) {
s_logger.warn("Unable to destroy uploaded template " + template.getUuid() + ". Error details: " + th.getMessage());
}
}
cleanupInactiveTemplates();
} finally {
scanLock.unlock();
}
}
} finally {
scanLock.releaseRef();
}
}
use of org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult in project cloudstack by apache.
the class SnapshotTest method createTemplateFromSnapshot.
@Test
public void createTemplateFromSnapshot() throws InterruptedException, ExecutionException {
VolumeInfo vol = createCopyBaseImage();
SnapshotVO snapshotVO = createSnapshotInDb(vol);
SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
boolean result = false;
SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
if (snapshotStrategy != null) {
snapshot = snapshotStrategy.takeSnapshot(snapshot);
result = true;
}
AssertJUnit.assertTrue(result);
LocalHostEndpoint ep = new LocalHostEndpoint();
ep.setResource(new MockLocalNfsSecondaryStorageResource());
Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep);
try {
VMTemplateVO templateVO = createTemplateInDb();
TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image);
DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
AsyncCallFuture<TemplateApiResult> templateFuture = this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore);
TemplateApiResult apiResult = templateFuture.get();
Assert.assertTrue(apiResult.isSuccess());
} finally {
Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(remoteEp);
}
}
Aggregations