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:
Prachi Damle 2014-06-18 16:09:51 -07:00
parent 569e94908b
commit 05c01a7dc9
2 changed files with 44 additions and 8 deletions

View File

@ -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///////////////////
/////////////////////////////////////////////////////

View File

@ -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());