diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index f54dfef865f..18edbc3a1b3 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -35,7 +35,8 @@ public interface Volume extends ControlledEntity, BasedOn, StateObject + diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CommandResult.java b/engine/storage/src/org/apache/cloudstack/storage/command/CommandResult.java index 998f35dd06b..d1528635945 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CommandResult.java +++ b/engine/storage/src/org/apache/cloudstack/storage/command/CommandResult.java @@ -23,7 +23,7 @@ public class CommandResult { private String result; public CommandResult() { - this.success = false; + this.success = true; this.result = ""; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeAnswer.java b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeAnswer.java index cfed00c60ab..42674de3cf2 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeAnswer.java +++ b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeAnswer.java @@ -32,6 +32,10 @@ public class CreateVolumeAnswer extends Answer { super(cmd); this.volumeUuid = volumeUuid; } + + public CreateVolumeAnswer(Command cmd, boolean status, String result) { + super(cmd, status, result); + } public String getVolumeUuid() { return this.volumeUuid; diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeCommand.java b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeCommand.java index e42d2651f51..c44970e36ff 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeCommand.java +++ b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeCommand.java @@ -23,11 +23,11 @@ import org.apache.cloudstack.storage.to.VolumeTO; import com.cloud.agent.api.Command; public class CreateVolumeCommand extends Command implements StorageSubSystemCommand { - protected VolumeTO volumeInfo; + protected VolumeTO volumeTO; - public CreateVolumeCommand(VolumeTO volumeInfo) { + public CreateVolumeCommand(VolumeTO volumeTO) { super(); - this.volumeInfo = volumeInfo; + this.volumeTO = volumeTO; } protected CreateVolumeCommand() { @@ -39,5 +39,9 @@ public class CreateVolumeCommand extends Command implements StorageSubSystemComm // TODO Auto-generated method stub return false; } + + public VolumeTO getVolume() { + return this.volumeTO; + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/DeleteVolume.java b/engine/storage/src/org/apache/cloudstack/storage/command/DeleteVolumeCommand.java similarity index 74% rename from engine/storage/src/org/apache/cloudstack/storage/command/DeleteVolume.java rename to engine/storage/src/org/apache/cloudstack/storage/command/DeleteVolumeCommand.java index 755d7f8294b..a30a83b1448 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/DeleteVolume.java +++ b/engine/storage/src/org/apache/cloudstack/storage/command/DeleteVolumeCommand.java @@ -18,17 +18,17 @@ */ package org.apache.cloudstack.storage.command; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.storage.to.VolumeTO; import com.cloud.agent.api.Command; -public class DeleteVolume extends Command { - - public DeleteVolume(VolumeInfo volume) { - +public class DeleteVolumeCommand extends Command implements StorageSubSystemCommand { + private VolumeTO volume; + public DeleteVolumeCommand(VolumeTO volume) { + this.volume = volume; } - protected DeleteVolume() { + protected DeleteVolumeCommand() { } @Override @@ -36,5 +36,9 @@ public class DeleteVolume extends Command { // TODO Auto-generated method stub return false; } + + public VolumeTO getVolume() { + return this.volume; + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java index fca97916032..51c8696b421 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java @@ -36,7 +36,7 @@ public interface PrimaryDataStore extends PrimaryDataStoreInfo { List getVolumes(); - boolean deleteVolume(VolumeInfo volume); + void deleteVolumeAsync(VolumeInfo volume, AsyncCompletionCallback callback); void createVolumeAsync(VolumeInfo vo, VolumeDiskType diskType, AsyncCompletionCallback callback); diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java index 6b8ab759f50..8ec117c605d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java @@ -11,6 +11,7 @@ public class VolumeTO { private final VolumeDiskType diskType; private PrimaryDataStoreTO dataStore; private final String name; + private final long size; public VolumeTO(VolumeInfo volume) { this.uuid = volume.getUuid(); this.path = volume.getPath(); @@ -22,6 +23,7 @@ public class VolumeTO { this.dataStore = null; } this.name = volume.getName(); + this.size = volume.getSize(); } public String getUuid() { @@ -51,4 +53,8 @@ public class VolumeTO { public String getName() { return this.name; } + + public long getSize() { + return this.size; + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java index c3bdf4e059a..f3e07e74d0d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java @@ -146,10 +146,6 @@ public class VolumeEntityImpl implements VolumeEntity { } - @Override - public void destroy() { - //vs.deleteVolume(volumeInfo); - } @Override public long getSize() { @@ -190,7 +186,7 @@ public class VolumeEntityImpl implements VolumeEntity { } - private Void createVolumeFromTemplateAsyncCallback(AsyncCallbackDispatcher callback, Object context) { + public Object createVolumeFromTemplateAsyncCallback(AsyncCallbackDispatcher callback, Object context) { synchronized (volumeInfo) { volumeInfo.notify(); } @@ -216,7 +212,33 @@ public class VolumeEntityImpl implements VolumeEntity { } } - private Void createVolumeCallback(AsyncCallbackDispatcher callback, Object context) { + public Void createVolumeCallback(AsyncCallbackDispatcher callback, Object context) { + synchronized (volumeInfo) { + this.result = callback.getResult(); + volumeInfo.notify(); + } + return null; + } + + + @Override + public void destroy() { + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().destroyCallback(null, null)); + vs.deleteVolumeAsync(volumeInfo, caller); + try { + synchronized (volumeInfo) { + volumeInfo.wait(); + } + if (!result.isSuccess()) { + throw new CloudRuntimeException("Failed to create volume:" + result.getResult()); + } + } catch (InterruptedException e) { + throw new CloudRuntimeException("wait volume info failed", e); + } + } + + public Void destroyCallback(AsyncCallbackDispatcher callback, Object context) { synchronized (volumeInfo) { this.result = callback.getResult(); volumeInfo.notify(); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java index 3d3ce68cc55..571f227667a 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java @@ -111,8 +111,13 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { } @Override - public boolean deleteVolume(VolumeInfo volume) { - return this.driver.deleteVolume((VolumeObject)volume); + public void deleteVolumeAsync(VolumeInfo volume, AsyncCompletionCallback callback) { + CommandResult result = new CommandResult(); + if (volume.isAttachedVM()) { + result.setResult("Can't delete volume: " + volume.getId() + ", if it's attached to a VM"); + callback.complete(result); + } + this.driver.deleteVolumeAsync((VolumeObject)volume, callback); } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java index 88eeca250f8..5567037501e 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java @@ -12,7 +12,7 @@ import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CreateVolumeAnswer; import org.apache.cloudstack.storage.command.CreateVolumeCommand; import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand; -import org.apache.cloudstack.storage.command.DeleteVolume; +import org.apache.cloudstack.storage.command.DeleteVolumeCommand; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; import org.apache.cloudstack.storage.to.VolumeTO; @@ -72,7 +72,7 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver ep.sendMessageAsync(createCmd, caller); } - protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { + public Void createVolumeAsyncCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { CommandResult result = new CommandResult(); CreateVolumeAnswer volAnswer = (CreateVolumeAnswer) callback.getResult(); if (volAnswer.getResult()) { @@ -85,14 +85,27 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver context.getParentCallback().complete(result); return null; } - + @Override - public boolean deleteVolume(VolumeObject vo) { - DeleteVolume cmd = new DeleteVolume((VolumeInfo)vo); + public void deleteVolumeAsync(VolumeObject vo, AsyncCompletionCallback callback) { + DeleteVolumeCommand cmd = new DeleteVolumeCommand(this.dataStore.getVolumeTO(vo)); List endPoints = vo.getDataStore().getEndPoints(); - sendOutCommand(cmd, endPoints); - - return true; + EndPoint ep = endPoints.get(0); + AsyncRpcConext context = new AsyncRpcConext(callback); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null)) + .setContext(context); + ep.sendMessageAsync(cmd, caller); + } + + public Void deleteVolumeCallback(AsyncCallbackDispatcher callback, AsyncRpcConext context) { + CommandResult result = new CommandResult(); + Answer answer = callback.getResult(); + if (!answer.getResult()) { + result.setResult(answer.getDetails()); + } + context.getParentCallback().complete(result); + return null; } @Override @@ -106,33 +119,6 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver // TODO Auto-generated method stub return true; } - - protected Answer sendOutCommand(Command cmd, List endPoints) { - Answer answer = null; - int retries = 3; - int i = 0; - for (EndPoint ep : endPoints) { - answer = ep.sendMessage(cmd); - if (answer == null || answer.getDetails() != null) { - if (i < retries) { - s_logger.debug("create volume failed, retrying: " + i); - } - i++; - } else { - break; - } - } - - if (answer == null || answer.getDetails() != null) { - if (answer == null) { - throw new CloudRuntimeException("Failed to created volume"); - } else { - throw new CloudRuntimeException(answer.getDetails()); - } - } - - return answer; - } private class CreateVolumeFromBaseImageContext extends AsyncRpcConext { private final VolumeObject volume; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java index 96e629e2447..eca7d798cf6 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java @@ -14,7 +14,7 @@ public interface PrimaryDataStoreDriver { void createVolumeFromBaseImageAsync(VolumeObject volume, TemplateOnPrimaryDataStoreInfo template, AsyncCompletionCallback callback); - boolean deleteVolume(VolumeObject vo); + void deleteVolumeAsync(VolumeObject vo, AsyncCompletionCallback callback); String grantAccess(VolumeObject vol, EndPoint ep); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java index 76f0b034cb4..98c6b69ee0f 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeManagerImpl.java @@ -54,18 +54,18 @@ public class VolumeManagerImpl implements VolumeManager { private void initStateMachine() { s_fsm.addTransition(Volume.State.Allocated, Event.CreateRequested, Volume.State.Creating); - s_fsm.addTransition(Volume.State.Allocated, Event.DestroyRequested, Volume.State.Destroy); + s_fsm.addTransition(Volume.State.Allocated, Event.DestroyRequested, Volume.State.Destroying); s_fsm.addTransition(Volume.State.Creating, Event.OperationRetry, Volume.State.Creating); s_fsm.addTransition(Volume.State.Creating, Event.OperationFailed, Volume.State.Allocated); s_fsm.addTransition(Volume.State.Creating, Event.OperationSucceeded, Volume.State.Ready); - s_fsm.addTransition(Volume.State.Creating, Event.DestroyRequested, Volume.State.Destroy); + s_fsm.addTransition(Volume.State.Creating, Event.DestroyRequested, Volume.State.Destroying); s_fsm.addTransition(Volume.State.Creating, Event.CreateRequested, Volume.State.Creating); s_fsm.addTransition(Volume.State.Allocated, Event.UploadRequested, Volume.State.UploadOp); s_fsm.addTransition(Volume.State.UploadOp, Event.CopyRequested, Volume.State.Creating);// CopyRequested for volume from sec to primary storage s_fsm.addTransition(Volume.State.Creating, Event.CopySucceeded, Volume.State.Ready); s_fsm.addTransition(Volume.State.Creating, Event.CopyFailed, Volume.State.UploadOp);// Copying volume from sec to primary failed. - s_fsm.addTransition(Volume.State.UploadOp, Event.DestroyRequested, Volume.State.Destroy); - s_fsm.addTransition(Volume.State.Ready, Event.DestroyRequested, Volume.State.Destroy); + s_fsm.addTransition(Volume.State.UploadOp, Event.DestroyRequested, Volume.State.Destroying); + s_fsm.addTransition(Volume.State.Ready, Event.DestroyRequested, Volume.State.Destroying); s_fsm.addTransition(Volume.State.Destroy, Event.ExpungingRequested, Volume.State.Expunging); s_fsm.addTransition(Volume.State.Ready, Event.SnapshotRequested, Volume.State.Snapshotting); s_fsm.addTransition(Volume.State.Snapshotting, Event.OperationSucceeded, Volume.State.Ready); @@ -74,6 +74,9 @@ public class VolumeManagerImpl implements VolumeManager { s_fsm.addTransition(Volume.State.Migrating, Event.OperationSucceeded, Volume.State.Ready); s_fsm.addTransition(Volume.State.Migrating, Event.OperationFailed, Volume.State.Ready); s_fsm.addTransition(Volume.State.Destroy, Event.OperationSucceeded, Volume.State.Destroy); + s_fsm.addTransition(Volume.State.Destroying, Event.OperationSucceeded, Volume.State.Destroy); + s_fsm.addTransition(Volume.State.Destroying, Event.OperationFailed, Volume.State.Destroying); + s_fsm.addTransition(Volume.State.Destroying, Event.DestroyRequested, Volume.State.Destroying); } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index b8c76316e30..a1eeb65b487 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -158,4 +158,9 @@ public class VolumeObject implements VolumeInfo { public String getName() { return this.volumeVO.getName(); } + + @Override + public boolean isAttachedVM() { + return (this.volumeVO.getInstanceId() == null) ? false : true; + } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 815033a477a..445e6b3d9b3 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -98,7 +98,7 @@ public class VolumeServiceImpl implements VolumeService { dataStore.createVolumeAsync(vo, diskType, caller); } - protected Void createVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { + public Void createVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { CommandResult result = callback.getResult(); VolumeObject vo = context.getVolume(); VolumeApiResult volResult = new VolumeApiResult(vo); @@ -112,11 +112,55 @@ public class VolumeServiceImpl implements VolumeService { context.getParentCallback().complete(volResult); return null; } + + private class DeleteVolumeContext extends AsyncRpcConext { + private final VolumeObject volume; + /** + * @param callback + */ + public DeleteVolumeContext(AsyncCompletionCallback callback, VolumeObject volume) { + super(callback); + this.volume = volume; + } + + public VolumeObject getVolume() { + return this.volume; + } + } @DB @Override public void deleteVolumeAsync(VolumeInfo volume, AsyncCompletionCallback callback) { + VolumeObject vo = (VolumeObject)volume; + PrimaryDataStore dataStore = vo.getDataStore(); + vo.stateTransit(Volume.Event.DestroyRequested); + if (dataStore == null) { + vo.stateTransit(Volume.Event.OperationSucceeded); + volDao.remove(vo.getId()); + return; + } + DeleteVolumeContext context = new DeleteVolumeContext(callback, vo); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null)) + .setContext(context); + + dataStore.deleteVolumeAsync(volume, caller); + } + + public Void deleteVolumeCallback(AsyncCallbackDispatcher callback, DeleteVolumeContext context) { + CommandResult result = callback.getResult(); + VolumeObject vo = context.getVolume(); + VolumeApiResult apiResult = new VolumeApiResult(vo); + if (result.isSuccess()) { + vo.stateTransit(Volume.Event.OperationSucceeded); + volDao.remove(vo.getId()); + } else { + vo.stateTransit(Volume.Event.OperationFailed); + apiResult.setResult(result.getResult()); + } + context.getParentCallback().complete(apiResult); + return null; } @Override diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 031d0e00e76..7322e02808d 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -34,7 +34,9 @@ import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageCmd; import org.apache.cloudstack.storage.command.CopyTemplateToPrimaryStorageAnswer; import org.apache.cloudstack.storage.command.CreatePrimaryDataStoreCmd; import org.apache.cloudstack.storage.command.CreateVolumeAnswer; +import org.apache.cloudstack.storage.command.CreateVolumeCommand; import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand; +import org.apache.cloudstack.storage.command.DeleteVolumeCommand; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.datastore.protocol.DataStoreProtocol; import org.apache.cloudstack.storage.to.ImageDataStoreTO; @@ -72,6 +74,7 @@ import com.xensource.xenapi.PBD; import com.xensource.xenapi.Pool; import com.xensource.xenapi.SR; import com.xensource.xenapi.Types; +import com.xensource.xenapi.VBD; import com.xensource.xenapi.Types.BadServerResponse; import com.xensource.xenapi.Types.XenAPIException; import com.xensource.xenapi.VDI; @@ -93,11 +96,96 @@ public class XenServerStorageResource { return execute((CreatePrimaryDataStoreCmd) command); } else if (command instanceof CreateVolumeFromBaseImageCommand) { return execute((CreateVolumeFromBaseImageCommand)command); + } else if (command instanceof CreateVolumeCommand) { + return execute((CreateVolumeCommand) command); + } else if (command instanceof DeleteVolumeCommand) { + return execute((DeleteVolumeCommand)command); } return new Answer((Command)command, false, "not implemented yet"); } - public Answer execute(CreateVolumeFromBaseImageCommand cmd) { + protected SR getSRByNameLabel(Connection conn, String nameLabel) throws BadServerResponse, XenAPIException, XmlRpcException { + Set srs = SR.getByNameLabel(conn, nameLabel); + if (srs.size() != 1) { + throw new CloudRuntimeException("storage uuid: " + nameLabel + " is not unique"); + } + SR poolsr = srs.iterator().next(); + return poolsr; + } + + protected VDI createVdi(Connection conn, String vdiName, SR sr, long size) throws BadServerResponse, XenAPIException, XmlRpcException { + VDI.Record vdir = new VDI.Record(); + vdir.nameLabel = vdiName; + vdir.SR = sr; + vdir.type = Types.VdiType.USER; + + vdir.virtualSize = size; + VDI vdi = VDI.create(conn, vdir); + return vdi; + } + + protected void deleteVDI(Connection conn, VDI vdi) throws BadServerResponse, XenAPIException, XmlRpcException { + vdi.destroy(conn); + } + + protected CreateVolumeAnswer execute(CreateVolumeCommand cmd) { + VolumeTO volume = cmd.getVolume(); + PrimaryDataStoreTO primaryDataStore = volume.getDataStore(); + Connection conn = hypervisorResource.getConnection(); + VDI vdi = null; + boolean result = false; + String errorMsg = null; + try { + SR primaryDataStoreSR = getSRByNameLabel(conn, primaryDataStore.getUuid()); + vdi = createVdi(conn, volume.getName(), primaryDataStoreSR, volume.getSize()); + VDI.Record record = vdi.getRecord(conn); + result = true; + return new CreateVolumeAnswer(cmd, record.uuid); + } catch (BadServerResponse e) { + s_logger.debug("Failed to create volume", e); + errorMsg = e.toString(); + } catch (XenAPIException e) { + s_logger.debug("Failed to create volume", e); + errorMsg = e.toString(); + } catch (XmlRpcException e) { + s_logger.debug("Failed to create volume", e); + errorMsg = e.toString(); + } finally { + if (!result && vdi != null) { + try { + deleteVDI(conn, vdi); + } catch (Exception e) { + s_logger.debug("Faled to delete vdi: " + vdi.toString()); + } + } + } + + return new CreateVolumeAnswer(cmd, false, errorMsg); + } + + protected Answer execute(DeleteVolumeCommand cmd) { + VolumeTO volume = cmd.getVolume(); + Connection conn = hypervisorResource.getConnection(); + String errorMsg = null; + try { + VDI vdi = VDI.getByUuid(conn, volume.getUuid()); + deleteVDI(conn, vdi); + return new Answer(cmd); + } catch (BadServerResponse e) { + s_logger.debug("Failed to delete volume", e); + errorMsg = e.toString(); + } catch (XenAPIException e) { + s_logger.debug("Failed to delete volume", e); + errorMsg = e.toString(); + } catch (XmlRpcException e) { + s_logger.debug("Failed to delete volume", e); + errorMsg = e.toString(); + } + + return new Answer(cmd, false, errorMsg); + } + + protected Answer execute(CreateVolumeFromBaseImageCommand cmd) { VolumeTO volume = cmd.getVolume(); ImageOnPrimayDataStoreTO baseImage = cmd.getImage(); Connection conn = hypervisorResource.getConnection(); diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java index 54d12c97fc9..afee8b03a96 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java @@ -11,11 +11,6 @@ import org.apache.cloudstack.storage.volume.VolumeObject; public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { - @Override - public boolean deleteVolume(VolumeObject vo) { - // TODO Auto-generated method stub - return false; - } @Override public String grantAccess(VolumeObject vol, EndPoint ep) { @@ -77,4 +72,10 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { } + @Override + public void deleteVolumeAsync(VolumeObject vo, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + + } + }