use of org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy in project cloudstack by apache.
the class VolumeOrchestrator method backupSnapshotIfNeeded.
private SnapshotInfo backupSnapshotIfNeeded(Snapshot snapshot, DataStoreRole dataStoreRole, SnapshotInfo snapInfo) {
boolean backupSnapToSecondary = SnapshotManager.BackupSnapshotAfterTakingSnapshot.value() == null || SnapshotManager.BackupSnapshotAfterTakingSnapshot.value();
StoragePoolVO srcPool = _storagePoolDao.findById(snapInfo.getBaseVolume().getPoolId());
// KVMStorageProcessor::createVolumeFromSnapshot and CloudStackPrimaryDataStoreDriverImpl::copyAsync/createAsync
if ((!backupSnapToSecondary && (StoragePoolType.NetworkFilesystem.equals(srcPool.getPoolType()) || StoragePoolType.Filesystem.equals(srcPool.getPoolType())))) {
SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
snapshotStrategy.backupSnapshot(snapInfo);
// Attempt to grab it again.
snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
if (snapInfo == null) {
throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId() + " on secondary and could not create backup");
}
}
return snapInfo;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy in project cloudstack by apache.
the class SnapshotTest method createSnapshot.
@Test
public void createSnapshot() throws InterruptedException, ExecutionException {
VolumeInfo vol = createCopyBaseImage();
SnapshotVO snapshotVO = createSnapshotInDb(vol);
SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
SnapshotInfo newSnapshot = null;
SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
if (snapshotStrategy != null) {
newSnapshot = snapshotStrategy.takeSnapshot(snapshot);
}
AssertJUnit.assertNotNull(newSnapshot);
LocalHostEndpoint ep = new MockLocalHostEndPoint();
ep.setResource(new MockLocalNfsSecondaryStorageResource());
Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep);
try {
for (SnapshotStrategy strategy : this.snapshotStrategies) {
if (strategy.canHandle(snapshot, SnapshotOperation.DELETE) != StrategyPriority.CANT_HANDLE) {
boolean res = strategy.deleteSnapshot(newSnapshot.getId());
Assert.assertTrue(res);
}
}
} finally {
Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(remoteEp);
}
}
use of org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy in project cloudstack by apache.
the class TemplateManagerImpl method createPrivateTemplate.
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", async = true)
public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) throws CloudRuntimeException {
final long templateId = command.getEntityId();
Long volumeId = command.getVolumeId();
Long snapshotId = command.getSnapshotId();
VMTemplateVO privateTemplate = null;
final Long accountId = CallContext.current().getCallingAccountId();
SnapshotVO snapshot = null;
VolumeVO volume = null;
Account caller = CallContext.current().getCallingAccount();
try {
TemplateInfo tmplInfo = _tmplFactory.getTemplate(templateId, DataStoreRole.Image);
long zoneId = 0;
if (snapshotId != null) {
snapshot = _snapshotDao.findById(snapshotId);
zoneId = snapshot.getDataCenterId();
} else if (volumeId != null) {
volume = _volumeDao.findById(volumeId);
zoneId = volume.getDataCenterId();
}
DataStore store = _dataStoreMgr.getImageStoreWithFreeCapacity(zoneId);
if (store == null) {
throw new CloudRuntimeException("cannot find an image store for zone " + zoneId);
}
AsyncCallFuture<TemplateApiResult> future = null;
if (snapshotId != null) {
DataStoreRole dataStoreRole = ApiResponseHelper.getDataStoreRole(snapshot, _snapshotStoreDao, _dataStoreMgr);
SnapshotInfo snapInfo = _snapshotFactory.getSnapshot(snapshotId, dataStoreRole);
if (dataStoreRole == DataStoreRole.Image) {
if (snapInfo == null) {
snapInfo = _snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
if (snapInfo == null) {
throw new CloudRuntimeException("Cannot find snapshot " + snapshotId);
}
// We need to copy the snapshot onto secondary.
SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
snapshotStrategy.backupSnapshot(snapInfo);
// Attempt to grab it again.
snapInfo = _snapshotFactory.getSnapshot(snapshotId, dataStoreRole);
if (snapInfo == null) {
throw new CloudRuntimeException("Cannot find snapshot " + snapshotId + " on secondary and could not create backup");
}
}
_accountMgr.checkAccess(caller, null, true, snapInfo);
DataStore snapStore = snapInfo.getDataStore();
if (snapStore != null) {
// pick snapshot image store to create template
store = snapStore;
}
}
future = _tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store);
} else if (volumeId != null) {
VolumeInfo volInfo = _volFactory.getVolume(volumeId);
if (volInfo == null) {
throw new InvalidParameterValueException("No such volume exist");
}
_accountMgr.checkAccess(caller, null, true, volInfo);
future = _tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store);
} else {
throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");
}
CommandResult result = null;
try {
result = future.get();
if (result.isFailed()) {
privateTemplate = null;
s_logger.debug("Failed to create template" + result.getResult());
throw new CloudRuntimeException("Failed to create template" + result.getResult());
}
// create entries in template_zone_ref table
if (_dataStoreMgr.isRegionStore(store)) {
// template created on region store
_tmpltSvr.associateTemplateToZone(templateId, null);
} else {
VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date());
_tmpltZoneDao.persist(templateZone);
}
privateTemplate = _tmpltDao.findById(templateId);
TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId);
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), zoneId, privateTemplate.getId(), privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(), srcTmpltStore.getPhysicalSize(), privateTemplate.getSize());
_usageEventDao.persist(usageEvent);
} catch (InterruptedException e) {
s_logger.debug("Failed to create template", e);
throw new CloudRuntimeException("Failed to create template", e);
} catch (ExecutionException e) {
s_logger.debug("Failed to create template", e);
throw new CloudRuntimeException("Failed to create template", e);
}
} finally {
if (privateTemplate == null) {
final VolumeVO volumeFinal = volume;
final SnapshotVO snapshotFinal = snapshot;
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
// template_store_ref entries should have been removed using our
// DataObject.processEvent command in case of failure, but clean
// it up here to avoid
// some leftovers which will cause removing template from
// vm_template table fail.
_tmplStoreDao.deletePrimaryRecordsForTemplate(templateId);
// Remove the template_zone_ref record
_tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId);
// Remove the template record
_tmpltDao.expunge(templateId);
// decrement resource count
if (accountId != null) {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(volumeFinal != null ? volumeFinal.getSize() : snapshotFinal.getSize()));
}
}
});
}
}
if (privateTemplate != null) {
return privateTemplate;
} else {
throw new CloudRuntimeException("Failed to create a template");
}
}
use of org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy in project cloudstack by apache.
the class SnapshotManagerImpl method takeSnapshot.
@Override
@DB
public SnapshotInfo takeSnapshot(VolumeInfo volume) throws ResourceAllocationException {
CreateSnapshotPayload payload = (CreateSnapshotPayload) volume.getpayload();
updateSnapshotPayload(volume.getPoolId(), payload);
Long snapshotId = payload.getSnapshotId();
Account snapshotOwner = payload.getAccount();
SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotId, volume.getDataStore());
snapshot.addPayload(payload);
try {
SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
if (snapshotStrategy == null) {
throw new CloudRuntimeException("Can't find snapshot strategy to deal with snapshot:" + snapshotId);
}
SnapshotInfo snapshotOnPrimary = snapshotStrategy.takeSnapshot(snapshot);
boolean backupSnapToSecondary = BackupSnapshotAfterTakingSnapshot.value() == null || BackupSnapshotAfterTakingSnapshot.value();
if (backupSnapToSecondary) {
backupSnapshotToSecondary(payload.getAsyncBackup(), snapshotStrategy, snapshotOnPrimary);
} else {
s_logger.debug("skipping backup of snapshot [uuid=" + snapshot.getUuid() + "] to secondary due to configuration");
snapshotOnPrimary.markBackedUp();
}
try {
postCreateSnapshot(volume.getId(), snapshotId, payload.getSnapshotPolicyId());
DataStoreRole dataStoreRole = getDataStoreRole(snapshot);
SnapshotDataStoreVO snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshotId, dataStoreRole);
if (snapshotStoreRef == null) {
throw new CloudRuntimeException(String.format("Could not find snapshot %s [%s] on [%s]", snapshot.getName(), snapshot.getUuid(), snapshot.getLocationType()));
}
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, snapshotStoreRef.getPhysicalSize(), volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
// Correct the resource count of snapshot in case of delta snapshots.
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.secondary_storage, new Long(volume.getSize() - snapshotStoreRef.getPhysicalSize()));
} catch (Exception e) {
s_logger.debug("post process snapshot failed", e);
}
} catch (CloudRuntimeException cre) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Failed to create snapshot" + cre.getLocalizedMessage());
}
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.secondary_storage, new Long(volume.getSize()));
throw cre;
} catch (Exception e) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Failed to create snapshot", e);
}
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
_resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.secondary_storage, new Long(volume.getSize()));
throw new CloudRuntimeException("Failed to create snapshot", e);
}
return snapshot;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy in project cloudstack by apache.
the class SnapshotManagerImpl method deleteSnapshotDirsForAccount.
@Override
public boolean deleteSnapshotDirsForAccount(long accountId) {
List<VolumeVO> volumes = _volsDao.findIncludingRemovedByAccount(accountId);
// The above call will list only non-destroyed volumes.
// So call this method before marking the volumes as destroyed.
// i.e Call them before the VMs for those volumes are destroyed.
boolean success = true;
for (VolumeVO volume : volumes) {
if (volume.getPoolId() == null) {
continue;
}
Long volumeId = volume.getId();
Long dcId = volume.getDataCenterId();
if (_snapshotDao.listByVolumeIdIncludingRemoved(volumeId).isEmpty()) {
// This volume doesn't have any snapshots. Nothing do delete.
continue;
}
List<DataStore> ssHosts = dataStoreMgr.getImageStoresByScope(new ZoneScope(dcId));
for (DataStore ssHost : ssHosts) {
String snapshotDir = TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + accountId + "/" + volumeId;
DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(ssHost.getTO(), snapshotDir);
EndPoint ep = _epSelector.select(ssHost);
Answer answer = null;
if (ep == null) {
String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(cmd, false, errMsg);
} else {
answer = ep.sendMessage(cmd);
}
if ((answer != null) && answer.getResult()) {
s_logger.debug("Deleted all snapshots for volume: " + volumeId + " under account: " + accountId);
} else {
success = false;
if (answer != null) {
s_logger.warn("Failed to delete all snapshot for volume " + volumeId + " on secondary storage " + ssHost.getUri());
s_logger.error(answer.getDetails());
}
}
}
// Either way delete the snapshots for this volume.
List<SnapshotVO> snapshots = listSnapsforVolume(volumeId);
for (SnapshotVO snapshot : snapshots) {
SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.DELETE);
if (snapshotStrategy == null) {
s_logger.error("Unable to find snaphot strategy to handle snapshot with id '" + snapshot.getId() + "'");
continue;
}
SnapshotDataStoreVO snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Image);
if (snapshotStrategy.deleteSnapshot(snapshot.getId())) {
if (Type.MANUAL == snapshot.getRecurringType()) {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.snapshot);
if (snapshotStoreRef != null) {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(snapshotStoreRef.getPhysicalSize()));
}
}
// Log event after successful deletion
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), volume.getDataCenterId(), snapshot.getId(), snapshot.getName(), null, null, volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
}
}
}
// Returns true if snapshotsDir has been deleted for all volumes.
return success;
}
Aggregations