Search in sources :

Example 11 with SnapshotInfo

use of com.cloud.engine.subsystem.api.storage.SnapshotInfo in project cosmic by MissionCriticalCloud.

the class ApiResponseHelper method createSnapshotResponse.

@Override
public SnapshotResponse createSnapshotResponse(final Snapshot snapshot) {
    final SnapshotResponse snapshotResponse = new SnapshotResponse();
    snapshotResponse.setId(snapshot.getUuid());
    populateOwner(snapshotResponse, snapshot);
    final VolumeVO volume = findVolumeById(snapshot.getVolumeId());
    final String snapshotTypeStr = snapshot.getRecurringType().name();
    snapshotResponse.setSnapshotType(snapshotTypeStr);
    if (volume != null) {
        snapshotResponse.setVolumeId(volume.getUuid());
        snapshotResponse.setVolumeName(volume.getName());
        snapshotResponse.setVolumeType(volume.getVolumeType().name());
        final DataCenter zone = ApiDBUtils.findZoneById(volume.getDataCenterId());
        if (zone != null) {
            snapshotResponse.setZoneId(zone.getUuid());
        }
    }
    snapshotResponse.setCreated(snapshot.getCreated());
    snapshotResponse.setName(snapshot.getName());
    snapshotResponse.setIntervalType(ApiDBUtils.getSnapshotIntervalTypes(snapshot.getId()));
    snapshotResponse.setState(snapshot.getState());
    final SnapshotInfo snapshotInfo;
    if (snapshot instanceof SnapshotInfo) {
        snapshotInfo = (SnapshotInfo) snapshot;
    } else {
        final DataStoreRole dataStoreRole = getDataStoreRole(snapshot, _snapshotStoreDao, _dataStoreMgr);
        snapshotInfo = snapshotfactory.getSnapshot(snapshot.getId(), dataStoreRole);
    }
    if (snapshotInfo == null) {
        s_logger.debug("Unable to find info for image store snapshot with uuid " + snapshot.getUuid());
        snapshotResponse.setRevertable(false);
    } else {
        snapshotResponse.setRevertable(snapshotInfo.isRevertable());
        snapshotResponse.setPhysicaSize(snapshotInfo.getPhysicalSize());
    }
    // set tag information
    final List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Snapshot, snapshot.getId());
    final List<ResourceTagResponse> tagResponses = new ArrayList<>();
    for (final ResourceTag tag : tags) {
        final ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
        CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
    }
    snapshotResponse.setTags(tagResponses);
    snapshotResponse.setObjectName("snapshot");
    return snapshotResponse;
}
Also used : DataStoreRole(com.cloud.storage.DataStoreRole) SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) DataCenter(com.cloud.dc.DataCenter) ResourceTag(com.cloud.server.ResourceTag) VolumeVO(com.cloud.storage.VolumeVO) VMSnapshotResponse(com.cloud.api.response.VMSnapshotResponse) SnapshotResponse(com.cloud.api.response.SnapshotResponse) ResourceTagResponse(com.cloud.api.response.ResourceTagResponse) ArrayList(java.util.ArrayList)

Example 12 with SnapshotInfo

use of com.cloud.engine.subsystem.api.storage.SnapshotInfo in project cosmic by MissionCriticalCloud.

the class TemplateManagerImpl method createPrivateTemplate.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", async = true)
public VirtualMachineTemplate createPrivateTemplate(final CreateTemplateCmd command) throws CloudRuntimeException {
    final long templateId = command.getEntityId();
    final Long volumeId = command.getVolumeId();
    final Long snapshotId = command.getSnapshotId();
    VMTemplateVO privateTemplate = null;
    final Long accountId = CallContext.current().getCallingAccountId();
    SnapshotVO snapshot = null;
    VolumeVO volume = null;
    try {
        final 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.getImageStore(zoneId);
        if (store == null) {
            throw new CloudRuntimeException("cannot find an image store for zone " + zoneId);
        }
        final AsyncCallFuture<TemplateApiResult> future;
        if (snapshotId != null) {
            final 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.
                    final 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");
                    }
                }
                final 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) {
            final VolumeInfo volInfo = _volFactory.getVolume(volumeId);
            future = _tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store);
        } else {
            throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");
        }
        final CommandResult result;
        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 {
                final VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date());
                _tmpltZoneDao.persist(templateZone);
            }
            privateTemplate = _tmpltDao.findById(templateId);
        } catch (final InterruptedException | 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(final 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 : VMTemplateZoneVO(com.cloud.storage.VMTemplateZoneVO) VMTemplateVO(com.cloud.storage.VMTemplateVO) TransactionStatus(com.cloud.utils.db.TransactionStatus) VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo) TransactionCallbackNoReturn(com.cloud.utils.db.TransactionCallbackNoReturn) TemplateApiResult(com.cloud.engine.subsystem.api.storage.TemplateService.TemplateApiResult) Date(java.util.Date) CommandResult(com.cloud.storage.command.CommandResult) DataStoreRole(com.cloud.storage.DataStoreRole) TemplateInfo(com.cloud.engine.subsystem.api.storage.TemplateInfo) SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) SnapshotVO(com.cloud.storage.SnapshotVO) VolumeVO(com.cloud.storage.VolumeVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DataStore(com.cloud.engine.subsystem.api.storage.DataStore) ExecutionException(java.util.concurrent.ExecutionException) SnapshotStrategy(com.cloud.engine.subsystem.api.storage.SnapshotStrategy) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 13 with SnapshotInfo

use of com.cloud.engine.subsystem.api.storage.SnapshotInfo in project cosmic by MissionCriticalCloud.

the class XenserverSnapshotStrategy method backupSnapshot.

@Override
public SnapshotInfo backupSnapshot(final SnapshotInfo snapshot) {
    final SnapshotInfo parentSnapshot = snapshot.getParent();
    if (parentSnapshot != null && snapshot.getPath().equalsIgnoreCase(parentSnapshot.getPath())) {
        s_logger.debug("backup an empty snapshot");
        // don't need to backup this snapshot
        final SnapshotDataStoreVO parentSnapshotOnBackupStore = snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image);
        if (parentSnapshotOnBackupStore != null && parentSnapshotOnBackupStore.getState() == State.Ready) {
            final DataStore store = dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), parentSnapshotOnBackupStore.getRole());
            final SnapshotInfo snapshotOnImageStore = (SnapshotInfo) store.create(snapshot);
            snapshotOnImageStore.processEvent(Event.CreateOnlyRequested);
            final SnapshotObjectTO snapTO = new SnapshotObjectTO();
            snapTO.setPath(parentSnapshotOnBackupStore.getInstallPath());
            final CreateObjectAnswer createSnapshotAnswer = new CreateObjectAnswer(snapTO);
            snapshotOnImageStore.processEvent(Event.OperationSuccessed, createSnapshotAnswer);
            final SnapshotObject snapObj = (SnapshotObject) snapshot;
            try {
                snapObj.processEvent(Snapshot.Event.OperationNotPerformed);
            } catch (final NoTransitionException e) {
                s_logger.debug("Failed to change state: " + snapshot.getId() + ": " + e.toString());
                throw new CloudRuntimeException(e.toString());
            }
            return snapshotDataFactory.getSnapshot(snapObj.getId(), store);
        } else {
            s_logger.debug("parent snapshot hasn't been backed up yet");
        }
    }
    // determine full snapshot backup or not
    boolean fullBackup = true;
    SnapshotDataStoreVO parentSnapshotOnBackupStore = snapshotStoreDao.findLatestSnapshotForVolume(snapshot.getVolumeId(), DataStoreRole.Image);
    final SnapshotDataStoreVO parentSnapshotOnPrimaryStore = snapshotStoreDao.findLatestSnapshotForVolume(snapshot.getVolumeId(), DataStoreRole.Primary);
    final HypervisorType hypervisorType = snapshot.getBaseVolume().getHypervisorType();
    if (parentSnapshotOnPrimaryStore != null && parentSnapshotOnBackupStore != null && hypervisorType == Hypervisor.HypervisorType.XenServer) {
        // CS does incremental backup
        // only for XenServer
        // In case of volume migration from one pool to other pool, CS should take full snapshot to avoid any issues with delta chain,
        // to check if this is a migrated volume, compare the current pool id of volume and store_id of oldest snapshot on primary for this volume.
        // Why oldest? Because at this point CS has two snapshot on primary entries for same volume, one with old pool_id and other one with
        // current pool id. So, verify and if volume found to be migrated, delete snapshot entry with previous pool store_id.
        final SnapshotDataStoreVO oldestSnapshotOnPrimary = snapshotStoreDao.findOldestSnapshotForVolume(snapshot.getVolumeId(), DataStoreRole.Primary);
        final VolumeVO volume = volumeDao.findById(snapshot.getVolumeId());
        if (oldestSnapshotOnPrimary != null) {
            if (oldestSnapshotOnPrimary.getDataStoreId() == volume.getPoolId()) {
                final int _deltaSnapshotMax = NumbersUtil.parseInt(configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX);
                final int deltaSnap = _deltaSnapshotMax;
                int i;
                for (i = 1; i < deltaSnap; i++) {
                    final Long prevBackupId = parentSnapshotOnBackupStore.getParentSnapshotId();
                    if (prevBackupId == 0) {
                        break;
                    }
                    parentSnapshotOnBackupStore = snapshotStoreDao.findBySnapshot(prevBackupId, DataStoreRole.Image);
                    if (parentSnapshotOnBackupStore == null) {
                        break;
                    }
                }
                if (i >= deltaSnap) {
                    fullBackup = true;
                } else {
                    fullBackup = false;
                }
            } else {
                // if there is an snapshot entry for previousPool(primary storage) of migrated volume, delete it becasue CS created one more snapshot entry for current pool
                snapshotStoreDao.remove(oldestSnapshotOnPrimary.getId());
            }
        }
    }
    snapshot.addPayload(fullBackup);
    return snapshotSvr.backupSnapshot(snapshot);
}
Also used : SnapshotObjectTO(com.cloud.storage.to.SnapshotObjectTO) SnapshotDataStoreVO(com.cloud.storage.datastore.db.SnapshotDataStoreVO) CreateObjectAnswer(com.cloud.storage.command.CreateObjectAnswer) HypervisorType(com.cloud.hypervisor.Hypervisor.HypervisorType) SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) VolumeVO(com.cloud.storage.VolumeVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DataStore(com.cloud.engine.subsystem.api.storage.DataStore) NoTransitionException(com.cloud.utils.fsm.NoTransitionException)

Example 14 with SnapshotInfo

use of com.cloud.engine.subsystem.api.storage.SnapshotInfo in project cosmic by MissionCriticalCloud.

the class XenserverSnapshotStrategy method deleteSnapshotChain.

protected boolean deleteSnapshotChain(SnapshotInfo snapshot) {
    s_logger.debug("delete snapshot chain for snapshot: " + snapshot.getId());
    boolean result = false;
    // need to track, the snapshot itself is deleted or not.
    boolean resultIsSet = false;
    try {
        while (snapshot != null && (snapshot.getState() == Snapshot.State.Destroying || snapshot.getState() == Snapshot.State.Destroyed || snapshot.getState() == Snapshot.State.Error)) {
            final SnapshotInfo child = snapshot.getChild();
            if (child != null) {
                s_logger.debug("the snapshot has child, can't delete it on the storage");
                break;
            }
            s_logger.debug("Snapshot: " + snapshot.getId() + " doesn't have children, so it's ok to delete it and its parents");
            final SnapshotInfo parent = snapshot.getParent();
            boolean deleted = false;
            if (parent != null) {
                if (parent.getPath() != null && parent.getPath().equalsIgnoreCase(snapshot.getPath())) {
                    // NOTE: if both snapshots share the same path, it's for xenserver's empty delta snapshot. We can't delete the snapshot on the backend, as parent snapshot
                    // still reference to it
                    // Instead, mark it as destroyed in the db.
                    s_logger.debug("for empty delta snapshot, only mark it as destroyed in db");
                    snapshot.processEvent(Event.DestroyRequested);
                    snapshot.processEvent(Event.OperationSuccessed);
                    deleted = true;
                    if (!resultIsSet) {
                        result = true;
                        resultIsSet = true;
                    }
                }
            }
            if (!deleted) {
                final boolean r = snapshotSvr.deleteSnapshot(snapshot);
                if (r) {
                    // delete snapshot in cache if there is
                    final List<SnapshotInfo> cacheSnaps = snapshotDataFactory.listSnapshotOnCache(snapshot.getId());
                    for (final SnapshotInfo cacheSnap : cacheSnaps) {
                        s_logger.debug("Delete snapshot " + snapshot.getId() + " from image cache store: " + cacheSnap.getDataStore().getName());
                        cacheSnap.delete();
                    }
                }
                if (!resultIsSet) {
                    result = r;
                    resultIsSet = true;
                }
            }
            snapshot = parent;
        }
    } catch (final Exception e) {
        s_logger.debug("delete snapshot failed: ", e);
    }
    return result;
}
Also used : SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException)

Example 15 with SnapshotInfo

use of com.cloud.engine.subsystem.api.storage.SnapshotInfo in project cosmic by MissionCriticalCloud.

the class XenserverSnapshotStrategy method takeSnapshot.

@Override
@DB
public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) {
    final Object payload = snapshot.getPayload();
    if (payload != null) {
        final CreateSnapshotPayload createSnapshotPayload = (CreateSnapshotPayload) payload;
        if (createSnapshotPayload.getQuiescevm()) {
            throw new InvalidParameterValueException("can't handle quiescevm equal true for volume snapshot");
        }
    }
    final SnapshotVO snapshotVO = snapshotDao.acquireInLockTable(snapshot.getId());
    if (snapshotVO == null) {
        throw new CloudRuntimeException("Failed to get lock on snapshot:" + snapshot.getId());
    }
    try {
        final VolumeInfo volumeInfo = snapshot.getBaseVolume();
        volumeInfo.stateTransit(Volume.Event.SnapshotRequested);
        SnapshotResult result = null;
        try {
            result = snapshotSvr.takeSnapshot(snapshot);
            if (result.isFailed()) {
                s_logger.debug("Failed to take snapshot: " + result.getResult());
                throw new CloudRuntimeException(result.getResult());
            }
        } finally {
            if (result != null && result.isSuccess()) {
                volumeInfo.stateTransit(Volume.Event.OperationSucceeded);
            } else {
                volumeInfo.stateTransit(Volume.Event.OperationFailed);
            }
        }
        snapshot = result.getSnashot();
        final DataStore primaryStore = snapshot.getDataStore();
        final boolean backupFlag = Boolean.parseBoolean(configDao.getValue(Config.BackupSnapshotAfterTakingSnapshot.toString()));
        final SnapshotInfo backupedSnapshot;
        if (backupFlag) {
            backupedSnapshot = backupSnapshot(snapshot);
        } else {
            // Fake it to get the transitions to fire in the proper order
            s_logger.debug("skipping backup of snapshot due to configuration " + Config.BackupSnapshotAfterTakingSnapshot.toString());
            final SnapshotObject snapObj = (SnapshotObject) snapshot;
            try {
                snapObj.processEvent(Snapshot.Event.OperationNotPerformed);
            } catch (final NoTransitionException e) {
                s_logger.debug("Failed to change state: " + snapshot.getId() + ": " + e.toString());
                throw new CloudRuntimeException(e.toString());
            }
            backupedSnapshot = snapshot;
        }
        try {
            final SnapshotInfo parent = snapshot.getParent();
            if (backupedSnapshot != null && parent != null) {
                Long parentSnapshotId = parent.getId();
                while (parentSnapshotId != null && parentSnapshotId != 0L) {
                    final SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), parentSnapshotId);
                    if (snapshotDataStoreVO != null) {
                        parentSnapshotId = snapshotDataStoreVO.getParentSnapshotId();
                        snapshotStoreDao.remove(snapshotDataStoreVO.getId());
                    } else {
                        parentSnapshotId = null;
                    }
                }
                final SnapshotDataStoreVO snapshotDataStoreVO = snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), primaryStore.getId(), snapshot.getId());
                if (snapshotDataStoreVO != null) {
                    snapshotDataStoreVO.setParentSnapshotId(0L);
                    snapshotStoreDao.update(snapshotDataStoreVO.getId(), snapshotDataStoreVO);
                }
            }
        } catch (final Exception e) {
            s_logger.debug("Failed to clean up snapshots on primary storage", e);
        }
        return backupedSnapshot;
    } finally {
        if (snapshotVO != null) {
            snapshotDao.releaseFromLockTable(snapshot.getId());
        }
    }
}
Also used : SnapshotResult(com.cloud.engine.subsystem.api.storage.SnapshotResult) SnapshotDataStoreVO(com.cloud.storage.datastore.db.SnapshotDataStoreVO) CreateSnapshotPayload(com.cloud.storage.CreateSnapshotPayload) VolumeInfo(com.cloud.engine.subsystem.api.storage.VolumeInfo) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) SnapshotInfo(com.cloud.engine.subsystem.api.storage.SnapshotInfo) SnapshotVO(com.cloud.storage.SnapshotVO) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DataStore(com.cloud.engine.subsystem.api.storage.DataStore) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) DB(com.cloud.utils.db.DB)

Aggregations

SnapshotInfo (com.cloud.engine.subsystem.api.storage.SnapshotInfo)28 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)20 NoTransitionException (com.cloud.utils.fsm.NoTransitionException)10 ExecutionException (java.util.concurrent.ExecutionException)10 DataStore (com.cloud.engine.subsystem.api.storage.DataStore)9 SnapshotDataStoreVO (com.cloud.storage.datastore.db.SnapshotDataStoreVO)9 InvalidParameterValueException (com.cloud.utils.exception.InvalidParameterValueException)9 SnapshotResult (com.cloud.engine.subsystem.api.storage.SnapshotResult)8 VolumeInfo (com.cloud.engine.subsystem.api.storage.VolumeInfo)8 CopyCommandResult (com.cloud.engine.subsystem.api.storage.CopyCommandResult)7 DB (com.cloud.utils.db.DB)7 SnapshotVO (com.cloud.storage.SnapshotVO)6 SnapshotStrategy (com.cloud.engine.subsystem.api.storage.SnapshotStrategy)5 StorageUnavailableException (com.cloud.exception.StorageUnavailableException)5 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)4 VolumeVO (com.cloud.storage.VolumeVO)4 CommandResult (com.cloud.storage.command.CommandResult)4 ConfigurationException (javax.naming.ConfigurationException)4 Answer (com.cloud.agent.api.Answer)3 MigrateVolumeAnswer (com.cloud.agent.api.storage.MigrateVolumeAnswer)3