/*
* Copyright 2016 Dell Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.emc.storageos.driver.dellsc.helpers;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.driver.dellsc.DellSCDriverException;
import com.emc.storageos.driver.dellsc.DellSCDriverTask;
import com.emc.storageos.driver.dellsc.DellSCUtil;
import com.emc.storageos.driver.dellsc.scapi.StorageCenterAPI;
import com.emc.storageos.driver.dellsc.scapi.StorageCenterAPIException;
import com.emc.storageos.driver.dellsc.scapi.objects.ScReplay;
import com.emc.storageos.storagedriver.DriverTask;
import com.emc.storageos.storagedriver.DriverTask.TaskStatus;
import com.emc.storageos.storagedriver.model.VolumeSnapshot;
import com.emc.storageos.storagedriver.storagecapabilities.StorageCapabilities;
/**
* Snapshot handling.
*/
public class DellSCSnapshots {
private static final Logger LOG = LoggerFactory.getLogger(DellSCSnapshots.class);
private DellSCConnectionManager connectionManager;
private DellSCUtil util;
/**
* Initialize the instance.
*/
public DellSCSnapshots() {
this.connectionManager = DellSCConnectionManager.getInstance();
this.util = DellSCUtil.getInstance();
}
/**
* Create volume snapshots.
*
* @param snapshots The list of snapshots to create.
* @param storageCapabilities The requested capabilities of the snapshots.
* @return The snapshot creation task.
*/
public DriverTask createVolumeSnapshot(List<VolumeSnapshot> snapshots, StorageCapabilities storageCapabilities) {
DellSCDriverTask task = new DellSCDriverTask("createVolumeSnapshot");
StringBuilder errBuffer = new StringBuilder();
int createCount = 0;
for (VolumeSnapshot snapshot : snapshots) {
try {
StorageCenterAPI api = connectionManager.getConnection(snapshot.getStorageSystemId());
// Make sure we can create a replay.
// Automated tests have an artificial workflow where they create a volume
// and try to create a snapshot without ever having data written to it. The
// SC array will not activate a volume until it is mapped, so if we try to
// create a snapshot right away it will fail. As a workaround, since we know
// this should only ever happen in a test scenario, we temporarily map/unmap
// it to get it to be activated.
api.checkAndInitVolume(snapshot.getParentId());
ScReplay replay = api.createReplay(snapshot.getParentId());
util.getVolumeSnapshotFromReplay(replay, snapshot);
createCount++;
} catch (DellSCDriverException | StorageCenterAPIException dex) {
String error = String.format(
"Error creating snapshot of volume %s: %s", snapshot.getParentId(), dex);
errBuffer.append(String.format("%s%n", error));
}
}
task.setMessage(errBuffer.toString());
if (createCount == snapshots.size()) {
task.setStatus(TaskStatus.READY);
} else if (createCount == 0) {
task.setStatus(TaskStatus.FAILED);
} else {
task.setStatus(TaskStatus.PARTIALLY_FAILED);
}
return task;
}
/**
* Restore volumes to a snapshot point in time.
* NOTE: not currently supported.
*
* @param snapshots The snapshots to restore to.
* @return The driver task.
*/
public DriverTask restoreSnapshot(List<VolumeSnapshot> snapshots) {
DriverTask task = new DellSCDriverTask("restoreVolumeSnapshot");
// The API to revert a volume to a specific snapshot is currently
// a private call. We can either support this by:
// 1) Creating a volume from the snapshot, perform a copy back to the original, delete volume
// 2) Wait until the snapshot revert call can be made public
// Going with option 2 for now.
task.setStatus(TaskStatus.FAILED);
task.setMessage("Snapshot restore is not supported at this time.");
LOG.warn("Snapshot restore is not supported at this time.");
return null;
}
/**
* Delete a snapshot.
*
* @param snapshot The snapshots to delete.
* @return The delete task.
*/
public DriverTask deleteVolumeSnapshot(VolumeSnapshot snapshot) {
DellSCDriverTask task = new DellSCDriverTask("deleteVolumeSnapshot");
try {
StorageCenterAPI api = connectionManager.getConnection(snapshot.getStorageSystemId());
api.expireReplay(snapshot.getNativeId());
task.setStatus(TaskStatus.READY);
} catch (StorageCenterAPIException | DellSCDriverException dex) {
String error = String.format(
"Error deleting snapshot %s: %s", snapshot.getNativeId(), dex);
LOG.error(error);
task.setFailed(error);
}
return task;
}
}