Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ProjectResponse;
import org.apache.cloudstack.api.response.SnapshotResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
Expand Down Expand Up @@ -109,6 +110,13 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd implements UserC
description = "The ID of the Instance; to be used with snapshot Id, Instance to which the volume gets attached after creation")
private Long virtualMachineId;

@Parameter(name = ApiConstants.STORAGE_ID,
type = CommandType.UUID,
entityType = StoragePoolResponse.class,
description = "Storage pool ID to create the volume in. Exclusive with SnapshotId parameter.",
authorized = {RoleType.Admin})
private Long storageId;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -153,6 +161,13 @@ private Long getProjectId() {
return projectId;
}

public Long getStorageId() {
if (snapshotId != null && storageId != null) {
throw new IllegalArgumentException("StorageId parameter cannot be specified with the SnapshotId parameter.");
}
return storageId;
}

public Boolean getDisplayVolume() {
return displayVolume;
}
Expand Down
32 changes: 32 additions & 0 deletions server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,36 @@ public boolean validateVolumeSizeInBytes(long size) {
return true;
}

private VolumeVO createVolumeOnStoragePool(Long volumeId, Long storageId) throws ExecutionException, InterruptedException {
VolumeVO volume = _volsDao.findById(volumeId);
StoragePool destPool = (StoragePool) dataStoreMgr.getDataStore(storageId, DataStoreRole.Primary);
if (destPool == null) {
throw new InvalidParameterValueException("Failed to find the destination storage pool: " + storageId);
} else if (destPool.isInMaintenance()) {
throw new InvalidParameterValueException(String.format("Cannot create volume %s on storage pool %s as the storage pool is in maintenance mode.",
volume.getUuid(), destPool.getName()));
}

if (destPool.getDataCenterId() != volume.getDataCenterId()) {
throw new InvalidParameterValueException(String.format("Cannot create volume %s in zone %s on storage pool %s in zone %s.",
volume.getUuid(), volume.getDataCenterId(), destPool.getUuid(), destPool.getDataCenterId()));
}

DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
if (!doesStoragePoolSupportDiskOffering(destPool, diskOffering)) {
throw new InvalidParameterValueException(String.format("Disk offering: %s is not compatible with the storage pool", diskOffering.getUuid()));
}

DataStore destStore = dataStoreMgr.getDataStore(storageId, DataStoreRole.Primary);
VolumeInfo destVolume = volFactory.getVolume(volumeId, destStore);
AsyncCallFuture<VolumeApiResult> createVolumeFuture = volService.createVolumeAsync(destVolume, destStore);
VolumeApiResult createVolumeResult = createVolumeFuture.get();
if (createVolumeResult.isFailed()) {
throw new CloudRuntimeException("Creation of a dest volume failed: " + createVolumeResult.getResult());
}
return _volsDao.findById(destVolume.getId());
}

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", async = true)
Expand Down Expand Up @@ -1074,6 +1104,8 @@ public VolumeVO createVolume(CreateVolumeCmd cmd) {
throw new CloudRuntimeException(message.toString());
}
}
} else if (cmd.getStorageId() != null) {
volume = createVolumeOnStoragePool(cmd.getEntityId(), cmd.getStorageId());
}
return volume;
} catch (Exception e) {
Expand Down
Loading