/* * 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.scapi.SizeUtil; 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.driver.dellsc.scapi.objects.ScVolume; import com.emc.storageos.storagedriver.DriverTask; import com.emc.storageos.storagedriver.DriverTask.TaskStatus; import com.emc.storageos.storagedriver.model.StorageObject.AccessStatus; import com.emc.storageos.storagedriver.model.VolumeClone; import com.emc.storageos.storagedriver.model.VolumeClone.ReplicationState; import com.emc.storageos.storagedriver.model.VolumeClone.SourceType; /** * Helper for cloning operations. */ public class DellSCCloning { private static final Logger LOG = LoggerFactory.getLogger(DellSCCloning.class); private DellSCConnectionManager connectionManager; /** * Initialize the instance. */ public DellSCCloning() { this.connectionManager = DellSCConnectionManager.getInstance(); } /** * Create a clone of a volume. * * @param clones The clones to create. * @return The clone task. */ public DriverTask createVolumeClone(List<VolumeClone> clones) { LOG.info("Creating volume clone"); DellSCDriverTask task = new DellSCDriverTask("createVolumeClone"); StringBuilder errBuffer = new StringBuilder(); int createCount = 0; for (VolumeClone clone : clones) { try { StorageCenterAPI api = connectionManager.getConnection(clone.getStorageSystemId()); ScReplay replay = null; //Make sure volume is active for the automated tests that try to //create temporary snapshot to create the clone from after immediate volume creation api.checkAndInitVolume(clone.getParentId()); if (clone.getSourceType() == SourceType.SNAPSHOT) { replay = api.getReplay(clone.getParentId()); } else { // Create temporary replay to create the clone from replay = api.createReplay(clone.getParentId(), 5); } // Now create a new volume from the snapshot ScVolume scVol = api.createViewVolume(clone.getDisplayName(), replay.instanceId); clone.setProvisionedCapacity(SizeUtil.sizeStrToBytes(scVol.configuredSize)); clone.setAllocatedCapacity(0L); // New volumes don't allocate any space clone.setWwn(scVol.deviceId); clone.setNativeId(scVol.instanceId); clone.setDeviceLabel(scVol.name); clone.setAccessStatus(AccessStatus.READ_WRITE); clone.setReplicationState(ReplicationState.SYNCHRONIZED); createCount++; } catch (DellSCDriverException | StorageCenterAPIException dex) { String error = String.format( "Error creating clone of volume %s: %s", clone.getParentId(), dex); errBuffer.append(String.format("%s%n", error)); } } task.setMessage(errBuffer.toString()); if (createCount == clones.size()) { task.setStatus(TaskStatus.READY); } else if (createCount == 0) { task.setStatus(TaskStatus.FAILED); } else { task.setStatus(TaskStatus.PARTIALLY_FAILED); } return task; } /** * Delete volume clone. * * @param clone The clone to delete. * @return The delete task. */ public DriverTask deleteVolumeClone(VolumeClone clone) { LOG.info("Deleting volume clone {}", clone); DellSCDriverTask task = new DellSCDriverTask("deleteVolumeClone"); try { StorageCenterAPI api = connectionManager.getConnection(clone.getStorageSystemId()); api.deleteVolume(clone.getNativeId()); task.setStatus(TaskStatus.READY); } catch (StorageCenterAPIException | DellSCDriverException dex) { String error = String.format( "Error deleting volume clone %s: %s", clone.getNativeId(), dex); LOG.error(error); task.setFailed(error); } return task; } /** * Detach volume clones. * * @param clones The clones to detach. * @return The detach task. */ public DriverTask detachVolumeClone(List<VolumeClone> clones) { LOG.info("Detaching volume clone"); // Clones are not connected to the original volume, so already "detached". // Potential future optimization: One volume can only have so many snapshots. // We could use this to perform a migrate operation to a new volume to make // the clone completely independent of the source and reduce the snapshot count. DriverTask task = new DellSCDriverTask("detachVolumeClone"); task.setStatus(TaskStatus.READY); return task; } /** * Restore from the volume clone. * * @param clones The clones to restore. * @return The restore task. */ public DriverTask restoreFromClone(List<VolumeClone> clones) { LOG.info("Restore from clone not currently supported."); DriverTask task = new DellSCDriverTask("restoreVolumeClone"); task.setStatus(TaskStatus.FAILED); task.setMessage("Restore from clone not currently supported."); return null; } }