mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-6941: Can't choose storage for the volume, when attaching uploaded data volume to VM
Changes: - Only way to choose a certain storage pool is by using disk_offering_tags - Added a parameter to take in a disk offering Id. - Admin will have to create a custom sized disk offering and tag it as necessary for the user - This custom offering Id should be passed during uploadVolume to associate the volume with this disk offering
This commit is contained in:
parent
569e94908b
commit
05c01a7dc9
@ -25,6 +25,7 @@ import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||
@ -89,6 +90,9 @@ public class UploadVolumeCmd extends BaseAsyncCmd {
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Upload volume for the project")
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.DISK_OFFERING_ID, required = false, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "the ID of the disk offering. This must be a custom sized offering since during uploadVolume volume size is unknown.")
|
||||
private Long diskOfferingId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -125,6 +129,10 @@ public class UploadVolumeCmd extends BaseAsyncCmd {
|
||||
return imageStoreUuid;
|
||||
}
|
||||
|
||||
public Long getDiskOfferingId() {
|
||||
return diskOfferingId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -247,12 +247,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
String volumeName = cmd.getVolumeName();
|
||||
String url = cmd.getUrl();
|
||||
String format = cmd.getFormat();
|
||||
Long diskOfferingId = cmd.getDiskOfferingId();
|
||||
String imageStoreUuid = cmd.getImageStoreUuid();
|
||||
DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId);
|
||||
|
||||
validateVolume(caller, ownerId, zoneId, volumeName, url, format);
|
||||
validateVolume(caller, ownerId, zoneId, volumeName, url, format, diskOfferingId);
|
||||
|
||||
VolumeVO volume = persistVolume(owner, zoneId, volumeName, url, cmd.getFormat());
|
||||
VolumeVO volume = persistVolume(owner, zoneId, volumeName, url, cmd.getFormat(), diskOfferingId);
|
||||
|
||||
VolumeInfo vol = volFactory.getVolume(volume.getId());
|
||||
|
||||
@ -263,13 +264,15 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
return volume;
|
||||
}
|
||||
|
||||
private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) throws ResourceAllocationException {
|
||||
private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url,
|
||||
String format, Long diskOfferingId) throws ResourceAllocationException {
|
||||
|
||||
// permission check
|
||||
_accountMgr.checkAccess(caller, null, true, _accountMgr.getActiveAccountById(ownerId));
|
||||
Account volumeOwner = _accountMgr.getActiveAccountById(ownerId);
|
||||
_accountMgr.checkAccess(caller, null, true, volumeOwner);
|
||||
|
||||
// Check that the resource limit for volumes won't be exceeded
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.volume);
|
||||
_resourceLimitMgr.checkResourceLimit(volumeOwner, ResourceType.volume);
|
||||
|
||||
// Verify that zone exists
|
||||
DataCenterVO zone = _dcDao.findById(zoneId);
|
||||
@ -316,9 +319,28 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
}
|
||||
UriUtils.validateUrl(url);
|
||||
|
||||
|
||||
// Check that the resource limit for secondary storage won't be exceeded
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
|
||||
|
||||
// Check that the the disk offering specified is valid
|
||||
if (diskOfferingId != null) {
|
||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||
if ((diskOffering == null) || diskOffering.getRemoved() != null
|
||||
|| !DiskOfferingVO.Type.Disk.equals(diskOffering.getType())) {
|
||||
throw new InvalidParameterValueException("Please specify a valid disk offering.");
|
||||
}
|
||||
if (!diskOffering.isCustomized()) {
|
||||
throw new InvalidParameterValueException("Please specify a custom sized disk offering.");
|
||||
}
|
||||
|
||||
if (diskOffering.getDomainId() == null) {
|
||||
// do nothing as offering is public
|
||||
} else {
|
||||
_configMgr.checkDiskOfferingAccess(volumeOwner, diskOffering);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -327,7 +349,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
}
|
||||
|
||||
@DB
|
||||
protected VolumeVO persistVolume(final Account owner, final Long zoneId, final String volumeName, final String url, final String format) {
|
||||
protected VolumeVO persistVolume(final Account owner, final Long zoneId, final String volumeName, final String url,
|
||||
final String format, final Long diskOfferingId) {
|
||||
return Transaction.execute(new TransactionCallback<VolumeVO>() {
|
||||
@Override
|
||||
public VolumeVO doInTransaction(TransactionStatus status) {
|
||||
@ -339,8 +362,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
// TODO Decide if this is valid or whether throwing a CloudRuntimeException is more appropriate
|
||||
volume.setAccountId((owner == null) ? Account.ACCOUNT_ID_SYSTEM : owner.getAccountId());
|
||||
volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId());
|
||||
long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId();
|
||||
volume.setDiskOfferingId(diskOfferingId);
|
||||
|
||||
if (diskOfferingId == null) {
|
||||
long defaultDiskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId();
|
||||
volume.setDiskOfferingId(defaultDiskOfferingId);
|
||||
} else {
|
||||
volume.setDiskOfferingId(diskOfferingId);
|
||||
}
|
||||
// volume.setSize(size);
|
||||
volume.setInstanceId(null);
|
||||
volume.setUpdated(new Date());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user