use of org.apache.cloudstack.storage.datastore.api.SnapshotGroup in project cloudstack by apache.
the class ScaleIOGatewayClientImpl method revertSnapshot.
@Override
public boolean revertSnapshot(final String systemId, final Map<String, String> srcSnapshotDestVolumeMap) {
Preconditions.checkArgument(StringUtils.isNotEmpty(systemId), "System id cannot be null");
Preconditions.checkArgument(srcSnapshotDestVolumeMap != null && !srcSnapshotDestVolumeMap.isEmpty(), "srcSnapshotDestVolumeMap cannot be null");
// Take group snapshot (needs additional storage pool capacity till revert operation) to keep the last state of all volumes ???
// and delete the group snapshot after revert operation
// If revert snapshot failed for any volume, use the group snapshot, to revert volumes to last state
Map<String, String> srcVolumeDestSnapshotMap = new HashMap<>();
List<String> originalVolumeIds = new ArrayList<>();
for (final String sourceSnapshotVolumeId : srcSnapshotDestVolumeMap.keySet()) {
String destVolumeId = srcSnapshotDestVolumeMap.get(sourceSnapshotVolumeId);
srcVolumeDestSnapshotMap.put(destVolumeId, "");
originalVolumeIds.add(destVolumeId);
}
SnapshotGroup snapshotGroup = takeSnapshot(srcVolumeDestSnapshotMap);
if (snapshotGroup == null) {
throw new CloudRuntimeException("Failed to snapshot the last vm state");
}
boolean revertSnapshotResult = true;
int revertStatusIndex = -1;
try {
// non-atomic operation, try revert each volume
for (final String sourceSnapshotVolumeId : srcSnapshotDestVolumeMap.keySet()) {
String destVolumeId = srcSnapshotDestVolumeMap.get(sourceSnapshotVolumeId);
boolean revertStatus = revertSnapshot(sourceSnapshotVolumeId, destVolumeId);
if (!revertStatus) {
revertSnapshotResult = false;
LOG.warn("Failed to revert snapshot for volume id: " + sourceSnapshotVolumeId);
throw new CloudRuntimeException("Failed to revert snapshot for volume id: " + sourceSnapshotVolumeId);
} else {
revertStatusIndex++;
}
}
} catch (final Exception e) {
LOG.error("Failed to revert vm snapshot due to: " + e.getMessage(), e);
throw new CloudRuntimeException("Failed to revert vm snapshot due to: " + e.getMessage());
} finally {
if (!revertSnapshotResult) {
// revert to volume with last state and delete the snapshot group, for already reverted volumes
List<String> volumesWithLastState = snapshotGroup.getVolumeIds();
for (int index = revertStatusIndex; index >= 0; index--) {
// Handling failure for revert again will become recursive ???
revertSnapshot(volumesWithLastState.get(index), originalVolumeIds.get(index));
}
}
deleteSnapshotGroup(systemId, snapshotGroup.getSnapshotGroupId());
}
return revertSnapshotResult;
}
use of org.apache.cloudstack.storage.datastore.api.SnapshotGroup in project cloudstack by apache.
the class ScaleIOVMSnapshotStrategy method takeVMSnapshot.
@Override
public VMSnapshot takeVMSnapshot(VMSnapshot vmSnapshot) {
UserVm userVm = userVmDao.findById(vmSnapshot.getVmId());
VMSnapshotVO vmSnapshotVO = (VMSnapshotVO) vmSnapshot;
try {
vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshotVO, VMSnapshot.Event.CreateRequested);
} catch (NoTransitionException e) {
throw new CloudRuntimeException(e.getMessage());
}
boolean result = false;
try {
Map<String, String> srcVolumeDestSnapshotMap = new HashMap<>();
List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(userVm.getId());
final Long storagePoolId = vmSnapshotHelper.getStoragePoolForVM(userVm.getId());
StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
long prev_chain_size = 0;
long virtual_size = 0;
for (VolumeObjectTO volume : volumeTOs) {
String volumeSnapshotName = String.format("%s-%s-%s-%s-%s", ScaleIOUtil.VMSNAPSHOT_PREFIX, vmSnapshotVO.getId(), volume.getId(), storagePool.getUuid().split("-")[0].substring(4), ManagementServerImpl.customCsIdentifier.value());
srcVolumeDestSnapshotMap.put(ScaleIOUtil.getVolumePath(volume.getPath()), volumeSnapshotName);
virtual_size += volume.getSize();
VolumeVO volumeVO = volumeDao.findById(volume.getId());
prev_chain_size += volumeVO.getVmSnapshotChainSize() == null ? 0 : volumeVO.getVmSnapshotChainSize();
}
VMSnapshotTO current = null;
VMSnapshotVO currentSnapshot = vmSnapshotDao.findCurrentSnapshotByVmId(userVm.getId());
if (currentSnapshot != null) {
current = vmSnapshotHelper.getSnapshotWithParents(currentSnapshot);
}
if (current == null)
vmSnapshotVO.setParent(null);
else
vmSnapshotVO.setParent(current.getId());
try {
final ScaleIOGatewayClient client = getScaleIOClient(storagePoolId);
SnapshotGroup snapshotGroup = client.takeSnapshot(srcVolumeDestSnapshotMap);
if (snapshotGroup == null) {
throw new CloudRuntimeException("Failed to take VM snapshot on PowerFlex storage pool");
}
String snapshotGroupId = snapshotGroup.getSnapshotGroupId();
List<String> volumeIds = snapshotGroup.getVolumeIds();
if (volumeIds != null && !volumeIds.isEmpty()) {
List<VMSnapshotDetailsVO> vmSnapshotDetails = new ArrayList<VMSnapshotDetailsVO>();
vmSnapshotDetails.add(new VMSnapshotDetailsVO(vmSnapshot.getId(), "SnapshotGroupId", snapshotGroupId, false));
for (int index = 0; index < volumeIds.size(); index++) {
String volumeSnapshotName = srcVolumeDestSnapshotMap.get(ScaleIOUtil.getVolumePath(volumeTOs.get(index).getPath()));
String pathWithScaleIOVolumeName = ScaleIOUtil.updatedPathWithVolumeName(volumeIds.get(index), volumeSnapshotName);
vmSnapshotDetails.add(new VMSnapshotDetailsVO(vmSnapshot.getId(), "Vol_" + volumeTOs.get(index).getId() + "_Snapshot", pathWithScaleIOVolumeName, false));
}
vmSnapshotDetailsDao.saveDetails(vmSnapshotDetails);
}
finalizeCreate(vmSnapshotVO, volumeTOs);
result = true;
LOGGER.debug("Create vm snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName());
long new_chain_size = 0;
for (VolumeObjectTO volumeTo : volumeTOs) {
publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_CREATE, vmSnapshot, userVm, volumeTo);
new_chain_size += volumeTo.getSize();
}
publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_ON_PRIMARY, vmSnapshot, userVm, new_chain_size - prev_chain_size, virtual_size);
return vmSnapshot;
} catch (Exception e) {
String errMsg = "Unable to take vm snapshot due to: " + e.getMessage();
LOGGER.warn(errMsg, e);
throw new CloudRuntimeException(errMsg);
}
} finally {
if (!result) {
try {
vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
String subject = "Take snapshot failed for VM: " + userVm.getDisplayName();
String message = "Snapshot operation failed for VM: " + userVm.getDisplayName() + ", Please check and delete if any stale volumes created with VM snapshot id: " + vmSnapshot.getVmId();
alertManager.sendAlert(AlertManager.AlertType.ALERT_TYPE_VM_SNAPSHOT, userVm.getDataCenterId(), userVm.getPodIdToDeployIn(), subject, message);
} catch (NoTransitionException e1) {
LOGGER.error("Cannot set vm snapshot state due to: " + e1.getMessage());
}
}
}
}
use of org.apache.cloudstack.storage.datastore.api.SnapshotGroup in project cloudstack by apache.
the class ScaleIOGatewayClientImpl method takeSnapshot.
@Override
public Volume takeSnapshot(final String volumeId, final String snapshotVolumeName) {
Preconditions.checkArgument(StringUtils.isNotEmpty(volumeId), "Volume id cannot be null");
Preconditions.checkArgument(StringUtils.isNotEmpty(snapshotVolumeName), "Snapshot name cannot be null");
final SnapshotDef[] snapshotDef = new SnapshotDef[1];
snapshotDef[0] = new SnapshotDef();
snapshotDef[0].setVolumeId(volumeId);
snapshotDef[0].setSnapshotName(snapshotVolumeName);
final SnapshotDefs snapshotDefs = new SnapshotDefs();
snapshotDefs.setSnapshotDefs(snapshotDef);
SnapshotGroup snapshotGroup = post("/instances/System/action/snapshotVolumes", snapshotDefs, SnapshotGroup.class);
if (snapshotGroup != null) {
List<String> volumeIds = snapshotGroup.getVolumeIds();
if (volumeIds != null && !volumeIds.isEmpty()) {
return getVolume(volumeIds.get(0));
}
}
return null;
}
Aggregations