Search in sources :

Example 1 with SnapshotStrategy

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;
}
Also used : CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) SnapshotStrategy(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy)

Example 2 with SnapshotStrategy

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);
    }
}
Also used : LocalHostEndpoint(org.apache.cloudstack.storage.LocalHostEndpoint) SnapshotInfo(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo) SnapshotVO(com.cloud.storage.SnapshotVO) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) MockLocalNfsSecondaryStorageResource(org.apache.cloudstack.storage.MockLocalNfsSecondaryStorageResource) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) SnapshotStrategy(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy) Test(org.testng.annotations.Test)

Example 3 with SnapshotStrategy

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");
    }
}
Also used : Account(com.cloud.user.Account) VMTemplateZoneVO(com.cloud.storage.VMTemplateZoneVO) VMTemplateVO(com.cloud.storage.VMTemplateVO) TransactionStatus(com.cloud.utils.db.TransactionStatus) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) UsageEventVO(com.cloud.event.UsageEventVO) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) DataStoreRole(com.cloud.storage.DataStoreRole) VolumeVO(com.cloud.storage.VolumeVO) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) PrimaryDataStore(org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) ExecutionException(java.util.concurrent.ExecutionException) SnapshotStrategy(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy) TemplateDataStoreVO(org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO) TemplateApiResult(org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult) Date(java.util.Date) CommandResult(org.apache.cloudstack.storage.command.CommandResult) TemplateInfo(org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo) SnapshotInfo(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo) SnapshotVO(com.cloud.storage.SnapshotVO) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 4 with SnapshotStrategy

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;
}
Also used : Account(com.cloud.user.Account) DataStoreRole(com.cloud.storage.DataStoreRole) SnapshotInfo(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) SnapshotDataStoreVO(org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO) CreateSnapshotPayload(com.cloud.storage.CreateSnapshotPayload) SnapshotStrategy(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) ConfigurationException(javax.naming.ConfigurationException) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) DB(com.cloud.utils.db.DB)

Example 5 with SnapshotStrategy

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;
}
Also used : SnapshotDataStoreVO(org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) ZoneScope(org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope) DeleteSnapshotsDirCommand(com.cloud.agent.api.DeleteSnapshotsDirCommand) Answer(com.cloud.agent.api.Answer) VMSnapshotVO(com.cloud.vm.snapshot.VMSnapshotVO) SnapshotVO(com.cloud.storage.SnapshotVO) VolumeVO(com.cloud.storage.VolumeVO) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) SnapshotStrategy(org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy)

Aggregations

SnapshotStrategy (org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy)11 SnapshotVO (com.cloud.storage.SnapshotVO)9 SnapshotInfo (org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo)8 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)6 VolumeInfo (org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo)6 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)5 DataStore (org.apache.cloudstack.engine.subsystem.api.storage.DataStore)5 DataStoreRole (com.cloud.storage.DataStoreRole)4 VolumeVO (com.cloud.storage.VolumeVO)4 Account (com.cloud.user.Account)4 VMSnapshotVO (com.cloud.vm.snapshot.VMSnapshotVO)4 SnapshotDataStoreVO (org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO)4 PermissionDeniedException (com.cloud.exception.PermissionDeniedException)3 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)3 StorageUnavailableException (com.cloud.exception.StorageUnavailableException)3 DB (com.cloud.utils.db.DB)3 ConfigurationException (javax.naming.ConfigurationException)3 Test (org.testng.annotations.Test)3 ActionEvent (com.cloud.event.ActionEvent)2 VMTemplateVO (com.cloud.storage.VMTemplateVO)2