Skip to content

Commit efbf9c8

Browse files
committed
Move ExtractVolumeCmd from ManagementServerImpl to VolumeManagerImpl,
also add support for S3 for ExtractVolumeCmd.
1 parent 0a52289 commit efbf9c8

7 files changed

Lines changed: 344 additions & 218 deletions

File tree

api/src/com/cloud/server/ManagementService.java

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -240,20 +240,6 @@ public interface ManagementService {
240240

241241
Map<String, Object> listCapabilities(ListCapabilitiesCmd cmd);
242242

243-
/**
244-
* Extracts the volume to a particular location.
245-
*
246-
* @param cmd
247-
* the command specifying url (where the volume needs to be extracted to), zoneId (zone where the volume
248-
* exists),
249-
* id (the id of the volume)
250-
* @throws URISyntaxException
251-
* @throws InternalErrorException
252-
* @throws PermissionDeniedException
253-
*
254-
*/
255-
Long extractVolume(ExtractVolumeCmd cmd) throws URISyntaxException;
256-
257243
/**
258244
* return an array of available hypervisors
259245
*
@@ -381,7 +367,7 @@ Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boo
381367
* @return List of capacities
382368
*/
383369
List<? extends Capacity> listTopConsumedResources(ListCapacityCmd cmd);
384-
370+
385371
List<String> listDeploymentPlanners();
386372

387373
VirtualMachine upgradeSystemVM(ScaleSystemVMCmd cmd) throws ResourceUnavailableException, ManagementServerException, VirtualMachineMigrationException, ConcurrentOperationException;

api/src/com/cloud/storage/VolumeApiService.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@
1818
*/
1919
package com.cloud.storage;
2020

21+
import java.net.URISyntaxException;
22+
2123
import org.apache.cloudstack.api.command.user.volume.*;
2224

2325
import com.cloud.exception.ConcurrentOperationException;
26+
import com.cloud.exception.InternalErrorException;
2427
import com.cloud.exception.PermissionDeniedException;
2528
import com.cloud.exception.ResourceAllocationException;
2629
import com.cloud.user.Account;
@@ -36,7 +39,7 @@ public interface VolumeApiService {
3639
* @throws PermissionDeniedException
3740
*/
3841
Volume allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException;
39-
42+
4043
/**
4144
* Creates the volume based on the given criteria
4245
*
@@ -50,7 +53,7 @@ public interface VolumeApiService {
5053

5154
/**
5255
* Resizes the volume based on the given criteria
53-
*
56+
*
5457
* @param cmd
5558
* the API command wrapping the criteria
5659
* @return the volume object
@@ -77,8 +80,22 @@ public interface VolumeApiService {
7780

7881
Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account)
7982
throws ResourceAllocationException;
80-
83+
8184
Snapshot allocSnapshot(Long volumeId, Long policyId)
8285
throws ResourceAllocationException;
8386
Volume updateVolume(UpdateVolumeCmd updateVolumeCmd);
87+
88+
/**
89+
* Extracts the volume to a particular location.
90+
*
91+
* @param cmd
92+
* the command specifying url (where the volume needs to be extracted to), zoneId (zone where the volume
93+
* exists),
94+
* id (the id of the volume)
95+
* @throws URISyntaxException
96+
* @throws InternalErrorException
97+
* @throws PermissionDeniedException
98+
*
99+
*/
100+
Long extractVolume(ExtractVolumeCmd cmd);
84101
}

api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ public String getEventDescription() {
126126

127127
@Override
128128
public void execute(){
129-
try {
129+
// try {
130130
UserContext.current().setEventDetails("Volume Id: "+getId());
131-
Long uploadId = _mgr.extractVolume(this);
131+
Long uploadId = _volumeService.extractVolume(this);
132132
if (uploadId != null){
133133
Upload uploadInfo = _entityMgr.findById(Upload.class, uploadId);
134134
ExtractResponse response = new ExtractResponse();
@@ -150,9 +150,9 @@ public void execute(){
150150
} else {
151151
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to extract volume");
152152
}
153-
} catch (URISyntaxException ex) {
154-
s_logger.info(ex);
155-
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
156-
}
153+
// } catch (URISyntaxException ex) {
154+
// s_logger.info(ex);
155+
// throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
156+
// }
157157
}
158158
}

engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import com.cloud.exception.ConcurrentOperationException;
6666
import com.cloud.exception.ResourceAllocationException;
6767
import com.cloud.host.Host;
68+
import com.cloud.storage.DataStoreRole;
6869
import com.cloud.storage.StoragePool;
6970
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
7071
import com.cloud.storage.Volume;
@@ -635,13 +636,73 @@ protected Void copyVolumeFromImageToPrimaryCallback(
635636
return null;
636637
}
637638

639+
640+
protected AsyncCallFuture<VolumeApiResult> copyVolumeFromPrimaryToImage(VolumeInfo srcVolume, DataStore destStore) {
641+
AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
642+
VolumeApiResult res = new VolumeApiResult(srcVolume);
643+
VolumeInfo destVolume = null;
644+
try {
645+
destVolume = (VolumeInfo)destStore.create(srcVolume);
646+
destVolume.processEvent(Event.CreateOnlyRequested);
647+
srcVolume.processEvent(Event.CopyingRequested); // this is just used for locking that src volume record in DB to avoid using lock
648+
649+
CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume,
650+
destVolume,
651+
destStore);
652+
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
653+
caller.setCallback(caller.getTarget().copyVolumeFromPrimaryToImageCallback(null, null))
654+
.setContext(context);
655+
656+
motionSrv.copyAsync(srcVolume, destVolume, caller);
657+
return future;
658+
} catch (Exception e) {
659+
s_logger.error("failed to copy volume to image store", e);
660+
if (destVolume != null) {
661+
destVolume.processEvent(Event.OperationFailed);
662+
}
663+
srcVolume.processEvent(Event.OperationFailed); // unlock source volume record
664+
res.setResult(e.toString());
665+
future.complete(res);
666+
return future;
667+
}
668+
}
669+
670+
protected Void copyVolumeFromPrimaryToImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
671+
VolumeInfo srcVolume = context.srcVolume;
672+
VolumeInfo destVolume = context.destVolume;
673+
CopyCommandResult result = callback.getResult();
674+
AsyncCallFuture<VolumeApiResult> future = context.future;
675+
VolumeApiResult res = new VolumeApiResult(destVolume);
676+
try {
677+
if (res.isFailed()) {
678+
destVolume.processEvent(Event.OperationFailed);
679+
srcVolume.processEvent(Event.OperationFailed);
680+
res.setResult(result.getResult());
681+
future.complete(res);
682+
}else{
683+
srcVolume.processEvent(Event.OperationSuccessed);
684+
destVolume.processEvent(Event.OperationSuccessed, result.getAnswer());
685+
future.complete(res);
686+
}
687+
} catch (Exception e) {
688+
res.setResult(e.toString());
689+
future.complete(res);
690+
}
691+
return null;
692+
}
693+
694+
638695
@Override
639696
public AsyncCallFuture<VolumeApiResult> copyVolume(VolumeInfo srcVolume, DataStore destStore) {
640697

641698
if (srcVolume.getState() == Volume.State.Uploaded) {
642699
return copyVolumeFromImageToPrimary(srcVolume, destStore);
643700
}
644701

702+
if (destStore.getRole() == DataStoreRole.Image) {
703+
return copyVolumeFromPrimaryToImage(srcVolume, destStore);
704+
}
705+
645706
AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
646707
VolumeApiResult res = new VolumeApiResult(srcVolume);
647708
try {
@@ -1056,7 +1117,7 @@ public void handleVolumeSync(DataStore store) {
10561117
* for (Long uniqueName : volumeInfos.keySet()) { TemplateProp vInfo =
10571118
* volumeInfos.get(uniqueName);
10581119
* expungeVolumeAsync(volFactory.getVolume(vInfo.getId(), store));
1059-
*
1120+
*
10601121
* String description = "Deleted volume " + vInfo.getTemplateName() +
10611122
* " on image store " + storeId; s_logger.info(description); }
10621123
*/

0 commit comments

Comments
 (0)