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.Parameter;
|
||||||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||||
import org.apache.cloudstack.api.ServerApiException;
|
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.DomainResponse;
|
||||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
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")
|
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Upload volume for the project")
|
||||||
private Long projectId;
|
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 ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -125,6 +129,10 @@ public class UploadVolumeCmd extends BaseAsyncCmd {
|
|||||||
return imageStoreUuid;
|
return imageStoreUuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getDiskOfferingId() {
|
||||||
|
return diskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -247,12 +247,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
String volumeName = cmd.getVolumeName();
|
String volumeName = cmd.getVolumeName();
|
||||||
String url = cmd.getUrl();
|
String url = cmd.getUrl();
|
||||||
String format = cmd.getFormat();
|
String format = cmd.getFormat();
|
||||||
|
Long diskOfferingId = cmd.getDiskOfferingId();
|
||||||
String imageStoreUuid = cmd.getImageStoreUuid();
|
String imageStoreUuid = cmd.getImageStoreUuid();
|
||||||
DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId);
|
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());
|
VolumeInfo vol = volFactory.getVolume(volume.getId());
|
||||||
|
|
||||||
@ -263,13 +264,15 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
return volume;
|
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
|
// 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
|
// 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
|
// Verify that zone exists
|
||||||
DataCenterVO zone = _dcDao.findById(zoneId);
|
DataCenterVO zone = _dcDao.findById(zoneId);
|
||||||
@ -316,9 +319,28 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
UriUtils.validateUrl(url);
|
UriUtils.validateUrl(url);
|
||||||
|
|
||||||
|
|
||||||
// Check that the resource limit for secondary storage won't be exceeded
|
// Check that the resource limit for secondary storage won't be exceeded
|
||||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
|
_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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +349,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DB
|
@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>() {
|
return Transaction.execute(new TransactionCallback<VolumeVO>() {
|
||||||
@Override
|
@Override
|
||||||
public VolumeVO doInTransaction(TransactionStatus status) {
|
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
|
// 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.setAccountId((owner == null) ? Account.ACCOUNT_ID_SYSTEM : owner.getAccountId());
|
||||||
volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId());
|
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.setSize(size);
|
||||||
volume.setInstanceId(null);
|
volume.setInstanceId(null);
|
||||||
volume.setUpdated(new Date());
|
volume.setUpdated(new Date());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user