mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
server: Decouple service (compute) offering and disk offering (#5008)
Currently, our compute offerings and disk offerings are tightly coupled with respect to many aspects. For example, if a compute offering is created, a corresponding disk offering entry is also created with the same ID as the reference. Also creating compute offering takes few disk-related parameters which anyway goes to the corresponding disk offering only. I think this design was initially made to address compute offering for the root volume created from a template. Also changing the offering of a volume is tightly coupled with storage tags and has to be done in different APIs either migrateVolume or resizeVolume. Changing of disk offering should be seamless and should consider new storage tags, new size and place the volume in appropriate state as defined in disk offering. more details are mentioned here https://cwiki.apache.org/confluence/display/CLOUDSTACK/Compute+offering+and+disk+offering+refactoring * Schema changes and disk offering column change from "type" to "compute_only" * Few more changes * Decoupled service offering and disk offering * Remove diskofferingid from vminstance VO * Decouple service offering and disk offering states * diskoffering getsize() is only for strict disk offerings * Fix deployVM flow * Added new API params to compute offering creation * Add diskofferingstrictness to serviceoffering vo under quota * Added overrideDiskOfferingId parameter in deploy VM API which will override disk offering for the root disk both in template and ISO case Added diskSizeStrictness parameter in create Disk offering API which will decide whether to restrict resize or disk offering change of a volume * Fix User vm response to show proper service offering and disk offerings * Added disk size strictness in disk offering response * Added disk offering strictness to the service offering response * Remove comments * Added UI changes for Disk offering strictness in add compute offering form and Disk size strictness in add disk offering form * Added diskoffering details to the service offering response * Added UI changes in deployvm wizard to accept override disk offering id * Fix delete compute offering * Fix VM deployment from custom service offering * Move uselocalstorage column access from service offering to disk offering * UI: Separated compute and disk releated parameters in add compute offering wizard, also added association to disk offering * Fixed diskoffering automatic selection on add compute offering wizard * UI: move compute only toggle button outside the box in add compute offering wizard * Added volumeId parameter to listDiskOfferings API and the disksizestrictness flag of the current disk offering is honored while list disk offerings * Added configuration parameter to decide whether to check volume tags on the destination storagepool during migration * Added disk offering change checks during resize volume operation * Added new API changeofferingforVolume API and corresponding changes * Add UI form for changeOfferingForVolume API * Fix UI conflicts * Fix service offering usage as disk offering * Fix unit test failures * fix user_vm_view * Addressed review comments * Fixed service_offering_view * Fix service offering edit flow * Fix service offering constructor to address custom offering * Fix domain_router_view to get proper service offering id * Removed unused import * Addressed review comments and fixed update service offering flow with storage tags * Added marvin test cases for checking disk offering strictness * review comments addressed * Remove system_use column from disk offering join * update volume_view to update system_use column from service offering and not disk offering * Fix changeOfferingForVolume API for custom disk offering * Fix global setting implementation * Fix list volumes, after changing system_use column from disk offering to service offering in volume_view * Changes for override root disk offering in deployvm wizard in case of custom offering * Fix a unit test case * Fixed recent unit test cases with new serviceofferingvo constructor * Fix unit test in VolumeApiServiceImpl * Added storage id for the list disk offering API and corresponding UI changes in migrateVolume and changeOfferingForVolume flow * Rename global configuration parameter from storage.pool.tags.disk.offering.strictness to match.storage.pool.tags.with.disk.offering * Fix smoke test failures * Added tool tip for migrate volume UI form * Address review comments and fix UI form of deploy VM in case of ISO. * Fixed resize volume UI form for data disk * UI changes to disable override root disk size when override root disk offering is enabled * UI fix in deploy vm wizard * Fix listdiskoffering after rebasing with main * Fixed UI in migrate and changeofferingfor volume to handle empty disk offering list Removed the volume's current disk offering from listDiskOffering response list * Added custom Iops to resize volume form and removed the current disk offering during change offering for volume UI form * Fix false response on updateDiskOffering API * Added search field for changeofferingforvolume UI form * Fix resize volume and migrate volume to update volume path if DRS is applied on volume in datastore cluster * Removed DB changes from 4.16 upgrade file * Resolving merge conflicts with main 4.17 * Added support for auto migration and auto resize of the root volume upon changing the service offering for VM. * UI: Added automigrate checkbox in scale VM form * Addes since attributes to new API params * Added shrinkOK parameter to changeofferingforvolume API * Added shrinkOk param to UI in changeOfferingforVolume form * Added shrinkOk flag to scaleVM and changeServiceForVirtualMachines and UI form * Removed old foreign key constraint on IDs of service offering and disk offering * Allow resize and automigrate of root volume if required in all cases of service offering change * Allow only resize to higher disk size from UI * Fixing vue syntax error * Make UI changes to provide root disk size box when the linked disk offering is of custom * Converted from check box to toggle in scale VM, changeoffering, resize and migrate volume forms * Fix resize volume operation to update the VM settings * Fix migratevolume form to pick selected storage pool id in list diskofferings API
This commit is contained in:
parent
b9905c7e37
commit
f15cab16da
@ -258,6 +258,7 @@ public class EventTypes {
|
|||||||
public static final String EVENT_VOLUME_UPDATE = "VOLUME.UPDATE";
|
public static final String EVENT_VOLUME_UPDATE = "VOLUME.UPDATE";
|
||||||
public static final String EVENT_VOLUME_DESTROY = "VOLUME.DESTROY";
|
public static final String EVENT_VOLUME_DESTROY = "VOLUME.DESTROY";
|
||||||
public static final String EVENT_VOLUME_RECOVER = "VOLUME.RECOVER";
|
public static final String EVENT_VOLUME_RECOVER = "VOLUME.RECOVER";
|
||||||
|
public static final String EVENT_VOLUME_CHANGE_DISK_OFFERING = "VOLUME.CHANGE.DISK.OFFERING";
|
||||||
|
|
||||||
// Domains
|
// Domains
|
||||||
public static final String EVENT_DOMAIN_CREATE = "DOMAIN.CREATE";
|
public static final String EVENT_DOMAIN_CREATE = "DOMAIN.CREATE";
|
||||||
@ -768,6 +769,7 @@ public class EventTypes {
|
|||||||
entityEventDetails.put(EVENT_VOLUME_RESIZE, Volume.class);
|
entityEventDetails.put(EVENT_VOLUME_RESIZE, Volume.class);
|
||||||
entityEventDetails.put(EVENT_VOLUME_DESTROY, Volume.class);
|
entityEventDetails.put(EVENT_VOLUME_DESTROY, Volume.class);
|
||||||
entityEventDetails.put(EVENT_VOLUME_RECOVER, Volume.class);
|
entityEventDetails.put(EVENT_VOLUME_RECOVER, Volume.class);
|
||||||
|
entityEventDetails.put(EVENT_VOLUME_CHANGE_DISK_OFFERING, Volume.class);
|
||||||
|
|
||||||
// Domains
|
// Domains
|
||||||
entityEventDetails.put(EVENT_DOMAIN_CREATE, Domain.class);
|
entityEventDetails.put(EVENT_DOMAIN_CREATE, Domain.class);
|
||||||
|
|||||||
@ -34,10 +34,6 @@ public interface DiskOffering extends InfrastructureEntity, Identity, InternalId
|
|||||||
Inactive, Active,
|
Inactive, Active,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Type {
|
|
||||||
Disk, Service
|
|
||||||
};
|
|
||||||
|
|
||||||
State getState();
|
State getState();
|
||||||
|
|
||||||
enum DiskCacheMode {
|
enum DiskCacheMode {
|
||||||
@ -61,8 +57,6 @@ public interface DiskOffering extends InfrastructureEntity, Identity, InternalId
|
|||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
boolean isSystemUse();
|
|
||||||
|
|
||||||
String getDisplayText();
|
String getDisplayText();
|
||||||
|
|
||||||
ProvisioningType getProvisioningType();
|
ProvisioningType getProvisioningType();
|
||||||
@ -152,5 +146,7 @@ public interface DiskOffering extends InfrastructureEntity, Identity, InternalId
|
|||||||
|
|
||||||
void setCacheMode(DiskCacheMode cacheMode);
|
void setCacheMode(DiskCacheMode cacheMode);
|
||||||
|
|
||||||
Type getType();
|
boolean isComputeOnly();
|
||||||
|
|
||||||
|
boolean getDiskSizeStrictness();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,37 +25,34 @@ import org.apache.cloudstack.api.InternalIdentity;
|
|||||||
/**
|
/**
|
||||||
* offered.
|
* offered.
|
||||||
*/
|
*/
|
||||||
public interface ServiceOffering extends DiskOffering, InfrastructureEntity, InternalIdentity, Identity {
|
public interface ServiceOffering extends InfrastructureEntity, InternalIdentity, Identity {
|
||||||
public static final String consoleProxyDefaultOffUniqueName = "Cloud.com-ConsoleProxy";
|
static final String consoleProxyDefaultOffUniqueName = "Cloud.com-ConsoleProxy";
|
||||||
public static final String ssvmDefaultOffUniqueName = "Cloud.com-SecondaryStorage";
|
static final String ssvmDefaultOffUniqueName = "Cloud.com-SecondaryStorage";
|
||||||
public static final String routerDefaultOffUniqueName = "Cloud.Com-SoftwareRouter";
|
static final String routerDefaultOffUniqueName = "Cloud.Com-SoftwareRouter";
|
||||||
public static final String elbVmDefaultOffUniqueName = "Cloud.Com-ElasticLBVm";
|
static final String elbVmDefaultOffUniqueName = "Cloud.Com-ElasticLBVm";
|
||||||
public static final String internalLbVmDefaultOffUniqueName = "Cloud.Com-InternalLBVm";
|
static final String internalLbVmDefaultOffUniqueName = "Cloud.Com-InternalLBVm";
|
||||||
// leaving cloud.com references as these are identifyers and no real world addresses (check against DB)
|
// leaving cloud.com references as these are identifyers and no real world addresses (check against DB)
|
||||||
|
|
||||||
public enum StorageType {
|
enum State {
|
||||||
|
Inactive, Active,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum StorageType {
|
||||||
local, shared
|
local, shared
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
String getDisplayText();
|
String getDisplayText();
|
||||||
|
|
||||||
@Override
|
|
||||||
Date getCreated();
|
Date getCreated();
|
||||||
|
|
||||||
@Override
|
|
||||||
String getTags();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return user readable description
|
* @return user readable description
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return is this a system service offering
|
* @return is this a system service offering
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
boolean isSystemUse();
|
boolean isSystemUse();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,12 +95,6 @@ public interface ServiceOffering extends DiskOffering, InfrastructureEntity, Int
|
|||||||
*/
|
*/
|
||||||
Integer getMulticastRateMbps();
|
Integer getMulticastRateMbps();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return whether or not the service offering requires local storage
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
boolean isUseLocalStorage();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return tag that should be present on the host needed, optional parameter
|
* @return tag that should be present on the host needed, optional parameter
|
||||||
*/
|
*/
|
||||||
@ -117,5 +108,35 @@ public interface ServiceOffering extends DiskOffering, InfrastructureEntity, Int
|
|||||||
|
|
||||||
boolean isDynamic();
|
boolean isDynamic();
|
||||||
|
|
||||||
|
void setState(ServiceOffering.State state);
|
||||||
|
|
||||||
|
ServiceOffering.State getState();
|
||||||
|
|
||||||
|
void setName(String name);
|
||||||
|
|
||||||
|
String getUniqueName();
|
||||||
|
|
||||||
|
void setUniqueName(String uniqueName);
|
||||||
|
|
||||||
|
void setDisplayText(String displayText);
|
||||||
|
|
||||||
|
boolean isCustomized();
|
||||||
|
|
||||||
|
void setCustomized(boolean customized);
|
||||||
|
|
||||||
|
Date getRemoved();
|
||||||
|
|
||||||
|
void setRemoved(Date removed);
|
||||||
|
|
||||||
|
void setSortKey(int key);
|
||||||
|
|
||||||
|
int getSortKey();
|
||||||
|
|
||||||
|
Long getDiskOfferingId();
|
||||||
|
|
||||||
boolean isDynamicScalingEnabled();
|
boolean isDynamicScalingEnabled();
|
||||||
|
|
||||||
|
Boolean getDiskOfferingStrictness();
|
||||||
|
|
||||||
|
void setDiskOfferingStrictness(boolean diskOfferingStrictness);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -394,7 +394,8 @@ public interface ManagementService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* List storage pools for live migrating of a volume. The API returns list of all pools in the cluster to which the
|
* List storage pools for live migrating of a volume. The API returns list of all pools in the cluster to which the
|
||||||
* volume can be migrated. Current pool is not included in the list.
|
* volume can be migrated. Current pool is not included in the list. In case of vSphere datastore cluster storage pools,
|
||||||
|
* this method removes the child storage pools and adds the corresponding parent datastore cluster for API response listing
|
||||||
*
|
*
|
||||||
* @param Long volumeId
|
* @param Long volumeId
|
||||||
* @return Pair<List<? extends StoragePool>, List<? extends StoragePool>> List of storage pools in cluster and list
|
* @return Pair<List<? extends StoragePool>, List<? extends StoragePool>> List of storage pools in cluster and list
|
||||||
@ -402,6 +403,8 @@ public interface ManagementService {
|
|||||||
*/
|
*/
|
||||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(Long volumeId);
|
Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(Long volumeId);
|
||||||
|
|
||||||
|
Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolumeInternal(Long volumeId, Long newDiskOfferingId, Long newSize, Long newMinIops, Long newMaxIops, boolean keepSourceStoragePool);
|
||||||
|
|
||||||
String[] listEventTypes();
|
String[] listEventTypes();
|
||||||
|
|
||||||
Pair<List<? extends HypervisorCapabilities>, Integer> listHypervisorCapabilities(Long id, HypervisorType hypervisorType, String keyword, Long startIndex,
|
Pair<List<? extends HypervisorCapabilities>, Integer> listHypervisorCapabilities(Long id, HypervisorType hypervisorType, String keyword, Long startIndex,
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import java.net.MalformedURLException;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.volume.ChangeOfferingForVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
|
||||||
@ -152,4 +153,6 @@ public interface VolumeApiService {
|
|||||||
Volume destroyVolume(long volumeId, Account caller, boolean expunge, boolean forceExpunge);
|
Volume destroyVolume(long volumeId, Account caller, boolean expunge, boolean forceExpunge);
|
||||||
|
|
||||||
Volume recoverVolume(long volumeId);
|
Volume recoverVolume(long volumeId);
|
||||||
|
|
||||||
|
Volume changeDiskOfferingForVolume(ChangeOfferingForVolumeCmd cmd) throws ResourceAllocationException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,8 @@ public class DiskProfile {
|
|||||||
private Long iopsReadRate;
|
private Long iopsReadRate;
|
||||||
private Long iopsWriteRate;
|
private Long iopsWriteRate;
|
||||||
private String cacheMode;
|
private String cacheMode;
|
||||||
|
private Long minIops;
|
||||||
|
private Long maxIops;
|
||||||
|
|
||||||
private HypervisorType hyperType;
|
private HypervisorType hyperType;
|
||||||
|
|
||||||
@ -227,4 +229,22 @@ public class DiskProfile {
|
|||||||
public String getCacheMode() {
|
public String getCacheMode() {
|
||||||
return cacheMode;
|
return cacheMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Long getMinIops() {
|
||||||
|
return minIops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinIops(Long minIops) {
|
||||||
|
this.minIops = minIops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getMaxIops() {
|
||||||
|
return maxIops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxIops(Long maxIops) {
|
||||||
|
this.maxIops = maxIops;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -218,7 +218,7 @@ public interface UserVmService {
|
|||||||
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
|
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
|
||||||
List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
|
List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
|
||||||
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
||||||
Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled) throws InsufficientCapacityException,
|
Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId) throws InsufficientCapacityException,
|
||||||
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
|
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -300,7 +300,7 @@ public interface UserVmService {
|
|||||||
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
|
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
|
||||||
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
|
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
|
||||||
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
||||||
Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled) throws InsufficientCapacityException,
|
Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId) throws InsufficientCapacityException,
|
||||||
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
|
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -379,7 +379,7 @@ public interface UserVmService {
|
|||||||
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
|
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
|
||||||
String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
|
String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
|
||||||
Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
||||||
Map<String, String> templateOvfPropertiesMap, boolean dynamicScalingEnabled, String type)
|
Map<String, String> templateOvfPropertiesMap, boolean dynamicScalingEnabled, String type, Long overrideDiskOfferingId)
|
||||||
|
|
||||||
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
|
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
|
||||||
|
|
||||||
|
|||||||
@ -323,8 +323,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Partition,
|
|||||||
|
|
||||||
long getServiceOfferingId();
|
long getServiceOfferingId();
|
||||||
|
|
||||||
Long getDiskOfferingId();
|
|
||||||
|
|
||||||
Long getBackupOfferingId();
|
Long getBackupOfferingId();
|
||||||
|
|
||||||
String getBackupExternalId();
|
String getBackupExternalId();
|
||||||
|
|||||||
@ -112,12 +112,15 @@ public class ApiConstants {
|
|||||||
public static final String DISK = "disk";
|
public static final String DISK = "disk";
|
||||||
public static final String DISK_OFFERING_ID = "diskofferingid";
|
public static final String DISK_OFFERING_ID = "diskofferingid";
|
||||||
public static final String NEW_DISK_OFFERING_ID = "newdiskofferingid";
|
public static final String NEW_DISK_OFFERING_ID = "newdiskofferingid";
|
||||||
|
public static final String OVERRIDE_DISK_OFFERING_ID = "overridediskofferingid";
|
||||||
public static final String DISK_KBS_READ = "diskkbsread";
|
public static final String DISK_KBS_READ = "diskkbsread";
|
||||||
public static final String DISK_KBS_WRITE = "diskkbswrite";
|
public static final String DISK_KBS_WRITE = "diskkbswrite";
|
||||||
public static final String DISK_IO_READ = "diskioread";
|
public static final String DISK_IO_READ = "diskioread";
|
||||||
public static final String DISK_IO_WRITE = "diskiowrite";
|
public static final String DISK_IO_WRITE = "diskiowrite";
|
||||||
public static final String DISK_IO_PSTOTAL = "diskiopstotal";
|
public static final String DISK_IO_PSTOTAL = "diskiopstotal";
|
||||||
public static final String DISK_SIZE = "disksize";
|
public static final String DISK_SIZE = "disksize";
|
||||||
|
public static final String DISK_SIZE_STRICTNESS = "disksizestrictness";
|
||||||
|
public static final String DISK_OFFERING_STRICTNESS = "diskofferingstrictness";
|
||||||
public static final String DOWNLOAD_DETAILS = "downloaddetails";
|
public static final String DOWNLOAD_DETAILS = "downloaddetails";
|
||||||
public static final String UTILIZATION = "utilization";
|
public static final String UTILIZATION = "utilization";
|
||||||
public static final String DRIVER = "driver";
|
public static final String DRIVER = "driver";
|
||||||
@ -589,6 +592,7 @@ public class ApiConstants {
|
|||||||
public static final String LIVE_MIGRATE = "livemigrate";
|
public static final String LIVE_MIGRATE = "livemigrate";
|
||||||
public static final String MIGRATE_ALLOWED = "migrateallowed";
|
public static final String MIGRATE_ALLOWED = "migrateallowed";
|
||||||
public static final String MIGRATE_TO = "migrateto";
|
public static final String MIGRATE_TO = "migrateto";
|
||||||
|
public static final String AUTO_MIGRATE = "automigrate";
|
||||||
public static final String GUID = "guid";
|
public static final String GUID = "guid";
|
||||||
public static final String VSWITCH_TYPE_GUEST_TRAFFIC = "guestvswitchtype";
|
public static final String VSWITCH_TYPE_GUEST_TRAFFIC = "guestvswitchtype";
|
||||||
public static final String VSWITCH_TYPE_PUBLIC_TRAFFIC = "publicvswitchtype";
|
public static final String VSWITCH_TYPE_PUBLIC_TRAFFIC = "publicvswitchtype";
|
||||||
|
|||||||
@ -159,6 +159,9 @@ public class CreateDiskOfferingCmd extends BaseCmd {
|
|||||||
@Parameter(name = ApiConstants.STORAGE_POLICY, type = CommandType.UUID, entityType = VsphereStoragePoliciesResponse.class,required = false, description = "Name of the storage policy defined at vCenter, this is applicable only for VMware", since = "4.15")
|
@Parameter(name = ApiConstants.STORAGE_POLICY, type = CommandType.UUID, entityType = VsphereStoragePoliciesResponse.class,required = false, description = "Name of the storage policy defined at vCenter, this is applicable only for VMware", since = "4.15")
|
||||||
private Long storagePolicy;
|
private Long storagePolicy;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.DISK_SIZE_STRICTNESS, type = CommandType.BOOLEAN, description = "To allow or disallow the resize operation on the disks created from this disk offering, if the flag is true then resize is not allowed", since = "4.17")
|
||||||
|
private Boolean diskSizeStrictness;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "details to specify disk offering parameters", since = "4.16")
|
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "details to specify disk offering parameters", since = "4.16")
|
||||||
private Map details;
|
private Map details;
|
||||||
|
|
||||||
@ -301,6 +304,11 @@ public class CreateDiskOfferingCmd extends BaseCmd {
|
|||||||
public Long getStoragePolicy() {
|
public Long getStoragePolicy() {
|
||||||
return storagePolicy;
|
return storagePolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getDiskSizeStrictness() {
|
||||||
|
return diskSizeStrictness != null ? diskSizeStrictness : false;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -33,6 +33,7 @@ import org.apache.cloudstack.api.response.DomainResponse;
|
|||||||
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
||||||
import org.apache.cloudstack.api.response.VsphereStoragePoliciesResponse;
|
import org.apache.cloudstack.api.response.VsphereStoragePoliciesResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
|
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||||
import org.apache.commons.collections.MapUtils;
|
import org.apache.commons.collections.MapUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
@ -210,13 +211,13 @@ public class CreateServiceOfferingCmd extends BaseCmd {
|
|||||||
|
|
||||||
@Parameter(name = ApiConstants.MAX_MEMORY,
|
@Parameter(name = ApiConstants.MAX_MEMORY,
|
||||||
type = CommandType.INTEGER,
|
type = CommandType.INTEGER,
|
||||||
description = "The maximum memroy size of the custom service offering in MB",
|
description = "The maximum memory size of the custom service offering in MB",
|
||||||
since = "4.13")
|
since = "4.13")
|
||||||
private Integer maxMemory;
|
private Integer maxMemory;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.MIN_MEMORY,
|
@Parameter(name = ApiConstants.MIN_MEMORY,
|
||||||
type = CommandType.INTEGER,
|
type = CommandType.INTEGER,
|
||||||
description = "The minimum memroy size of the custom service offering in MB",
|
description = "The minimum memory size of the custom service offering in MB",
|
||||||
since = "4.13")
|
since = "4.13")
|
||||||
private Integer minMemory;
|
private Integer minMemory;
|
||||||
|
|
||||||
@ -227,6 +228,20 @@ public class CreateServiceOfferingCmd extends BaseCmd {
|
|||||||
description = "true if virtual machine needs to be dynamically scalable of cpu or memory")
|
description = "true if virtual machine needs to be dynamically scalable of cpu or memory")
|
||||||
protected Boolean isDynamicScalingEnabled;
|
protected Boolean isDynamicScalingEnabled;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.DISK_OFFERING_ID,
|
||||||
|
required = false,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
entityType = DiskOfferingResponse.class,
|
||||||
|
description = "the ID of the disk offering to which service offering should be mapped",
|
||||||
|
since = "4.17")
|
||||||
|
private Long diskOfferingId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.DISK_OFFERING_STRICTNESS,
|
||||||
|
type = CommandType.BOOLEAN,
|
||||||
|
description = "True/False to indicate the strictness of the disk offering association with the compute offering. When set to true, override of disk offering is not allowed when VM is deployed and change disk offering is not allowed for the ROOT disk after the VM is deployed",
|
||||||
|
since = "4.17")
|
||||||
|
private Boolean diskOfferingStrictness;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -449,6 +464,14 @@ public class CreateServiceOfferingCmd extends BaseCmd {
|
|||||||
return isDynamicScalingEnabled == null ? true : isDynamicScalingEnabled;
|
return isDynamicScalingEnabled == null ? true : isDynamicScalingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getDiskOfferingId() {
|
||||||
|
return diskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getDiskOfferingStrictness() {
|
||||||
|
return diskOfferingStrictness == null ? false : diskOfferingStrictness;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -26,4 +26,5 @@ import com.cloud.storage.Volume;
|
|||||||
|
|
||||||
@APICommand(name = "migrateVolume", description = "Migrate volume", responseObject = VolumeResponse.class, since = "3.0.0", responseView = ResponseView.Full, entityType = {
|
@APICommand(name = "migrateVolume", description = "Migrate volume", responseObject = VolumeResponse.class, since = "3.0.0", responseView = ResponseView.Full, entityType = {
|
||||||
Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
public class MigrateVolumeCmdByAdmin extends MigrateVolumeCmd implements AdminCmd {}
|
public class MigrateVolumeCmdByAdmin extends MigrateVolumeCmd implements AdminCmd {
|
||||||
|
}
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.command.user.offering;
|
package org.apache.cloudstack.api.command.user.offering;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||||
|
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
@ -50,6 +52,12 @@ public class ListDiskOfferingsCmd extends BaseListDomainResourcesCmd {
|
|||||||
since = "4.13")
|
since = "4.13")
|
||||||
private Long zoneId;
|
private Long zoneId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, description = "The ID of the volume, tags of the volume are used to filter the offerings", since = "4.17")
|
||||||
|
private Long volumeId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.STORAGE_ID, type = CommandType.UUID, entityType = StoragePoolResponse.class, description = "The ID of the storage pool, tags of the storage pool are used to filter the offerings", since = "4.17")
|
||||||
|
private Long storagePoolId;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -66,6 +74,14 @@ public class ListDiskOfferingsCmd extends BaseListDomainResourcesCmd {
|
|||||||
return zoneId;
|
return zoneId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getVolumeId() {
|
||||||
|
return volumeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getStoragePoolId() {
|
||||||
|
return storagePoolId;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -239,6 +239,10 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
|
|||||||
description = "true if virtual machine needs to be dynamically scalable")
|
description = "true if virtual machine needs to be dynamically scalable")
|
||||||
protected Boolean dynamicScalingEnabled;
|
protected Boolean dynamicScalingEnabled;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.OVERRIDE_DISK_OFFERING_ID, type = CommandType.UUID, since = "4.17", entityType = DiskOfferingResponse.class, description = "the ID of the disk offering for the virtual machine to be used for root volume instead of the disk offering mapped in service offering." +
|
||||||
|
"In case of virtual machine deploying from ISO, then the diskofferingid specified for root volume is ignored and uses this override disk offering id")
|
||||||
|
private Long overrideDiskOfferingId;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -637,6 +641,10 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
|
|||||||
return dynamicScalingEnabled == null ? true : dynamicScalingEnabled;
|
return dynamicScalingEnabled == null ? true : dynamicScalingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getOverrideDiskOfferingId() {
|
||||||
|
return overrideDiskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -70,6 +70,19 @@ public class ScaleVMCmd extends BaseAsyncCmd implements UserCmd {
|
|||||||
@Parameter(name = ApiConstants.DETAILS, type = BaseCmd.CommandType.MAP, description = "name value pairs of custom parameters for cpu,memory and cpunumber. example details[i].name=value")
|
@Parameter(name = ApiConstants.DETAILS, type = BaseCmd.CommandType.MAP, description = "name value pairs of custom parameters for cpu,memory and cpunumber. example details[i].name=value")
|
||||||
private Map<String, String> details;
|
private Map<String, String> details;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "New minimum number of IOPS for the custom disk offering", since = "4.17")
|
||||||
|
private Long minIops;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "New maximum number of IOPS for the custom disk offering", since = "4.17")
|
||||||
|
private Long maxIops;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.AUTO_MIGRATE, type = CommandType.BOOLEAN, required = false, description = "Flag for automatic migration of the root volume " +
|
||||||
|
"with new compute offering whenever migration is required to apply the offering", since = "4.17")
|
||||||
|
private Boolean autoMigrate;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.SHRINK_OK, type = CommandType.BOOLEAN, required = false, description = "Verify OK to Shrink", since = "4.17")
|
||||||
|
private Boolean shrinkOk;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -97,9 +110,29 @@ public class ScaleVMCmd extends BaseAsyncCmd implements UserCmd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shrinkOk != null) customparameterMap.put(ApiConstants.SHRINK_OK, String.valueOf(isShrinkOk()));
|
||||||
|
if (autoMigrate != null) customparameterMap.put(ApiConstants.AUTO_MIGRATE, String.valueOf(getAutoMigrate()));
|
||||||
|
if (getMinIops() != null) customparameterMap.put(ApiConstants.MIN_IOPS, String.valueOf(getMinIops()));
|
||||||
|
if (getMaxIops() != null) customparameterMap.put(ApiConstants.MAX_IOPS, String.valueOf(getMaxIops()));
|
||||||
|
|
||||||
return customparameterMap;
|
return customparameterMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getMinIops() {
|
||||||
|
return minIops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getMaxIops() {
|
||||||
|
return maxIops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getAutoMigrate() {
|
||||||
|
return autoMigrate == null ? true : autoMigrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShrinkOk() { return shrinkOk == null ? true : shrinkOk; }
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -68,6 +68,19 @@ public class UpgradeVMCmd extends BaseCmd implements UserCmd {
|
|||||||
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "name value pairs of custom parameters for cpu, memory and cpunumber. example details[i].name=value")
|
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "name value pairs of custom parameters for cpu, memory and cpunumber. example details[i].name=value")
|
||||||
private Map<String, String> details;
|
private Map<String, String> details;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "New minimum number of IOPS for the custom disk offering", since = "4.17")
|
||||||
|
private Long minIops;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "New maximum number of IOPS for the custom disk offering", since = "4.17")
|
||||||
|
private Long maxIops;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.AUTO_MIGRATE, type = CommandType.BOOLEAN, required = false, description = "Flag for automatic migration of the root volume " +
|
||||||
|
"with new compute offering whenever migration is required to apply the offering", since = "4.17")
|
||||||
|
private Boolean autoMigrate;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.SHRINK_OK, type = CommandType.BOOLEAN, required = false, description = "Verify OK to Shrink", since = "4.17")
|
||||||
|
private Boolean shrinkOk;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -92,9 +105,29 @@ public class UpgradeVMCmd extends BaseCmd implements UserCmd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shrinkOk != null) customparameterMap.put(ApiConstants.SHRINK_OK, String.valueOf(isShrinkOk()));
|
||||||
|
if (autoMigrate != null) customparameterMap.put(ApiConstants.AUTO_MIGRATE, String.valueOf(getAutoMigrate()));
|
||||||
|
if (getMinIops() != null) customparameterMap.put(ApiConstants.MIN_IOPS, String.valueOf(getMinIops()));
|
||||||
|
if (getMaxIops() != null) customparameterMap.put(ApiConstants.MAX_IOPS, String.valueOf(getMaxIops()));
|
||||||
|
|
||||||
return customparameterMap;
|
return customparameterMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getMinIops() {
|
||||||
|
return minIops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getMaxIops() {
|
||||||
|
return maxIops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getAutoMigrate() {
|
||||||
|
return autoMigrate == null ? true : autoMigrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShrinkOk() { return shrinkOk == null ? true : shrinkOk; }
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -0,0 +1,155 @@
|
|||||||
|
// Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
// or more contributor license agreements. See the NOTICE file
|
||||||
|
// distributed with this work for additional information
|
||||||
|
// regarding copyright ownership. The ASF licenses this file
|
||||||
|
// to you under the Apache License, Version 2.0 (the
|
||||||
|
// "License"); you may not use this file except in compliance
|
||||||
|
// with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing,
|
||||||
|
// software distributed under the License is distributed on an
|
||||||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
// KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations
|
||||||
|
// under the License.
|
||||||
|
package org.apache.cloudstack.api.command.user.volume;
|
||||||
|
|
||||||
|
import com.cloud.event.EventTypes;
|
||||||
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
|
import com.cloud.exception.NetworkRuleConflictException;
|
||||||
|
import com.cloud.exception.InsufficientCapacityException;
|
||||||
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
|
import com.cloud.exception.ResourceUnavailableException;
|
||||||
|
import com.cloud.offering.DiskOffering;
|
||||||
|
import com.cloud.storage.Volume;
|
||||||
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
|
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.ResponseObject;
|
||||||
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||||
|
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||||
|
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
|
||||||
|
@APICommand(name = ChangeOfferingForVolumeCmd.APINAME,
|
||||||
|
description = "Change disk offering of the volume and also an option to auto migrate if required to apply the new disk offering",
|
||||||
|
responseObject = VolumeResponse.class,
|
||||||
|
requestHasSensitiveInfo = false,
|
||||||
|
responseHasSensitiveInfo = false,
|
||||||
|
authorized = { RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User},
|
||||||
|
since = "4.17")
|
||||||
|
public class ChangeOfferingForVolumeCmd extends BaseAsyncCmd implements UserCmd {
|
||||||
|
public static final String APINAME = "changeOfferingForVolume";
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
//////////////// API parameters /////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ID, entityType = VolumeResponse.class, required = true, type = CommandType.UUID, description = "the ID of the volume")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.DISK_OFFERING_ID,
|
||||||
|
entityType = DiskOfferingResponse.class,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
required = true,
|
||||||
|
description = "new disk offering id")
|
||||||
|
private Long newDiskOfferingId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, required = false, description = "New volume size in GB for the custom disk offering")
|
||||||
|
private Long size;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "New minimum number of IOPS for the custom disk offering")
|
||||||
|
private Long minIops;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "New maximum number of IOPS for the custom disk offering")
|
||||||
|
private Long maxIops;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.AUTO_MIGRATE, type = CommandType.BOOLEAN, required = false, description = "Flag for automatic migration of the volume " +
|
||||||
|
"with new disk offering whenever migration is required to apply the offering")
|
||||||
|
private Boolean autoMigrate;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.SHRINK_OK, type = CommandType.BOOLEAN, required = false, description = "Verify OK to Shrink")
|
||||||
|
private Boolean shrinkOk;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
/////////////////// Accessors ///////////////////////
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public ChangeOfferingForVolumeCmd() {}
|
||||||
|
|
||||||
|
public ChangeOfferingForVolumeCmd(Long volumeId, long newDiskOfferingId, Long minIops, Long maxIops, boolean autoMigrate, boolean shrinkOk) {
|
||||||
|
this.id = volumeId;
|
||||||
|
this.minIops = minIops;
|
||||||
|
this.maxIops = maxIops;
|
||||||
|
this.newDiskOfferingId = newDiskOfferingId;
|
||||||
|
this.autoMigrate = autoMigrate;
|
||||||
|
this.shrinkOk = shrinkOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getNewDiskOfferingId() {
|
||||||
|
return newDiskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getMinIops() {
|
||||||
|
return minIops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getMaxIops() {
|
||||||
|
return maxIops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getAutoMigrate() {
|
||||||
|
return autoMigrate == null ? true : autoMigrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShrinkOk() {
|
||||||
|
return shrinkOk == null ? false: shrinkOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEventType() {
|
||||||
|
return EventTypes.EVENT_VOLUME_CHANGE_DISK_OFFERING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEventDescription() {
|
||||||
|
return "Changing Disk offering of Volume Id: " + this._uuidMgr.getUuid(Volume.class, getId()) + " to " + this._uuidMgr.getUuid(DiskOffering.class, getNewDiskOfferingId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||||
|
CallContext.current().setEventDetails("Volume Id: " + getId());
|
||||||
|
Volume result = _volumeService.changeDiskOfferingForVolume(this);
|
||||||
|
if (result != null) {
|
||||||
|
VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseObject.ResponseView.Restricted, result);
|
||||||
|
response.setResponseName(getCommandName());
|
||||||
|
setResponseObject(response);
|
||||||
|
} else {
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to change disk offering of volume");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCommandName() {
|
||||||
|
return APINAME.toLowerCase() + BaseAsyncCmd.RESPONSE_SUFFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntityOwnerId() {
|
||||||
|
return CallContext.current().getCallingAccountId();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,6 +25,7 @@ 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.command.user.UserCmd;
|
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||||
|
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||||
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||||
|
|
||||||
@ -50,8 +51,8 @@ public class MigrateVolumeCmd extends BaseAsyncCmd implements UserCmd {
|
|||||||
@Parameter(name = ApiConstants.LIVE_MIGRATE, type = CommandType.BOOLEAN, required = false, description = "if the volume should be live migrated when it is attached to a running vm")
|
@Parameter(name = ApiConstants.LIVE_MIGRATE, type = CommandType.BOOLEAN, required = false, description = "if the volume should be live migrated when it is attached to a running vm")
|
||||||
private Boolean liveMigrate;
|
private Boolean liveMigrate;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.NEW_DISK_OFFERING_ID, type = CommandType.STRING, description = "The new disk offering ID that replaces the current one used by the volume. This new disk offering is used to better reflect the new storage where the volume is going to be migrated to.")
|
@Parameter(name = ApiConstants.NEW_DISK_OFFERING_ID, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "The new disk offering ID that replaces the current one used by the volume. This new disk offering is used to better reflect the new storage where the volume is going to be migrated to.")
|
||||||
private String newDiskOfferingUuid;
|
private Long newDiskOfferingId;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
@ -74,6 +75,14 @@ public class MigrateVolumeCmd extends BaseAsyncCmd implements UserCmd {
|
|||||||
return (liveMigrate != null) ? liveMigrate : false;
|
return (liveMigrate != null) ? liveMigrate : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MigrateVolumeCmd() {
|
||||||
|
}
|
||||||
|
public MigrateVolumeCmd(Long volumeId, Long storageId, Long newDiskOfferingId, Boolean liveMigrate) {
|
||||||
|
this.volumeId = volumeId;
|
||||||
|
this.storageId = storageId;
|
||||||
|
this.newDiskOfferingId = newDiskOfferingId;
|
||||||
|
this.liveMigrate = liveMigrate;
|
||||||
|
}
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -103,8 +112,8 @@ public class MigrateVolumeCmd extends BaseAsyncCmd implements UserCmd {
|
|||||||
return "Attempting to migrate volume Id: " + this._uuidMgr.getUuid(Volume.class, getVolumeId()) + " to storage pool Id: " + this._uuidMgr.getUuid(StoragePool.class, getStoragePoolId());
|
return "Attempting to migrate volume Id: " + this._uuidMgr.getUuid(Volume.class, getVolumeId()) + " to storage pool Id: " + this._uuidMgr.getUuid(StoragePool.class, getStoragePoolId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNewDiskOfferingUuid() {
|
public Long getNewDiskOfferingId() {
|
||||||
return newDiskOfferingUuid;
|
return newDiskOfferingId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -155,6 +155,10 @@ public class DiskOfferingResponse extends BaseResponseWithAnnotations {
|
|||||||
@Param(description = "the vsphere storage policy tagged to the disk offering in case of VMware", since = "4.15")
|
@Param(description = "the vsphere storage policy tagged to the disk offering in case of VMware", since = "4.15")
|
||||||
private String vsphereStoragePolicy;
|
private String vsphereStoragePolicy;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.DISK_SIZE_STRICTNESS)
|
||||||
|
@Param(description = "To allow or disallow the resize operation on the disks created from this disk offering, if the flag is true then resize is not allowed", since = "4.17")
|
||||||
|
private Boolean diskSizeStrictness;
|
||||||
|
|
||||||
public Boolean getDisplayOffering() {
|
public Boolean getDisplayOffering() {
|
||||||
return displayOffering;
|
return displayOffering;
|
||||||
}
|
}
|
||||||
@ -363,4 +367,12 @@ public class DiskOfferingResponse extends BaseResponseWithAnnotations {
|
|||||||
public void setVsphereStoragePolicy(String vsphereStoragePolicy) {
|
public void setVsphereStoragePolicy(String vsphereStoragePolicy) {
|
||||||
this.vsphereStoragePolicy = vsphereStoragePolicy;
|
this.vsphereStoragePolicy = vsphereStoragePolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean getDiskSizeStrictness() {
|
||||||
|
return diskSizeStrictness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiskSizeStrictness(Boolean diskSizeStrictness) {
|
||||||
|
this.diskSizeStrictness = diskSizeStrictness;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -208,6 +208,24 @@ public class ServiceOfferingResponse extends BaseResponseWithAnnotations {
|
|||||||
@Param(description = "true if virtual machine needs to be dynamically scalable of cpu or memory", since = "4.16")
|
@Param(description = "true if virtual machine needs to be dynamically scalable of cpu or memory", since = "4.16")
|
||||||
private Boolean dynamicScalingEnabled;
|
private Boolean dynamicScalingEnabled;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.DISK_OFFERING_STRICTNESS)
|
||||||
|
@Param(description = "True/False to indicate the strictness of the disk offering association with the compute offering. " +
|
||||||
|
"When set to true, override of disk offering is not allowed when VM is deployed and " +
|
||||||
|
"change disk offering is not allowed for the ROOT disk after the VM is deployed", since = "4.17")
|
||||||
|
private Boolean diskOfferingStrictness;
|
||||||
|
|
||||||
|
@SerializedName(ApiConstants.DISK_OFFERING_ID)
|
||||||
|
@Param(description = "the ID of the disk offering to which service offering is linked", since = "4.17")
|
||||||
|
private String diskOfferingId;
|
||||||
|
|
||||||
|
@SerializedName("diskofferingname")
|
||||||
|
@Param(description = "name of the disk offering", since = "4.17")
|
||||||
|
private String diskOfferingName;
|
||||||
|
|
||||||
|
@SerializedName("diskofferingdisplaytext")
|
||||||
|
@Param(description = "the display text of the disk offering", since = "4.17")
|
||||||
|
private String diskOfferingDisplayText;
|
||||||
|
|
||||||
public ServiceOfferingResponse() {
|
public ServiceOfferingResponse() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,4 +504,36 @@ public class ServiceOfferingResponse extends BaseResponseWithAnnotations {
|
|||||||
public void setDynamicScalingEnabled(Boolean dynamicScalingEnabled) {
|
public void setDynamicScalingEnabled(Boolean dynamicScalingEnabled) {
|
||||||
this.dynamicScalingEnabled = dynamicScalingEnabled;
|
this.dynamicScalingEnabled = dynamicScalingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean getDiskOfferingStrictness() {
|
||||||
|
return diskOfferingStrictness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiskOfferingStrictness(Boolean diskOfferingStrictness) {
|
||||||
|
this.diskOfferingStrictness = diskOfferingStrictness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiskOfferingId(String diskOfferingId) {
|
||||||
|
this.diskOfferingId = diskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiskOfferingName(String diskOfferingName) {
|
||||||
|
this.diskOfferingName = diskOfferingName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiskOfferingDisplayText(String diskOfferingDisplayText) {
|
||||||
|
this.diskOfferingDisplayText = diskOfferingDisplayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDiskOfferingId() {
|
||||||
|
return diskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDiskOfferingName() {
|
||||||
|
return diskOfferingName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDiskOfferingDisplayText() {
|
||||||
|
return diskOfferingDisplayText;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -209,7 +209,7 @@ public class CheckNetworkAnswerTest {
|
|||||||
Long newSize = 4194304L;
|
Long newSize = 4194304L;
|
||||||
Long currentSize = 1048576L;
|
Long currentSize = 1048576L;
|
||||||
|
|
||||||
ResizeVolumeCommand rv = new ResizeVolumeCommand("dummydiskpath", new StorageFilerTO(dummypool), currentSize, newSize, false, "vmName");
|
ResizeVolumeCommand rv = new ResizeVolumeCommand("dummydiskpath", new StorageFilerTO(dummypool), currentSize, newSize, false, "vmName", null);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecuteInSequence() {
|
public void testExecuteInSequence() {
|
||||||
|
|||||||
@ -137,6 +137,8 @@ public interface VolumeOrchestrationService {
|
|||||||
|
|
||||||
StoragePool findStoragePool(DiskProfile dskCh, DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Set<StoragePool> avoid);
|
StoragePool findStoragePool(DiskProfile dskCh, DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Set<StoragePool> avoid);
|
||||||
|
|
||||||
|
List<StoragePool> findStoragePoolsForVolumeWithNewDiskOffering(DiskProfile dskCh, DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Set<StoragePool> avoid);
|
||||||
|
|
||||||
void updateVolumeDiskChain(long volumeId, String path, String chainInfo, String updatedDataStoreUUID);
|
void updateVolumeDiskChain(long volumeId, String path, String chainInfo, String updatedDataStoreUUID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -67,14 +67,15 @@ public interface OrchestrationService {
|
|||||||
@QueryParam("compute-tags") List<String> computeTags, @QueryParam("root-disk-tags") List<String> rootDiskTags,
|
@QueryParam("compute-tags") List<String> computeTags, @QueryParam("root-disk-tags") List<String> rootDiskTags,
|
||||||
@QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan,
|
@QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan,
|
||||||
@QueryParam("root-disk-size") Long rootDiskSize, @QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap,
|
@QueryParam("root-disk-size") Long rootDiskSize, @QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap,
|
||||||
@QueryParam("datadisktemplate-diskoffering-map") Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap) throws InsufficientCapacityException;
|
@QueryParam("datadisktemplate-diskoffering-map") Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap, @QueryParam("disk-offering-id") Long diskOfferingId, @QueryParam("root-disk-offering-id") Long rootDiskOfferingId) throws InsufficientCapacityException;
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
VirtualMachineEntity createVirtualMachineFromScratch(@QueryParam("id") String id, @QueryParam("owner") String owner, @QueryParam("iso-id") String isoId,
|
VirtualMachineEntity createVirtualMachineFromScratch(@QueryParam("id") String id, @QueryParam("owner") String owner, @QueryParam("iso-id") String isoId,
|
||||||
@QueryParam("host-name") String hostName, @QueryParam("display-name") String displayName, @QueryParam("hypervisor") String hypervisor,
|
@QueryParam("host-name") String hostName, @QueryParam("display-name") String displayName, @QueryParam("hypervisor") String hypervisor,
|
||||||
@QueryParam("os") String os, @QueryParam("cpu") int cpu, @QueryParam("speed") int speed, @QueryParam("ram") long memory, @QueryParam("disk-size") Long diskSize,
|
@QueryParam("os") String os, @QueryParam("cpu") int cpu, @QueryParam("speed") int speed, @QueryParam("ram") long memory, @QueryParam("disk-size") Long diskSize,
|
||||||
@QueryParam("compute-tags") List<String> computeTags, @QueryParam("root-disk-tags") List<String> rootDiskTags,
|
@QueryParam("compute-tags") List<String> computeTags, @QueryParam("root-disk-tags") List<String> rootDiskTags,
|
||||||
@QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan, @QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap) throws InsufficientCapacityException;
|
@QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan,
|
||||||
|
@QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap, @QueryParam("disk-offering-id") Long diskOfferingId) throws InsufficientCapacityException;
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
NetworkEntity createNetwork(String id, String name, String domainName, String cidr, String gateway);
|
NetworkEntity createNetwork(String id, String name, String domainName, String cidr, String gateway);
|
||||||
|
|||||||
@ -228,9 +228,9 @@ public interface StorageManager extends StorageService {
|
|||||||
|
|
||||||
HypervisorType getHypervisorTypeFromFormat(ImageFormat format);
|
HypervisorType getHypervisorTypeFromFormat(ImageFormat format);
|
||||||
|
|
||||||
boolean storagePoolHasEnoughIops(List<Volume> volume, StoragePool pool);
|
boolean storagePoolHasEnoughIops(List<Pair<Volume, DiskProfile>> volumeDiskProfilePairs, StoragePool pool);
|
||||||
|
|
||||||
boolean storagePoolHasEnoughSpace(List<Volume> volume, StoragePool pool);
|
boolean storagePoolHasEnoughSpace(List<Pair<Volume, DiskProfile>> volumeDiskProfilePairs, StoragePool pool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This comment is relevant to managed storage only.
|
* This comment is relevant to managed storage only.
|
||||||
@ -254,13 +254,13 @@ public interface StorageManager extends StorageService {
|
|||||||
*
|
*
|
||||||
* Cloning volumes on the back-end instead of copying down a new template for each new volume helps to alleviate load on the hypervisors.
|
* Cloning volumes on the back-end instead of copying down a new template for each new volume helps to alleviate load on the hypervisors.
|
||||||
*/
|
*/
|
||||||
boolean storagePoolHasEnoughSpace(List<Volume> volume, StoragePool pool, Long clusterId);
|
boolean storagePoolHasEnoughSpace(List<Pair<Volume, DiskProfile>> volume, StoragePool pool, Long clusterId);
|
||||||
|
|
||||||
boolean storagePoolHasEnoughSpaceForResize(StoragePool pool, long currentSize, long newSize);
|
boolean storagePoolHasEnoughSpaceForResize(StoragePool pool, long currentSize, long newSize);
|
||||||
|
|
||||||
boolean storagePoolCompatibleWithVolumePool(StoragePool pool, Volume volume);
|
boolean storagePoolCompatibleWithVolumePool(StoragePool pool, Volume volume);
|
||||||
|
|
||||||
boolean isStoragePoolCompliantWithStoragePolicy(List<Volume> volumes, StoragePool pool) throws StorageUnavailableException;
|
boolean isStoragePoolCompliantWithStoragePolicy(List<Pair<Volume, DiskProfile>> volumes, StoragePool pool) throws StorageUnavailableException;
|
||||||
|
|
||||||
boolean registerHostListener(String providerUuid, HypervisorHostListener listener);
|
boolean registerHostListener(String providerUuid, HypervisorHostListener listener);
|
||||||
|
|
||||||
|
|||||||
@ -523,7 +523,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
@Override
|
@Override
|
||||||
public void allocate(final String vmInstanceName, final VirtualMachineTemplate template, final ServiceOffering serviceOffering,
|
public void allocate(final String vmInstanceName, final VirtualMachineTemplate template, final ServiceOffering serviceOffering,
|
||||||
final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final DeploymentPlan plan, final HypervisorType hyperType) throws InsufficientCapacityException {
|
final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final DeploymentPlan plan, final HypervisorType hyperType) throws InsufficientCapacityException {
|
||||||
allocate(vmInstanceName, template, serviceOffering, new DiskOfferingInfo(serviceOffering), new ArrayList<>(), networks, plan, hyperType, null, null);
|
DiskOffering diskOffering = _diskOfferingDao.findById(serviceOffering.getId());
|
||||||
|
allocate(vmInstanceName, template, serviceOffering, new DiskOfferingInfo(diskOffering), new ArrayList<>(), networks, plan, hyperType, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private VirtualMachineGuru getVmGuru(final VirtualMachine vm) {
|
private VirtualMachineGuru getVmGuru(final VirtualMachine vm) {
|
||||||
@ -3738,8 +3739,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
}
|
}
|
||||||
|
|
||||||
final ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
|
final ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
|
||||||
|
final DiskOfferingVO currentDiskOffering = _diskOfferingDao.findByIdIncludingRemoved(currentServiceOffering.getDiskOfferingId());
|
||||||
|
final DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(newServiceOffering.getDiskOfferingId());
|
||||||
|
|
||||||
checkIfNewOfferingStorageScopeMatchesStoragePool(vmInstance, newServiceOffering);
|
checkIfNewOfferingStorageScopeMatchesStoragePool(vmInstance, newDiskOffering);
|
||||||
|
|
||||||
if (currentServiceOffering.isSystemUse() != newServiceOffering.isSystemUse()) {
|
if (currentServiceOffering.isSystemUse() != newServiceOffering.isSystemUse()) {
|
||||||
throw new InvalidParameterValueException("isSystem property is different for current service offering and new service offering");
|
throw new InvalidParameterValueException("isSystem property is different for current service offering and new service offering");
|
||||||
@ -3750,8 +3753,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
newServiceOffering.getCpu() + " cpu(s) at " + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory");
|
newServiceOffering.getCpu() + " cpu(s) at " + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<String> currentTags = StringUtils.csvTagsToList(currentServiceOffering.getTags());
|
final List<String> currentTags = StringUtils.csvTagsToList(currentDiskOffering.getTags());
|
||||||
final List<String> newTags = StringUtils.csvTagsToList(newServiceOffering.getTags());
|
final List<String> newTags = StringUtils.csvTagsToList(newDiskOffering.getTags());
|
||||||
if (!newTags.containsAll(currentTags)) {
|
if (!newTags.containsAll(currentTags)) {
|
||||||
throw new InvalidParameterValueException("Unable to upgrade virtual machine; the current service offering " + " should have tags as subset of " +
|
throw new InvalidParameterValueException("Unable to upgrade virtual machine; the current service offering " + " should have tags as subset of " +
|
||||||
"the new service offering tags. Current service offering tags: " + currentTags + "; " + "new service " + "offering tags: " + newTags);
|
"the new service offering tags. Current service offering tags: " + currentTags + "; " + "new service " + "offering tags: " + newTags);
|
||||||
@ -3761,16 +3764,16 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||||||
/**
|
/**
|
||||||
* Throws an InvalidParameterValueException in case the new service offerings does not match the storage scope (e.g. local or shared).
|
* Throws an InvalidParameterValueException in case the new service offerings does not match the storage scope (e.g. local or shared).
|
||||||
*/
|
*/
|
||||||
protected void checkIfNewOfferingStorageScopeMatchesStoragePool(VirtualMachine vmInstance, ServiceOffering newServiceOffering) {
|
protected void checkIfNewOfferingStorageScopeMatchesStoragePool(VirtualMachine vmInstance, DiskOffering newDiskOffering) {
|
||||||
boolean isRootVolumeOnLocalStorage = isRootVolumeOnLocalStorage(vmInstance.getId());
|
boolean isRootVolumeOnLocalStorage = isRootVolumeOnLocalStorage(vmInstance.getId());
|
||||||
|
|
||||||
if (newServiceOffering.isUseLocalStorage() && !isRootVolumeOnLocalStorage) {
|
if (newDiskOffering.isUseLocalStorage() && !isRootVolumeOnLocalStorage) {
|
||||||
String message = String .format("Unable to upgrade virtual machine %s, target offering use local storage but the storage pool where "
|
String message = String .format("Unable to upgrade virtual machine %s, target offering use local storage but the storage pool where "
|
||||||
+ "the volume is allocated is a shared storage.", vmInstance.toString());
|
+ "the volume is allocated is a shared storage.", vmInstance.toString());
|
||||||
throw new InvalidParameterValueException(message);
|
throw new InvalidParameterValueException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newServiceOffering.isUseLocalStorage() && isRootVolumeOnLocalStorage) {
|
if (!newDiskOffering.isUseLocalStorage() && isRootVolumeOnLocalStorage) {
|
||||||
String message = String.format("Unable to upgrade virtual machine %s, target offering use shared storage but the storage pool where "
|
String message = String.format("Unable to upgrade virtual machine %s, target offering use shared storage but the storage pool where "
|
||||||
+ "the volume is allocated is a local storage.", vmInstance.toString());
|
+ "the volume is allocated is a local storage.", vmInstance.toString());
|
||||||
throw new InvalidParameterValueException(message);
|
throw new InvalidParameterValueException(message);
|
||||||
|
|||||||
@ -156,7 +156,7 @@ public class CloudOrchestrator implements OrchestrationService {
|
|||||||
@Override
|
@Override
|
||||||
public VirtualMachineEntity createVirtualMachine(String id, String owner, String templateId, String hostName, String displayName, String hypervisor, int cpu,
|
public VirtualMachineEntity createVirtualMachine(String id, String owner, String templateId, String hostName, String displayName, String hypervisor, int cpu,
|
||||||
int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, List<NicProfile>> networkNicMap, DeploymentPlan plan,
|
int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, List<NicProfile>> networkNicMap, DeploymentPlan plan,
|
||||||
Long rootDiskSize, Map<String, Map<Integer, String>> extraDhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException {
|
Long rootDiskSize, Map<String, Map<Integer, String>> extraDhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Long dataDiskOfferingId, Long rootDiskOfferingId) throws InsufficientCapacityException {
|
||||||
|
|
||||||
// VirtualMachineEntityImpl vmEntity = new VirtualMachineEntityImpl(id, owner, hostName, displayName, cpu, speed, memory, computeTags, rootDiskTags, networks,
|
// VirtualMachineEntityImpl vmEntity = new VirtualMachineEntityImpl(id, owner, hostName, displayName, cpu, speed, memory, computeTags, rootDiskTags, networks,
|
||||||
// vmEntityManager);
|
// vmEntityManager);
|
||||||
@ -185,10 +185,14 @@ public class CloudOrchestrator implements OrchestrationService {
|
|||||||
|
|
||||||
ServiceOfferingVO computeOffering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
|
ServiceOfferingVO computeOffering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
|
||||||
|
|
||||||
rootDiskOfferingInfo.setDiskOffering(computeOffering);
|
DiskOfferingVO rootDiskOffering = _diskOfferingDao.findById(rootDiskOfferingId);
|
||||||
|
if (rootDiskOffering == null) {
|
||||||
|
throw new InvalidParameterValueException("Unable to find root disk offering " + rootDiskOfferingId);
|
||||||
|
}
|
||||||
|
rootDiskOfferingInfo.setDiskOffering(rootDiskOffering);
|
||||||
rootDiskOfferingInfo.setSize(rootDiskSize);
|
rootDiskOfferingInfo.setSize(rootDiskSize);
|
||||||
|
|
||||||
if (computeOffering.isCustomizedIops() != null && computeOffering.isCustomizedIops()) {
|
if (rootDiskOffering.isCustomizedIops() != null && rootDiskOffering.isCustomizedIops()) {
|
||||||
Map<String, String> userVmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
|
Map<String, String> userVmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
|
||||||
|
|
||||||
if (userVmDetails != null) {
|
if (userVmDetails != null) {
|
||||||
@ -200,48 +204,50 @@ public class CloudOrchestrator implements OrchestrationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vm.getDiskOfferingId() != null) {
|
if (dataDiskOfferingId != null) {
|
||||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(vm.getDiskOfferingId());
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(dataDiskOfferingId);
|
||||||
if (diskOffering == null) {
|
if (diskOffering == null) {
|
||||||
throw new InvalidParameterValueException("Unable to find disk offering " + vm.getDiskOfferingId());
|
throw new InvalidParameterValueException("Unable to find data disk offering " + dataDiskOfferingId);
|
||||||
}
|
}
|
||||||
Long size = null;
|
if (!diskOffering.isComputeOnly()) {
|
||||||
if (diskOffering.getDiskSize() == 0) {
|
Long size = null;
|
||||||
size = diskSize;
|
if (diskOffering.getDiskSize() == 0) {
|
||||||
if (size == null) {
|
size = diskSize;
|
||||||
throw new InvalidParameterValueException("Disk offering " + diskOffering + " requires size parameter.");
|
if (size == null) {
|
||||||
|
throw new InvalidParameterValueException("Disk offering " + diskOffering + " requires size parameter.");
|
||||||
|
}
|
||||||
|
_volumeMgr.validateVolumeSizeRange(size * 1024 * 1024 * 1024);
|
||||||
}
|
}
|
||||||
_volumeMgr.validateVolumeSizeRange(size * 1024 * 1024 * 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
DiskOfferingInfo dataDiskOfferingInfo = new DiskOfferingInfo();
|
DiskOfferingInfo dataDiskOfferingInfo = new DiskOfferingInfo();
|
||||||
|
|
||||||
dataDiskOfferingInfo.setDiskOffering(diskOffering);
|
dataDiskOfferingInfo.setDiskOffering(diskOffering);
|
||||||
dataDiskOfferingInfo.setSize(size);
|
dataDiskOfferingInfo.setSize(size);
|
||||||
|
|
||||||
if (diskOffering.isCustomizedIops() != null && diskOffering.isCustomizedIops()) {
|
if (diskOffering.isCustomizedIops() != null && diskOffering.isCustomizedIops()) {
|
||||||
Map<String, String> userVmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
|
Map<String, String> userVmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
|
||||||
|
|
||||||
if (userVmDetails != null) {
|
if (userVmDetails != null) {
|
||||||
String minIops = userVmDetails.get("minIopsDo");
|
String minIops = userVmDetails.get("minIopsDo");
|
||||||
String maxIops = userVmDetails.get("maxIopsDo");
|
String maxIops = userVmDetails.get("maxIopsDo");
|
||||||
|
|
||||||
dataDiskOfferingInfo.setMinIops(minIops != null && minIops.trim().length() > 0 ? Long.parseLong(minIops) : null);
|
dataDiskOfferingInfo.setMinIops(minIops != null && minIops.trim().length() > 0 ? Long.parseLong(minIops) : null);
|
||||||
dataDiskOfferingInfo.setMaxIops(maxIops != null && maxIops.trim().length() > 0 ? Long.parseLong(maxIops) : null);
|
dataDiskOfferingInfo.setMaxIops(maxIops != null && maxIops.trim().length() > 0 ? Long.parseLong(maxIops) : null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
dataDiskOfferings.add(dataDiskOfferingInfo);
|
dataDiskOfferings.add(dataDiskOfferingInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataDiskTemplateToDiskOfferingMap != null && !dataDiskTemplateToDiskOfferingMap.isEmpty()) {
|
if (dataDiskTemplateToDiskOfferingMap != null && !dataDiskTemplateToDiskOfferingMap.isEmpty()) {
|
||||||
for (Entry<Long, DiskOffering> datadiskTemplateToDiskOffering : dataDiskTemplateToDiskOfferingMap.entrySet()) {
|
for (Entry<Long, DiskOffering> datadiskTemplateToDiskOffering : dataDiskTemplateToDiskOfferingMap.entrySet()) {
|
||||||
DiskOffering diskOffering = datadiskTemplateToDiskOffering.getValue();
|
DiskOffering dataDiskOffering = datadiskTemplateToDiskOffering.getValue();
|
||||||
if (diskOffering == null) {
|
if (dataDiskOffering == null) {
|
||||||
throw new InvalidParameterValueException("Unable to find disk offering " + vm.getDiskOfferingId());
|
throw new InvalidParameterValueException("Unable to find disk offering " + dataDiskOfferingId);
|
||||||
}
|
}
|
||||||
if (diskOffering.getDiskSize() == 0) { // Custom disk offering is not supported for volumes created from datadisk templates
|
if (dataDiskOffering.getDiskSize() == 0) { // Custom disk offering is not supported for volumes created from datadisk templates
|
||||||
throw new InvalidParameterValueException("Disk offering " + diskOffering + " requires size parameter.");
|
throw new InvalidParameterValueException("Disk offering " + dataDiskOffering + " requires size parameter.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,7 +260,8 @@ public class CloudOrchestrator implements OrchestrationService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VirtualMachineEntity createVirtualMachineFromScratch(String id, String owner, String isoId, String hostName, String displayName, String hypervisor, String os,
|
public VirtualMachineEntity createVirtualMachineFromScratch(String id, String owner, String isoId, String hostName, String displayName, String hypervisor, String os,
|
||||||
int cpu, int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, List<NicProfile>> networkNicMap, DeploymentPlan plan, Map<String, Map<Integer, String>> extraDhcpOptionMap)
|
int cpu, int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, List<NicProfile>> networkNicMap, DeploymentPlan plan,
|
||||||
|
Map<String, Map<Integer, String>> extraDhcpOptionMap, Long diskOfferingId)
|
||||||
throws InsufficientCapacityException {
|
throws InsufficientCapacityException {
|
||||||
|
|
||||||
// VirtualMachineEntityImpl vmEntity = new VirtualMachineEntityImpl(id, owner, hostName, displayName, cpu, speed, memory, computeTags, rootDiskTags, networks, vmEntityManager);
|
// VirtualMachineEntityImpl vmEntity = new VirtualMachineEntityImpl(id, owner, hostName, displayName, cpu, speed, memory, computeTags, rootDiskTags, networks, vmEntityManager);
|
||||||
@ -268,9 +275,6 @@ public class CloudOrchestrator implements OrchestrationService {
|
|||||||
|
|
||||||
DiskOfferingInfo rootDiskOfferingInfo = new DiskOfferingInfo();
|
DiskOfferingInfo rootDiskOfferingInfo = new DiskOfferingInfo();
|
||||||
|
|
||||||
rootDiskOfferingInfo.setDiskOffering(computeOffering);
|
|
||||||
|
|
||||||
Long diskOfferingId = vm.getDiskOfferingId();
|
|
||||||
if (diskOfferingId == null) {
|
if (diskOfferingId == null) {
|
||||||
throw new InvalidParameterValueException("Installing from ISO requires a disk offering to be specified for the root disk.");
|
throw new InvalidParameterValueException("Installing from ISO requires a disk offering to be specified for the root disk.");
|
||||||
}
|
}
|
||||||
@ -278,8 +282,10 @@ public class CloudOrchestrator implements OrchestrationService {
|
|||||||
if (diskOffering == null) {
|
if (diskOffering == null) {
|
||||||
throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingId);
|
throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingId);
|
||||||
}
|
}
|
||||||
|
rootDiskOfferingInfo.setDiskOffering(diskOffering);
|
||||||
|
|
||||||
Long size = null;
|
Long size = null;
|
||||||
if (diskOffering.getDiskSize() == 0) {
|
if (!diskOffering.isComputeOnly() && diskOffering.getDiskSize() == 0) {
|
||||||
size = diskSize;
|
size = diskSize;
|
||||||
if (size == null) {
|
if (size == null) {
|
||||||
throw new InvalidParameterValueException("Disk offering " + diskOffering + " requires size parameter.");
|
throw new InvalidParameterValueException("Disk offering " + diskOffering + " requires size parameter.");
|
||||||
|
|||||||
@ -365,6 +365,36 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<StoragePool> findStoragePoolsForVolumeWithNewDiskOffering(DiskProfile dskCh, DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, final Set<StoragePool> avoid) {
|
||||||
|
Long podId = null;
|
||||||
|
if (pod != null) {
|
||||||
|
podId = pod.getId();
|
||||||
|
} else if (clusterId != null) {
|
||||||
|
Cluster cluster = _entityMgr.findById(Cluster.class, clusterId);
|
||||||
|
if (cluster != null) {
|
||||||
|
podId = cluster.getPodId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
|
||||||
|
List<StoragePool> suitablePools = new ArrayList<>();
|
||||||
|
for (StoragePoolAllocator allocator : _storagePoolAllocators) {
|
||||||
|
|
||||||
|
ExcludeList avoidList = new ExcludeList();
|
||||||
|
for (StoragePool pool : avoid) {
|
||||||
|
avoidList.addPool(pool.getId());
|
||||||
|
}
|
||||||
|
DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), podId, clusterId, hostId, null, null);
|
||||||
|
|
||||||
|
final List<StoragePool> poolList = allocator.allocateToPool(dskCh, profile, plan, avoidList, StoragePoolAllocator.RETURN_UPTO_ALL);
|
||||||
|
if (CollectionUtils.isEmpty(poolList)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
suitablePools.addAll(poolList);
|
||||||
|
}
|
||||||
|
return suitablePools;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StoragePool findChildDataStoreInDataStoreCluster(DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Long datastoreClusterId) {
|
public StoragePool findChildDataStoreInDataStoreCluster(DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Long datastoreClusterId) {
|
||||||
Long podId = null;
|
Long podId = null;
|
||||||
@ -634,7 +664,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
|
|
||||||
DiskProfile dskCh = null;
|
DiskProfile dskCh = null;
|
||||||
if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
|
if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
|
||||||
dskCh = createDiskCharacteristics(volume, template, dc, offering);
|
dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
|
||||||
storageMgr.setDiskProfileThrottling(dskCh, offering, diskOffering);
|
storageMgr.setDiskProfileThrottling(dskCh, offering, diskOffering);
|
||||||
} else {
|
} else {
|
||||||
dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
|
dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
|
||||||
@ -893,7 +923,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
|
|
||||||
Long offeringId = null;
|
Long offeringId = null;
|
||||||
|
|
||||||
if (offering.getType() == DiskOffering.Type.Disk) {
|
if (!offering.isComputeOnly()) {
|
||||||
offeringId = offering.getId();
|
offeringId = offering.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -95,6 +95,9 @@ public class VirtualMachineManagerImplTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private ServiceOfferingVO serviceOfferingMock;
|
private ServiceOfferingVO serviceOfferingMock;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private DiskOfferingVO diskOfferingMock;
|
||||||
|
|
||||||
private long hostMockId = 1L;
|
private long hostMockId = 1L;
|
||||||
@Mock
|
@Mock
|
||||||
private HostVO hostMock;
|
private HostVO hostMock;
|
||||||
@ -218,14 +221,15 @@ public class VirtualMachineManagerImplTest {
|
|||||||
when(serviceOfferingMock.getId()).thenReturn(2l);
|
when(serviceOfferingMock.getId()).thenReturn(2l);
|
||||||
|
|
||||||
ServiceOfferingVO mockCurrentServiceOffering = mock(ServiceOfferingVO.class);
|
ServiceOfferingVO mockCurrentServiceOffering = mock(ServiceOfferingVO.class);
|
||||||
|
DiskOfferingVO mockCurrentDiskOffering = mock(DiskOfferingVO.class);
|
||||||
|
|
||||||
when(serviceOfferingDaoMock.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn(mockCurrentServiceOffering);
|
when(serviceOfferingDaoMock.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn(mockCurrentServiceOffering);
|
||||||
when(mockCurrentServiceOffering.isUseLocalStorage()).thenReturn(true);
|
when(mockCurrentDiskOffering.isUseLocalStorage()).thenReturn(true);
|
||||||
when(serviceOfferingMock.isUseLocalStorage()).thenReturn(true);
|
when(diskOfferingMock.isUseLocalStorage()).thenReturn(true);
|
||||||
when(mockCurrentServiceOffering.isSystemUse()).thenReturn(true);
|
when(mockCurrentServiceOffering.isSystemUse()).thenReturn(true);
|
||||||
when(serviceOfferingMock.isSystemUse()).thenReturn(true);
|
when(serviceOfferingMock.isSystemUse()).thenReturn(true);
|
||||||
when(mockCurrentServiceOffering.getTags()).thenReturn("x,y");
|
when(mockCurrentDiskOffering.getTags()).thenReturn("x,y");
|
||||||
when(serviceOfferingMock.getTags()).thenReturn("z,x,y");
|
when(diskOfferingMock.getTags()).thenReturn("z,x,y");
|
||||||
|
|
||||||
virtualMachineManagerImpl.checkIfCanUpgrade(vmInstanceMock, serviceOfferingMock);
|
virtualMachineManagerImpl.checkIfCanUpgrade(vmInstanceMock, serviceOfferingMock);
|
||||||
}
|
}
|
||||||
@ -677,7 +681,7 @@ public class VirtualMachineManagerImplTest {
|
|||||||
private void prepareAndRunCheckIfNewOfferingStorageScopeMatchesStoragePool(boolean isRootOnLocal, boolean isOfferingUsingLocal) {
|
private void prepareAndRunCheckIfNewOfferingStorageScopeMatchesStoragePool(boolean isRootOnLocal, boolean isOfferingUsingLocal) {
|
||||||
Mockito.doReturn(isRootOnLocal).when(virtualMachineManagerImpl).isRootVolumeOnLocalStorage(Mockito.anyLong());
|
Mockito.doReturn(isRootOnLocal).when(virtualMachineManagerImpl).isRootVolumeOnLocalStorage(Mockito.anyLong());
|
||||||
Mockito.doReturn("vmInstanceMockedToString").when(vmInstanceMock).toString();
|
Mockito.doReturn("vmInstanceMockedToString").when(vmInstanceMock).toString();
|
||||||
Mockito.doReturn(isOfferingUsingLocal).when(serviceOfferingMock).isUseLocalStorage();
|
Mockito.doReturn(isOfferingUsingLocal).when(diskOfferingMock).isUseLocalStorage();
|
||||||
virtualMachineManagerImpl.checkIfNewOfferingStorageScopeMatchesStoragePool(vmInstanceMock, serviceOfferingMock);
|
virtualMachineManagerImpl.checkIfNewOfferingStorageScopeMatchesStoragePool(vmInstanceMock, diskOfferingMock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,25 +16,66 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.service;
|
package com.cloud.service;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.DiscriminatorValue;
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.PrimaryKeyJoinColumn;
|
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.Transient;
|
import javax.persistence.Transient;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
|
||||||
import com.cloud.offering.ServiceOffering;
|
import com.cloud.offering.ServiceOffering;
|
||||||
import com.cloud.storage.DiskOfferingVO;
|
import com.cloud.utils.db.GenericDao;
|
||||||
import com.cloud.storage.Storage.ProvisioningType;
|
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "service_offering")
|
@Table(name = "service_offering")
|
||||||
@DiscriminatorValue(value = "Service")
|
public class ServiceOfferingVO implements ServiceOffering {
|
||||||
@PrimaryKeyJoinColumn(name = "id")
|
|
||||||
public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering {
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@Column(name = "id")
|
||||||
|
long id;
|
||||||
|
|
||||||
|
@Column(name = "uuid")
|
||||||
|
private String uuid;
|
||||||
|
|
||||||
|
@Column(name = "name")
|
||||||
|
private String name = null;
|
||||||
|
|
||||||
|
@Column(name = "unique_name")
|
||||||
|
private String uniqueName;
|
||||||
|
|
||||||
|
@Column(name = "display_text", length = 4096)
|
||||||
|
private String displayText = null;
|
||||||
|
|
||||||
|
@Column(name = "customized")
|
||||||
|
private boolean customized;
|
||||||
|
|
||||||
|
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date removed;
|
||||||
|
|
||||||
|
@Column(name = GenericDao.CREATED_COLUMN)
|
||||||
|
private Date created;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(name = "state")
|
||||||
|
ServiceOffering.State state = ServiceOffering.State.Active;
|
||||||
|
|
||||||
|
@Column(name = "disk_offering_id")
|
||||||
|
private Long diskOfferingId;
|
||||||
|
|
||||||
|
@Column(name = "disk_offering_strictness")
|
||||||
|
private boolean diskOfferingStrictness = false;
|
||||||
|
|
||||||
@Column(name = "cpu")
|
@Column(name = "cpu")
|
||||||
private Integer cpu;
|
private Integer cpu;
|
||||||
@ -75,6 +116,9 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
@Column(name = "deployment_planner")
|
@Column(name = "deployment_planner")
|
||||||
private String deploymentPlanner = null;
|
private String deploymentPlanner = null;
|
||||||
|
|
||||||
|
@Column(name = "system_use")
|
||||||
|
private boolean systemUse;
|
||||||
|
|
||||||
@Column(name = "dynamic_scaling_enabled")
|
@Column(name = "dynamic_scaling_enabled")
|
||||||
private boolean dynamicScalingEnabled = true;
|
private boolean dynamicScalingEnabled = true;
|
||||||
|
|
||||||
@ -94,8 +138,7 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText,
|
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText,
|
||||||
ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
|
boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
|
||||||
super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true);
|
|
||||||
this.cpu = cpu;
|
this.cpu = cpu;
|
||||||
this.ramSize = ramSize;
|
this.ramSize = ramSize;
|
||||||
this.speed = speed;
|
this.speed = speed;
|
||||||
@ -106,12 +149,15 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
volatileVm = false;
|
volatileVm = false;
|
||||||
this.defaultUse = defaultUse;
|
this.defaultUse = defaultUse;
|
||||||
this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
|
this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
|
||||||
|
uuid = UUID.randomUUID().toString();
|
||||||
|
this.systemUse = systemUse;
|
||||||
|
this.name = name;
|
||||||
|
this.displayText = displayText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA,
|
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA,
|
||||||
boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
|
boolean limitResourceUse, boolean volatileVm, String displayText, boolean systemUse,
|
||||||
VirtualMachine.Type vmType, String hostTag, String deploymentPlanner, boolean dynamicScalingEnabled) {
|
VirtualMachine.Type vmType, String hostTag, String deploymentPlanner, boolean dynamicScalingEnabled, boolean isCustomized) {
|
||||||
super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true);
|
|
||||||
this.cpu = cpu;
|
this.cpu = cpu;
|
||||||
this.ramSize = ramSize;
|
this.ramSize = ramSize;
|
||||||
this.speed = speed;
|
this.speed = speed;
|
||||||
@ -123,23 +169,20 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
|
this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
|
||||||
this.hostTag = hostTag;
|
this.hostTag = hostTag;
|
||||||
this.deploymentPlanner = deploymentPlanner;
|
this.deploymentPlanner = deploymentPlanner;
|
||||||
|
uuid = UUID.randomUUID().toString();
|
||||||
|
this.systemUse = systemUse;
|
||||||
|
this.name = name;
|
||||||
|
this.displayText = displayText;
|
||||||
this.dynamicScalingEnabled = dynamicScalingEnabled;
|
this.dynamicScalingEnabled = dynamicScalingEnabled;
|
||||||
|
this.customized = isCustomized;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceOfferingVO(ServiceOfferingVO offering) {
|
public ServiceOfferingVO(ServiceOfferingVO offering) {
|
||||||
super(offering.getId(),
|
id = offering.getId();
|
||||||
offering.getName(),
|
diskOfferingId = offering.getDiskOfferingId();
|
||||||
offering.getDisplayText(),
|
name = offering.getName();
|
||||||
offering.getProvisioningType(),
|
displayText = offering.getDisplayText();
|
||||||
false,
|
customized = true;
|
||||||
offering.getTags(),
|
|
||||||
offering.isRecreatable(),
|
|
||||||
offering.isUseLocalStorage(),
|
|
||||||
offering.isSystemUse(),
|
|
||||||
true,
|
|
||||||
offering.isCustomizedIops()== null ? false:offering.isCustomizedIops(),
|
|
||||||
offering.getMinIops(),
|
|
||||||
offering.getMaxIops());
|
|
||||||
cpu = offering.getCpu();
|
cpu = offering.getCpu();
|
||||||
ramSize = offering.getRamSize();
|
ramSize = offering.getRamSize();
|
||||||
speed = offering.getSpeed();
|
speed = offering.getSpeed();
|
||||||
@ -150,6 +193,7 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
volatileVm = offering.isVolatileVm();
|
volatileVm = offering.isVolatileVm();
|
||||||
hostTag = offering.getHostTag();
|
hostTag = offering.getHostTag();
|
||||||
vmType = offering.getSystemVmType();
|
vmType = offering.getSystemVmType();
|
||||||
|
systemUse = offering.isSystemUse();
|
||||||
dynamicScalingEnabled = offering.isDynamicScalingEnabled();
|
dynamicScalingEnabled = offering.isDynamicScalingEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,17 +220,6 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
return defaultUse;
|
return defaultUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transient
|
|
||||||
public String[] getTagsArray() {
|
|
||||||
String tags = getTags();
|
|
||||||
if (tags == null || tags.length() == 0) {
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return tags.split(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer getCpu() {
|
public Integer getCpu() {
|
||||||
return cpu;
|
return cpu;
|
||||||
@ -297,6 +330,98 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
return isCustomized() && getDetail("minCPU") != null;
|
return isCustomized() && getDetail("minCPU") != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSystemUse() {
|
||||||
|
return systemUse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueName() {
|
||||||
|
return uniqueName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUniqueName(String uniqueName) {
|
||||||
|
this.uniqueName = uniqueName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayText() {
|
||||||
|
return displayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDisplayText(String displayText) {
|
||||||
|
this.displayText = displayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCustomized() {
|
||||||
|
return customized;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCustomized(boolean customized) {
|
||||||
|
this.customized = customized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoved(Date removed) {
|
||||||
|
this.removed = removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getRemoved() {
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServiceOffering.State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setState(ServiceOffering.State state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getDiskOfferingId() {
|
||||||
|
return diskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiskOfferingId(Long diskOfferingId) {
|
||||||
|
this.diskOfferingId = diskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("Service offering {\"id\": %s, \"name\": \"%s\", \"uuid\": \"%s\"}", getId(), getName(), getUuid());
|
return String.format("Service offering {\"id\": %s, \"name\": \"%s\", \"uuid\": \"%s\"}", getId(), getName(), getUuid());
|
||||||
@ -309,4 +434,12 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
public void setDynamicScalingEnabled(boolean dynamicScalingEnabled) {
|
public void setDynamicScalingEnabled(boolean dynamicScalingEnabled) {
|
||||||
this.dynamicScalingEnabled = dynamicScalingEnabled;
|
this.dynamicScalingEnabled = dynamicScalingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean getDiskOfferingStrictness() {
|
||||||
|
return diskOfferingStrictness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiskOfferingStrictness(boolean diskOfferingStrictness) {
|
||||||
|
this.diskOfferingStrictness = diskOfferingStrictness;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,4 +53,6 @@ public interface ServiceOfferingDao extends GenericDao<ServiceOfferingVO, Long>
|
|||||||
ServiceOfferingVO findDefaultSystemOffering(String offeringName, Boolean useLocalStorage);
|
ServiceOfferingVO findDefaultSystemOffering(String offeringName, Boolean useLocalStorage);
|
||||||
|
|
||||||
List<ServiceOfferingVO> listPublicByCpuAndMemory(Integer cpus, Integer memory);
|
List<ServiceOfferingVO> listPublicByCpuAndMemory(Integer cpus, Integer memory);
|
||||||
|
|
||||||
|
ServiceOfferingVO findServiceOfferingByComputeOnlyDiskOffering(long diskOfferingId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,8 @@ import java.util.Map;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.persistence.EntityExistsException;
|
import javax.persistence.EntityExistsException;
|
||||||
|
|
||||||
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
|
import com.cloud.storage.dao.DiskOfferingDao;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -48,17 +50,20 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
|||||||
protected ServiceOfferingDetailsDao detailsDao;
|
protected ServiceOfferingDetailsDao detailsDao;
|
||||||
@Inject
|
@Inject
|
||||||
protected UserVmDetailsDao userVmDetailsDao;
|
protected UserVmDetailsDao userVmDetailsDao;
|
||||||
|
@Inject
|
||||||
|
private DiskOfferingDao diskOfferingDao;
|
||||||
|
|
||||||
protected final SearchBuilder<ServiceOfferingVO> UniqueNameSearch;
|
protected final SearchBuilder<ServiceOfferingVO> UniqueNameSearch;
|
||||||
protected final SearchBuilder<ServiceOfferingVO> ServiceOfferingsByKeywordSearch;
|
protected final SearchBuilder<ServiceOfferingVO> ServiceOfferingsByKeywordSearch;
|
||||||
protected final SearchBuilder<ServiceOfferingVO> PublicCpuRamSearch;
|
protected final SearchBuilder<ServiceOfferingVO> PublicCpuRamSearch;
|
||||||
|
protected final SearchBuilder<ServiceOfferingVO> SearchComputeOfferingByComputeOnlyDiskOffering;
|
||||||
|
|
||||||
public ServiceOfferingDaoImpl() {
|
public ServiceOfferingDaoImpl() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
UniqueNameSearch = createSearchBuilder();
|
UniqueNameSearch = createSearchBuilder();
|
||||||
UniqueNameSearch.and("name", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
|
UniqueNameSearch.and("name", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
|
||||||
UniqueNameSearch.and("system", UniqueNameSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
|
UniqueNameSearch.and("system_use", UniqueNameSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
|
||||||
UniqueNameSearch.done();
|
UniqueNameSearch.done();
|
||||||
|
|
||||||
ServiceOfferingsByKeywordSearch = createSearchBuilder();
|
ServiceOfferingsByKeywordSearch = createSearchBuilder();
|
||||||
@ -71,13 +76,17 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
|||||||
PublicCpuRamSearch.and("ram", PublicCpuRamSearch.entity().getRamSize(), SearchCriteria.Op.EQ);
|
PublicCpuRamSearch.and("ram", PublicCpuRamSearch.entity().getRamSize(), SearchCriteria.Op.EQ);
|
||||||
PublicCpuRamSearch.and("system_use", PublicCpuRamSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
|
PublicCpuRamSearch.and("system_use", PublicCpuRamSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
|
||||||
PublicCpuRamSearch.done();
|
PublicCpuRamSearch.done();
|
||||||
|
|
||||||
|
SearchComputeOfferingByComputeOnlyDiskOffering = createSearchBuilder();
|
||||||
|
SearchComputeOfferingByComputeOnlyDiskOffering.and("disk_offering_id", SearchComputeOfferingByComputeOnlyDiskOffering.entity().getDiskOfferingId(), SearchCriteria.Op.EQ);
|
||||||
|
SearchComputeOfferingByComputeOnlyDiskOffering.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServiceOfferingVO findByName(String name) {
|
public ServiceOfferingVO findByName(String name) {
|
||||||
SearchCriteria<ServiceOfferingVO> sc = UniqueNameSearch.create();
|
SearchCriteria<ServiceOfferingVO> sc = UniqueNameSearch.create();
|
||||||
sc.setParameters("name", name);
|
sc.setParameters("name", name);
|
||||||
sc.setParameters("system", true);
|
sc.setParameters("system_use", true);
|
||||||
List<ServiceOfferingVO> vos = search(sc, null, null, false);
|
List<ServiceOfferingVO> vos = search(sc, null, null, false);
|
||||||
if (vos.size() == 0) {
|
if (vos.size() == 0) {
|
||||||
return null;
|
return null;
|
||||||
@ -92,13 +101,14 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
|||||||
assert offering.getUniqueName() != null : "how are you going to find this later if you don't set it?";
|
assert offering.getUniqueName() != null : "how are you going to find this later if you don't set it?";
|
||||||
ServiceOfferingVO vo = findByName(offering.getUniqueName());
|
ServiceOfferingVO vo = findByName(offering.getUniqueName());
|
||||||
if (vo != null) {
|
if (vo != null) {
|
||||||
|
DiskOfferingVO diskOfferingVO = diskOfferingDao.findById(vo.getDiskOfferingId());
|
||||||
// check invalid CPU speed in system service offering, set it to default value of 500 Mhz if 0 CPU speed is found
|
// check invalid CPU speed in system service offering, set it to default value of 500 Mhz if 0 CPU speed is found
|
||||||
if (vo.getSpeed() <= 0) {
|
if (vo.getSpeed() <= 0) {
|
||||||
vo.setSpeed(500);
|
vo.setSpeed(500);
|
||||||
update(vo.getId(), vo);
|
update(vo.getId(), vo);
|
||||||
}
|
}
|
||||||
if (!vo.getUniqueName().endsWith("-Local")) {
|
if (!vo.getUniqueName().endsWith("-Local")) {
|
||||||
if (vo.isUseLocalStorage()) {
|
if (diskOfferingVO.isUseLocalStorage()) {
|
||||||
vo.setUniqueName(vo.getUniqueName() + "-Local");
|
vo.setUniqueName(vo.getUniqueName() + "-Local");
|
||||||
vo.setName(vo.getName() + " - Local Storage");
|
vo.setName(vo.getName() + " - Local Storage");
|
||||||
update(vo.getId(), vo);
|
update(vo.getId(), vo);
|
||||||
@ -214,23 +224,33 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
|||||||
public List<ServiceOfferingVO> createSystemServiceOfferings(String name, String uniqueName, int cpuCount, int ramSize, int cpuSpeed,
|
public List<ServiceOfferingVO> createSystemServiceOfferings(String name, String uniqueName, int cpuCount, int ramSize, int cpuSpeed,
|
||||||
Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText, ProvisioningType provisioningType,
|
Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText, ProvisioningType provisioningType,
|
||||||
boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
|
boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
|
||||||
|
DiskOfferingVO diskOfferingVO = new DiskOfferingVO(name, displayText, provisioningType, false, tags, recreatable, false, true);
|
||||||
|
diskOfferingVO.setUniqueName(uniqueName);
|
||||||
|
diskOfferingVO = diskOfferingDao.persistDefaultDiskOffering(diskOfferingVO);
|
||||||
|
|
||||||
List<ServiceOfferingVO> list = new ArrayList<ServiceOfferingVO>();
|
List<ServiceOfferingVO> list = new ArrayList<ServiceOfferingVO>();
|
||||||
ServiceOfferingVO offering = new ServiceOfferingVO(name, cpuCount, ramSize, cpuSpeed, rateMbps, multicastRateMbps, offerHA, displayText,
|
ServiceOfferingVO offering = new ServiceOfferingVO(name, cpuCount, ramSize, cpuSpeed, rateMbps, multicastRateMbps, offerHA, displayText,
|
||||||
provisioningType, false, recreatable, tags, systemUse, vmType, defaultUse);
|
systemUse, vmType, defaultUse);
|
||||||
offering.setUniqueName(uniqueName);
|
offering.setUniqueName(uniqueName);
|
||||||
|
offering.setDiskOfferingId(diskOfferingVO.getId());
|
||||||
offering = persistSystemServiceOffering(offering);
|
offering = persistSystemServiceOffering(offering);
|
||||||
if (offering != null) {
|
if (offering != null) {
|
||||||
list.add(offering);
|
list.add(offering);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean useLocal = true;
|
boolean useLocal = true;
|
||||||
if (offering.isUseLocalStorage()) { // if 1st one is already local then 2nd needs to be shared
|
if (diskOfferingVO.isUseLocalStorage()) { // if 1st one is already local then 2nd needs to be shared
|
||||||
useLocal = false;
|
useLocal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diskOfferingVO = new DiskOfferingVO(name + (useLocal ? " - Local Storage" : ""), displayText, provisioningType, false, tags, recreatable, useLocal, true);
|
||||||
|
diskOfferingVO.setUniqueName(uniqueName + (useLocal ? "-Local" : ""));
|
||||||
|
diskOfferingVO = diskOfferingDao.persistDefaultDiskOffering(diskOfferingVO);
|
||||||
|
|
||||||
offering = new ServiceOfferingVO(name + (useLocal ? " - Local Storage" : ""), cpuCount, ramSize, cpuSpeed, rateMbps, multicastRateMbps, offerHA, displayText,
|
offering = new ServiceOfferingVO(name + (useLocal ? " - Local Storage" : ""), cpuCount, ramSize, cpuSpeed, rateMbps, multicastRateMbps, offerHA, displayText,
|
||||||
provisioningType, useLocal, recreatable, tags, systemUse, vmType, defaultUse);
|
systemUse, vmType, defaultUse);
|
||||||
offering.setUniqueName(uniqueName + (useLocal ? "-Local" : ""));
|
offering.setUniqueName(uniqueName + (useLocal ? "-Local" : ""));
|
||||||
|
offering.setDiskOfferingId(diskOfferingVO.getId());
|
||||||
offering = persistSystemServiceOffering(offering);
|
offering = persistSystemServiceOffering(offering);
|
||||||
if (offering != null) {
|
if (offering != null) {
|
||||||
list.add(offering);
|
list.add(offering);
|
||||||
@ -262,4 +282,15 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
|||||||
sc.setParameters("system_use", false);
|
sc.setParameters("system_use", false);
|
||||||
return listBy(sc);
|
return listBy(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServiceOfferingVO findServiceOfferingByComputeOnlyDiskOffering(long diskOfferingId) {
|
||||||
|
SearchCriteria<ServiceOfferingVO> sc = SearchComputeOfferingByComputeOnlyDiskOffering.create();
|
||||||
|
sc.setParameters("disk_offering_id", diskOfferingId);
|
||||||
|
List<ServiceOfferingVO> vos = listBy(sc);
|
||||||
|
if (vos.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return vos.get(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,16 +21,12 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.DiscriminatorColumn;
|
|
||||||
import javax.persistence.DiscriminatorType;
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
import javax.persistence.Enumerated;
|
import javax.persistence.Enumerated;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Inheritance;
|
|
||||||
import javax.persistence.InheritanceType;
|
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.Temporal;
|
import javax.persistence.Temporal;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
@ -41,8 +37,6 @@ import com.cloud.utils.db.GenericDao;
|
|||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "disk_offering")
|
@Table(name = "disk_offering")
|
||||||
@Inheritance(strategy = InheritanceType.JOINED)
|
|
||||||
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING, length = 32)
|
|
||||||
public class DiskOfferingVO implements DiskOffering {
|
public class DiskOfferingVO implements DiskOffering {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@ -65,8 +59,8 @@ public class DiskOfferingVO implements DiskOffering {
|
|||||||
@Column(name = "tags", length = 4096)
|
@Column(name = "tags", length = 4096)
|
||||||
String tags;
|
String tags;
|
||||||
|
|
||||||
@Column(name = "type")
|
@Column(name = "compute_only")
|
||||||
Type type;
|
boolean computeOnly;
|
||||||
|
|
||||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
@ -81,9 +75,6 @@ public class DiskOfferingVO implements DiskOffering {
|
|||||||
@Column(name = "use_local_storage")
|
@Column(name = "use_local_storage")
|
||||||
private boolean useLocalStorage;
|
private boolean useLocalStorage;
|
||||||
|
|
||||||
@Column(name = "system_use")
|
|
||||||
private boolean systemUse;
|
|
||||||
|
|
||||||
@Column(name = "customized")
|
@Column(name = "customized")
|
||||||
private boolean customized;
|
private boolean customized;
|
||||||
|
|
||||||
@ -156,6 +147,9 @@ public class DiskOfferingVO implements DiskOffering {
|
|||||||
@Column(name = "hv_ss_reserve")
|
@Column(name = "hv_ss_reserve")
|
||||||
Integer hypervisorSnapshotReserve;
|
Integer hypervisorSnapshotReserve;
|
||||||
|
|
||||||
|
@Column(name = "disk_size_strictness")
|
||||||
|
boolean diskSizeStrictness = false;
|
||||||
|
|
||||||
public DiskOfferingVO() {
|
public DiskOfferingVO() {
|
||||||
uuid = UUID.randomUUID().toString();
|
uuid = UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
@ -168,7 +162,7 @@ public class DiskOfferingVO implements DiskOffering {
|
|||||||
this.diskSize = diskSize;
|
this.diskSize = diskSize;
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
recreatable = false;
|
recreatable = false;
|
||||||
type = Type.Disk;
|
computeOnly = false;
|
||||||
useLocalStorage = false;
|
useLocalStorage = false;
|
||||||
customized = isCustomized;
|
customized = isCustomized;
|
||||||
uuid = UUID.randomUUID().toString();
|
uuid = UUID.randomUUID().toString();
|
||||||
@ -186,7 +180,7 @@ public class DiskOfferingVO implements DiskOffering {
|
|||||||
this.diskSize = diskSize;
|
this.diskSize = diskSize;
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
recreatable = false;
|
recreatable = false;
|
||||||
type = Type.Disk;
|
computeOnly = false;
|
||||||
useLocalStorage = false;
|
useLocalStorage = false;
|
||||||
customized = isCustomized;
|
customized = isCustomized;
|
||||||
uuid = UUID.randomUUID().toString();
|
uuid = UUID.randomUUID().toString();
|
||||||
@ -196,32 +190,30 @@ public class DiskOfferingVO implements DiskOffering {
|
|||||||
state = State.Active;
|
state = State.Active;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiskOfferingVO(String name, String displayText, Storage.ProvisioningType provisioningType, boolean mirrored, String tags, boolean recreatable, boolean useLocalStorage, boolean systemUse,
|
public DiskOfferingVO(String name, String displayText, Storage.ProvisioningType provisioningType, boolean mirrored, String tags, boolean recreatable, boolean useLocalStorage,
|
||||||
boolean customized) {
|
boolean customized) {
|
||||||
type = Type.Service;
|
computeOnly = true;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.displayText = displayText;
|
this.displayText = displayText;
|
||||||
this.provisioningType = provisioningType;
|
this.provisioningType = provisioningType;
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
this.recreatable = recreatable;
|
this.recreatable = recreatable;
|
||||||
this.useLocalStorage = useLocalStorage;
|
this.useLocalStorage = useLocalStorage;
|
||||||
this.systemUse = systemUse;
|
|
||||||
this.customized = customized;
|
this.customized = customized;
|
||||||
uuid = UUID.randomUUID().toString();
|
uuid = UUID.randomUUID().toString();
|
||||||
state = State.Active;
|
state = State.Active;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiskOfferingVO(long id, String name, String displayText, Storage.ProvisioningType provisioningType, boolean mirrored, String tags, boolean recreatable, boolean useLocalStorage,
|
public DiskOfferingVO(long id, String name, String displayText, Storage.ProvisioningType provisioningType, boolean mirrored, String tags, boolean recreatable, boolean useLocalStorage,
|
||||||
boolean systemUse, boolean customized, boolean customizedIops, Long minIops, Long maxIops) {
|
boolean customized, boolean customizedIops, Long minIops, Long maxIops) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
type = Type.Service;
|
computeOnly = true;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.displayText = displayText;
|
this.displayText = displayText;
|
||||||
this.provisioningType = provisioningType;
|
this.provisioningType = provisioningType;
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
this.recreatable = recreatable;
|
this.recreatable = recreatable;
|
||||||
this.useLocalStorage = useLocalStorage;
|
this.useLocalStorage = useLocalStorage;
|
||||||
this.systemUse = systemUse;
|
|
||||||
this.customized = customized;
|
this.customized = customized;
|
||||||
this.customizedIops = customizedIops;
|
this.customizedIops = customizedIops;
|
||||||
uuid = UUID.randomUUID().toString();
|
uuid = UUID.randomUUID().toString();
|
||||||
@ -304,8 +296,8 @@ public class DiskOfferingVO implements DiskOffering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type getType() {
|
public boolean isComputeOnly() {
|
||||||
return type;
|
return computeOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -322,15 +314,6 @@ public class DiskOfferingVO implements DiskOffering {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSystemUse() {
|
|
||||||
return systemUse;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSystemUse(boolean systemUse) {
|
|
||||||
this.systemUse = systemUse;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayText() {
|
public String getDisplayText() {
|
||||||
return displayText;
|
return displayText;
|
||||||
@ -588,4 +571,12 @@ public class DiskOfferingVO implements DiskOffering {
|
|||||||
public boolean isShared() {
|
public boolean isShared() {
|
||||||
return !useLocalStorage;
|
return !useLocalStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getDiskSizeStrictness() {
|
||||||
|
return diskSizeStrictness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiskSizeStrictness(boolean diskSizeStrictness) {
|
||||||
|
this.diskSizeStrictness = diskSizeStrictness;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,13 +24,9 @@ import com.cloud.utils.db.GenericDao;
|
|||||||
|
|
||||||
public interface DiskOfferingDao extends GenericDao<DiskOfferingVO, Long> {
|
public interface DiskOfferingDao extends GenericDao<DiskOfferingVO, Long> {
|
||||||
|
|
||||||
List<DiskOfferingVO> findPrivateDiskOffering();
|
|
||||||
|
|
||||||
List<DiskOfferingVO> findPublicDiskOfferings();
|
|
||||||
|
|
||||||
DiskOfferingVO findByUniqueName(String uniqueName);
|
DiskOfferingVO findByUniqueName(String uniqueName);
|
||||||
|
|
||||||
DiskOfferingVO persistDeafultDiskOffering(DiskOfferingVO offering);
|
DiskOfferingVO persistDefaultDiskOffering(DiskOfferingVO offering);
|
||||||
|
|
||||||
List<DiskOfferingVO> listAllBySizeAndProvisioningType(long size, Storage.ProvisioningType provisioningType);
|
List<DiskOfferingVO> listAllBySizeAndProvisioningType(long size, Storage.ProvisioningType provisioningType);
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,6 @@ import javax.persistence.EntityExistsException;
|
|||||||
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
|
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.cloud.offering.DiskOffering.Type;
|
|
||||||
import com.cloud.storage.DiskOfferingVO;
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
import com.cloud.storage.Storage;
|
import com.cloud.storage.Storage;
|
||||||
import com.cloud.utils.db.Attribute;
|
import com.cloud.utils.db.Attribute;
|
||||||
@ -37,7 +36,6 @@ import com.cloud.utils.db.Filter;
|
|||||||
import com.cloud.utils.db.GenericDaoBase;
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
import com.cloud.utils.db.SearchCriteria.Op;
|
|
||||||
import com.cloud.utils.db.TransactionLegacy;
|
import com.cloud.utils.db.TransactionLegacy;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
@ -47,48 +45,28 @@ public class DiskOfferingDaoImpl extends GenericDaoBase<DiskOfferingVO, Long> im
|
|||||||
@Inject
|
@Inject
|
||||||
protected DiskOfferingDetailsDao detailsDao;
|
protected DiskOfferingDetailsDao detailsDao;
|
||||||
|
|
||||||
private final SearchBuilder<DiskOfferingVO> PrivateDiskOfferingSearch;
|
|
||||||
private final SearchBuilder<DiskOfferingVO> PublicDiskOfferingSearch;
|
|
||||||
protected final SearchBuilder<DiskOfferingVO> UniqueNameSearch;
|
protected final SearchBuilder<DiskOfferingVO> UniqueNameSearch;
|
||||||
private final String SizeDiskOfferingSearch = "SELECT * FROM disk_offering WHERE " +
|
private final String SizeDiskOfferingSearch = "SELECT * FROM disk_offering WHERE " +
|
||||||
"disk_size = ? AND provisioning_type = ? AND removed IS NULL";
|
"disk_size = ? AND provisioning_type = ? AND removed IS NULL";
|
||||||
|
|
||||||
private final Attribute _typeAttr;
|
private final Attribute _computeOnlyAttr;
|
||||||
protected final static long GB_UNIT_BYTES = 1024 * 1024 * 1024;
|
protected final static long GB_UNIT_BYTES = 1024 * 1024 * 1024;
|
||||||
|
|
||||||
protected DiskOfferingDaoImpl() {
|
protected DiskOfferingDaoImpl() {
|
||||||
PrivateDiskOfferingSearch = createSearchBuilder();
|
|
||||||
PrivateDiskOfferingSearch.and("diskSize", PrivateDiskOfferingSearch.entity().getDiskSize(), SearchCriteria.Op.EQ);
|
|
||||||
PrivateDiskOfferingSearch.done();
|
|
||||||
|
|
||||||
PublicDiskOfferingSearch = createSearchBuilder();
|
|
||||||
PublicDiskOfferingSearch.and("system", PublicDiskOfferingSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
|
|
||||||
PublicDiskOfferingSearch.and("removed", PublicDiskOfferingSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
|
|
||||||
PublicDiskOfferingSearch.done();
|
|
||||||
|
|
||||||
UniqueNameSearch = createSearchBuilder();
|
UniqueNameSearch = createSearchBuilder();
|
||||||
UniqueNameSearch.and("name", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
|
UniqueNameSearch.and("name", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
|
||||||
UniqueNameSearch.done();
|
UniqueNameSearch.done();
|
||||||
|
|
||||||
_typeAttr = _allAttributes.get("type");
|
_computeOnlyAttr = _allAttributes.get("computeOnly");
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<DiskOfferingVO> findPrivateDiskOffering() {
|
|
||||||
SearchCriteria<DiskOfferingVO> sc = PrivateDiskOfferingSearch.create();
|
|
||||||
sc.setParameters("diskSize", 0);
|
|
||||||
return listBy(sc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DiskOfferingVO> searchIncludingRemoved(SearchCriteria<DiskOfferingVO> sc, final Filter filter, final Boolean lock, final boolean cache) {
|
public List<DiskOfferingVO> searchIncludingRemoved(SearchCriteria<DiskOfferingVO> sc, final Filter filter, final Boolean lock, final boolean cache) {
|
||||||
sc.addAnd(_typeAttr, Op.EQ, Type.Disk);
|
|
||||||
return super.searchIncludingRemoved(sc, filter, lock, cache);
|
return super.searchIncludingRemoved(sc, filter, lock, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <K> List<K> customSearchIncludingRemoved(SearchCriteria<K> sc, final Filter filter) {
|
public <K> List<K> customSearchIncludingRemoved(SearchCriteria<K> sc, final Filter filter) {
|
||||||
sc.addAnd(_typeAttr, Op.EQ, Type.Disk);
|
|
||||||
return super.customSearchIncludingRemoved(sc, filter);
|
return super.customSearchIncludingRemoved(sc, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,23 +75,12 @@ public class DiskOfferingDaoImpl extends GenericDaoBase<DiskOfferingVO, Long> im
|
|||||||
StringBuilder builder = new StringBuilder(sql);
|
StringBuilder builder = new StringBuilder(sql);
|
||||||
int index = builder.indexOf("WHERE");
|
int index = builder.indexOf("WHERE");
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
builder.append(" WHERE type=?");
|
builder.append(" WHERE compute_only=?");
|
||||||
} else {
|
} else {
|
||||||
builder.insert(index + 6, "type=? ");
|
builder.insert(index + 6, "compute_only=? ");
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.executeList(sql, Type.Disk, params);
|
return super.executeList(sql, false, params);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<DiskOfferingVO> findPublicDiskOfferings() {
|
|
||||||
SearchCriteria<DiskOfferingVO> sc = PublicDiskOfferingSearch.create();
|
|
||||||
sc.setParameters("system", false);
|
|
||||||
List<DiskOfferingVO> offerings = listBy(sc);
|
|
||||||
if(offerings!=null) {
|
|
||||||
offerings.removeIf(o -> (!detailsDao.findDomainIds(o.getId()).isEmpty()));
|
|
||||||
}
|
|
||||||
return offerings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -129,7 +96,7 @@ public class DiskOfferingDaoImpl extends GenericDaoBase<DiskOfferingVO, Long> im
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiskOfferingVO persistDeafultDiskOffering(DiskOfferingVO offering) {
|
public DiskOfferingVO persistDefaultDiskOffering(DiskOfferingVO offering) {
|
||||||
assert offering.getUniqueName() != null : "unique name shouldn't be null for the disk offering";
|
assert offering.getUniqueName() != null : "unique name shouldn't be null for the disk offering";
|
||||||
DiskOfferingVO vo = findByUniqueName(offering.getUniqueName());
|
DiskOfferingVO vo = findByUniqueName(offering.getUniqueName());
|
||||||
if (vo != null) {
|
if (vo != null) {
|
||||||
|
|||||||
@ -73,8 +73,8 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public UserVmVO(long id, String instanceName, String displayName, long templateId, HypervisorType hypervisorType, long guestOsId, boolean haEnabled,
|
public UserVmVO(long id, String instanceName, String displayName, long templateId, HypervisorType hypervisorType, long guestOsId, boolean haEnabled,
|
||||||
boolean limitCpuUse, long domainId, long accountId, long userId, long serviceOfferingId, String userData, String name, Long diskOfferingId) {
|
boolean limitCpuUse, long domainId, long accountId, long userId, long serviceOfferingId, String userData, String name) {
|
||||||
super(id, serviceOfferingId, name, instanceName, Type.User, templateId, hypervisorType, guestOsId, domainId, accountId, userId, haEnabled, limitCpuUse, diskOfferingId);
|
super(id, serviceOfferingId, name, instanceName, Type.User, templateId, hypervisorType, guestOsId, domainId, accountId, userId, haEnabled, limitCpuUse);
|
||||||
this.userData = userData;
|
this.userData = userData;
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
this.details = new HashMap<String, String>();
|
this.details = new HashMap<String, String>();
|
||||||
|
|||||||
@ -174,9 +174,6 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
|
|||||||
@Column(name = "uuid")
|
@Column(name = "uuid")
|
||||||
protected String uuid = UUID.randomUUID().toString();
|
protected String uuid = UUID.randomUUID().toString();
|
||||||
|
|
||||||
@Column(name = "disk_offering_id")
|
|
||||||
protected Long diskOfferingId;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Power state for VM state sync
|
// Power state for VM state sync
|
||||||
//
|
//
|
||||||
@ -232,10 +229,9 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
|
|||||||
}
|
}
|
||||||
|
|
||||||
public VMInstanceVO(long id, long serviceOfferingId, String name, String instanceName, Type type, Long vmTemplateId, HypervisorType hypervisorType, long guestOSId,
|
public VMInstanceVO(long id, long serviceOfferingId, String name, String instanceName, Type type, Long vmTemplateId, HypervisorType hypervisorType, long guestOSId,
|
||||||
long domainId, long accountId, long userId, boolean haEnabled, boolean limitResourceUse, Long diskOfferingId) {
|
long domainId, long accountId, long userId, boolean haEnabled, boolean limitResourceUse) {
|
||||||
this(id, serviceOfferingId, name, instanceName, type, vmTemplateId, hypervisorType, guestOSId, domainId, accountId, userId, haEnabled);
|
this(id, serviceOfferingId, name, instanceName, type, vmTemplateId, hypervisorType, guestOSId, domainId, accountId, userId, haEnabled);
|
||||||
limitCpuUse = limitResourceUse;
|
limitCpuUse = limitResourceUse;
|
||||||
this.diskOfferingId = diskOfferingId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public VMInstanceVO() {
|
public VMInstanceVO() {
|
||||||
@ -535,11 +531,6 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
|
|||||||
this.serviceOfferingId = serviceOfferingId;
|
this.serviceOfferingId = serviceOfferingId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long getDiskOfferingId() {
|
|
||||||
return diskOfferingId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDynamicallyScalable(boolean dynamicallyScalable) {
|
public void setDynamicallyScalable(boolean dynamicallyScalable) {
|
||||||
this.dynamicallyScalable = dynamicallyScalable;
|
this.dynamicallyScalable = dynamicallyScalable;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -174,9 +174,6 @@ public class VMEntityVO implements VirtualMachine, FiniteStateObject<State, Virt
|
|||||||
@Transient
|
@Transient
|
||||||
List<String> networkIds;
|
List<String> networkIds;
|
||||||
|
|
||||||
@Column(name = "disk_offering_id")
|
|
||||||
protected Long diskOfferingId;
|
|
||||||
|
|
||||||
@Column(name = "display_vm", updatable = true, nullable = false)
|
@Column(name = "display_vm", updatable = true, nullable = false)
|
||||||
protected boolean display = true;
|
protected boolean display = true;
|
||||||
|
|
||||||
@ -196,7 +193,7 @@ public class VMEntityVO implements VirtualMachine, FiniteStateObject<State, Virt
|
|||||||
private VMReservationVO vmReservation;
|
private VMReservationVO vmReservation;
|
||||||
|
|
||||||
public VMEntityVO(long id, long serviceOfferingId, String name, String instanceName, Type type, Long vmTemplateId, HypervisorType hypervisorType, long guestOSId,
|
public VMEntityVO(long id, long serviceOfferingId, String name, String instanceName, Type type, Long vmTemplateId, HypervisorType hypervisorType, long guestOSId,
|
||||||
long domainId, long accountId, boolean haEnabled, Long diskOfferingId) {
|
long domainId, long accountId, boolean haEnabled) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
hostName = name != null ? name : uuid;
|
hostName = name != null ? name : uuid;
|
||||||
if (vmTemplateId != null) {
|
if (vmTemplateId != null) {
|
||||||
@ -213,12 +210,11 @@ public class VMEntityVO implements VirtualMachine, FiniteStateObject<State, Virt
|
|||||||
this.serviceOfferingId = serviceOfferingId;
|
this.serviceOfferingId = serviceOfferingId;
|
||||||
this.hypervisorType = hypervisorType;
|
this.hypervisorType = hypervisorType;
|
||||||
limitCpuUse = false;
|
limitCpuUse = false;
|
||||||
this.diskOfferingId = diskOfferingId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public VMEntityVO(long id, long serviceOfferingId, String name, String instanceName, Type type, Long vmTemplateId, HypervisorType hypervisorType, long guestOSId,
|
public VMEntityVO(long id, long serviceOfferingId, String name, String instanceName, Type type, Long vmTemplateId, HypervisorType hypervisorType, long guestOSId,
|
||||||
long domainId, long accountId, boolean haEnabled, boolean limitResourceUse) {
|
long domainId, long accountId, boolean haEnabled, boolean limitResourceUse) {
|
||||||
this(id, serviceOfferingId, name, instanceName, type, vmTemplateId, hypervisorType, guestOSId, domainId, accountId, haEnabled, null);
|
this(id, serviceOfferingId, name, instanceName, type, vmTemplateId, hypervisorType, guestOSId, domainId, accountId, haEnabled);
|
||||||
limitCpuUse = limitResourceUse;
|
limitCpuUse = limitResourceUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,11 +537,6 @@ public class VMEntityVO implements VirtualMachine, FiniteStateObject<State, Virt
|
|||||||
this.networkIds = networkIds;
|
this.networkIds = networkIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long getDiskOfferingId() {
|
|
||||||
return diskOfferingId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VMReservationVO getVmReservation() {
|
public VMReservationVO getVmReservation() {
|
||||||
return vmReservation;
|
return vmReservation;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,3 +21,621 @@
|
|||||||
|
|
||||||
-- PR#5668 Change the type of the 'ipsec_psk' field to allow large PSK.
|
-- PR#5668 Change the type of the 'ipsec_psk' field to allow large PSK.
|
||||||
ALTER TABLE cloud.remote_access_vpn MODIFY ipsec_psk text NOT NULL;
|
ALTER TABLE cloud.remote_access_vpn MODIFY ipsec_psk text NOT NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `uuid` varchar(40) UNIQUE DEFAULT NULL;
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `name` varchar(255) NOT NULL;
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `display_text` varchar(4096) DEFAULT NULL ;
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `unique_name` varchar(32) DEFAULT NULL COMMENT 'unique name for system offerings';
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `customized` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '0 implies not customized by default';
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `created` datetime DEFAULT NULL COMMENT 'date when service offering was created';
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `removed` datetime DEFAULT NULL COMMENT 'date when service offering was removed';
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `state` CHAR(40) NOT NULL DEFAULT 'Active' COMMENT 'state of service offering either Active or Inactive';
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `disk_offering_id` bigint unsigned;
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `system_use` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'is this offering for system used only';
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `disk_offering_strictness` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'strict binding with disk offering or not';
|
||||||
|
ALTER TABLE `cloud`.`service_offering` ADD CONSTRAINT `fk_service_offering__disk_offering_id` FOREIGN KEY `fk_service_offering__disk_offering_id`(`disk_offering_id`) REFERENCES `disk_offering`(`id`) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE `cloud`.`service_offering` DROP FOREIGN KEY `fk_service_offering__id`;
|
||||||
|
|
||||||
|
ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `disk_size_strictness` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'To allow or disallow the resize operation on the disks created from this offering';
|
||||||
|
ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `compute_only` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'when set to 1, disk offering has one to one binding with service offering';
|
||||||
|
|
||||||
|
ALTER TABLE `cloud`.`vm_instance` DROP COLUMN `disk_offering_id`;
|
||||||
|
|
||||||
|
UPDATE `cloud`.`service_offering` so, `cloud`.`disk_offering` do SET so.`uuid` = do.`uuid`,
|
||||||
|
so.`name` = do.`name`,
|
||||||
|
so.`display_text` = do.`display_text`,
|
||||||
|
so.`unique_name` = do.`unique_name`,
|
||||||
|
so.`customized` = do.`customized`,
|
||||||
|
so.`created` = do.`created`,
|
||||||
|
so.`removed` = do.`removed`,
|
||||||
|
so.`state` = do.`state`,
|
||||||
|
so.`disk_offering_id` = do.`id`,
|
||||||
|
so.`system_use` = do.`system_use` WHERE so.`id` = do.`id`;
|
||||||
|
|
||||||
|
UPDATE `cloud`.`disk_offering` SET `compute_only` = 1 where `type` = 'Service';
|
||||||
|
UPDATE `cloud`.`disk_offering` SET `disk_size_strictness` = 1 WHERE `compute_only` = 1 AND `disk_size` != 0;
|
||||||
|
|
||||||
|
ALTER TABLE `cloud`.`disk_offering` DROP COLUMN `type`;
|
||||||
|
ALTER TABLE `cloud`.`disk_offering` DROP COLUMN `system_use`;
|
||||||
|
|
||||||
|
DROP VIEW IF EXISTS `cloud`.`disk_offering_view`;
|
||||||
|
CREATE VIEW `cloud`.`disk_offering_view` AS
|
||||||
|
SELECT
|
||||||
|
`disk_offering`.`id` AS `id`,
|
||||||
|
`disk_offering`.`uuid` AS `uuid`,
|
||||||
|
`disk_offering`.`name` AS `name`,
|
||||||
|
`disk_offering`.`display_text` AS `display_text`,
|
||||||
|
`disk_offering`.`provisioning_type` AS `provisioning_type`,
|
||||||
|
`disk_offering`.`disk_size` AS `disk_size`,
|
||||||
|
`disk_offering`.`min_iops` AS `min_iops`,
|
||||||
|
`disk_offering`.`max_iops` AS `max_iops`,
|
||||||
|
`disk_offering`.`created` AS `created`,
|
||||||
|
`disk_offering`.`tags` AS `tags`,
|
||||||
|
`disk_offering`.`customized` AS `customized`,
|
||||||
|
`disk_offering`.`customized_iops` AS `customized_iops`,
|
||||||
|
`disk_offering`.`removed` AS `removed`,
|
||||||
|
`disk_offering`.`use_local_storage` AS `use_local_storage`,
|
||||||
|
`disk_offering`.`hv_ss_reserve` AS `hv_ss_reserve`,
|
||||||
|
`disk_offering`.`bytes_read_rate` AS `bytes_read_rate`,
|
||||||
|
`disk_offering`.`bytes_read_rate_max` AS `bytes_read_rate_max`,
|
||||||
|
`disk_offering`.`bytes_read_rate_max_length` AS `bytes_read_rate_max_length`,
|
||||||
|
`disk_offering`.`bytes_write_rate` AS `bytes_write_rate`,
|
||||||
|
`disk_offering`.`bytes_write_rate_max` AS `bytes_write_rate_max`,
|
||||||
|
`disk_offering`.`bytes_write_rate_max_length` AS `bytes_write_rate_max_length`,
|
||||||
|
`disk_offering`.`iops_read_rate` AS `iops_read_rate`,
|
||||||
|
`disk_offering`.`iops_read_rate_max` AS `iops_read_rate_max`,
|
||||||
|
`disk_offering`.`iops_read_rate_max_length` AS `iops_read_rate_max_length`,
|
||||||
|
`disk_offering`.`iops_write_rate` AS `iops_write_rate`,
|
||||||
|
`disk_offering`.`iops_write_rate_max` AS `iops_write_rate_max`,
|
||||||
|
`disk_offering`.`iops_write_rate_max_length` AS `iops_write_rate_max_length`,
|
||||||
|
`disk_offering`.`cache_mode` AS `cache_mode`,
|
||||||
|
`disk_offering`.`sort_key` AS `sort_key`,
|
||||||
|
`disk_offering`.`compute_only` AS `compute_only`,
|
||||||
|
`disk_offering`.`display_offering` AS `display_offering`,
|
||||||
|
`disk_offering`.`state` AS `state`,
|
||||||
|
`disk_offering`.`disk_size_strictness` AS `disk_size_strictness`,
|
||||||
|
`vsphere_storage_policy`.`value` AS `vsphere_storage_policy`,
|
||||||
|
GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id,
|
||||||
|
GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid,
|
||||||
|
GROUP_CONCAT(DISTINCT(domain.name)) AS domain_name,
|
||||||
|
GROUP_CONCAT(DISTINCT(domain.path)) AS domain_path,
|
||||||
|
GROUP_CONCAT(DISTINCT(zone.id)) AS zone_id,
|
||||||
|
GROUP_CONCAT(DISTINCT(zone.uuid)) AS zone_uuid,
|
||||||
|
GROUP_CONCAT(DISTINCT(zone.name)) AS zone_name
|
||||||
|
FROM
|
||||||
|
`cloud`.`disk_offering`
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`disk_offering_details` AS `domain_details` ON `domain_details`.`offering_id` = `disk_offering`.`id` AND `domain_details`.`name`='domainid'
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`domain` AS `domain` ON FIND_IN_SET(`domain`.`id`, `domain_details`.`value`)
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`disk_offering_details` AS `zone_details` ON `zone_details`.`offering_id` = `disk_offering`.`id` AND `zone_details`.`name`='zoneid'
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`data_center` AS `zone` ON FIND_IN_SET(`zone`.`id`, `zone_details`.`value`)
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`disk_offering_details` AS `vsphere_storage_policy` ON `vsphere_storage_policy`.`offering_id` = `disk_offering`.`id`
|
||||||
|
AND `vsphere_storage_policy`.`name` = 'storagepolicy'
|
||||||
|
WHERE
|
||||||
|
`disk_offering`.`state`='Active'
|
||||||
|
GROUP BY
|
||||||
|
`disk_offering`.`id`;
|
||||||
|
|
||||||
|
DROP VIEW IF EXISTS `cloud`.`service_offering_view`;
|
||||||
|
CREATE VIEW `cloud`.`service_offering_view` AS
|
||||||
|
SELECT
|
||||||
|
`service_offering`.`id` AS `id`,
|
||||||
|
`service_offering`.`uuid` AS `uuid`,
|
||||||
|
`service_offering`.`name` AS `name`,
|
||||||
|
`service_offering`.`display_text` AS `display_text`,
|
||||||
|
`disk_offering`.`provisioning_type` AS `provisioning_type`,
|
||||||
|
`service_offering`.`created` AS `created`,
|
||||||
|
`disk_offering`.`tags` AS `tags`,
|
||||||
|
`service_offering`.`removed` AS `removed`,
|
||||||
|
`disk_offering`.`use_local_storage` AS `use_local_storage`,
|
||||||
|
`service_offering`.`system_use` AS `system_use`,
|
||||||
|
`disk_offering`.`id` AS `disk_offering_id`,
|
||||||
|
`disk_offering`.`name` AS `disk_offering_name`,
|
||||||
|
`disk_offering`.`uuid` AS `disk_offering_uuid`,
|
||||||
|
`disk_offering`.`display_text` AS `disk_offering_display_text`,
|
||||||
|
`disk_offering`.`customized_iops` AS `customized_iops`,
|
||||||
|
`disk_offering`.`min_iops` AS `min_iops`,
|
||||||
|
`disk_offering`.`max_iops` AS `max_iops`,
|
||||||
|
`disk_offering`.`hv_ss_reserve` AS `hv_ss_reserve`,
|
||||||
|
`disk_offering`.`bytes_read_rate` AS `bytes_read_rate`,
|
||||||
|
`disk_offering`.`bytes_read_rate_max` AS `bytes_read_rate_max`,
|
||||||
|
`disk_offering`.`bytes_read_rate_max_length` AS `bytes_read_rate_max_length`,
|
||||||
|
`disk_offering`.`bytes_write_rate` AS `bytes_write_rate`,
|
||||||
|
`disk_offering`.`bytes_write_rate_max` AS `bytes_write_rate_max`,
|
||||||
|
`disk_offering`.`bytes_write_rate_max_length` AS `bytes_write_rate_max_length`,
|
||||||
|
`disk_offering`.`iops_read_rate` AS `iops_read_rate`,
|
||||||
|
`disk_offering`.`iops_read_rate_max` AS `iops_read_rate_max`,
|
||||||
|
`disk_offering`.`iops_read_rate_max_length` AS `iops_read_rate_max_length`,
|
||||||
|
`disk_offering`.`iops_write_rate` AS `iops_write_rate`,
|
||||||
|
`disk_offering`.`iops_write_rate_max` AS `iops_write_rate_max`,
|
||||||
|
`disk_offering`.`iops_write_rate_max_length` AS `iops_write_rate_max_length`,
|
||||||
|
`disk_offering`.`cache_mode` AS `cache_mode`,
|
||||||
|
`disk_offering`.`disk_size` AS `root_disk_size`,
|
||||||
|
`service_offering`.`cpu` AS `cpu`,
|
||||||
|
`service_offering`.`speed` AS `speed`,
|
||||||
|
`service_offering`.`ram_size` AS `ram_size`,
|
||||||
|
`service_offering`.`nw_rate` AS `nw_rate`,
|
||||||
|
`service_offering`.`mc_rate` AS `mc_rate`,
|
||||||
|
`service_offering`.`ha_enabled` AS `ha_enabled`,
|
||||||
|
`service_offering`.`limit_cpu_use` AS `limit_cpu_use`,
|
||||||
|
`service_offering`.`host_tag` AS `host_tag`,
|
||||||
|
`service_offering`.`default_use` AS `default_use`,
|
||||||
|
`service_offering`.`vm_type` AS `vm_type`,
|
||||||
|
`service_offering`.`sort_key` AS `sort_key`,
|
||||||
|
`service_offering`.`is_volatile` AS `is_volatile`,
|
||||||
|
`service_offering`.`deployment_planner` AS `deployment_planner`,
|
||||||
|
`service_offering`.`dynamic_scaling_enabled` AS `dynamic_scaling_enabled`,
|
||||||
|
`service_offering`.`disk_offering_strictness` AS `disk_offering_strictness`,
|
||||||
|
`vsphere_storage_policy`.`value` AS `vsphere_storage_policy`,
|
||||||
|
GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id,
|
||||||
|
GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid,
|
||||||
|
GROUP_CONCAT(DISTINCT(domain.name)) AS domain_name,
|
||||||
|
GROUP_CONCAT(DISTINCT(domain.path)) AS domain_path,
|
||||||
|
GROUP_CONCAT(DISTINCT(zone.id)) AS zone_id,
|
||||||
|
GROUP_CONCAT(DISTINCT(zone.uuid)) AS zone_uuid,
|
||||||
|
GROUP_CONCAT(DISTINCT(zone.name)) AS zone_name,
|
||||||
|
IFNULL(`min_compute_details`.`value`, `cpu`) AS min_cpu,
|
||||||
|
IFNULL(`max_compute_details`.`value`, `cpu`) AS max_cpu,
|
||||||
|
IFNULL(`min_memory_details`.`value`, `ram_size`) AS min_memory,
|
||||||
|
IFNULL(`max_memory_details`.`value`, `ram_size`) AS max_memory
|
||||||
|
FROM
|
||||||
|
`cloud`.`service_offering`
|
||||||
|
INNER JOIN
|
||||||
|
`cloud`.`disk_offering_view` AS `disk_offering` ON service_offering.disk_offering_id = disk_offering.id
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`service_offering_details` AS `domain_details` ON `domain_details`.`service_offering_id` = `service_offering`.`id` AND `domain_details`.`name`='domainid'
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`domain` AS `domain` ON FIND_IN_SET(`domain`.`id`, `domain_details`.`value`)
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`service_offering_details` AS `zone_details` ON `zone_details`.`service_offering_id` = `service_offering`.`id` AND `zone_details`.`name`='zoneid'
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`data_center` AS `zone` ON FIND_IN_SET(`zone`.`id`, `zone_details`.`value`)
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`service_offering_details` AS `min_compute_details` ON `min_compute_details`.`service_offering_id` = `service_offering`.`id`
|
||||||
|
AND `min_compute_details`.`name` = 'mincpunumber'
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`service_offering_details` AS `max_compute_details` ON `max_compute_details`.`service_offering_id` = `service_offering`.`id`
|
||||||
|
AND `max_compute_details`.`name` = 'maxcpunumber'
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`service_offering_details` AS `min_memory_details` ON `min_memory_details`.`service_offering_id` = `service_offering`.`id`
|
||||||
|
AND `min_memory_details`.`name` = 'minmemory'
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`service_offering_details` AS `max_memory_details` ON `max_memory_details`.`service_offering_id` = `service_offering`.`id`
|
||||||
|
AND `max_memory_details`.`name` = 'maxmemory'
|
||||||
|
LEFT JOIN
|
||||||
|
`cloud`.`service_offering_details` AS `vsphere_storage_policy` ON `vsphere_storage_policy`.`service_offering_id` = `service_offering`.`id`
|
||||||
|
AND `vsphere_storage_policy`.`name` = 'storagepolicy'
|
||||||
|
WHERE
|
||||||
|
`service_offering`.`state`='Active'
|
||||||
|
GROUP BY
|
||||||
|
`service_offering`.`id`;
|
||||||
|
|
||||||
|
DROP VIEW IF EXISTS `cloud`.`volume_view`;
|
||||||
|
CREATE VIEW `cloud`.`volume_view` AS
|
||||||
|
SELECT
|
||||||
|
volumes.id,
|
||||||
|
volumes.uuid,
|
||||||
|
volumes.name,
|
||||||
|
volumes.device_id,
|
||||||
|
volumes.volume_type,
|
||||||
|
volumes.provisioning_type,
|
||||||
|
volumes.size,
|
||||||
|
volumes.min_iops,
|
||||||
|
volumes.max_iops,
|
||||||
|
volumes.created,
|
||||||
|
volumes.state,
|
||||||
|
volumes.attached,
|
||||||
|
volumes.removed,
|
||||||
|
volumes.display_volume,
|
||||||
|
volumes.format,
|
||||||
|
volumes.path,
|
||||||
|
volumes.chain_info,
|
||||||
|
account.id account_id,
|
||||||
|
account.uuid account_uuid,
|
||||||
|
account.account_name account_name,
|
||||||
|
account.type account_type,
|
||||||
|
domain.id domain_id,
|
||||||
|
domain.uuid domain_uuid,
|
||||||
|
domain.name domain_name,
|
||||||
|
domain.path domain_path,
|
||||||
|
projects.id project_id,
|
||||||
|
projects.uuid project_uuid,
|
||||||
|
projects.name project_name,
|
||||||
|
data_center.id data_center_id,
|
||||||
|
data_center.uuid data_center_uuid,
|
||||||
|
data_center.name data_center_name,
|
||||||
|
data_center.networktype data_center_type,
|
||||||
|
vm_instance.id vm_id,
|
||||||
|
vm_instance.uuid vm_uuid,
|
||||||
|
vm_instance.name vm_name,
|
||||||
|
vm_instance.state vm_state,
|
||||||
|
vm_instance.vm_type,
|
||||||
|
user_vm.display_name vm_display_name,
|
||||||
|
volume_store_ref.size volume_store_size,
|
||||||
|
volume_store_ref.download_pct,
|
||||||
|
volume_store_ref.download_state,
|
||||||
|
volume_store_ref.error_str,
|
||||||
|
volume_store_ref.created created_on_store,
|
||||||
|
disk_offering.id disk_offering_id,
|
||||||
|
disk_offering.uuid disk_offering_uuid,
|
||||||
|
disk_offering.name disk_offering_name,
|
||||||
|
disk_offering.display_text disk_offering_display_text,
|
||||||
|
disk_offering.use_local_storage,
|
||||||
|
service_offering.system_use,
|
||||||
|
disk_offering.bytes_read_rate,
|
||||||
|
disk_offering.bytes_write_rate,
|
||||||
|
disk_offering.iops_read_rate,
|
||||||
|
disk_offering.iops_write_rate,
|
||||||
|
disk_offering.cache_mode,
|
||||||
|
storage_pool.id pool_id,
|
||||||
|
storage_pool.uuid pool_uuid,
|
||||||
|
storage_pool.name pool_name,
|
||||||
|
cluster.id cluster_id,
|
||||||
|
cluster.name cluster_name,
|
||||||
|
cluster.uuid cluster_uuid,
|
||||||
|
cluster.hypervisor_type,
|
||||||
|
vm_template.id template_id,
|
||||||
|
vm_template.uuid template_uuid,
|
||||||
|
vm_template.extractable,
|
||||||
|
vm_template.type template_type,
|
||||||
|
vm_template.name template_name,
|
||||||
|
vm_template.display_text template_display_text,
|
||||||
|
iso.id iso_id,
|
||||||
|
iso.uuid iso_uuid,
|
||||||
|
iso.name iso_name,
|
||||||
|
iso.display_text iso_display_text,
|
||||||
|
resource_tags.id tag_id,
|
||||||
|
resource_tags.uuid tag_uuid,
|
||||||
|
resource_tags.key tag_key,
|
||||||
|
resource_tags.value tag_value,
|
||||||
|
resource_tags.domain_id tag_domain_id,
|
||||||
|
resource_tags.account_id tag_account_id,
|
||||||
|
resource_tags.resource_id tag_resource_id,
|
||||||
|
resource_tags.resource_uuid tag_resource_uuid,
|
||||||
|
resource_tags.resource_type tag_resource_type,
|
||||||
|
resource_tags.customer tag_customer,
|
||||||
|
async_job.id job_id,
|
||||||
|
async_job.uuid job_uuid,
|
||||||
|
async_job.job_status job_status,
|
||||||
|
async_job.account_id job_account_id,
|
||||||
|
host_pod_ref.id pod_id,
|
||||||
|
host_pod_ref.uuid pod_uuid,
|
||||||
|
host_pod_ref.name pod_name,
|
||||||
|
resource_tag_account.account_name tag_account_name,
|
||||||
|
resource_tag_domain.uuid tag_domain_uuid,
|
||||||
|
resource_tag_domain.name tag_domain_name
|
||||||
|
from
|
||||||
|
`cloud`.`volumes`
|
||||||
|
inner join
|
||||||
|
`cloud`.`account` ON volumes.account_id = account.id
|
||||||
|
inner join
|
||||||
|
`cloud`.`domain` ON volumes.domain_id = domain.id
|
||||||
|
left join
|
||||||
|
`cloud`.`projects` ON projects.project_account_id = account.id
|
||||||
|
left join
|
||||||
|
`cloud`.`data_center` ON volumes.data_center_id = data_center.id
|
||||||
|
left join
|
||||||
|
`cloud`.`vm_instance` ON volumes.instance_id = vm_instance.id
|
||||||
|
left join
|
||||||
|
`cloud`.`user_vm` ON user_vm.id = vm_instance.id
|
||||||
|
left join
|
||||||
|
`cloud`.`volume_store_ref` ON volumes.id = volume_store_ref.volume_id
|
||||||
|
left join
|
||||||
|
`cloud`.`service_offering` ON vm_instance.service_offering_id = service_offering.id
|
||||||
|
left join
|
||||||
|
`cloud`.`disk_offering` ON volumes.disk_offering_id = disk_offering.id
|
||||||
|
left join
|
||||||
|
`cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id
|
||||||
|
left join
|
||||||
|
`cloud`.`host_pod_ref` ON storage_pool.pod_id = host_pod_ref.id
|
||||||
|
left join
|
||||||
|
`cloud`.`cluster` ON storage_pool.cluster_id = cluster.id
|
||||||
|
left join
|
||||||
|
`cloud`.`vm_template` ON volumes.template_id = vm_template.id
|
||||||
|
left join
|
||||||
|
`cloud`.`vm_template` iso ON iso.id = volumes.iso_id
|
||||||
|
left join
|
||||||
|
`cloud`.`resource_tags` ON resource_tags.resource_id = volumes.id
|
||||||
|
and resource_tags.resource_type = 'Volume'
|
||||||
|
left join
|
||||||
|
`cloud`.`async_job` ON async_job.instance_id = volumes.id
|
||||||
|
and async_job.instance_type = 'Volume'
|
||||||
|
and async_job.job_status = 0
|
||||||
|
left join
|
||||||
|
`cloud`.`account` resource_tag_account ON resource_tag_account.id = resource_tags.account_id
|
||||||
|
left join
|
||||||
|
`cloud`.`domain` resource_tag_domain ON resource_tag_domain.id = resource_tags.domain_id;
|
||||||
|
|
||||||
|
DROP VIEW IF EXISTS `cloud`.`user_vm_view`;
|
||||||
|
CREATE
|
||||||
|
VIEW `user_vm_view` AS
|
||||||
|
SELECT
|
||||||
|
`vm_instance`.`id` AS `id`,
|
||||||
|
`vm_instance`.`name` AS `name`,
|
||||||
|
`user_vm`.`display_name` AS `display_name`,
|
||||||
|
`user_vm`.`user_data` AS `user_data`,
|
||||||
|
`account`.`id` AS `account_id`,
|
||||||
|
`account`.`uuid` AS `account_uuid`,
|
||||||
|
`account`.`account_name` AS `account_name`,
|
||||||
|
`account`.`type` AS `account_type`,
|
||||||
|
`domain`.`id` AS `domain_id`,
|
||||||
|
`domain`.`uuid` AS `domain_uuid`,
|
||||||
|
`domain`.`name` AS `domain_name`,
|
||||||
|
`domain`.`path` AS `domain_path`,
|
||||||
|
`projects`.`id` AS `project_id`,
|
||||||
|
`projects`.`uuid` AS `project_uuid`,
|
||||||
|
`projects`.`name` AS `project_name`,
|
||||||
|
`instance_group`.`id` AS `instance_group_id`,
|
||||||
|
`instance_group`.`uuid` AS `instance_group_uuid`,
|
||||||
|
`instance_group`.`name` AS `instance_group_name`,
|
||||||
|
`vm_instance`.`uuid` AS `uuid`,
|
||||||
|
`vm_instance`.`user_id` AS `user_id`,
|
||||||
|
`vm_instance`.`last_host_id` AS `last_host_id`,
|
||||||
|
`vm_instance`.`vm_type` AS `type`,
|
||||||
|
`vm_instance`.`limit_cpu_use` AS `limit_cpu_use`,
|
||||||
|
`vm_instance`.`created` AS `created`,
|
||||||
|
`vm_instance`.`state` AS `state`,
|
||||||
|
`vm_instance`.`update_time` AS `update_time`,
|
||||||
|
`vm_instance`.`removed` AS `removed`,
|
||||||
|
`vm_instance`.`ha_enabled` AS `ha_enabled`,
|
||||||
|
`vm_instance`.`hypervisor_type` AS `hypervisor_type`,
|
||||||
|
`vm_instance`.`instance_name` AS `instance_name`,
|
||||||
|
`vm_instance`.`guest_os_id` AS `guest_os_id`,
|
||||||
|
`vm_instance`.`display_vm` AS `display_vm`,
|
||||||
|
`guest_os`.`uuid` AS `guest_os_uuid`,
|
||||||
|
`vm_instance`.`pod_id` AS `pod_id`,
|
||||||
|
`host_pod_ref`.`uuid` AS `pod_uuid`,
|
||||||
|
`vm_instance`.`private_ip_address` AS `private_ip_address`,
|
||||||
|
`vm_instance`.`private_mac_address` AS `private_mac_address`,
|
||||||
|
`vm_instance`.`vm_type` AS `vm_type`,
|
||||||
|
`data_center`.`id` AS `data_center_id`,
|
||||||
|
`data_center`.`uuid` AS `data_center_uuid`,
|
||||||
|
`data_center`.`name` AS `data_center_name`,
|
||||||
|
`data_center`.`is_security_group_enabled` AS `security_group_enabled`,
|
||||||
|
`data_center`.`networktype` AS `data_center_type`,
|
||||||
|
`host`.`id` AS `host_id`,
|
||||||
|
`host`.`uuid` AS `host_uuid`,
|
||||||
|
`host`.`name` AS `host_name`,
|
||||||
|
`host`.`cluster_id` AS `cluster_id`,
|
||||||
|
`vm_template`.`id` AS `template_id`,
|
||||||
|
`vm_template`.`uuid` AS `template_uuid`,
|
||||||
|
`vm_template`.`name` AS `template_name`,
|
||||||
|
`vm_template`.`display_text` AS `template_display_text`,
|
||||||
|
`vm_template`.`enable_password` AS `password_enabled`,
|
||||||
|
`iso`.`id` AS `iso_id`,
|
||||||
|
`iso`.`uuid` AS `iso_uuid`,
|
||||||
|
`iso`.`name` AS `iso_name`,
|
||||||
|
`iso`.`display_text` AS `iso_display_text`,
|
||||||
|
`service_offering`.`id` AS `service_offering_id`,
|
||||||
|
`service_offering`.`uuid` AS `service_offering_uuid`,
|
||||||
|
`disk_offering`.`uuid` AS `disk_offering_uuid`,
|
||||||
|
`disk_offering`.`id` AS `disk_offering_id`,
|
||||||
|
(CASE
|
||||||
|
WHEN ISNULL(`service_offering`.`cpu`) THEN `custom_cpu`.`value`
|
||||||
|
ELSE `service_offering`.`cpu`
|
||||||
|
END) AS `cpu`,
|
||||||
|
(CASE
|
||||||
|
WHEN ISNULL(`service_offering`.`speed`) THEN `custom_speed`.`value`
|
||||||
|
ELSE `service_offering`.`speed`
|
||||||
|
END) AS `speed`,
|
||||||
|
(CASE
|
||||||
|
WHEN ISNULL(`service_offering`.`ram_size`) THEN `custom_ram_size`.`value`
|
||||||
|
ELSE `service_offering`.`ram_size`
|
||||||
|
END) AS `ram_size`,
|
||||||
|
`backup_offering`.`uuid` AS `backup_offering_uuid`,
|
||||||
|
`backup_offering`.`id` AS `backup_offering_id`,
|
||||||
|
`service_offering`.`name` AS `service_offering_name`,
|
||||||
|
`disk_offering`.`name` AS `disk_offering_name`,
|
||||||
|
`backup_offering`.`name` AS `backup_offering_name`,
|
||||||
|
`storage_pool`.`id` AS `pool_id`,
|
||||||
|
`storage_pool`.`uuid` AS `pool_uuid`,
|
||||||
|
`storage_pool`.`pool_type` AS `pool_type`,
|
||||||
|
`volumes`.`id` AS `volume_id`,
|
||||||
|
`volumes`.`uuid` AS `volume_uuid`,
|
||||||
|
`volumes`.`device_id` AS `volume_device_id`,
|
||||||
|
`volumes`.`volume_type` AS `volume_type`,
|
||||||
|
`security_group`.`id` AS `security_group_id`,
|
||||||
|
`security_group`.`uuid` AS `security_group_uuid`,
|
||||||
|
`security_group`.`name` AS `security_group_name`,
|
||||||
|
`security_group`.`description` AS `security_group_description`,
|
||||||
|
`nics`.`id` AS `nic_id`,
|
||||||
|
`nics`.`uuid` AS `nic_uuid`,
|
||||||
|
`nics`.`device_id` AS `nic_device_id`,
|
||||||
|
`nics`.`network_id` AS `network_id`,
|
||||||
|
`nics`.`ip4_address` AS `ip_address`,
|
||||||
|
`nics`.`ip6_address` AS `ip6_address`,
|
||||||
|
`nics`.`ip6_gateway` AS `ip6_gateway`,
|
||||||
|
`nics`.`ip6_cidr` AS `ip6_cidr`,
|
||||||
|
`nics`.`default_nic` AS `is_default_nic`,
|
||||||
|
`nics`.`gateway` AS `gateway`,
|
||||||
|
`nics`.`netmask` AS `netmask`,
|
||||||
|
`nics`.`mac_address` AS `mac_address`,
|
||||||
|
`nics`.`broadcast_uri` AS `broadcast_uri`,
|
||||||
|
`nics`.`isolation_uri` AS `isolation_uri`,
|
||||||
|
`vpc`.`id` AS `vpc_id`,
|
||||||
|
`vpc`.`uuid` AS `vpc_uuid`,
|
||||||
|
`networks`.`uuid` AS `network_uuid`,
|
||||||
|
`networks`.`name` AS `network_name`,
|
||||||
|
`networks`.`traffic_type` AS `traffic_type`,
|
||||||
|
`networks`.`guest_type` AS `guest_type`,
|
||||||
|
`user_ip_address`.`id` AS `public_ip_id`,
|
||||||
|
`user_ip_address`.`uuid` AS `public_ip_uuid`,
|
||||||
|
`user_ip_address`.`public_ip_address` AS `public_ip_address`,
|
||||||
|
`ssh_keypairs`.`keypair_name` AS `keypair_name`,
|
||||||
|
`resource_tags`.`id` AS `tag_id`,
|
||||||
|
`resource_tags`.`uuid` AS `tag_uuid`,
|
||||||
|
`resource_tags`.`key` AS `tag_key`,
|
||||||
|
`resource_tags`.`value` AS `tag_value`,
|
||||||
|
`resource_tags`.`domain_id` AS `tag_domain_id`,
|
||||||
|
`domain`.`uuid` AS `tag_domain_uuid`,
|
||||||
|
`domain`.`name` AS `tag_domain_name`,
|
||||||
|
`resource_tags`.`account_id` AS `tag_account_id`,
|
||||||
|
`account`.`account_name` AS `tag_account_name`,
|
||||||
|
`resource_tags`.`resource_id` AS `tag_resource_id`,
|
||||||
|
`resource_tags`.`resource_uuid` AS `tag_resource_uuid`,
|
||||||
|
`resource_tags`.`resource_type` AS `tag_resource_type`,
|
||||||
|
`resource_tags`.`customer` AS `tag_customer`,
|
||||||
|
`async_job`.`id` AS `job_id`,
|
||||||
|
`async_job`.`uuid` AS `job_uuid`,
|
||||||
|
`async_job`.`job_status` AS `job_status`,
|
||||||
|
`async_job`.`account_id` AS `job_account_id`,
|
||||||
|
`affinity_group`.`id` AS `affinity_group_id`,
|
||||||
|
`affinity_group`.`uuid` AS `affinity_group_uuid`,
|
||||||
|
`affinity_group`.`name` AS `affinity_group_name`,
|
||||||
|
`affinity_group`.`description` AS `affinity_group_description`,
|
||||||
|
`vm_instance`.`dynamically_scalable` AS `dynamically_scalable`
|
||||||
|
FROM
|
||||||
|
(((((((((((((((((((((((((((((((((`user_vm`
|
||||||
|
JOIN `vm_instance` ON (((`vm_instance`.`id` = `user_vm`.`id`)
|
||||||
|
AND ISNULL(`vm_instance`.`removed`))))
|
||||||
|
JOIN `account` ON ((`vm_instance`.`account_id` = `account`.`id`)))
|
||||||
|
JOIN `domain` ON ((`vm_instance`.`domain_id` = `domain`.`id`)))
|
||||||
|
LEFT JOIN `guest_os` ON ((`vm_instance`.`guest_os_id` = `guest_os`.`id`)))
|
||||||
|
LEFT JOIN `host_pod_ref` ON ((`vm_instance`.`pod_id` = `host_pod_ref`.`id`)))
|
||||||
|
LEFT JOIN `projects` ON ((`projects`.`project_account_id` = `account`.`id`)))
|
||||||
|
LEFT JOIN `instance_group_vm_map` ON ((`vm_instance`.`id` = `instance_group_vm_map`.`instance_id`)))
|
||||||
|
LEFT JOIN `instance_group` ON ((`instance_group_vm_map`.`group_id` = `instance_group`.`id`)))
|
||||||
|
LEFT JOIN `data_center` ON ((`vm_instance`.`data_center_id` = `data_center`.`id`)))
|
||||||
|
LEFT JOIN `host` ON ((`vm_instance`.`host_id` = `host`.`id`)))
|
||||||
|
LEFT JOIN `vm_template` ON ((`vm_instance`.`vm_template_id` = `vm_template`.`id`)))
|
||||||
|
LEFT JOIN `vm_template` `iso` ON ((`iso`.`id` = `user_vm`.`iso_id`)))
|
||||||
|
LEFT JOIN `volumes` ON ((`vm_instance`.`id` = `volumes`.`instance_id`)))
|
||||||
|
LEFT JOIN `service_offering` ON ((`vm_instance`.`service_offering_id` = `service_offering`.`id`)))
|
||||||
|
LEFT JOIN `disk_offering` `svc_disk_offering` ON ((`volumes`.`disk_offering_id` = `svc_disk_offering`.`id`)))
|
||||||
|
LEFT JOIN `disk_offering` ON ((`volumes`.`disk_offering_id` = `disk_offering`.`id`)))
|
||||||
|
LEFT JOIN `backup_offering` ON ((`vm_instance`.`backup_offering_id` = `backup_offering`.`id`)))
|
||||||
|
LEFT JOIN `storage_pool` ON ((`volumes`.`pool_id` = `storage_pool`.`id`)))
|
||||||
|
LEFT JOIN `security_group_vm_map` ON ((`vm_instance`.`id` = `security_group_vm_map`.`instance_id`)))
|
||||||
|
LEFT JOIN `security_group` ON ((`security_group_vm_map`.`security_group_id` = `security_group`.`id`)))
|
||||||
|
LEFT JOIN `nics` ON (((`vm_instance`.`id` = `nics`.`instance_id`)
|
||||||
|
AND ISNULL(`nics`.`removed`))))
|
||||||
|
LEFT JOIN `networks` ON ((`nics`.`network_id` = `networks`.`id`)))
|
||||||
|
LEFT JOIN `vpc` ON (((`networks`.`vpc_id` = `vpc`.`id`)
|
||||||
|
AND ISNULL(`vpc`.`removed`))))
|
||||||
|
LEFT JOIN `user_ip_address` ON ((`user_ip_address`.`vm_id` = `vm_instance`.`id`)))
|
||||||
|
LEFT JOIN `user_vm_details` `ssh_details` ON (((`ssh_details`.`vm_id` = `vm_instance`.`id`)
|
||||||
|
AND (`ssh_details`.`name` = 'SSH.PublicKey'))))
|
||||||
|
LEFT JOIN `ssh_keypairs` ON (((`ssh_keypairs`.`public_key` = `ssh_details`.`value`)
|
||||||
|
AND (`ssh_keypairs`.`account_id` = `account`.`id`))))
|
||||||
|
LEFT JOIN `resource_tags` ON (((`resource_tags`.`resource_id` = `vm_instance`.`id`)
|
||||||
|
AND (`resource_tags`.`resource_type` = 'UserVm'))))
|
||||||
|
LEFT JOIN `async_job` ON (((`async_job`.`instance_id` = `vm_instance`.`id`)
|
||||||
|
AND (`async_job`.`instance_type` = 'VirtualMachine')
|
||||||
|
AND (`async_job`.`job_status` = 0))))
|
||||||
|
LEFT JOIN `affinity_group_vm_map` ON ((`vm_instance`.`id` = `affinity_group_vm_map`.`instance_id`)))
|
||||||
|
LEFT JOIN `affinity_group` ON ((`affinity_group_vm_map`.`affinity_group_id` = `affinity_group`.`id`)))
|
||||||
|
LEFT JOIN `user_vm_details` `custom_cpu` ON (((`custom_cpu`.`vm_id` = `vm_instance`.`id`)
|
||||||
|
AND (`custom_cpu`.`name` = 'CpuNumber'))))
|
||||||
|
LEFT JOIN `user_vm_details` `custom_speed` ON (((`custom_speed`.`vm_id` = `vm_instance`.`id`)
|
||||||
|
AND (`custom_speed`.`name` = 'CpuSpeed'))))
|
||||||
|
LEFT JOIN `user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `vm_instance`.`id`)
|
||||||
|
AND (`custom_ram_size`.`name` = 'memory'))));
|
||||||
|
|
||||||
|
DROP VIEW IF EXISTS `cloud`.`domain_router_view`;
|
||||||
|
CREATE VIEW `cloud`.`domain_router_view` AS
|
||||||
|
select
|
||||||
|
vm_instance.id id,
|
||||||
|
vm_instance.name name,
|
||||||
|
account.id account_id,
|
||||||
|
account.uuid account_uuid,
|
||||||
|
account.account_name account_name,
|
||||||
|
account.type account_type,
|
||||||
|
domain.id domain_id,
|
||||||
|
domain.uuid domain_uuid,
|
||||||
|
domain.name domain_name,
|
||||||
|
domain.path domain_path,
|
||||||
|
projects.id project_id,
|
||||||
|
projects.uuid project_uuid,
|
||||||
|
projects.name project_name,
|
||||||
|
vm_instance.uuid uuid,
|
||||||
|
vm_instance.created created,
|
||||||
|
vm_instance.state state,
|
||||||
|
vm_instance.removed removed,
|
||||||
|
vm_instance.pod_id pod_id,
|
||||||
|
vm_instance.instance_name instance_name,
|
||||||
|
host_pod_ref.uuid pod_uuid,
|
||||||
|
data_center.id data_center_id,
|
||||||
|
data_center.uuid data_center_uuid,
|
||||||
|
data_center.name data_center_name,
|
||||||
|
data_center.networktype data_center_type,
|
||||||
|
data_center.dns1 dns1,
|
||||||
|
data_center.dns2 dns2,
|
||||||
|
data_center.ip6_dns1 ip6_dns1,
|
||||||
|
data_center.ip6_dns2 ip6_dns2,
|
||||||
|
host.id host_id,
|
||||||
|
host.uuid host_uuid,
|
||||||
|
host.name host_name,
|
||||||
|
host.hypervisor_type,
|
||||||
|
host.cluster_id cluster_id,
|
||||||
|
vm_template.id template_id,
|
||||||
|
vm_template.uuid template_uuid,
|
||||||
|
service_offering.id service_offering_id,
|
||||||
|
service_offering.uuid service_offering_uuid,
|
||||||
|
service_offering.name service_offering_name,
|
||||||
|
nics.id nic_id,
|
||||||
|
nics.uuid nic_uuid,
|
||||||
|
nics.network_id network_id,
|
||||||
|
nics.ip4_address ip_address,
|
||||||
|
nics.ip6_address ip6_address,
|
||||||
|
nics.ip6_gateway ip6_gateway,
|
||||||
|
nics.ip6_cidr ip6_cidr,
|
||||||
|
nics.default_nic is_default_nic,
|
||||||
|
nics.gateway gateway,
|
||||||
|
nics.netmask netmask,
|
||||||
|
nics.mac_address mac_address,
|
||||||
|
nics.broadcast_uri broadcast_uri,
|
||||||
|
nics.isolation_uri isolation_uri,
|
||||||
|
vpc.id vpc_id,
|
||||||
|
vpc.uuid vpc_uuid,
|
||||||
|
vpc.name vpc_name,
|
||||||
|
networks.uuid network_uuid,
|
||||||
|
networks.name network_name,
|
||||||
|
networks.network_domain network_domain,
|
||||||
|
networks.traffic_type traffic_type,
|
||||||
|
networks.guest_type guest_type,
|
||||||
|
async_job.id job_id,
|
||||||
|
async_job.uuid job_uuid,
|
||||||
|
async_job.job_status job_status,
|
||||||
|
async_job.account_id job_account_id,
|
||||||
|
domain_router.template_version template_version,
|
||||||
|
domain_router.scripts_version scripts_version,
|
||||||
|
domain_router.is_redundant_router is_redundant_router,
|
||||||
|
domain_router.redundant_state redundant_state,
|
||||||
|
domain_router.stop_pending stop_pending,
|
||||||
|
domain_router.role role
|
||||||
|
from
|
||||||
|
`cloud`.`domain_router`
|
||||||
|
inner join
|
||||||
|
`cloud`.`vm_instance` ON vm_instance.id = domain_router.id
|
||||||
|
inner join
|
||||||
|
`cloud`.`account` ON vm_instance.account_id = account.id
|
||||||
|
inner join
|
||||||
|
`cloud`.`domain` ON vm_instance.domain_id = domain.id
|
||||||
|
left join
|
||||||
|
`cloud`.`host_pod_ref` ON vm_instance.pod_id = host_pod_ref.id
|
||||||
|
left join
|
||||||
|
`cloud`.`projects` ON projects.project_account_id = account.id
|
||||||
|
left join
|
||||||
|
`cloud`.`data_center` ON vm_instance.data_center_id = data_center.id
|
||||||
|
left join
|
||||||
|
`cloud`.`host` ON vm_instance.host_id = host.id
|
||||||
|
left join
|
||||||
|
`cloud`.`vm_template` ON vm_instance.vm_template_id = vm_template.id
|
||||||
|
left join
|
||||||
|
`cloud`.`service_offering` ON vm_instance.service_offering_id = service_offering.id
|
||||||
|
left join
|
||||||
|
`cloud`.`nics` ON vm_instance.id = nics.instance_id and nics.removed is null
|
||||||
|
left join
|
||||||
|
`cloud`.`networks` ON nics.network_id = networks.id
|
||||||
|
left join
|
||||||
|
`cloud`.`vpc` ON domain_router.vpc_id = vpc.id and vpc.removed is null
|
||||||
|
left join
|
||||||
|
`cloud`.`async_job` ON async_job.instance_id = vm_instance.id
|
||||||
|
and async_job.instance_type = 'DomainRouter'
|
||||||
|
and async_job.job_status = 0;
|
||||||
@ -17,7 +17,6 @@
|
|||||||
package com.cloud.host;
|
package com.cloud.host;
|
||||||
|
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.storage.Storage.ProvisioningType;
|
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
@ -32,7 +31,8 @@ public class HostVOTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
host = new HostVO();
|
host = new HostVO();
|
||||||
offering = new ServiceOfferingVO("TestSO", 0, 0, 0, 0, 0, false, "TestSO", ProvisioningType.THIN, true, true,"",false,VirtualMachine.Type.User,false);
|
offering = new ServiceOfferingVO("TestSO", 0, 0, 0, 0, 0,
|
||||||
|
false, "TestSO", false,VirtualMachine.Type.User,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@ -740,7 +740,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
|
|||||||
StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destVolumeInfo.getDataStore().getId(), DataStoreRole.Primary);
|
StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destVolumeInfo.getDataStore().getId(), DataStoreRole.Primary);
|
||||||
|
|
||||||
MigrateVolumeCommand command = new MigrateVolumeCommand(srcVolumeInfo.getId(), srcVolumeInfo.getPath(), destPool, srcVolumeInfo.getAttachedVmName(),
|
MigrateVolumeCommand command = new MigrateVolumeCommand(srcVolumeInfo.getId(), srcVolumeInfo.getPath(), destPool, srcVolumeInfo.getAttachedVmName(),
|
||||||
srcVolumeInfo.getVolumeType(), waitInterval);
|
srcVolumeInfo.getVolumeType(), waitInterval, null);
|
||||||
|
|
||||||
Map<String, String> details = new HashMap<>();
|
Map<String, String> details = new HashMap<>();
|
||||||
|
|
||||||
|
|||||||
@ -338,7 +338,7 @@ public class DefaultVMSnapshotStrategy extends ManagerBase implements VMSnapshot
|
|||||||
Long offeringId = null;
|
Long offeringId = null;
|
||||||
if (diskOfferingId != null) {
|
if (diskOfferingId != null) {
|
||||||
DiskOfferingVO offering = diskOfferingDao.findById(diskOfferingId);
|
DiskOfferingVO offering = diskOfferingDao.findById(diskOfferingId);
|
||||||
if (offering != null && (offering.getType() == DiskOfferingVO.Type.Disk)) {
|
if (offering != null && !offering.isComputeOnly()) {
|
||||||
offeringId = offering.getId();
|
offeringId = offering.getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -456,7 +456,7 @@ public class ScaleIOVMSnapshotStrategy extends ManagerBase implements VMSnapshot
|
|||||||
Long offeringId = null;
|
Long offeringId = null;
|
||||||
if (diskOfferingId != null) {
|
if (diskOfferingId != null) {
|
||||||
DiskOfferingVO offering = diskOfferingDao.findById(diskOfferingId);
|
DiskOfferingVO offering = diskOfferingDao.findById(diskOfferingId);
|
||||||
if (offering != null && (offering.getType() == DiskOfferingVO.Type.Disk)) {
|
if (offering != null && !offering.isComputeOnly()) {
|
||||||
offeringId = offering.getId();
|
offeringId = offering.getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
|
|||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
@ -265,8 +266,8 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check capacity
|
// check capacity
|
||||||
List<Volume> requestVolumes = new ArrayList<>();
|
List<Pair<Volume, DiskProfile>> requestVolumeDiskProfilePairs = new ArrayList<>();
|
||||||
requestVolumes.add(volume);
|
requestVolumeDiskProfilePairs.add(new Pair<>(volume, dskCh));
|
||||||
if (dskCh.getHypervisorType() == HypervisorType.VMware) {
|
if (dskCh.getHypervisorType() == HypervisorType.VMware) {
|
||||||
// Skip the parent datastore cluster, consider only child storage pools in it
|
// Skip the parent datastore cluster, consider only child storage pools in it
|
||||||
if (pool.getPoolType() == Storage.StoragePoolType.DatastoreCluster && storageMgr.isStoragePoolDatastoreClusterParent(pool)) {
|
if (pool.getPoolType() == Storage.StoragePoolType.DatastoreCluster && storageMgr.isStoragePoolDatastoreClusterParent(pool)) {
|
||||||
@ -281,7 +282,7 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boolean isStoragePoolStoragepolicyComplaince = storageMgr.isStoragePoolCompliantWithStoragePolicy(requestVolumes, pool);
|
boolean isStoragePoolStoragepolicyComplaince = storageMgr.isStoragePoolCompliantWithStoragePolicy(requestVolumeDiskProfilePairs, pool);
|
||||||
if (!isStoragePoolStoragepolicyComplaince) {
|
if (!isStoragePoolStoragepolicyComplaince) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -290,7 +291,7 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return storageMgr.storagePoolHasEnoughIops(requestVolumes, pool) && storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool, plan.getClusterId());
|
return storageMgr.storagePoolHasEnoughIops(requestVolumeDiskProfilePairs, pool) && storageMgr.storagePoolHasEnoughSpace(requestVolumeDiskProfilePairs, pool, plan.getClusterId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkDiskProvisioningSupport(DiskProfile dskCh, StoragePool pool) {
|
private boolean checkDiskProvisioningSupport(DiskProfile dskCh, StoragePool pool) {
|
||||||
|
|||||||
@ -16,26 +16,66 @@
|
|||||||
//under the License.
|
//under the License.
|
||||||
package org.apache.cloudstack.quota.vo;
|
package org.apache.cloudstack.quota.vo;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.DiscriminatorValue;
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.PrimaryKeyJoinColumn;
|
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
import javax.persistence.Transient;
|
import javax.persistence.Transient;
|
||||||
|
|
||||||
import com.cloud.offering.ServiceOffering;
|
import com.cloud.offering.ServiceOffering;
|
||||||
import com.cloud.storage.DiskOfferingVO;
|
import com.cloud.utils.db.GenericDao;
|
||||||
import com.cloud.storage.Storage.ProvisioningType;
|
|
||||||
import com.cloud.vm.VirtualMachine;
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "service_offering")
|
@Table(name = "service_offering")
|
||||||
@DiscriminatorValue(value = "Service")
|
public class ServiceOfferingVO implements ServiceOffering {
|
||||||
@PrimaryKeyJoinColumn(name = "id")
|
|
||||||
public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering {
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@Column(name = "id")
|
||||||
|
long id;
|
||||||
|
|
||||||
|
@Column(name = "uuid")
|
||||||
|
private String uuid;
|
||||||
|
|
||||||
|
@Column(name = "name")
|
||||||
|
private String name = null;
|
||||||
|
|
||||||
|
@Column(name = "unique_name")
|
||||||
|
private String uniqueName;
|
||||||
|
|
||||||
|
@Column(name = "display_text", length = 4096)
|
||||||
|
private String displayText = null;
|
||||||
|
|
||||||
|
@Column(name = "customized")
|
||||||
|
private boolean customized;
|
||||||
|
|
||||||
|
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date removed;
|
||||||
|
|
||||||
|
@Column(name = GenericDao.CREATED_COLUMN)
|
||||||
|
private Date created;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(name = "state")
|
||||||
|
ServiceOffering.State state = ServiceOffering.State.Active;
|
||||||
|
|
||||||
|
@Column(name = "disk_offering_id")
|
||||||
|
private Long diskOfferingId;
|
||||||
|
|
||||||
|
@Column(name = "disk_offering_strictness")
|
||||||
|
private boolean diskOfferingStrictness = false;
|
||||||
|
|
||||||
@Column(name = "cpu")
|
@Column(name = "cpu")
|
||||||
private Integer cpu;
|
private Integer cpu;
|
||||||
|
|
||||||
@ -78,6 +118,9 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
@Column(name = "dynamic_scaling_enabled")
|
@Column(name = "dynamic_scaling_enabled")
|
||||||
private boolean dynamicScalingEnabled;
|
private boolean dynamicScalingEnabled;
|
||||||
|
|
||||||
|
@Column(name = "system_use")
|
||||||
|
private boolean systemUse;
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
Map<String, String> details = new HashMap<String, String>();
|
Map<String, String> details = new HashMap<String, String>();
|
||||||
|
|
||||||
@ -88,56 +131,12 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText,
|
|
||||||
ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
|
|
||||||
super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true);
|
|
||||||
this.cpu = cpu;
|
|
||||||
this.ramSize = ramSize;
|
|
||||||
this.speed = speed;
|
|
||||||
this.rateMbps = rateMbps;
|
|
||||||
this.multicastRateMbps = multicastRateMbps;
|
|
||||||
this.offerHA = offerHA;
|
|
||||||
limitCpuUse = false;
|
|
||||||
volatileVm = false;
|
|
||||||
this.defaultUse = defaultUse;
|
|
||||||
this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitCpuUse,
|
|
||||||
boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
|
|
||||||
VirtualMachine.Type vmType, Long domainId) {
|
|
||||||
super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true);
|
|
||||||
this.cpu = cpu;
|
|
||||||
this.ramSize = ramSize;
|
|
||||||
this.speed = speed;
|
|
||||||
this.rateMbps = rateMbps;
|
|
||||||
this.multicastRateMbps = multicastRateMbps;
|
|
||||||
this.offerHA = offerHA;
|
|
||||||
this.limitCpuUse = limitCpuUse;
|
|
||||||
this.volatileVm = volatileVm;
|
|
||||||
this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse,
|
|
||||||
boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
|
|
||||||
VirtualMachine.Type vmType, Long domainId, String hostTag) {
|
|
||||||
this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm, displayText, provisioningType, useLocalStorage, recreatable, tags,
|
|
||||||
systemUse, vmType, domainId);
|
|
||||||
this.hostTag = hostTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse,
|
|
||||||
boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
|
|
||||||
VirtualMachine.Type vmType, Long domainId, String hostTag, String deploymentPlanner) {
|
|
||||||
this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm, displayText, provisioningType, useLocalStorage, recreatable, tags,
|
|
||||||
systemUse, vmType, domainId, hostTag);
|
|
||||||
this.deploymentPlanner = deploymentPlanner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServiceOfferingVO(ServiceOfferingVO offering) {
|
public ServiceOfferingVO(ServiceOfferingVO offering) {
|
||||||
super(offering.getId(), offering.getName(), offering.getDisplayText(), offering.getProvisioningType(), false, offering.getTags(), offering.isRecreatable(),
|
id = offering.getId();
|
||||||
offering.isUseLocalStorage(), offering.isSystemUse(), true, offering.isCustomizedIops() == null ? false : offering.isCustomizedIops(),
|
diskOfferingId = offering.getDiskOfferingId();
|
||||||
offering.getMinIops(), offering.getMaxIops());
|
name = offering.getName();
|
||||||
|
displayText = offering.getDisplayText();
|
||||||
|
customized = true;
|
||||||
cpu = offering.getCpu();
|
cpu = offering.getCpu();
|
||||||
ramSize = offering.getRamSize();
|
ramSize = offering.getRamSize();
|
||||||
speed = offering.getSpeed();
|
speed = offering.getSpeed();
|
||||||
@ -148,6 +147,8 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
volatileVm = offering.isVolatileVm();
|
volatileVm = offering.isVolatileVm();
|
||||||
hostTag = offering.getHostTag();
|
hostTag = offering.getHostTag();
|
||||||
vmType = offering.getSystemVmType();
|
vmType = offering.getSystemVmType();
|
||||||
|
systemUse = offering.isSystemUse();
|
||||||
|
dynamicScalingEnabled = offering.isDynamicScalingEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -173,17 +174,6 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
return defaultUse;
|
return defaultUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transient
|
|
||||||
public String[] getTagsArray() {
|
|
||||||
String tags = getTags();
|
|
||||||
if (tags == null || tags.length() == 0) {
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return tags.split(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer getCpu() {
|
public Integer getCpu() {
|
||||||
return cpu;
|
return cpu;
|
||||||
@ -288,6 +278,108 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
|
|||||||
isDynamic = isdynamic;
|
isDynamic = isdynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSystemUse() {
|
||||||
|
return systemUse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueName() {
|
||||||
|
return uniqueName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUniqueName(String uniqueName) {
|
||||||
|
this.uniqueName = uniqueName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayText() {
|
||||||
|
return displayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDisplayText(String displayText) {
|
||||||
|
this.displayText = displayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCustomized() {
|
||||||
|
return customized;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCustomized(boolean customized) {
|
||||||
|
this.customized = customized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoved(Date removed) {
|
||||||
|
this.removed = removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getRemoved() {
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServiceOffering.State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setState(ServiceOffering.State state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getDiskOfferingId() {
|
||||||
|
return diskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean getDiskOfferingStrictness() {
|
||||||
|
return diskOfferingStrictness;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDiskOfferingStrictness(boolean diskOfferingStrictness) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiskOfferingId(Long diskOfferingId) {
|
||||||
|
this.diskOfferingId = diskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDynamicScalingEnabled() {
|
public boolean isDynamicScalingEnabled() {
|
||||||
return dynamicScalingEnabled;
|
return dynamicScalingEnabled;
|
||||||
|
|||||||
@ -4836,7 +4836,7 @@ public class LibvirtComputingResourceTest {
|
|||||||
final boolean shrinkOk = true;
|
final boolean shrinkOk = true;
|
||||||
final String vmInstance = "Test";
|
final String vmInstance = "Test";
|
||||||
|
|
||||||
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
|
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance, null);
|
||||||
|
|
||||||
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
|
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
|
||||||
final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
|
final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
|
||||||
@ -4889,7 +4889,7 @@ public class LibvirtComputingResourceTest {
|
|||||||
final boolean shrinkOk = false;
|
final boolean shrinkOk = false;
|
||||||
final String vmInstance = "Test";
|
final String vmInstance = "Test";
|
||||||
|
|
||||||
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
|
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance, null);
|
||||||
|
|
||||||
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
|
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
|
||||||
final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
|
final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
|
||||||
@ -4929,7 +4929,7 @@ public class LibvirtComputingResourceTest {
|
|||||||
final boolean shrinkOk = false;
|
final boolean shrinkOk = false;
|
||||||
final String vmInstance = "Test";
|
final String vmInstance = "Test";
|
||||||
|
|
||||||
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
|
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance, null);
|
||||||
|
|
||||||
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
|
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
|
||||||
assertNotNull(wrapper);
|
assertNotNull(wrapper);
|
||||||
@ -4947,7 +4947,7 @@ public class LibvirtComputingResourceTest {
|
|||||||
final boolean shrinkOk = true;
|
final boolean shrinkOk = true;
|
||||||
final String vmInstance = "Test";
|
final String vmInstance = "Test";
|
||||||
|
|
||||||
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
|
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance, null);
|
||||||
|
|
||||||
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
|
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
|
||||||
final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
|
final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
|
||||||
@ -4976,7 +4976,7 @@ public class LibvirtComputingResourceTest {
|
|||||||
final boolean shrinkOk = false;
|
final boolean shrinkOk = false;
|
||||||
final String vmInstance = "Test";
|
final String vmInstance = "Test";
|
||||||
|
|
||||||
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
|
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance, null);
|
||||||
|
|
||||||
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
|
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
|
||||||
final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
|
final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
|
||||||
@ -5024,7 +5024,7 @@ public class LibvirtComputingResourceTest {
|
|||||||
final boolean shrinkOk = false;
|
final boolean shrinkOk = false;
|
||||||
final String vmInstance = "Test";
|
final String vmInstance = "Test";
|
||||||
|
|
||||||
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
|
final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance, null);
|
||||||
|
|
||||||
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
|
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
|
||||||
final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
|
final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
|
||||||
|
|||||||
@ -454,8 +454,13 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||||||
*/
|
*/
|
||||||
private ServiceOfferingVO createServiceOfferingForVMImporting(Integer cpus, Integer memory, Integer maxCpuUsage) {
|
private ServiceOfferingVO createServiceOfferingForVMImporting(Integer cpus, Integer memory, Integer maxCpuUsage) {
|
||||||
String name = "Imported-" + cpus + "-" + memory;
|
String name = "Imported-" + cpus + "-" + memory;
|
||||||
ServiceOfferingVO vo = new ServiceOfferingVO(name, cpus, memory, maxCpuUsage, null, null, false, name, Storage.ProvisioningType.THIN, false, false, null, false, Type.User,
|
|
||||||
|
DiskOfferingVO diskOfferingVO = new DiskOfferingVO(name, name, Storage.ProvisioningType.THIN, false, null, false, false, true);
|
||||||
|
diskOfferingVO = diskOfferingDao.persistDefaultDiskOffering(diskOfferingVO);
|
||||||
|
|
||||||
|
ServiceOfferingVO vo = new ServiceOfferingVO(name, cpus, memory, maxCpuUsage, null, null, false, name, false, Type.User,
|
||||||
false);
|
false);
|
||||||
|
vo.setDiskOfferingId(diskOfferingVO.getId());
|
||||||
return serviceOfferingDao.persist(vo);
|
return serviceOfferingDao.persist(vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,7 +670,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||||||
vmInternalName, id, vmInternalName, templateId, guestOsId, serviceOfferingId));
|
vmInternalName, id, vmInternalName, templateId, guestOsId, serviceOfferingId));
|
||||||
|
|
||||||
UserVmVO vmInstanceVO = new UserVmVO(id, vmInternalName, vmInternalName, templateId, HypervisorType.VMware, guestOsId, false, false, domainId, accountId, userId,
|
UserVmVO vmInstanceVO = new UserVmVO(id, vmInternalName, vmInternalName, templateId, HypervisorType.VMware, guestOsId, false, false, domainId, accountId, userId,
|
||||||
serviceOfferingId, null, vmInternalName, null);
|
serviceOfferingId, null, vmInternalName);
|
||||||
vmInstanceVO.setDataCenterId(zoneId);
|
vmInstanceVO.setDataCenterId(zoneId);
|
||||||
return userVmDao.persist(vmInstanceVO);
|
return userVmDao.persist(vmInstanceVO);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -430,7 +430,7 @@ public class CitrixRequestWrapperTest {
|
|||||||
public void testResizeVolumeCommand() {
|
public void testResizeVolumeCommand() {
|
||||||
final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
|
final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
|
||||||
|
|
||||||
final ResizeVolumeCommand resizeCommand = new ResizeVolumeCommand("Test", pool, 1l, 3l, false, "Tests-1");
|
final ResizeVolumeCommand resizeCommand = new ResizeVolumeCommand("Test", pool, 1l, 3l, false, "Tests-1", null);
|
||||||
|
|
||||||
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
|
final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
|
||||||
assertNotNull(wrapper);
|
assertNotNull(wrapper);
|
||||||
|
|||||||
@ -380,7 +380,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
|
|||||||
nodeVm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, owner,
|
nodeVm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, owner,
|
||||||
hostName, hostName, null, null, null,
|
hostName, hostName, null, null, null,
|
||||||
Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, base64UserData, kubernetesCluster.getKeyPair(),
|
Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, base64UserData, kubernetesCluster.getKeyPair(),
|
||||||
null, addrs, null, null, null, customParameterMap, null, null, null, null, true, UserVmManager.CKS_NODE);
|
null, addrs, null, null, null, customParameterMap, null, null, null, null, true, UserVmManager.CKS_NODE, null);
|
||||||
if (LOGGER.isInfoEnabled()) {
|
if (LOGGER.isInfoEnabled()) {
|
||||||
LOGGER.info(String.format("Created node VM : %s, %s in the Kubernetes cluster : %s", hostName, nodeVm.getUuid(), kubernetesCluster.getName()));
|
LOGGER.info(String.format("Created node VM : %s, %s in the Kubernetes cluster : %s", hostName, nodeVm.getUuid(), kubernetesCluster.getName()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -209,7 +209,7 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
|
|||||||
controlVm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, owner,
|
controlVm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, owner,
|
||||||
hostName, hostName, null, null, null,
|
hostName, hostName, null, null, null,
|
||||||
Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, base64UserData, kubernetesCluster.getKeyPair(),
|
Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, base64UserData, kubernetesCluster.getKeyPair(),
|
||||||
requestedIps, addrs, null, null, null, customParameterMap, null, null, null, null, true, UserVmManager.CKS_NODE);
|
requestedIps, addrs, null, null, null, customParameterMap, null, null, null, null, true, UserVmManager.CKS_NODE, null);
|
||||||
if (LOGGER.isInfoEnabled()) {
|
if (LOGGER.isInfoEnabled()) {
|
||||||
LOGGER.info(String.format("Created control VM ID: %s, %s in the Kubernetes cluster : %s", controlVm.getUuid(), hostName, kubernetesCluster.getName()));
|
LOGGER.info(String.format("Created control VM ID: %s, %s in the Kubernetes cluster : %s", controlVm.getUuid(), hostName, kubernetesCluster.getName()));
|
||||||
}
|
}
|
||||||
@ -264,7 +264,7 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
|
|||||||
additionalControlVm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, owner,
|
additionalControlVm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, owner,
|
||||||
hostName, hostName, null, null, null,
|
hostName, hostName, null, null, null,
|
||||||
Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, base64UserData, kubernetesCluster.getKeyPair(),
|
Hypervisor.HypervisorType.None, BaseCmd.HTTPMethod.POST, base64UserData, kubernetesCluster.getKeyPair(),
|
||||||
null, addrs, null, null, null, customParameterMap, null, null, null, null, true, UserVmManager.CKS_NODE);
|
null, addrs, null, null, null, customParameterMap, null, null, null, null, true, UserVmManager.CKS_NODE, null);
|
||||||
if (LOGGER.isInfoEnabled()) {
|
if (LOGGER.isInfoEnabled()) {
|
||||||
LOGGER.info(String.format("Created control VM ID : %s, %s in the Kubernetes cluster : %s", additionalControlVm.getUuid(), hostName, kubernetesCluster.getName()));
|
LOGGER.info(String.format("Created control VM ID : %s, %s in the Kubernetes cluster : %s", additionalControlVm.getUuid(), hostName, kubernetesCluster.getName()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,7 +58,6 @@ import com.cloud.offerings.NetworkOfferingVO;
|
|||||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.storage.Storage;
|
|
||||||
import com.cloud.storage.Storage.ProvisioningType;
|
import com.cloud.storage.Storage.ProvisioningType;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
import com.cloud.user.AccountVO;
|
import com.cloud.user.AccountVO;
|
||||||
@ -121,7 +120,7 @@ public class InternalLBVMManagerTest extends TestCase {
|
|||||||
//mock system offering creation as it's used by configure() method called by initComponentsLifeCycle
|
//mock system offering creation as it's used by configure() method called by initComponentsLifeCycle
|
||||||
Mockito.when(_accountMgr.getAccount(1L)).thenReturn(new AccountVO());
|
Mockito.when(_accountMgr.getAccount(1L)).thenReturn(new AccountVO());
|
||||||
ServiceOfferingVO off = new ServiceOfferingVO("alena", 1, 1,
|
ServiceOfferingVO off = new ServiceOfferingVO("alena", 1, 1,
|
||||||
1, 1, 1, false, "alena", Storage.ProvisioningType.THIN, false, false, null, false, VirtualMachine.Type.InternalLoadBalancerVm, false);
|
1, 1, 1, false, "alena", false, VirtualMachine.Type.InternalLoadBalancerVm, false);
|
||||||
off = setId(off, 1);
|
off = setId(off, 1);
|
||||||
List<ServiceOfferingVO> list = new ArrayList<ServiceOfferingVO>();
|
List<ServiceOfferingVO> list = new ArrayList<ServiceOfferingVO>();
|
||||||
list.add(off);
|
list.add(off);
|
||||||
@ -341,7 +340,7 @@ public class InternalLBVMManagerTest extends TestCase {
|
|||||||
final ServiceOfferingVO voToReturn = vo;
|
final ServiceOfferingVO voToReturn = vo;
|
||||||
final Class<?> c = voToReturn.getClass();
|
final Class<?> c = voToReturn.getClass();
|
||||||
try {
|
try {
|
||||||
final Field f = c.getSuperclass().getDeclaredField("id");
|
final Field f = c.getDeclaredField("id");
|
||||||
f.setAccessible(true);
|
f.setAccessible(true);
|
||||||
f.setLong(voToReturn, id);
|
f.setLong(voToReturn, id);
|
||||||
} catch (final NoSuchFieldException ex) {
|
} catch (final NoSuchFieldException ex) {
|
||||||
|
|||||||
@ -45,7 +45,6 @@ import com.cloud.network.router.VirtualRouter;
|
|||||||
import com.cloud.network.router.VirtualRouter.Role;
|
import com.cloud.network.router.VirtualRouter.Role;
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.storage.Storage;
|
|
||||||
import com.cloud.storage.Storage.ProvisioningType;
|
import com.cloud.storage.Storage.ProvisioningType;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
import com.cloud.user.AccountVO;
|
import com.cloud.user.AccountVO;
|
||||||
@ -93,7 +92,7 @@ public class InternalLBVMServiceTest extends TestCase {
|
|||||||
//mock system offering creation as it's used by configure() method called by initComponentsLifeCycle
|
//mock system offering creation as it's used by configure() method called by initComponentsLifeCycle
|
||||||
Mockito.when(_accountMgr.getAccount(1L)).thenReturn(new AccountVO());
|
Mockito.when(_accountMgr.getAccount(1L)).thenReturn(new AccountVO());
|
||||||
ServiceOfferingVO off = new ServiceOfferingVO("alena", 1, 1,
|
ServiceOfferingVO off = new ServiceOfferingVO("alena", 1, 1,
|
||||||
1, 1, 1, false, "alena", Storage.ProvisioningType.THIN, false, false, null, false, VirtualMachine.Type.InternalLoadBalancerVm, false);
|
1, 1, 1, false, "alena", false, VirtualMachine.Type.InternalLoadBalancerVm, false);
|
||||||
off = setId(off, 1);
|
off = setId(off, 1);
|
||||||
List<ServiceOfferingVO> list = new ArrayList<ServiceOfferingVO>();
|
List<ServiceOfferingVO> list = new ArrayList<ServiceOfferingVO>();
|
||||||
list.add(off);
|
list.add(off);
|
||||||
@ -251,7 +250,7 @@ public class InternalLBVMServiceTest extends TestCase {
|
|||||||
final ServiceOfferingVO voToReturn = vo;
|
final ServiceOfferingVO voToReturn = vo;
|
||||||
final Class<?> c = voToReturn.getClass();
|
final Class<?> c = voToReturn.getClass();
|
||||||
try {
|
try {
|
||||||
final Field f = c.getSuperclass().getDeclaredField("id");
|
final Field f = c.getDeclaredField("id");
|
||||||
f.setAccessible(true);
|
f.setAccessible(true);
|
||||||
f.setLong(voToReturn, id);
|
f.setLong(voToReturn, id);
|
||||||
} catch (final NoSuchFieldException ex) {
|
} catch (final NoSuchFieldException ex) {
|
||||||
|
|||||||
@ -23,6 +23,6 @@ import com.cloud.vm.UserVmVO;
|
|||||||
public class ServiceVirtualMachine extends UserVmVO {
|
public class ServiceVirtualMachine extends UserVmVO {
|
||||||
public ServiceVirtualMachine(long id, String instanceName, String name, long templateId, long serviceOfferingId, HypervisorType hypervisorType, long guestOSId,
|
public ServiceVirtualMachine(long id, String instanceName, String name, long templateId, long serviceOfferingId, HypervisorType hypervisorType, long guestOSId,
|
||||||
long dataCenterId, long domainId, long accountId, long userId, boolean haEnabled) {
|
long dataCenterId, long domainId, long accountId, long userId, boolean haEnabled) {
|
||||||
super(id, instanceName, name, templateId, hypervisorType, guestOSId, false, false, domainId, accountId, userId, serviceOfferingId, null, name, null);
|
super(id, instanceName, name, templateId, hypervisorType, guestOSId, false, false, domainId, accountId, userId, serviceOfferingId, null, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -240,7 +240,7 @@ public class ManagementServerMock {
|
|||||||
long id = _userVmDao.getNextInSequence(Long.class, "id");
|
long id = _userVmDao.getNextInSequence(Long.class, "id");
|
||||||
UserVmVO vm =
|
UserVmVO vm =
|
||||||
new UserVmVO(id, name, name, tmpl.getId(), HypervisorType.XenServer, tmpl.getGuestOSId(), false, false, _zone.getDomainId(), Account.ACCOUNT_ID_SYSTEM,
|
new UserVmVO(id, name, name, tmpl.getId(), HypervisorType.XenServer, tmpl.getGuestOSId(), false, false, _zone.getDomainId(), Account.ACCOUNT_ID_SYSTEM,
|
||||||
1, small.getId(), null, name, null);
|
1, small.getId(), null, name);
|
||||||
vm.setState(com.cloud.vm.VirtualMachine.State.Running);
|
vm.setState(com.cloud.vm.VirtualMachine.State.Running);
|
||||||
vm.setHostId(_hostId);
|
vm.setHostId(_hostId);
|
||||||
vm.setDataCenterId(network.getDataCenterId());
|
vm.setDataCenterId(network.getDataCenterId());
|
||||||
|
|||||||
@ -617,7 +617,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
|
|
||||||
ResizeVolumeCommand resizeCmd =
|
ResizeVolumeCommand resizeCmd =
|
||||||
new ResizeVolumeCommand(vol.getPath(), new StorageFilerTO(pool), oldSize, resizeParameter.newSize, resizeParameter.shrinkOk,
|
new ResizeVolumeCommand(vol.getPath(), new StorageFilerTO(pool), oldSize, resizeParameter.newSize, resizeParameter.shrinkOk,
|
||||||
resizeParameter.instanceName);
|
resizeParameter.instanceName, null);
|
||||||
CreateCmdResult result = new CreateCmdResult(null, null);
|
CreateCmdResult result = new CreateCmdResult(null, null);
|
||||||
try {
|
try {
|
||||||
ResizeVolumeAnswer answer = (ResizeVolumeAnswer) _storageMgr.sendToPool(pool, resizeParameter.hosts, resizeCmd);
|
ResizeVolumeAnswer answer = (ResizeVolumeAnswer) _storageMgr.sendToPool(pool, resizeParameter.hosts, resizeCmd);
|
||||||
|
|||||||
@ -1043,14 +1043,26 @@ public class ApiDBUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DiskOfferingVO findDiskOfferingById(Long diskOfferingId) {
|
public static DiskOfferingVO findComputeOnlyDiskOfferingById(Long diskOfferingId) {
|
||||||
DiskOfferingVO off = s_diskOfferingDao.findByIdIncludingRemoved(diskOfferingId);
|
DiskOfferingVO off = s_diskOfferingDao.findByIdIncludingRemoved(diskOfferingId);
|
||||||
if (off.getType() == DiskOfferingVO.Type.Disk) {
|
if (off.isComputeOnly()) {
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DiskOfferingVO findDiskOfferingById(Long diskOfferingId) {
|
||||||
|
DiskOfferingVO off = s_diskOfferingDao.findByIdIncludingRemoved(diskOfferingId);
|
||||||
|
if (!off.isComputeOnly()) {
|
||||||
|
return off;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ServiceOfferingVO findServiceOfferingByComputeOnlyDiskOffering(Long diskOfferingId) {
|
||||||
|
ServiceOfferingVO off = s_serviceOfferingDao.findServiceOfferingByComputeOnlyDiskOffering(diskOfferingId);
|
||||||
|
return off;
|
||||||
|
}
|
||||||
public static DomainVO findDomainById(Long domainId) {
|
public static DomainVO findDomainById(Long domainId) {
|
||||||
return s_domainDao.findByIdIncludingRemoved(domainId);
|
return s_domainDao.findByIdIncludingRemoved(domainId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import java.util.Date;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -30,6 +31,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.cloud.storage.VolumeApiServiceImpl;
|
||||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
|
import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||||
@ -124,6 +126,7 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
|
|||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -194,6 +197,7 @@ import com.cloud.network.router.VirtualNetworkApplianceManager;
|
|||||||
import com.cloud.network.security.SecurityGroupVMMapVO;
|
import com.cloud.network.security.SecurityGroupVMMapVO;
|
||||||
import com.cloud.network.security.dao.SecurityGroupVMMapDao;
|
import com.cloud.network.security.dao.SecurityGroupVMMapDao;
|
||||||
import com.cloud.org.Grouping;
|
import com.cloud.org.Grouping;
|
||||||
|
import com.cloud.offering.DiskOffering;
|
||||||
import com.cloud.projects.Project;
|
import com.cloud.projects.Project;
|
||||||
import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
||||||
import com.cloud.projects.ProjectInvitation;
|
import com.cloud.projects.ProjectInvitation;
|
||||||
@ -213,17 +217,19 @@ import com.cloud.service.ServiceOfferingVO;
|
|||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
||||||
import com.cloud.storage.DataStoreRole;
|
import com.cloud.storage.DataStoreRole;
|
||||||
import com.cloud.storage.DiskOfferingVO;
|
|
||||||
import com.cloud.storage.ScopeType;
|
import com.cloud.storage.ScopeType;
|
||||||
import com.cloud.storage.Storage;
|
import com.cloud.storage.Storage;
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
import com.cloud.storage.Storage.TemplateType;
|
import com.cloud.storage.Storage.TemplateType;
|
||||||
import com.cloud.storage.StoragePoolTagVO;
|
import com.cloud.storage.StoragePoolTagVO;
|
||||||
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
import com.cloud.storage.VMTemplateVO;
|
import com.cloud.storage.VMTemplateVO;
|
||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.storage.dao.StoragePoolTagsDao;
|
import com.cloud.storage.dao.StoragePoolTagsDao;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
import com.cloud.storage.dao.VMTemplateDetailsDao;
|
import com.cloud.storage.dao.VMTemplateDetailsDao;
|
||||||
|
import com.cloud.storage.dao.DiskOfferingDao;
|
||||||
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
import com.cloud.tags.ResourceTagVO;
|
import com.cloud.tags.ResourceTagVO;
|
||||||
import com.cloud.tags.dao.ResourceTagDao;
|
import com.cloud.tags.dao.ResourceTagDao;
|
||||||
import com.cloud.template.VirtualMachineTemplate.State;
|
import com.cloud.template.VirtualMachineTemplate.State;
|
||||||
@ -366,6 +372,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Inject
|
@Inject
|
||||||
private ServiceOfferingDetailsDao _srvOfferingDetailsDao;
|
private ServiceOfferingDetailsDao _srvOfferingDetailsDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private DiskOfferingDao _diskOfferingDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DataCenterJoinDao _dcJoinDao;
|
private DataCenterJoinDao _dcJoinDao;
|
||||||
|
|
||||||
@ -445,6 +454,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private VirtualMachineManager virtualMachineManager;
|
private VirtualMachineManager virtualMachineManager;
|
||||||
|
@Inject
|
||||||
|
private VolumeDao volumeDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ResourceIconDao resourceIconDao;
|
private ResourceIconDao resourceIconDao;
|
||||||
@ -2077,7 +2088,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sb.and("display", sb.entity().isDisplayVolume(), SearchCriteria.Op.EQ);
|
sb.and("display", sb.entity().isDisplayVolume(), SearchCriteria.Op.EQ);
|
||||||
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
|
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
|
||||||
sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ);
|
sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ);
|
||||||
sb.and("systemUse", sb.entity().isSystemUse(), SearchCriteria.Op.NEQ);
|
sb.and().op("systemUse", sb.entity().isSystemUse(), SearchCriteria.Op.NEQ);
|
||||||
|
sb.or("nulltype", sb.entity().isSystemUse(), SearchCriteria.Op.NULL);
|
||||||
|
sb.cp();
|
||||||
|
|
||||||
// display UserVM volumes only
|
// display UserVM volumes only
|
||||||
sb.and().op("type", sb.entity().getVmType(), SearchCriteria.Op.NIN);
|
sb.and().op("type", sb.entity().getVmType(), SearchCriteria.Op.NIN);
|
||||||
sb.or("nulltype", sb.entity().getVmType(), SearchCriteria.Op.NULL);
|
sb.or("nulltype", sb.entity().getVmType(), SearchCriteria.Op.NULL);
|
||||||
@ -2882,7 +2896,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Filter searchFilter = new Filter(DiskOfferingJoinVO.class, "sortKey", SortKeyAscending.value(), cmd.getStartIndex(), cmd.getPageSizeVal());
|
Filter searchFilter = new Filter(DiskOfferingJoinVO.class, "sortKey", SortKeyAscending.value(), cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||||
searchFilter.addOrderBy(DiskOfferingJoinVO.class, "id", true);
|
searchFilter.addOrderBy(DiskOfferingJoinVO.class, "id", true);
|
||||||
SearchCriteria<DiskOfferingJoinVO> sc = _diskOfferingJoinDao.createSearchCriteria();
|
SearchCriteria<DiskOfferingJoinVO> sc = _diskOfferingJoinDao.createSearchCriteria();
|
||||||
sc.addAnd("type", Op.EQ, DiskOfferingVO.Type.Disk);
|
sc.addAnd("computeOnly", Op.EQ, false);
|
||||||
|
|
||||||
Account account = CallContext.current().getCallingAccount();
|
Account account = CallContext.current().getCallingAccount();
|
||||||
Object name = cmd.getDiskOfferingName();
|
Object name = cmd.getDiskOfferingName();
|
||||||
@ -2892,6 +2906,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Boolean isRootAdmin = _accountMgr.isRootAdmin(account.getAccountId());
|
Boolean isRootAdmin = _accountMgr.isRootAdmin(account.getAccountId());
|
||||||
Boolean isRecursive = cmd.isRecursive();
|
Boolean isRecursive = cmd.isRecursive();
|
||||||
Long zoneId = cmd.getZoneId();
|
Long zoneId = cmd.getZoneId();
|
||||||
|
Long volumeId = cmd.getVolumeId();
|
||||||
|
Long storagePoolId = cmd.getStoragePoolId();
|
||||||
// Keeping this logic consistent with domain specific zones
|
// Keeping this logic consistent with domain specific zones
|
||||||
// if a domainId is provided, we just return the disk offering
|
// if a domainId is provided, we just return the disk offering
|
||||||
// associated with this domain
|
// associated with this domain
|
||||||
@ -2922,6 +2938,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (volumeId != null && storagePoolId != null) {
|
||||||
|
throw new InvalidParameterValueException("Both volume ID and storage pool ID are not allowed at the same time");
|
||||||
|
}
|
||||||
|
|
||||||
if (keyword != null) {
|
if (keyword != null) {
|
||||||
SearchCriteria<DiskOfferingJoinVO> ssc = _diskOfferingJoinDao.createSearchCriteria();
|
SearchCriteria<DiskOfferingJoinVO> ssc = _diskOfferingJoinDao.createSearchCriteria();
|
||||||
ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
||||||
@ -2948,6 +2968,23 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sc.addAnd("zoneId", SearchCriteria.Op.SC, zoneSC);
|
sc.addAnd("zoneId", SearchCriteria.Op.SC, zoneSC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiskOffering currentDiskOffering = null;
|
||||||
|
if (volumeId != null) {
|
||||||
|
Volume volume = volumeDao.findById(volumeId);
|
||||||
|
if (volume == null) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Unable to find a volume with specified id %s", volumeId));
|
||||||
|
}
|
||||||
|
currentDiskOffering = _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId());
|
||||||
|
if (!currentDiskOffering.isComputeOnly() && currentDiskOffering.getDiskSizeStrictness()) {
|
||||||
|
SearchCriteria<DiskOfferingJoinVO> ssc = _diskOfferingJoinDao.createSearchCriteria();
|
||||||
|
ssc.addOr("diskSize", Op.EQ, volume.getSize());
|
||||||
|
ssc.addOr("customized", SearchCriteria.Op.EQ, true);
|
||||||
|
sc.addAnd("diskSizeOrCustomized", SearchCriteria.Op.SC, ssc);
|
||||||
|
}
|
||||||
|
sc.addAnd("id", SearchCriteria.Op.NEQ, currentDiskOffering.getId());
|
||||||
|
sc.addAnd("diskSizeStrictness", Op.EQ, currentDiskOffering.getDiskSizeStrictness());
|
||||||
|
}
|
||||||
|
|
||||||
// Filter offerings that are not associated with caller's domain
|
// Filter offerings that are not associated with caller's domain
|
||||||
// Fetch the offering ids from the details table since theres no smart way to filter them in the join ... yet!
|
// Fetch the offering ids from the details table since theres no smart way to filter them in the join ... yet!
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
@ -2971,6 +3008,28 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
}
|
}
|
||||||
|
|
||||||
Pair<List<DiskOfferingJoinVO>, Integer> result = _diskOfferingJoinDao.searchAndCount(sc, searchFilter);
|
Pair<List<DiskOfferingJoinVO>, Integer> result = _diskOfferingJoinDao.searchAndCount(sc, searchFilter);
|
||||||
|
String[] requiredTagsArray = new String[0];
|
||||||
|
if (CollectionUtils.isNotEmpty(result.first()) && VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.valueIn(zoneId)) {
|
||||||
|
if (volumeId != null) {
|
||||||
|
Volume volume = volumeDao.findById(volumeId);
|
||||||
|
currentDiskOffering = _diskOfferingDao.findByIdIncludingRemoved(volume.getDiskOfferingId());
|
||||||
|
requiredTagsArray = currentDiskOffering.getTagsArray();
|
||||||
|
} else if (storagePoolId != null) {
|
||||||
|
requiredTagsArray = _storageTagDao.getStoragePoolTags(storagePoolId).toArray(new String[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (requiredTagsArray.length != 0) {
|
||||||
|
ListIterator<DiskOfferingJoinVO> iteratorForTagsChecking = result.first().listIterator();
|
||||||
|
while (iteratorForTagsChecking.hasNext()) {
|
||||||
|
DiskOfferingJoinVO offering = iteratorForTagsChecking.next();
|
||||||
|
String offeringTags = offering.getTags();
|
||||||
|
String[] offeringTagsArray = (offeringTags == null || offeringTags.isEmpty()) ? new String[0] : offeringTags.split(",");
|
||||||
|
if (!CollectionUtils.isSubCollection(Arrays.asList(requiredTagsArray), Arrays.asList(offeringTagsArray))) {
|
||||||
|
iteratorForTagsChecking.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new Pair<>(result.first(), result.second());
|
return new Pair<>(result.first(), result.second());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3054,6 +3113,13 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sc.addAnd("id", SearchCriteria.Op.NEQ, currentVmOffering.getId());
|
sc.addAnd("id", SearchCriteria.Op.NEQ, currentVmOffering.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentVmOffering.getDiskOfferingStrictness()) {
|
||||||
|
sc.addAnd("diskOfferingId", Op.EQ, currentVmOffering.getDiskOfferingId());
|
||||||
|
sc.addAnd("diskOfferingStrictness", Op.EQ, true);
|
||||||
|
} else {
|
||||||
|
sc.addAnd("diskOfferingStrictness", Op.EQ, false);
|
||||||
|
}
|
||||||
|
|
||||||
boolean isRootVolumeUsingLocalStorage = virtualMachineManager.isRootVolumeOnLocalStorage(vmId);
|
boolean isRootVolumeUsingLocalStorage = virtualMachineManager.isRootVolumeOnLocalStorage(vmId);
|
||||||
|
|
||||||
// 1. Only return offerings with the same storage type than the storage pool where the VM's root volume is allocated
|
// 1. Only return offerings with the same storage type than the storage pool where the VM's root volume is allocated
|
||||||
@ -3199,7 +3265,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentVmOffering != null) {
|
if (currentVmOffering != null) {
|
||||||
List<String> storageTags = com.cloud.utils.StringUtils.csvTagsToList(currentVmOffering.getTags());
|
DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(currentVmOffering.getDiskOfferingId());
|
||||||
|
List<String> storageTags = com.cloud.utils.StringUtils.csvTagsToList(diskOffering.getTags());
|
||||||
if (!storageTags.isEmpty()) {
|
if (!storageTags.isEmpty()) {
|
||||||
SearchBuilder<ServiceOfferingJoinVO> sb = _srvOfferingJoinDao.createSearchBuilder();
|
SearchBuilder<ServiceOfferingJoinVO> sb = _srvOfferingJoinDao.createSearchBuilder();
|
||||||
for(String tag : storageTags) {
|
for(String tag : storageTags) {
|
||||||
|
|||||||
@ -139,6 +139,7 @@ public class DiskOfferingJoinDaoImpl extends GenericDaoBase<DiskOfferingJoinVO,
|
|||||||
diskOfferingResponse.setVsphereStoragePolicy(vsphereStoragePolicyVO.getName());
|
diskOfferingResponse.setVsphereStoragePolicy(vsphereStoragePolicyVO.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
diskOfferingResponse.setDiskSizeStrictness(offering.getDiskSizeStrictness());
|
||||||
|
|
||||||
return diskOfferingResponse;
|
return diskOfferingResponse;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import com.cloud.dc.dao.VsphereStoragePolicyDao;
|
|||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
import org.apache.cloudstack.annotation.AnnotationService;
|
import org.apache.cloudstack.annotation.AnnotationService;
|
||||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||||
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
@ -141,6 +142,13 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJo
|
|||||||
|
|
||||||
long rootDiskSizeInGb = (long) offering.getRootDiskSize() / GB_TO_BYTES;
|
long rootDiskSizeInGb = (long) offering.getRootDiskSize() / GB_TO_BYTES;
|
||||||
offeringResponse.setRootDiskSize(rootDiskSizeInGb);
|
offeringResponse.setRootDiskSize(rootDiskSizeInGb);
|
||||||
|
offeringResponse.setDiskOfferingStrictness(offering.getDiskOfferingStrictness());
|
||||||
|
DiskOfferingVO diskOfferingVO = ApiDBUtils.findDiskOfferingById(offering.getDiskOfferingId());
|
||||||
|
if (diskOfferingVO != null) {
|
||||||
|
offeringResponse.setDiskOfferingId(offering.getDiskOfferingUuid());
|
||||||
|
offeringResponse.setDiskOfferingName(offering.getDiskOfferingName());
|
||||||
|
offeringResponse.setDiskOfferingDisplayText(offering.getDiskOfferingDisplayText());
|
||||||
|
}
|
||||||
|
|
||||||
offeringResponse.setHasAnnotation(annotationDao.hasAnnotations(offering.getUuid(), AnnotationService.EntityType.SERVICE_OFFERING.name(),
|
offeringResponse.setHasAnnotation(annotationDao.hasAnnotations(offering.getUuid(), AnnotationService.EntityType.SERVICE_OFFERING.name(),
|
||||||
accountManager.isRootAdmin(CallContext.current().getCallingAccount().getId())));
|
accountManager.isRootAdmin(CallContext.current().getCallingAccount().getId())));
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||||
import org.apache.cloudstack.annotation.AnnotationService;
|
import org.apache.cloudstack.annotation.AnnotationService;
|
||||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||||
@ -183,8 +184,11 @@ public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJo
|
|||||||
userVmResponse.setServiceOfferingName(userVm.getServiceOfferingName());
|
userVmResponse.setServiceOfferingName(userVm.getServiceOfferingName());
|
||||||
}
|
}
|
||||||
if (details.contains(VMDetails.all) || details.contains(VMDetails.diskoff)) {
|
if (details.contains(VMDetails.all) || details.contains(VMDetails.diskoff)) {
|
||||||
userVmResponse.setDiskOfferingId(userVm.getDiskOfferingUuid());
|
DiskOfferingVO diskOfferingVO = ApiDBUtils.findDiskOfferingById(userVm.getDiskOfferingId());
|
||||||
userVmResponse.setDiskOfferingName(userVm.getDiskOfferingName());
|
if (diskOfferingVO != null) {
|
||||||
|
userVmResponse.setDiskOfferingId(userVm.getDiskOfferingUuid());
|
||||||
|
userVmResponse.setDiskOfferingName(userVm.getDiskOfferingName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (details.contains(VMDetails.all) || details.contains(VMDetails.backoff)) {
|
if (details.contains(VMDetails.all) || details.contains(VMDetails.backoff)) {
|
||||||
userVmResponse.setBackupOfferingId(userVm.getBackupOfferingUuid());
|
userVmResponse.setBackupOfferingId(userVm.getBackupOfferingUuid());
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.cloud.offering.DiskOffering;
|
||||||
import org.apache.cloudstack.annotation.AnnotationService;
|
import org.apache.cloudstack.annotation.AnnotationService;
|
||||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||||
@ -178,10 +179,12 @@ public class VolumeJoinDaoImpl extends GenericDaoBaseWithTagInformation<VolumeJo
|
|||||||
ApiResponseHelper.populateOwner(volResponse, volume);
|
ApiResponseHelper.populateOwner(volResponse, volume);
|
||||||
|
|
||||||
if (volume.getDiskOfferingId() > 0) {
|
if (volume.getDiskOfferingId() > 0) {
|
||||||
if (ApiDBUtils.findServiceOfferingByUuid(volume.getDiskOfferingUuid()) != null) {
|
DiskOffering computeOnlyDiskOffering = ApiDBUtils.findComputeOnlyDiskOfferingById(volume.getDiskOfferingId());
|
||||||
volResponse.setServiceOfferingId(volume.getDiskOfferingUuid());
|
if (computeOnlyDiskOffering != null) {
|
||||||
volResponse.setServiceOfferingName(volume.getDiskOfferingName());
|
ServiceOffering serviceOffering = ApiDBUtils.findServiceOfferingByComputeOnlyDiskOffering(volume.getDiskOfferingId());
|
||||||
volResponse.setServiceOfferingDisplayText(volume.getDiskOfferingDisplayText());
|
volResponse.setServiceOfferingId(String.valueOf(serviceOffering.getId()));
|
||||||
|
volResponse.setServiceOfferingName(serviceOffering.getName());
|
||||||
|
volResponse.setServiceOfferingDisplayText(serviceOffering.getDisplayText());
|
||||||
} else {
|
} else {
|
||||||
volResponse.setDiskOfferingId(volume.getDiskOfferingUuid());
|
volResponse.setDiskOfferingId(volume.getDiskOfferingUuid());
|
||||||
volResponse.setDiskOfferingName(volume.getDiskOfferingName());
|
volResponse.setDiskOfferingName(volume.getDiskOfferingName());
|
||||||
|
|||||||
@ -29,7 +29,6 @@ import org.apache.cloudstack.api.Identity;
|
|||||||
import org.apache.cloudstack.api.InternalIdentity;
|
import org.apache.cloudstack.api.InternalIdentity;
|
||||||
|
|
||||||
import com.cloud.offering.DiskOffering;
|
import com.cloud.offering.DiskOffering;
|
||||||
import com.cloud.offering.DiskOffering.Type;
|
|
||||||
import com.cloud.storage.Storage;
|
import com.cloud.storage.Storage;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
|
||||||
@ -62,9 +61,6 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity,
|
|||||||
@Column(name = "use_local_storage")
|
@Column(name = "use_local_storage")
|
||||||
private boolean useLocalStorage;
|
private boolean useLocalStorage;
|
||||||
|
|
||||||
@Column(name = "system_use")
|
|
||||||
private boolean systemUse;
|
|
||||||
|
|
||||||
@Column(name = "customized")
|
@Column(name = "customized")
|
||||||
private boolean customized;
|
private boolean customized;
|
||||||
|
|
||||||
@ -122,8 +118,8 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity,
|
|||||||
@Column(name = "cache_mode")
|
@Column(name = "cache_mode")
|
||||||
String cacheMode;
|
String cacheMode;
|
||||||
|
|
||||||
@Column(name = "type")
|
@Column(name = "compute_only")
|
||||||
Type type;
|
boolean computeOnly;
|
||||||
|
|
||||||
@Column(name = GenericDao.CREATED_COLUMN)
|
@Column(name = GenericDao.CREATED_COLUMN)
|
||||||
private Date created;
|
private Date created;
|
||||||
@ -162,6 +158,9 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity,
|
|||||||
@Column(name = "vsphere_storage_policy")
|
@Column(name = "vsphere_storage_policy")
|
||||||
String vsphereStoragePolicy;
|
String vsphereStoragePolicy;
|
||||||
|
|
||||||
|
@Column(name = "disk_size_strictness")
|
||||||
|
boolean diskSizeStrictness;
|
||||||
|
|
||||||
public DiskOfferingJoinVO() {
|
public DiskOfferingJoinVO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,10 +198,6 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity,
|
|||||||
return useLocalStorage;
|
return useLocalStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSystemUse() {
|
|
||||||
return systemUse;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCustomized() {
|
public boolean isCustomized() {
|
||||||
return customized;
|
return customized;
|
||||||
}
|
}
|
||||||
@ -247,8 +242,8 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity,
|
|||||||
return sortKey;
|
return sortKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getType() {
|
public boolean isComputeOnly() {
|
||||||
return type;
|
return computeOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getBytesReadRate() {
|
public Long getBytesReadRate() {
|
||||||
@ -350,4 +345,8 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity,
|
|||||||
public String getVsphereStoragePolicy() {
|
public String getVsphereStoragePolicy() {
|
||||||
return vsphereStoragePolicy;
|
return vsphereStoragePolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getDiskSizeStrictness() {
|
||||||
|
return diskSizeStrictness;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -196,6 +196,21 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit
|
|||||||
@Column(name = "dynamic_scaling_enabled")
|
@Column(name = "dynamic_scaling_enabled")
|
||||||
private boolean dynamicScalingEnabled;
|
private boolean dynamicScalingEnabled;
|
||||||
|
|
||||||
|
@Column(name = "disk_offering_strictness")
|
||||||
|
private boolean diskOfferingStrictness;
|
||||||
|
|
||||||
|
@Column(name = "disk_offering_id")
|
||||||
|
private long diskOfferingId;
|
||||||
|
|
||||||
|
@Column(name = "disk_offering_uuid")
|
||||||
|
private String diskOfferingUuid;
|
||||||
|
|
||||||
|
@Column(name = "disk_offering_name")
|
||||||
|
private String diskOfferingName;
|
||||||
|
|
||||||
|
@Column(name = "disk_offering_display_text")
|
||||||
|
private String diskOfferingDisplayText;
|
||||||
|
|
||||||
public ServiceOfferingJoinVO() {
|
public ServiceOfferingJoinVO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,4 +423,24 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit
|
|||||||
public void setDynamicScalingEnabled(boolean dynamicScalingEnabled) {
|
public void setDynamicScalingEnabled(boolean dynamicScalingEnabled) {
|
||||||
this.dynamicScalingEnabled = dynamicScalingEnabled;
|
this.dynamicScalingEnabled = dynamicScalingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getDiskOfferingStrictness() {
|
||||||
|
return diskOfferingStrictness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDiskOfferingId() {
|
||||||
|
return diskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDiskOfferingUuid() {
|
||||||
|
return diskOfferingUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDiskOfferingName() {
|
||||||
|
return diskOfferingName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDiskOfferingDisplayText() {
|
||||||
|
return diskOfferingDisplayText;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2865,6 +2865,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Long diskOfferingId = cmd.getDiskOfferingId();
|
||||||
|
if (diskOfferingId != null) {
|
||||||
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||||
|
if ((diskOffering == null) || diskOffering.isComputeOnly()) {
|
||||||
|
throw new InvalidParameterValueException("Please specify a valid disk offering.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return createServiceOffering(userId, cmd.isSystem(), vmType, cmd.getServiceOfferingName(), cpuNumber, memory, cpuSpeed, cmd.getDisplayText(),
|
return createServiceOffering(userId, cmd.isSystem(), vmType, cmd.getServiceOfferingName(), cpuNumber, memory, cpuSpeed, cmd.getDisplayText(),
|
||||||
cmd.getProvisioningType(), localStorageRequired, offerHA, limitCpuUse, volatileVm, cmd.getTags(), cmd.getDomainIds(), cmd.getZoneIds(), cmd.getHostTag(),
|
cmd.getProvisioningType(), localStorageRequired, offerHA, limitCpuUse, volatileVm, cmd.getTags(), cmd.getDomainIds(), cmd.getZoneIds(), cmd.getHostTag(),
|
||||||
cmd.getNetworkRate(), cmd.getDeploymentPlanner(), details, cmd.getRootDiskSize(), isCustomizedIops, cmd.getMinIops(), cmd.getMaxIops(),
|
cmd.getNetworkRate(), cmd.getDeploymentPlanner(), details, cmd.getRootDiskSize(), isCustomizedIops, cmd.getMinIops(), cmd.getMaxIops(),
|
||||||
@ -2872,7 +2880,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
cmd.getBytesWriteRate(), cmd.getBytesWriteRateMax(), cmd.getBytesWriteRateMaxLength(),
|
cmd.getBytesWriteRate(), cmd.getBytesWriteRateMax(), cmd.getBytesWriteRateMaxLength(),
|
||||||
cmd.getIopsReadRate(), cmd.getIopsReadRateMax(), cmd.getIopsReadRateMaxLength(),
|
cmd.getIopsReadRate(), cmd.getIopsReadRateMax(), cmd.getIopsReadRateMaxLength(),
|
||||||
cmd.getIopsWriteRate(), cmd.getIopsWriteRateMax(), cmd.getIopsWriteRateMaxLength(),
|
cmd.getIopsWriteRate(), cmd.getIopsWriteRateMax(), cmd.getIopsWriteRateMaxLength(),
|
||||||
cmd.getHypervisorSnapshotReserve(), cmd.getCacheMode(), storagePolicyId, cmd.getDynamicScalingEnabled());
|
cmd.getHypervisorSnapshotReserve(), cmd.getCacheMode(), storagePolicyId, cmd.getDynamicScalingEnabled(), diskOfferingId, cmd.getDiskOfferingStrictness(), cmd.isCustomized());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ServiceOfferingVO createServiceOffering(final long userId, final boolean isSystem, final VirtualMachine.Type vmType,
|
protected ServiceOfferingVO createServiceOffering(final long userId, final boolean isSystem, final VirtualMachine.Type vmType,
|
||||||
@ -2883,7 +2891,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength,
|
Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength,
|
||||||
Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength,
|
Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength,
|
||||||
Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength,
|
Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength,
|
||||||
final Integer hypervisorSnapshotReserve, String cacheMode, final Long storagePolicyID, final boolean dynamicScalingEnabled) {
|
final Integer hypervisorSnapshotReserve, String cacheMode, final Long storagePolicyID, final boolean dynamicScalingEnabled, final Long diskOfferingId, final boolean diskOfferingStrictness, final boolean isCustomized) {
|
||||||
// Filter child domains when both parent and child domains are present
|
// Filter child domains when both parent and child domains are present
|
||||||
List<Long> filteredDomainIds = filterChildSubDomains(domainIds);
|
List<Long> filteredDomainIds = filterChildSubDomains(domainIds);
|
||||||
|
|
||||||
@ -2913,55 +2921,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
|
|
||||||
tags = com.cloud.utils.StringUtils.cleanupTags(tags);
|
tags = com.cloud.utils.StringUtils.cleanupTags(tags);
|
||||||
|
|
||||||
ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, networkRate, null, offerHA,
|
ServiceOfferingVO serviceOffering = new ServiceOfferingVO(name, cpu, ramSize, speed, networkRate, null, offerHA,
|
||||||
limitResourceUse, volatileVm, displayText, typedProvisioningType, localStorageRequired, false, tags, isSystem, vmType,
|
limitResourceUse, volatileVm, displayText, isSystem, vmType,
|
||||||
hostTag, deploymentPlanner, dynamicScalingEnabled);
|
hostTag, deploymentPlanner, dynamicScalingEnabled, isCustomized);
|
||||||
|
|
||||||
if (Boolean.TRUE.equals(isCustomizedIops) || isCustomizedIops == null) {
|
|
||||||
minIops = null;
|
|
||||||
maxIops = null;
|
|
||||||
} else {
|
|
||||||
if (minIops == null && maxIops == null) {
|
|
||||||
minIops = 0L;
|
|
||||||
maxIops = 0L;
|
|
||||||
} else {
|
|
||||||
if (minIops == null || minIops <= 0) {
|
|
||||||
throw new InvalidParameterValueException("The min IOPS must be greater than 0.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxIops == null) {
|
|
||||||
maxIops = 0L;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (minIops > maxIops) {
|
|
||||||
throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rootDiskSizeInGiB != null && rootDiskSizeInGiB <= 0L) {
|
|
||||||
throw new InvalidParameterValueException(String.format("The Root disk size is of %s GB but it must be greater than 0.", rootDiskSizeInGiB));
|
|
||||||
} else if (rootDiskSizeInGiB != null) {
|
|
||||||
long rootDiskSizeInBytes = rootDiskSizeInGiB * GiB_TO_BYTES;
|
|
||||||
offering.setDiskSize(rootDiskSizeInBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
offering.setCustomizedIops(isCustomizedIops);
|
|
||||||
offering.setMinIops(minIops);
|
|
||||||
offering.setMaxIops(maxIops);
|
|
||||||
|
|
||||||
setBytesRate(offering, bytesReadRate, bytesReadRateMax, bytesReadRateMaxLength, bytesWriteRate, bytesWriteRateMax, bytesWriteRateMaxLength);
|
|
||||||
setIopsRate(offering, iopsReadRate, iopsReadRateMax, iopsReadRateMaxLength, iopsWriteRate, iopsWriteRateMax, iopsWriteRateMaxLength);
|
|
||||||
|
|
||||||
if(cacheMode != null) {
|
|
||||||
offering.setCacheMode(DiskOffering.DiskCacheMode.valueOf(cacheMode.toUpperCase()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hypervisorSnapshotReserve != null && hypervisorSnapshotReserve < 0) {
|
|
||||||
throw new InvalidParameterValueException("If provided, Hypervisor Snapshot Reserve must be greater than or equal to 0.");
|
|
||||||
}
|
|
||||||
|
|
||||||
offering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
|
|
||||||
|
|
||||||
List<ServiceOfferingDetailsVO> detailsVO = new ArrayList<ServiceOfferingDetailsVO>();
|
List<ServiceOfferingDetailsVO> detailsVO = new ArrayList<ServiceOfferingDetailsVO>();
|
||||||
if (details != null) {
|
if (details != null) {
|
||||||
@ -2996,51 +2958,137 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
// Add in disk offering details
|
// Add in disk offering details
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), detailEntry.getKey(), detailEntryValue, true));
|
detailsVO.add(new ServiceOfferingDetailsVO(serviceOffering.getId(), detailEntry.getKey(), detailEntryValue, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storagePolicyID != null) {
|
if (storagePolicyID != null) {
|
||||||
detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), ApiConstants.STORAGE_POLICY, String.valueOf(storagePolicyID), false));
|
detailsVO.add(new ServiceOfferingDetailsVO(serviceOffering.getId(), ApiConstants.STORAGE_POLICY, String.valueOf(storagePolicyID), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((offering = _serviceOfferingDao.persist(offering)) != null) {
|
serviceOffering.setDiskOfferingStrictness(diskOfferingStrictness);
|
||||||
|
|
||||||
|
DiskOfferingVO diskOffering = null;
|
||||||
|
if (diskOfferingId == null) {
|
||||||
|
diskOffering = createDiskOfferingInternal(userId, isSystem, vmType,
|
||||||
|
name, cpu, ramSize, speed, displayText, typedProvisioningType, localStorageRequired,
|
||||||
|
offerHA, limitResourceUse, volatileVm, tags, domainIds, zoneIds, hostTag,
|
||||||
|
networkRate, deploymentPlanner, details, rootDiskSizeInGiB, isCustomizedIops, minIops, maxIops,
|
||||||
|
bytesReadRate, bytesReadRateMax, bytesReadRateMaxLength,
|
||||||
|
bytesWriteRate, bytesWriteRateMax, bytesWriteRateMaxLength,
|
||||||
|
iopsReadRate, iopsReadRateMax, iopsReadRateMaxLength,
|
||||||
|
iopsWriteRate, iopsWriteRateMax, iopsWriteRateMaxLength,
|
||||||
|
hypervisorSnapshotReserve, cacheMode, storagePolicyID);
|
||||||
|
} else {
|
||||||
|
diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||||
|
}
|
||||||
|
if (diskOffering != null) {
|
||||||
|
serviceOffering.setDiskOfferingId(diskOffering.getId());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((serviceOffering = _serviceOfferingDao.persist(serviceOffering)) != null) {
|
||||||
for (Long domainId : filteredDomainIds) {
|
for (Long domainId : filteredDomainIds) {
|
||||||
detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), ApiConstants.DOMAIN_ID, String.valueOf(domainId), false));
|
detailsVO.add(new ServiceOfferingDetailsVO(serviceOffering.getId(), ApiConstants.DOMAIN_ID, String.valueOf(domainId), false));
|
||||||
}
|
}
|
||||||
if (CollectionUtils.isNotEmpty(zoneIds)) {
|
if (CollectionUtils.isNotEmpty(zoneIds)) {
|
||||||
for (Long zoneId : zoneIds) {
|
for (Long zoneId : zoneIds) {
|
||||||
detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), ApiConstants.ZONE_ID, String.valueOf(zoneId), false));
|
detailsVO.add(new ServiceOfferingDetailsVO(serviceOffering.getId(), ApiConstants.ZONE_ID, String.valueOf(zoneId), false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!detailsVO.isEmpty()) {
|
if (CollectionUtils.isNotEmpty(detailsVO)) {
|
||||||
for (ServiceOfferingDetailsVO detail : detailsVO) {
|
for (ServiceOfferingDetailsVO detail : detailsVO) {
|
||||||
detail.setResourceId(offering.getId());
|
detail.setResourceId(serviceOffering.getId());
|
||||||
}
|
}
|
||||||
_serviceOfferingDetailsDao.saveDetails(detailsVO);
|
_serviceOfferingDetailsDao.saveDetails(detailsVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (details != null && !details.isEmpty()) {
|
CallContext.current().setEventDetails("Service offering id=" + serviceOffering.getId());
|
||||||
List<DiskOfferingDetailVO> diskDetailsVO = new ArrayList<DiskOfferingDetailVO>();
|
return serviceOffering;
|
||||||
// Support disk offering details for below parameters
|
|
||||||
if (details.containsKey(Volume.BANDWIDTH_LIMIT_IN_MBPS)) {
|
|
||||||
diskDetailsVO.add(new DiskOfferingDetailVO(offering.getId(), Volume.BANDWIDTH_LIMIT_IN_MBPS, details.get(Volume.BANDWIDTH_LIMIT_IN_MBPS), false));
|
|
||||||
}
|
|
||||||
if (details.containsKey(Volume.IOPS_LIMIT)) {
|
|
||||||
diskDetailsVO.add(new DiskOfferingDetailVO(offering.getId(), Volume.IOPS_LIMIT, details.get(Volume.IOPS_LIMIT), false));
|
|
||||||
}
|
|
||||||
if (!diskDetailsVO.isEmpty()) {
|
|
||||||
diskOfferingDetailsDao.saveDetails(diskDetailsVO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CallContext.current().setEventDetails("Service offering id=" + offering.getId());
|
|
||||||
return offering;
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DiskOfferingVO createDiskOfferingInternal(final long userId, final boolean isSystem, final VirtualMachine.Type vmType,
|
||||||
|
final String name, final Integer cpu, final Integer ramSize, final Integer speed, final String displayText, final ProvisioningType typedProvisioningType, final boolean localStorageRequired,
|
||||||
|
final boolean offerHA, final boolean limitResourceUse, final boolean volatileVm, String tags, final List<Long> domainIds, List<Long> zoneIds, final String hostTag,
|
||||||
|
final Integer networkRate, final String deploymentPlanner, final Map<String, String> details, Long rootDiskSizeInGiB, final Boolean isCustomizedIops, Long minIops, Long maxIops,
|
||||||
|
Long bytesReadRate, Long bytesReadRateMax, Long bytesReadRateMaxLength,
|
||||||
|
Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength,
|
||||||
|
Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength,
|
||||||
|
Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength,
|
||||||
|
final Integer hypervisorSnapshotReserve, String cacheMode, final Long storagePolicyID) {
|
||||||
|
|
||||||
|
DiskOfferingVO diskOffering = new DiskOfferingVO(name, displayText, typedProvisioningType, false, tags, false, localStorageRequired, false);
|
||||||
|
|
||||||
|
if (Boolean.TRUE.equals(isCustomizedIops) || isCustomizedIops == null) {
|
||||||
|
minIops = null;
|
||||||
|
maxIops = null;
|
||||||
|
} else {
|
||||||
|
if (minIops == null && maxIops == null) {
|
||||||
|
minIops = 0L;
|
||||||
|
maxIops = 0L;
|
||||||
|
} else {
|
||||||
|
if (minIops == null || minIops <= 0) {
|
||||||
|
throw new InvalidParameterValueException("The min IOPS must be greater than 0.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxIops == null) {
|
||||||
|
maxIops = 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minIops > maxIops) {
|
||||||
|
throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rootDiskSizeInGiB != null && rootDiskSizeInGiB <= 0L) {
|
||||||
|
throw new InvalidParameterValueException(String.format("The Root disk size is of %s GB but it must be greater than 0.", rootDiskSizeInGiB));
|
||||||
|
} else if (rootDiskSizeInGiB != null) {
|
||||||
|
long rootDiskSizeInBytes = rootDiskSizeInGiB * GiB_TO_BYTES;
|
||||||
|
diskOffering.setDiskSize(rootDiskSizeInBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
diskOffering.setCustomizedIops(isCustomizedIops);
|
||||||
|
diskOffering.setMinIops(minIops);
|
||||||
|
diskOffering.setMaxIops(maxIops);
|
||||||
|
|
||||||
|
setBytesRate(diskOffering, bytesReadRate, bytesReadRateMax, bytesReadRateMaxLength, bytesWriteRate, bytesWriteRateMax, bytesWriteRateMaxLength);
|
||||||
|
setIopsRate(diskOffering, iopsReadRate, iopsReadRateMax, iopsReadRateMaxLength, iopsWriteRate, iopsWriteRateMax, iopsWriteRateMaxLength);
|
||||||
|
|
||||||
|
if(cacheMode != null) {
|
||||||
|
diskOffering.setCacheMode(DiskOffering.DiskCacheMode.valueOf(cacheMode.toUpperCase()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hypervisorSnapshotReserve != null && hypervisorSnapshotReserve < 0) {
|
||||||
|
throw new InvalidParameterValueException("If provided, Hypervisor Snapshot Reserve must be greater than or equal to 0.");
|
||||||
|
}
|
||||||
|
|
||||||
|
diskOffering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
|
||||||
|
|
||||||
|
if ((diskOffering = _diskOfferingDao.persist(diskOffering)) != null) {
|
||||||
|
if (details != null && !details.isEmpty()) {
|
||||||
|
List<DiskOfferingDetailVO> diskDetailsVO = new ArrayList<DiskOfferingDetailVO>();
|
||||||
|
// Support disk offering details for below parameters
|
||||||
|
if (details.containsKey(Volume.BANDWIDTH_LIMIT_IN_MBPS)) {
|
||||||
|
diskDetailsVO.add(new DiskOfferingDetailVO(diskOffering.getId(), Volume.BANDWIDTH_LIMIT_IN_MBPS, details.get(Volume.BANDWIDTH_LIMIT_IN_MBPS), false));
|
||||||
|
}
|
||||||
|
if (details.containsKey(Volume.IOPS_LIMIT)) {
|
||||||
|
diskDetailsVO.add(new DiskOfferingDetailVO(diskOffering.getId(), Volume.IOPS_LIMIT, details.get(Volume.IOPS_LIMIT), false));
|
||||||
|
}
|
||||||
|
if (!diskDetailsVO.isEmpty()) {
|
||||||
|
diskOfferingDetailsDao.saveDetails(diskDetailsVO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return diskOffering;
|
||||||
|
}
|
||||||
private void setIopsRate(DiskOffering offering, Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength, Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength) {
|
private void setIopsRate(DiskOffering offering, Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength, Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength) {
|
||||||
if (iopsReadRate != null && iopsReadRate > 0) {
|
if (iopsReadRate != null && iopsReadRate > 0) {
|
||||||
offering.setIopsReadRate(iopsReadRate);
|
offering.setIopsReadRate(iopsReadRate);
|
||||||
@ -3196,7 +3244,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
offering.setSortKey(sortKey);
|
offering.setSortKey(sortKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateOfferingTagsIfIsNotNull(storageTags, offering);
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(offeringHandle.getDiskOfferingId());
|
||||||
|
updateOfferingTagsIfIsNotNull(storageTags, diskOffering);
|
||||||
|
_diskOfferingDao.update(diskOffering.getId(), diskOffering);
|
||||||
|
|
||||||
updateServiceOfferingHostTagsIfNotNull(hostTags, offering);
|
updateServiceOfferingHostTagsIfNotNull(hostTags, offering);
|
||||||
|
|
||||||
@ -3261,7 +3311,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength,
|
Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength,
|
||||||
Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength,
|
Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength,
|
||||||
Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength,
|
Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength,
|
||||||
final Integer hypervisorSnapshotReserve, String cacheMode, final Map<String, String> details, final Long storagePolicyID) {
|
final Integer hypervisorSnapshotReserve, String cacheMode, final Map<String, String> details, final Long storagePolicyID, final boolean diskSizeStrictness) {
|
||||||
long diskSize = 0;// special case for custom disk offerings
|
long diskSize = 0;// special case for custom disk offerings
|
||||||
if (numGibibytes != null && numGibibytes <= 0) {
|
if (numGibibytes != null && numGibibytes <= 0) {
|
||||||
throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb.");
|
throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb.");
|
||||||
@ -3343,6 +3393,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
}
|
}
|
||||||
|
|
||||||
newDiskOffering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
|
newDiskOffering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
|
||||||
|
newDiskOffering.setDiskSizeStrictness(diskSizeStrictness);
|
||||||
|
|
||||||
CallContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId());
|
CallContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId());
|
||||||
final DiskOfferingVO offering = _diskOfferingDao.persist(newDiskOffering);
|
final DiskOfferingVO offering = _diskOfferingDao.persist(newDiskOffering);
|
||||||
@ -3391,6 +3442,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
final List<Long> zoneIds = cmd.getZoneIds();
|
final List<Long> zoneIds = cmd.getZoneIds();
|
||||||
final Map<String, String> details = cmd.getDetails();
|
final Map<String, String> details = cmd.getDetails();
|
||||||
final Long storagePolicyId = cmd.getStoragePolicy();
|
final Long storagePolicyId = cmd.getStoragePolicy();
|
||||||
|
final boolean diskSizeStrictness = cmd.getDiskSizeStrictness();
|
||||||
|
|
||||||
// check if valid domain
|
// check if valid domain
|
||||||
if (CollectionUtils.isNotEmpty(domainIds)) {
|
if (CollectionUtils.isNotEmpty(domainIds)) {
|
||||||
@ -3466,7 +3518,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
localStorageRequired, isDisplayOfferingEnabled, isCustomizedIops, minIops,
|
localStorageRequired, isDisplayOfferingEnabled, isCustomizedIops, minIops,
|
||||||
maxIops, bytesReadRate, bytesReadRateMax, bytesReadRateMaxLength, bytesWriteRate, bytesWriteRateMax, bytesWriteRateMaxLength,
|
maxIops, bytesReadRate, bytesReadRateMax, bytesReadRateMaxLength, bytesWriteRate, bytesWriteRateMax, bytesWriteRateMaxLength,
|
||||||
iopsReadRate, iopsReadRateMax, iopsReadRateMaxLength, iopsWriteRate, iopsWriteRateMax, iopsWriteRateMaxLength,
|
iopsReadRate, iopsReadRateMax, iopsReadRateMaxLength, iopsWriteRate, iopsWriteRateMax, iopsWriteRateMaxLength,
|
||||||
hypervisorSnapshotReserve, cacheMode, details, storagePolicyId);
|
hypervisorSnapshotReserve, cacheMode, details, storagePolicyId, diskSizeStrictness);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3858,6 +3910,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
throw new InvalidParameterValueException("unable to find service offering " + offeringId);
|
throw new InvalidParameterValueException("unable to find service offering " + offeringId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify disk offering id mapped to the service offering
|
||||||
|
final DiskOfferingVO diskOffering = _diskOfferingDao.findById(offering.getDiskOfferingId());
|
||||||
|
if (diskOffering == null) {
|
||||||
|
throw new InvalidParameterValueException("unable to find disk offering " + offering.getDiskOfferingId() + " mapped to the service offering " + offeringId);
|
||||||
|
}
|
||||||
|
|
||||||
if (offering.getDefaultUse()) {
|
if (offering.getDefaultUse()) {
|
||||||
throw new InvalidParameterValueException("Default service offerings cannot be deleted");
|
throw new InvalidParameterValueException("Default service offerings cannot be deleted");
|
||||||
}
|
}
|
||||||
@ -3882,7 +3940,13 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
}
|
}
|
||||||
|
|
||||||
annotationDao.removeByEntityType(AnnotationService.EntityType.SERVICE_OFFERING.name(), offering.getUuid());
|
annotationDao.removeByEntityType(AnnotationService.EntityType.SERVICE_OFFERING.name(), offering.getUuid());
|
||||||
offering.setState(DiskOffering.State.Inactive);
|
if (diskOffering.isComputeOnly()) {
|
||||||
|
diskOffering.setState(DiskOffering.State.Inactive);
|
||||||
|
if (!_diskOfferingDao.update(diskOffering.getId(), diskOffering)) {
|
||||||
|
throw new CloudRuntimeException(String.format("Unable to delete disk offering %s mapped to the service offering %s", diskOffering.getUuid(), offering.getUuid()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offering.setState(ServiceOffering.State.Inactive);
|
||||||
if (_serviceOfferingDao.update(offeringId, offering)) {
|
if (_serviceOfferingDao.update(offeringId, offering)) {
|
||||||
CallContext.current().setEventDetails("Service offering id=" + offeringId);
|
CallContext.current().setEventDetails("Service offering id=" + offeringId);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -17,7 +17,6 @@
|
|||||||
package com.cloud.deploy;
|
package com.cloud.deploy;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -113,7 +112,6 @@ import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
|||||||
import com.cloud.storage.DiskOfferingVO;
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
import com.cloud.storage.GuestOSVO;
|
import com.cloud.storage.GuestOSVO;
|
||||||
import com.cloud.storage.ScopeType;
|
import com.cloud.storage.ScopeType;
|
||||||
import com.cloud.storage.Storage;
|
|
||||||
import com.cloud.storage.StorageManager;
|
import com.cloud.storage.StorageManager;
|
||||||
import com.cloud.storage.StoragePool;
|
import com.cloud.storage.StoragePool;
|
||||||
import com.cloud.storage.StoragePoolHostVO;
|
import com.cloud.storage.StoragePoolHostVO;
|
||||||
@ -1404,6 +1402,7 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||||||
|
|
||||||
List<Volume> allVolumes = new ArrayList<>();
|
List<Volume> allVolumes = new ArrayList<>();
|
||||||
allVolumes.addAll(volumesOrderBySizeDesc);
|
allVolumes.addAll(volumesOrderBySizeDesc);
|
||||||
|
List<Pair<Volume, DiskProfile>> volumeDiskProfilePair = getVolumeDiskProfilePairs(allVolumes);
|
||||||
for (StoragePool storagePool : suitablePools) {
|
for (StoragePool storagePool : suitablePools) {
|
||||||
haveEnoughSpace = false;
|
haveEnoughSpace = false;
|
||||||
hostCanAccessPool = false;
|
hostCanAccessPool = false;
|
||||||
@ -1412,7 +1411,7 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||||||
hostCanAccessPool = true;
|
hostCanAccessPool = true;
|
||||||
if (potentialHost.getHypervisorType() == HypervisorType.VMware) {
|
if (potentialHost.getHypervisorType() == HypervisorType.VMware) {
|
||||||
try {
|
try {
|
||||||
boolean isStoragePoolStoragepolicyComplaince = _storageMgr.isStoragePoolCompliantWithStoragePolicy(allVolumes, storagePool);
|
boolean isStoragePoolStoragepolicyComplaince = _storageMgr.isStoragePoolCompliantWithStoragePolicy(volumeDiskProfilePair, storagePool);
|
||||||
if (!isStoragePoolStoragepolicyComplaince) {
|
if (!isStoragePoolStoragepolicyComplaince) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1448,10 +1447,10 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||||||
else
|
else
|
||||||
requestVolumes = new ArrayList<Volume>();
|
requestVolumes = new ArrayList<Volume>();
|
||||||
requestVolumes.add(vol);
|
requestVolumes.add(vol);
|
||||||
|
List<Pair<Volume, DiskProfile>> volumeDiskProfilePair = getVolumeDiskProfilePairs(requestVolumes);
|
||||||
if (potentialHost.getHypervisorType() == HypervisorType.VMware) {
|
if (potentialHost.getHypervisorType() == HypervisorType.VMware) {
|
||||||
try {
|
try {
|
||||||
boolean isStoragePoolStoragepolicyComplaince = _storageMgr.isStoragePoolCompliantWithStoragePolicy(requestVolumes, potentialSPool);
|
boolean isStoragePoolStoragepolicyComplaince = _storageMgr.isStoragePoolCompliantWithStoragePolicy(volumeDiskProfilePair, potentialSPool);
|
||||||
if (!isStoragePoolStoragepolicyComplaince) {
|
if (!isStoragePoolStoragepolicyComplaince) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1461,8 +1460,8 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_storageMgr.storagePoolHasEnoughIops(requestVolumes, potentialSPool) ||
|
if (!_storageMgr.storagePoolHasEnoughIops(volumeDiskProfilePair, potentialSPool) ||
|
||||||
!_storageMgr.storagePoolHasEnoughSpace(requestVolumes, potentialSPool, potentialHost.getClusterId()))
|
!_storageMgr.storagePoolHasEnoughSpace(volumeDiskProfilePair, potentialSPool, potentialHost.getClusterId()))
|
||||||
continue;
|
continue;
|
||||||
volumeAllocationMap.put(potentialSPool, requestVolumes);
|
volumeAllocationMap.put(potentialSPool, requestVolumes);
|
||||||
}
|
}
|
||||||
@ -1498,6 +1497,16 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Pair<Volume, DiskProfile>> getVolumeDiskProfilePairs(List<Volume> volumes) {
|
||||||
|
List<Pair<Volume, DiskProfile>> volumeDiskProfilePairs = new ArrayList<>();
|
||||||
|
for (Volume volume: volumes) {
|
||||||
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
|
||||||
|
DiskProfile diskProfile = new DiskProfile(volume, diskOffering, _volsDao.getHypervisorType(volume.getId()));
|
||||||
|
volumeDiskProfilePairs.add(new Pair<>(volume, diskProfile));
|
||||||
|
}
|
||||||
|
return volumeDiskProfilePairs;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if:
|
* True if:
|
||||||
* - Affinity is not enabled (preferred host is empty)
|
* - Affinity is not enabled (preferred host is empty)
|
||||||
@ -1639,10 +1648,11 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||||||
|
|
||||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId());
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId());
|
||||||
|
|
||||||
if ((vmProfile.getTemplate().getFormat() == Storage.ImageFormat.ISO || toBeCreated.getVolumeType() == Volume.Type.ROOT)
|
//FR123 check how is it different for service offering getTagsArray and disk offering's
|
||||||
&& vmProfile.getServiceOffering().getTagsArray().length != 0) {
|
//if ((vmProfile.getTemplate().getFormat() == Storage.ImageFormat.ISO || toBeCreated.getVolumeType() == Volume.Type.ROOT)
|
||||||
diskOffering.setTagsArray(Arrays.asList(vmProfile.getServiceOffering().getTagsArray()));
|
// && vmProfile.getServiceOffering().getTagsArray().length != 0) {
|
||||||
}
|
// diskOffering.setTagsArray(Arrays.asList(vmProfile.getServiceOffering().getTagsArray()));
|
||||||
|
//}
|
||||||
|
|
||||||
DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType());
|
DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType());
|
||||||
boolean useLocalStorage = false;
|
boolean useLocalStorage = false;
|
||||||
@ -1656,19 +1666,6 @@ StateListener<State, VirtualMachine.Event, VirtualMachine>, Configurable {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
useLocalStorage = diskOffering.isUseLocalStorage();
|
useLocalStorage = diskOffering.isUseLocalStorage();
|
||||||
|
|
||||||
// TODO: this is a hacking fix for the problem of deploy
|
|
||||||
// ISO-based VM on local storage
|
|
||||||
// when deploying VM based on ISO, we have a service offering
|
|
||||||
// and an additional disk offering, use-local storage flag is
|
|
||||||
// actually
|
|
||||||
// saved in service offering, override the flag from service
|
|
||||||
// offering when it is a ROOT disk
|
|
||||||
if (!useLocalStorage && vmProfile.getServiceOffering().isUseLocalStorage()) {
|
|
||||||
if (toBeCreated.getVolumeType() == Volume.Type.ROOT) {
|
|
||||||
useLocalStorage = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
diskProfile.setUseLocalStorage(useLocalStorage);
|
diskProfile.setUseLocalStorage(useLocalStorage);
|
||||||
|
|
||||||
|
|||||||
@ -276,7 +276,7 @@ public class HighAvailabilityManagerImpl extends ManagerBase implements Configur
|
|||||||
|
|
||||||
for (VMInstanceVO vm : reorderedVMList) {
|
for (VMInstanceVO vm : reorderedVMList) {
|
||||||
ServiceOfferingVO vmOffering = _serviceOfferingDao.findById(vm.getServiceOfferingId());
|
ServiceOfferingVO vmOffering = _serviceOfferingDao.findById(vm.getServiceOfferingId());
|
||||||
if (vmOffering.isUseLocalStorage()) {
|
if (_itMgr.isRootVolumeOnLocalStorage(vm.getId())) {
|
||||||
if (s_logger.isDebugEnabled()){
|
if (s_logger.isDebugEnabled()){
|
||||||
s_logger.debug("Skipping HA on vm " + vm + ", because it uses local storage. Its fate is tied to the host.");
|
s_logger.debug("Skipping HA on vm " + vm + ", because it uses local storage. Its fate is tied to the host.");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.cloud.offering.DiskOffering;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
@ -1307,6 +1308,11 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
|
|||||||
throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
|
throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, serviceOffering.getDiskOfferingId());
|
||||||
|
if (diskOffering == null) {
|
||||||
|
throw new InvalidParameterValueException("Unable to find disk offering: " + serviceOffering.getDiskOfferingId());
|
||||||
|
}
|
||||||
|
|
||||||
VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
|
VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
|
||||||
// Make sure a valid template ID was specified
|
// Make sure a valid template ID was specified
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
@ -1314,8 +1320,8 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!zone.isLocalStorageEnabled()) {
|
if (!zone.isLocalStorageEnabled()) {
|
||||||
if (serviceOffering.isUseLocalStorage()) {
|
if (diskOffering.isUseLocalStorage()) {
|
||||||
throw new InvalidParameterValueException("Zone is not configured to use local storage but service offering " + serviceOffering.getName() + " uses it");
|
throw new InvalidParameterValueException("Zone is not configured to use local storage but disk offering " + diskOffering.getName() + " associated to the service offering " + serviceOffering.getName() + " uses it");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1325,18 +1331,18 @@ public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScale
|
|||||||
vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" +
|
vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" +
|
||||||
getCurrentTimeStampString(),
|
getCurrentTimeStampString(),
|
||||||
"autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null,
|
"autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null,
|
||||||
null, true, null, null, null, null, null, null, null, true);
|
null, true, null, null, null, null, null, null, null, true, null);
|
||||||
} else {
|
} else {
|
||||||
if (zone.isSecurityGroupEnabled()) {
|
if (zone.isSecurityGroupEnabled()) {
|
||||||
vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, null, null,
|
vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, null, null,
|
||||||
owner, "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(),
|
owner, "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(),
|
||||||
"autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null,
|
"autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null,
|
||||||
null, null, true, null, null, null, null, null, null, null, true);
|
null, null, true, null, null, null, null, null, null, null, true, null);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" +
|
vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" +
|
||||||
getCurrentTimeStampString(), "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(),
|
getCurrentTimeStampString(), "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(),
|
||||||
null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null, addrs, true, null, null, null, null, null, null, null, true, null);
|
null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null, addrs, true, null, null, null, null, null, null, null, true, null, null);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,6 +45,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import com.cloud.offering.DiskOffering;
|
||||||
import org.apache.cloudstack.alert.AlertService;
|
import org.apache.cloudstack.alert.AlertService;
|
||||||
import org.apache.cloudstack.alert.AlertService.AlertType;
|
import org.apache.cloudstack.alert.AlertService.AlertType;
|
||||||
import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd;
|
import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd;
|
||||||
@ -417,6 +418,10 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
|
|||||||
if (newServiceOffering == null) {
|
if (newServiceOffering == null) {
|
||||||
throw new InvalidParameterValueException("Unable to find service offering with id " + serviceOfferingId);
|
throw new InvalidParameterValueException("Unable to find service offering with id " + serviceOfferingId);
|
||||||
}
|
}
|
||||||
|
DiskOffering newDiskOffering = _entityMgr.findById(DiskOffering.class, newServiceOffering.getDiskOfferingId());
|
||||||
|
if (newDiskOffering == null) {
|
||||||
|
throw new InvalidParameterValueException("Unable to find disk offering: " + newServiceOffering.getDiskOfferingId());
|
||||||
|
}
|
||||||
|
|
||||||
// check if it is a system service offering, if yes return with error as
|
// check if it is a system service offering, if yes return with error as
|
||||||
// it cannot be used for user vms
|
// it cannot be used for user vms
|
||||||
@ -436,9 +441,9 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
|
|||||||
// Check that the service offering being upgraded to has the same
|
// Check that the service offering being upgraded to has the same
|
||||||
// storage pool preference as the VM's current service
|
// storage pool preference as the VM's current service
|
||||||
// offering
|
// offering
|
||||||
if (currentServiceOffering.isUseLocalStorage() != newServiceOffering.isUseLocalStorage()) {
|
if (_itMgr.isRootVolumeOnLocalStorage(routerId) != newDiskOffering.isUseLocalStorage()) {
|
||||||
throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + newServiceOffering.isUseLocalStorage() + " is different from "
|
throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + newDiskOffering.isUseLocalStorage() + " is different from "
|
||||||
+ "curruent local storage status: " + currentServiceOffering.isUseLocalStorage());
|
+ "current local storage status of router " + routerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
router.setServiceOfferingId(serviceOfferingId);
|
router.setServiceOfferingId(serviceOfferingId);
|
||||||
|
|||||||
@ -128,7 +128,7 @@ public class SecurityManagerMBeanImpl extends StandardMBean implements SecurityG
|
|||||||
@Override
|
@Override
|
||||||
public void simulateVmStart(Long vmId) {
|
public void simulateVmStart(Long vmId) {
|
||||||
//all we need is the vmId
|
//all we need is the vmId
|
||||||
VMInstanceVO vm = new VMInstanceVO(vmId, 5, "foo", "foo", Type.User, null, HypervisorType.Any, 8, 1, 1, 1, false, false, null);
|
VMInstanceVO vm = new VMInstanceVO(vmId, 5, "foo", "foo", Type.User, null, HypervisorType.Any, 8, 1, 1, 1, false, false);
|
||||||
_sgMgr.handleVmStarted(vm);
|
_sgMgr.handleVmStarted(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -920,18 +920,22 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
|
|||||||
|
|
||||||
DiskOfferingVO newDiskOffering = new DiskOfferingVO(name, description, provisioningType, diskSize, tags, isCustomized, null, null, null);
|
DiskOfferingVO newDiskOffering = new DiskOfferingVO(name, description, provisioningType, diskSize, tags, isCustomized, null, null, null);
|
||||||
newDiskOffering.setUniqueName("Cloud.Com-" + name);
|
newDiskOffering.setUniqueName("Cloud.Com-" + name);
|
||||||
// leaving the above reference to cloud.com in as it is an identifyer and has no real world relevance
|
// leaving the above reference to cloud.com in as it is an identifier and has no real world relevance
|
||||||
newDiskOffering.setSystemUse(isSystemUse);
|
newDiskOffering = _diskOfferingDao.persistDefaultDiskOffering(newDiskOffering);
|
||||||
newDiskOffering = _diskOfferingDao.persistDeafultDiskOffering(newDiskOffering);
|
|
||||||
return newDiskOffering;
|
return newDiskOffering;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText,
|
private ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText,
|
||||||
ProvisioningType provisioningType, boolean localStorageRequired, boolean offerHA, String tags) {
|
ProvisioningType provisioningType, boolean localStorageRequired, boolean offerHA, String tags) {
|
||||||
tags = cleanupTags(tags);
|
tags = cleanupTags(tags);
|
||||||
|
DiskOfferingVO diskOfferingVO = new DiskOfferingVO(name, displayText, provisioningType, false, tags, false, false, true);
|
||||||
|
diskOfferingVO.setUniqueName("Cloud.Com-" + name);
|
||||||
|
diskOfferingVO = _diskOfferingDao.persistDefaultDiskOffering(diskOfferingVO);
|
||||||
|
|
||||||
ServiceOfferingVO offering =
|
ServiceOfferingVO offering =
|
||||||
new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, offerHA, displayText, provisioningType, localStorageRequired, false, tags, false, null, false);
|
new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, offerHA, displayText, false, null, false);
|
||||||
offering.setUniqueName("Cloud.Com-" + name);
|
offering.setUniqueName("Cloud.Com-" + name);
|
||||||
|
offering.setDiskOfferingId(diskOfferingVO.getId());
|
||||||
// leaving the above reference to cloud.com in as it is an identifyer and has no real world relevance
|
// leaving the above reference to cloud.com in as it is an identifyer and has no real world relevance
|
||||||
offering = _serviceOfferingDao.persistSystemServiceOffering(offering);
|
offering = _serviceOfferingDao.persistSystemServiceOffering(offering);
|
||||||
return offering;
|
return offering;
|
||||||
|
|||||||
@ -509,6 +509,7 @@ import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
|
|||||||
import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToVMSnapshotCmd;
|
import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToVMSnapshotCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.AddResourceDetailCmd;
|
import org.apache.cloudstack.api.command.user.volume.AddResourceDetailCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.volume.ChangeOfferingForVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.DeleteVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.DeleteVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.DestroyVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.DestroyVolumeCmd;
|
||||||
@ -1482,6 +1483,24 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(final Long volumeId) {
|
public Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(final Long volumeId) {
|
||||||
|
|
||||||
|
Pair<List<? extends StoragePool>, List<? extends StoragePool>> allPoolsAndSuitablePoolsPair = listStoragePoolsForMigrationOfVolumeInternal(volumeId, null, null, null, null, false);
|
||||||
|
List<? extends StoragePool> allPools = allPoolsAndSuitablePoolsPair.first();
|
||||||
|
List<? extends StoragePool> suitablePools = allPoolsAndSuitablePoolsPair.second();
|
||||||
|
List<StoragePool> avoidPools = new ArrayList<>();
|
||||||
|
|
||||||
|
final VolumeVO volume = _volumeDao.findById(volumeId);
|
||||||
|
StoragePool srcVolumePool = _poolDao.findById(volume.getPoolId());
|
||||||
|
if (srcVolumePool.getParent() != 0L) {
|
||||||
|
StoragePool datastoreCluster = _poolDao.findById(srcVolumePool.getParent());
|
||||||
|
avoidPools.add(datastoreCluster);
|
||||||
|
}
|
||||||
|
abstractDataStoreClustersList((List<StoragePool>) allPools, new ArrayList<StoragePool>());
|
||||||
|
abstractDataStoreClustersList((List<StoragePool>) suitablePools, avoidPools);
|
||||||
|
return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolumeInternal(final Long volumeId, Long newDiskOfferingId, Long newSize, Long newMinIops, Long newMaxIops, boolean keepSourceStoragePool) {
|
||||||
final Account caller = getCaller();
|
final Account caller = getCaller();
|
||||||
if (!_accountMgr.isRootAdmin(caller.getId())) {
|
if (!_accountMgr.isRootAdmin(caller.getId())) {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
@ -1497,6 +1516,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Long diskOfferingId = volume.getDiskOfferingId();
|
||||||
|
if (newDiskOfferingId != null) {
|
||||||
|
diskOfferingId = newDiskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
// Volume must be attached to an instance for live migration.
|
// Volume must be attached to an instance for live migration.
|
||||||
List<? extends StoragePool> allPools = new ArrayList<StoragePool>();
|
List<? extends StoragePool> allPools = new ArrayList<StoragePool>();
|
||||||
List<? extends StoragePool> suitablePools = new ArrayList<StoragePool>();
|
List<? extends StoragePool> suitablePools = new ArrayList<StoragePool>();
|
||||||
@ -1550,24 +1574,35 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
Host vmHost = hostClusterPair.first();
|
Host vmHost = hostClusterPair.first();
|
||||||
List<Cluster> clusters = hostClusterPair.second();
|
List<Cluster> clusters = hostClusterPair.second();
|
||||||
allPools = getAllStoragePoolCompatibleWithVolumeSourceStoragePool(srcVolumePool, hypervisorType, clusters);
|
allPools = getAllStoragePoolCompatibleWithVolumeSourceStoragePool(srcVolumePool, hypervisorType, clusters);
|
||||||
allPools.remove(srcVolumePool);
|
ExcludeList avoid = new ExcludeList();
|
||||||
|
if (!keepSourceStoragePool) {
|
||||||
|
allPools.remove(srcVolumePool);
|
||||||
|
avoid.addPool(srcVolumePool.getId());
|
||||||
|
}
|
||||||
if (vm != null) {
|
if (vm != null) {
|
||||||
suitablePools = findAllSuitableStoragePoolsForVm(volume, vm, vmHost, srcVolumePool,
|
suitablePools = findAllSuitableStoragePoolsForVm(volume, diskOfferingId, newSize, newMinIops, newMaxIops, vm, vmHost, avoid,
|
||||||
CollectionUtils.isNotEmpty(clusters) ? clusters.get(0) : null, hypervisorType);
|
CollectionUtils.isNotEmpty(clusters) ? clusters.get(0) : null, hypervisorType);
|
||||||
} else {
|
} else {
|
||||||
suitablePools = findAllSuitableStoragePoolsForDetachedVolume(volume, allPools);
|
suitablePools = findAllSuitableStoragePoolsForDetachedVolume(volume, diskOfferingId, allPools);
|
||||||
}
|
}
|
||||||
List<StoragePool> avoidPools = new ArrayList<>();
|
removeDataStoreClusterParents((List<StoragePool>) allPools);
|
||||||
if (srcVolumePool.getParent() != 0L) {
|
removeDataStoreClusterParents((List<StoragePool>) suitablePools);
|
||||||
StoragePool datastoreCluster = _poolDao.findById(srcVolumePool.getParent());
|
|
||||||
avoidPools.add(datastoreCluster);
|
|
||||||
}
|
|
||||||
abstractDataStoreClustersList((List<StoragePool>) allPools, new ArrayList<StoragePool>());
|
|
||||||
abstractDataStoreClustersList((List<StoragePool>) suitablePools, avoidPools);
|
|
||||||
return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
|
return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void abstractDataStoreClustersList(List<StoragePool> storagePools, List<StoragePool> avoidPools) {
|
private void removeDataStoreClusterParents(List<StoragePool> storagePools) {
|
||||||
|
Predicate<StoragePool> childDatastorePredicate = pool -> (pool.getParent() != 0);
|
||||||
|
List<StoragePool> childDatastores = storagePools.stream().filter(childDatastorePredicate).collect(Collectors.toList());
|
||||||
|
if (!childDatastores.isEmpty()) {
|
||||||
|
Set<Long> parentStoragePoolIds = childDatastores.stream().map(mo -> mo.getParent()).collect(Collectors.toSet());
|
||||||
|
for (Long parentStoragePoolId : parentStoragePoolIds) {
|
||||||
|
StoragePool parentPool = _poolDao.findById(parentStoragePoolId);
|
||||||
|
storagePools.remove(parentPool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void abstractDataStoreClustersList(List<StoragePool> storagePools, List<StoragePool> avoidPools) {
|
||||||
Predicate<StoragePool> childDatastorePredicate = pool -> (pool.getParent() != 0);
|
Predicate<StoragePool> childDatastorePredicate = pool -> (pool.getParent() != 0);
|
||||||
List<StoragePool> childDatastores = storagePools.stream().filter(childDatastorePredicate).collect(Collectors.toList());
|
List<StoragePool> childDatastores = storagePools.stream().filter(childDatastorePredicate).collect(Collectors.toList());
|
||||||
storagePools.removeAll(avoidPools);
|
storagePools.removeAll(avoidPools);
|
||||||
@ -1637,10 +1672,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
*
|
*
|
||||||
* Side note: the idea behind this method is to provide power for administrators of manually overriding deployments defined by CloudStack.
|
* Side note: the idea behind this method is to provide power for administrators of manually overriding deployments defined by CloudStack.
|
||||||
*/
|
*/
|
||||||
private List<StoragePool> findAllSuitableStoragePoolsForVm(final VolumeVO volume, VMInstanceVO vm, Host vmHost, StoragePool srcVolumePool, Cluster srcCluster, HypervisorType hypervisorType) {
|
private List<StoragePool> findAllSuitableStoragePoolsForVm(final VolumeVO volume, Long diskOfferingId, Long newSize, Long newMinIops, Long newMaxIops, VMInstanceVO vm, Host vmHost, ExcludeList avoid, Cluster srcCluster, HypervisorType hypervisorType) {
|
||||||
List<StoragePool> suitablePools = new ArrayList<>();
|
List<StoragePool> suitablePools = new ArrayList<>();
|
||||||
ExcludeList avoid = new ExcludeList();
|
|
||||||
avoid.addPool(srcVolumePool.getId());
|
|
||||||
Long clusterId = null;
|
Long clusterId = null;
|
||||||
Long podId = null;
|
Long podId = null;
|
||||||
if (srcCluster != null) {
|
if (srcCluster != null) {
|
||||||
@ -1652,8 +1685,13 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
|
VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
|
||||||
// OfflineVmwareMigration: vm might be null here; deal!
|
// OfflineVmwareMigration: vm might be null here; deal!
|
||||||
|
|
||||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||||
DiskProfile diskProfile = new DiskProfile(volume, diskOffering, hypervisorType);
|
DiskProfile diskProfile = new DiskProfile(volume, diskOffering, hypervisorType);
|
||||||
|
if (volume.getDiskOfferingId() != diskOfferingId) {
|
||||||
|
diskProfile.setSize(newSize);
|
||||||
|
diskProfile.setMinIops(newMinIops);
|
||||||
|
diskProfile.setMaxIops(newMaxIops);
|
||||||
|
}
|
||||||
|
|
||||||
for (StoragePoolAllocator allocator : _storagePoolAllocators) {
|
for (StoragePoolAllocator allocator : _storagePoolAllocators) {
|
||||||
List<StoragePool> pools = allocator.allocateToPool(diskProfile, profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL, true);
|
List<StoragePool> pools = allocator.allocateToPool(diskProfile, profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL, true);
|
||||||
@ -1671,12 +1709,12 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
return suitablePools;
|
return suitablePools;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<StoragePool> findAllSuitableStoragePoolsForDetachedVolume(Volume volume, List<? extends StoragePool> allPools) {
|
private List<StoragePool> findAllSuitableStoragePoolsForDetachedVolume(Volume volume, Long diskOfferingId, List<? extends StoragePool> allPools) {
|
||||||
List<StoragePool> suitablePools = new ArrayList<>();
|
List<StoragePool> suitablePools = new ArrayList<>();
|
||||||
if (CollectionUtils.isEmpty(allPools)) {
|
if (CollectionUtils.isEmpty(allPools)) {
|
||||||
return suitablePools;
|
return suitablePools;
|
||||||
}
|
}
|
||||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||||
List<String> tags = new ArrayList<>();
|
List<String> tags = new ArrayList<>();
|
||||||
String[] tagsArray = diskOffering.getTagsArray();
|
String[] tagsArray = diskOffering.getTagsArray();
|
||||||
if (tagsArray != null && tagsArray.length > 0) {
|
if (tagsArray != null && tagsArray.length > 0) {
|
||||||
@ -3313,6 +3351,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
cmdList.add(UploadVolumeCmd.class);
|
cmdList.add(UploadVolumeCmd.class);
|
||||||
cmdList.add(DestroyVolumeCmd.class);
|
cmdList.add(DestroyVolumeCmd.class);
|
||||||
cmdList.add(RecoverVolumeCmd.class);
|
cmdList.add(RecoverVolumeCmd.class);
|
||||||
|
cmdList.add(ChangeOfferingForVolumeCmd.class);
|
||||||
cmdList.add(CreateStaticRouteCmd.class);
|
cmdList.add(CreateStaticRouteCmd.class);
|
||||||
cmdList.add(CreateVPCCmd.class);
|
cmdList.add(CreateVPCCmd.class);
|
||||||
cmdList.add(DeleteStaticRouteCmd.class);
|
cmdList.add(DeleteStaticRouteCmd.class);
|
||||||
|
|||||||
@ -2312,7 +2312,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean storagePoolHasEnoughIops(List<Volume> requestedVolumes, StoragePool pool) {
|
public boolean storagePoolHasEnoughIops(List<Pair<Volume, DiskProfile>> requestedVolumes, StoragePool pool) {
|
||||||
if (requestedVolumes == null || requestedVolumes.isEmpty() || pool == null) {
|
if (requestedVolumes == null || requestedVolumes.isEmpty() || pool == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2330,8 +2330,13 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
long requestedIops = 0;
|
long requestedIops = 0;
|
||||||
|
|
||||||
for (Volume requestedVolume : requestedVolumes) {
|
for (Pair<Volume, DiskProfile> volumeDiskProfilePair : requestedVolumes) {
|
||||||
|
Volume requestedVolume = volumeDiskProfilePair.first();
|
||||||
|
DiskProfile diskProfile = volumeDiskProfilePair.second();
|
||||||
Long minIops = requestedVolume.getMinIops();
|
Long minIops = requestedVolume.getMinIops();
|
||||||
|
if (requestedVolume.getDiskOfferingId() != diskProfile.getDiskOfferingId()) {
|
||||||
|
minIops = diskProfile.getMinIops();
|
||||||
|
}
|
||||||
|
|
||||||
if (minIops != null && minIops > 0) {
|
if (minIops != null && minIops > 0) {
|
||||||
requestedIops += minIops;
|
requestedIops += minIops;
|
||||||
@ -2344,13 +2349,13 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean storagePoolHasEnoughSpace(List<Volume> volumes, StoragePool pool) {
|
public boolean storagePoolHasEnoughSpace(List<Pair<Volume, DiskProfile>> volumeDiskProfilePairs, StoragePool pool) {
|
||||||
return storagePoolHasEnoughSpace(volumes, pool, null);
|
return storagePoolHasEnoughSpace(volumeDiskProfilePairs, pool, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean storagePoolHasEnoughSpace(List<Volume> volumes, StoragePool pool, Long clusterId) {
|
public boolean storagePoolHasEnoughSpace(List<Pair<Volume, DiskProfile>> volumeDiskProfilesList, StoragePool pool, Long clusterId) {
|
||||||
if (volumes == null || volumes.isEmpty()) {
|
if (CollectionUtils.isEmpty(volumeDiskProfilesList)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2367,10 +2372,12 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
long allocatedSizeWithTemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, null);
|
long allocatedSizeWithTemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, null);
|
||||||
long totalAskingSize = 0;
|
long totalAskingSize = 0;
|
||||||
|
|
||||||
for (Volume volume : volumes) {
|
for (Pair<Volume, DiskProfile> volumeDiskProfilePair : volumeDiskProfilesList) {
|
||||||
// refreshing the volume from the DB to get latest hv_ss_reserve (hypervisor snapshot reserve) field
|
// refreshing the volume from the DB to get latest hv_ss_reserve (hypervisor snapshot reserve) field
|
||||||
// I could have just assigned this to "volume", but decided to make a new variable for it so that it
|
// I could have just assigned this to "volume", but decided to make a new variable for it so that it
|
||||||
// might be clearer that this "volume" in "volumes" still might have an old value for hv_ss_reverse.
|
// might be clearer that this "volume" in "volumeDiskProfilesList" still might have an old value for hv_ss_reverse.
|
||||||
|
Volume volume = volumeDiskProfilePair.first();
|
||||||
|
DiskProfile diskProfile = volumeDiskProfilePair.second();
|
||||||
VolumeVO volumeVO = _volumeDao.findById(volume.getId());
|
VolumeVO volumeVO = _volumeDao.findById(volume.getId());
|
||||||
|
|
||||||
if (volumeVO.getHypervisorSnapshotReserve() == null) {
|
if (volumeVO.getHypervisorSnapshotReserve() == null) {
|
||||||
@ -2398,7 +2405,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
// A ready-state volume is already allocated in a pool, so the asking size is zero for it.
|
// A ready-state volume is already allocated in a pool, so the asking size is zero for it.
|
||||||
// In case the volume is moving across pools or is not ready yet, the asking size has to be computed.
|
// In case the volume is moving across pools or is not ready yet, the asking size has to be computed.
|
||||||
if ((volumeVO.getState() != Volume.State.Ready) || (volumeVO.getPoolId() != pool.getId())) {
|
if ((volumeVO.getState() != Volume.State.Ready) || (volumeVO.getPoolId() != pool.getId())) {
|
||||||
totalAskingSize += getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeVO, poolVO);
|
totalAskingSize += getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeVO, diskProfile, poolVO);
|
||||||
|
|
||||||
totalAskingSize += getAskingSizeForTemplateBasedOnClusterAndStoragePool(volumeVO.getTemplateId(), clusterId, poolVO);
|
totalAskingSize += getAskingSizeForTemplateBasedOnClusterAndStoragePool(volumeVO.getTemplateId(), clusterId, poolVO);
|
||||||
}
|
}
|
||||||
@ -2427,14 +2434,16 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isStoragePoolCompliantWithStoragePolicy(List<Volume> volumes, StoragePool pool) throws StorageUnavailableException {
|
public boolean isStoragePoolCompliantWithStoragePolicy(List<Pair<Volume, DiskProfile>> volumes, StoragePool pool) throws StorageUnavailableException {
|
||||||
if (CollectionUtils.isEmpty(volumes)) {
|
if (CollectionUtils.isEmpty(volumes)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
List<Pair<Volume, Answer>> answers = new ArrayList<Pair<Volume, Answer>>();
|
List<Pair<Volume, Answer>> answers = new ArrayList<Pair<Volume, Answer>>();
|
||||||
|
|
||||||
for (Volume volume : volumes) {
|
for (Pair<Volume, DiskProfile> volumeDiskProfilePair : volumes) {
|
||||||
String storagePolicyId = null;
|
String storagePolicyId = null;
|
||||||
|
Volume volume = volumeDiskProfilePair.first();
|
||||||
|
DiskProfile diskProfile = volumeDiskProfilePair.second();
|
||||||
if (volume.getVolumeType() == Type.ROOT) {
|
if (volume.getVolumeType() == Type.ROOT) {
|
||||||
Long vmId = volume.getInstanceId();
|
Long vmId = volume.getInstanceId();
|
||||||
if (vmId != null) {
|
if (vmId != null) {
|
||||||
@ -2442,7 +2451,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
storagePolicyId = _serviceOfferingDetailsDao.getDetail(vm.getServiceOfferingId(), ApiConstants.STORAGE_POLICY);
|
storagePolicyId = _serviceOfferingDetailsDao.getDetail(vm.getServiceOfferingId(), ApiConstants.STORAGE_POLICY);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
storagePolicyId = _diskOfferingDetailsDao.getDetail(volume.getDiskOfferingId(), ApiConstants.STORAGE_POLICY);
|
storagePolicyId = _diskOfferingDetailsDao.getDetail(diskProfile.getDiskOfferingId(), ApiConstants.STORAGE_POLICY);
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(storagePolicyId)) {
|
if (StringUtils.isNotEmpty(storagePolicyId)) {
|
||||||
VsphereStoragePolicyVO storagePolicyVO = _vsphereStoragePolicyDao.findById(Long.parseLong(storagePolicyId));
|
VsphereStoragePolicyVO storagePolicyVO = _vsphereStoragePolicyDao.findById(Long.parseLong(storagePolicyId));
|
||||||
@ -2556,7 +2565,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getDataObjectSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
|
private long getDataObjectSizeIncludingHypervisorSnapshotReserve(Volume volume, DiskProfile diskProfile, StoragePool pool) {
|
||||||
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
|
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
|
||||||
DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
|
DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
|
||||||
|
|
||||||
@ -2564,7 +2573,9 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
|
PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
|
||||||
|
|
||||||
VolumeInfo volumeInfo = volFactory.getVolume(volume.getId());
|
VolumeInfo volumeInfo = volFactory.getVolume(volume.getId());
|
||||||
|
if (volume.getDiskOfferingId() != diskProfile.getDiskOfferingId()) {
|
||||||
|
return diskProfile.getSize();
|
||||||
|
}
|
||||||
return primaryStoreDriver.getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, pool);
|
return primaryStoreDriver.getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3244,8 +3255,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
// get bytesReadRate from service_offering, disk_offering and vm.disk.throttling.bytes_read_rate
|
// get bytesReadRate from service_offering, disk_offering and vm.disk.throttling.bytes_read_rate
|
||||||
@Override
|
@Override
|
||||||
public Long getDiskBytesReadRate(final ServiceOffering offering, final DiskOffering diskOffering) {
|
public Long getDiskBytesReadRate(final ServiceOffering offering, final DiskOffering diskOffering) {
|
||||||
if ((offering != null) && (offering.getBytesReadRate() != null) && (offering.getBytesReadRate() > 0)) {
|
if ((diskOffering != null) && (diskOffering.getBytesReadRate() != null) && (diskOffering.getBytesReadRate() > 0)) {
|
||||||
return offering.getBytesReadRate();
|
return diskOffering.getBytesReadRate();
|
||||||
} else if ((diskOffering != null) && (diskOffering.getBytesReadRate() != null) && (diskOffering.getBytesReadRate() > 0)) {
|
} else if ((diskOffering != null) && (diskOffering.getBytesReadRate() != null) && (diskOffering.getBytesReadRate() > 0)) {
|
||||||
return diskOffering.getBytesReadRate();
|
return diskOffering.getBytesReadRate();
|
||||||
} else {
|
} else {
|
||||||
@ -3260,9 +3271,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
// get bytesWriteRate from service_offering, disk_offering and vm.disk.throttling.bytes_write_rate
|
// get bytesWriteRate from service_offering, disk_offering and vm.disk.throttling.bytes_write_rate
|
||||||
@Override
|
@Override
|
||||||
public Long getDiskBytesWriteRate(final ServiceOffering offering, final DiskOffering diskOffering) {
|
public Long getDiskBytesWriteRate(final ServiceOffering offering, final DiskOffering diskOffering) {
|
||||||
if ((offering != null) && (offering.getBytesWriteRate() != null) && (offering.getBytesWriteRate() > 0)) {
|
if ((diskOffering != null) && (diskOffering.getBytesWriteRate() != null) && (diskOffering.getBytesWriteRate() > 0)) {
|
||||||
return offering.getBytesWriteRate();
|
|
||||||
} else if ((diskOffering != null) && (diskOffering.getBytesWriteRate() != null) && (diskOffering.getBytesWriteRate() > 0)) {
|
|
||||||
return diskOffering.getBytesWriteRate();
|
return diskOffering.getBytesWriteRate();
|
||||||
} else {
|
} else {
|
||||||
Long bytesWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesWriteRate.key()));
|
Long bytesWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesWriteRate.key()));
|
||||||
@ -3276,9 +3285,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
// get iopsReadRate from service_offering, disk_offering and vm.disk.throttling.iops_read_rate
|
// get iopsReadRate from service_offering, disk_offering and vm.disk.throttling.iops_read_rate
|
||||||
@Override
|
@Override
|
||||||
public Long getDiskIopsReadRate(final ServiceOffering offering, final DiskOffering diskOffering) {
|
public Long getDiskIopsReadRate(final ServiceOffering offering, final DiskOffering diskOffering) {
|
||||||
if ((offering != null) && (offering.getIopsReadRate() != null) && (offering.getIopsReadRate() > 0)) {
|
if ((diskOffering != null) && (diskOffering.getIopsReadRate() != null) && (diskOffering.getIopsReadRate() > 0)) {
|
||||||
return offering.getIopsReadRate();
|
|
||||||
} else if ((diskOffering != null) && (diskOffering.getIopsReadRate() != null) && (diskOffering.getIopsReadRate() > 0)) {
|
|
||||||
return diskOffering.getIopsReadRate();
|
return diskOffering.getIopsReadRate();
|
||||||
} else {
|
} else {
|
||||||
Long iopsReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsReadRate.key()));
|
Long iopsReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsReadRate.key()));
|
||||||
@ -3292,9 +3299,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
// get iopsWriteRate from service_offering, disk_offering and vm.disk.throttling.iops_write_rate
|
// get iopsWriteRate from service_offering, disk_offering and vm.disk.throttling.iops_write_rate
|
||||||
@Override
|
@Override
|
||||||
public Long getDiskIopsWriteRate(final ServiceOffering offering, final DiskOffering diskOffering) {
|
public Long getDiskIopsWriteRate(final ServiceOffering offering, final DiskOffering diskOffering) {
|
||||||
if ((offering != null) && (offering.getIopsWriteRate() != null) && (offering.getIopsWriteRate() > 0)) {
|
if ((diskOffering != null) && (diskOffering.getIopsWriteRate() != null) && (diskOffering.getIopsWriteRate() > 0)) {
|
||||||
return offering.getIopsWriteRate();
|
|
||||||
} else if ((diskOffering != null) && (diskOffering.getIopsWriteRate() != null) && (diskOffering.getIopsWriteRate() > 0)) {
|
|
||||||
return diskOffering.getIopsWriteRate();
|
return diskOffering.getIopsWriteRate();
|
||||||
} else {
|
} else {
|
||||||
Long iopsWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsWriteRate.key()));
|
Long iopsWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsWriteRate.key()));
|
||||||
|
|||||||
@ -33,7 +33,17 @@ import java.util.concurrent.ExecutionException;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.cloud.api.query.dao.ServiceOfferingJoinDao;
|
||||||
|
import com.cloud.api.query.vo.ServiceOfferingJoinVO;
|
||||||
|
import com.cloud.server.ManagementService;
|
||||||
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
|
import com.cloud.vm.DiskProfile;
|
||||||
|
import com.cloud.vm.UserVmDetailVO;
|
||||||
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.volume.ChangeOfferingForVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
|
||||||
@ -99,8 +109,6 @@ import com.cloud.agent.api.ModifyTargetsCommand;
|
|||||||
import com.cloud.agent.api.to.DataTO;
|
import com.cloud.agent.api.to.DataTO;
|
||||||
import com.cloud.agent.api.to.DiskTO;
|
import com.cloud.agent.api.to.DiskTO;
|
||||||
import com.cloud.api.ApiDBUtils;
|
import com.cloud.api.ApiDBUtils;
|
||||||
import com.cloud.api.query.dao.ServiceOfferingJoinDao;
|
|
||||||
import com.cloud.api.query.vo.ServiceOfferingJoinVO;
|
|
||||||
import com.cloud.configuration.Config;
|
import com.cloud.configuration.Config;
|
||||||
import com.cloud.configuration.ConfigurationManager;
|
import com.cloud.configuration.ConfigurationManager;
|
||||||
import com.cloud.configuration.Resource.ResourceType;
|
import com.cloud.configuration.Resource.ResourceType;
|
||||||
@ -247,6 +255,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
@Inject
|
@Inject
|
||||||
private DiskOfferingDao _diskOfferingDao;
|
private DiskOfferingDao _diskOfferingDao;
|
||||||
@Inject
|
@Inject
|
||||||
|
private ServiceOfferingDao _serviceOfferingDao;
|
||||||
|
@Inject
|
||||||
private DiskOfferingDetailsDao _diskOfferingDetailsDao;
|
private DiskOfferingDetailsDao _diskOfferingDetailsDao;
|
||||||
@Inject
|
@Inject
|
||||||
private AccountDao _accountDao;
|
private AccountDao _accountDao;
|
||||||
@ -290,6 +300,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
public TaggedResourceService taggedResourceService;
|
public TaggedResourceService taggedResourceService;
|
||||||
@Inject
|
@Inject
|
||||||
VirtualMachineManager virtualMachineManager;
|
VirtualMachineManager virtualMachineManager;
|
||||||
|
@Inject
|
||||||
|
private ManagementService managementService;
|
||||||
|
|
||||||
protected Gson _gson;
|
protected Gson _gson;
|
||||||
|
|
||||||
@ -309,10 +321,14 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
public static final ConfigKey<Boolean> AllowUserExpungeRecoverVolume = new ConfigKey<Boolean>("Advanced", Boolean.class, "allow.user.expunge.recover.volume", "true",
|
public static final ConfigKey<Boolean> AllowUserExpungeRecoverVolume = new ConfigKey<Boolean>("Advanced", Boolean.class, "allow.user.expunge.recover.volume", "true",
|
||||||
"Determines whether users can expunge or recover their volume", true, ConfigKey.Scope.Account);
|
"Determines whether users can expunge or recover their volume", true, ConfigKey.Scope.Account);
|
||||||
|
|
||||||
|
public static final ConfigKey<Boolean> MatchStoragePoolTagsWithDiskOffering = new ConfigKey<Boolean>("Advanced", Boolean.class, "match.storage.pool.tags.with.disk.offering", "true",
|
||||||
|
"If true, volume's disk offering can be changed only with the matched storage tags", true, ConfigKey.Scope.Zone);
|
||||||
|
|
||||||
private long _maxVolumeSizeInGb;
|
private long _maxVolumeSizeInGb;
|
||||||
private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
|
private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
|
||||||
|
|
||||||
private static final Set<Volume.State> STATES_VOLUME_CANNOT_BE_DESTROYED = new HashSet<>(Arrays.asList(Volume.State.Destroy, Volume.State.Expunging, Volume.State.Expunged, Volume.State.Allocated));
|
private static final Set<Volume.State> STATES_VOLUME_CANNOT_BE_DESTROYED = new HashSet<>(Arrays.asList(Volume.State.Destroy, Volume.State.Expunging, Volume.State.Expunged, Volume.State.Allocated));
|
||||||
|
private static final long GiB_TO_BYTES = 1024 * 1024 * 1024;
|
||||||
|
|
||||||
protected VolumeApiServiceImpl() {
|
protected VolumeApiServiceImpl() {
|
||||||
_volStateMachine = Volume.State.getStateMachine();
|
_volStateMachine = Volume.State.getStateMachine();
|
||||||
@ -471,7 +487,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
// Check that the the disk offering specified is valid
|
// Check that the the disk offering specified is valid
|
||||||
if (diskOfferingId != null) {
|
if (diskOfferingId != null) {
|
||||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||||
if ((diskOffering == null) || diskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(diskOffering.getType())) {
|
if ((diskOffering == null) || diskOffering.getRemoved() != null || diskOffering.isComputeOnly()) {
|
||||||
throw new InvalidParameterValueException("Please specify a valid disk offering.");
|
throw new InvalidParameterValueException("Please specify a valid disk offering.");
|
||||||
}
|
}
|
||||||
if (!diskOffering.isCustomized()) {
|
if (!diskOffering.isCustomized()) {
|
||||||
@ -632,7 +648,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
// Check that the the disk offering is specified
|
// Check that the the disk offering is specified
|
||||||
diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||||
if ((diskOffering == null) || diskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(diskOffering.getType())) {
|
if ((diskOffering == null) || diskOffering.getRemoved() != null || diskOffering.isComputeOnly()) {
|
||||||
throw new InvalidParameterValueException("Please specify a valid disk offering.");
|
throw new InvalidParameterValueException("Please specify a valid disk offering.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -799,7 +815,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
|
|
||||||
private VolumeVO commitVolume(final CreateVolumeCmd cmd, final Account caller, final Account owner, final Boolean displayVolume, final Long zoneId, final Long diskOfferingId,
|
private VolumeVO commitVolume(final CreateVolumeCmd cmd, final Account caller, final Account owner, final Boolean displayVolume, final Long zoneId, final Long diskOfferingId,
|
||||||
final Storage.ProvisioningType provisioningType, final Long size, final Long minIops, final Long maxIops, final VolumeVO parentVolume, final String userSpecifiedName, final String uuid, final Map<String, String> details) {
|
final Storage.ProvisioningType provisioningType, final Long size, final Long minIops, final Long maxIops, final VolumeVO parentVolume, final String userSpecifiedName, final String uuid, final Map<String, String> details) {
|
||||||
return Transaction.execute(new TransactionCallback<VolumeVO>() {
|
return Transaction.execute(new TransactionCallback<VolumeVO>() {
|
||||||
@Override
|
@Override
|
||||||
public VolumeVO doInTransaction(TransactionStatus status) {
|
public VolumeVO doInTransaction(TransactionStatus status) {
|
||||||
@ -936,10 +952,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
@DB
|
@DB
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_RESIZE, eventDescription = "resizing volume", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_RESIZE, eventDescription = "resizing volume", async = true)
|
||||||
public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationException {
|
public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationException {
|
||||||
Long newSize;
|
Long newSize = cmd.getSize();
|
||||||
Long newMinIops;
|
Long newMinIops = cmd.getMinIops();
|
||||||
Long newMaxIops;
|
Long newMaxIops = cmd.getMaxIops();
|
||||||
Integer newHypervisorSnapshotReserve;
|
Integer newHypervisorSnapshotReserve = null;
|
||||||
boolean shrinkOk = cmd.isShrinkOk();
|
boolean shrinkOk = cmd.isShrinkOk();
|
||||||
|
|
||||||
VolumeVO volume = _volsDao.findById(cmd.getEntityId());
|
VolumeVO volume = _volsDao.findById(cmd.getEntityId());
|
||||||
@ -976,14 +992,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
// if we are to use the existing disk offering
|
// if we are to use the existing disk offering
|
||||||
if (newDiskOffering == null) {
|
if (newDiskOffering == null) {
|
||||||
newSize = cmd.getSize();
|
|
||||||
newHypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve();
|
newHypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve();
|
||||||
|
|
||||||
// if the caller is looking to change the size of the volume
|
// if the caller is looking to change the size of the volume
|
||||||
if (newSize != null) {
|
if (newSize != null) {
|
||||||
if (!diskOffering.isCustomized() && !volume.getVolumeType().equals(Volume.Type.ROOT)) {
|
if (diskOffering.getDiskSizeStrictness()) {
|
||||||
throw new InvalidParameterValueException("To change a volume's size without providing a new disk offering, its current disk offering must be "
|
throw new InvalidParameterValueException(String.format("Resize of volume %s is not allowed, since disk size is strictly fixed as per the disk offering", volume.getUuid()));
|
||||||
+ "customizable or it must be a root volume (if providing a disk offering, make sure it is different from the current disk offering).");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNotPossibleToResize(volume, diskOffering)) {
|
if (isNotPossibleToResize(volume, diskOffering)) {
|
||||||
@ -1028,6 +1042,23 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
throw new InvalidParameterValueException("Requested disk offering has been removed.");
|
throw new InvalidParameterValueException("Requested disk offering has been removed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (diskOffering.getDiskSizeStrictness() != newDiskOffering.getDiskSizeStrictness()) {
|
||||||
|
throw new InvalidParameterValueException("Disk offering size strictness does not match with new disk offering");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diskOffering.getDiskSizeStrictness() && (diskOffering.getDiskSize() != newDiskOffering.getDiskSize())) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Resize volume for %s is not allowed since disk offering's size is fixed", volume.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Long instanceId = volume.getInstanceId();
|
||||||
|
VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(instanceId);
|
||||||
|
if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
|
||||||
|
ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(vmInstanceVO.getServiceOfferingId());
|
||||||
|
if (serviceOffering != null && serviceOffering.getDiskOfferingStrictness()) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Cannot resize ROOT volume [%s] with new disk offering since existing disk offering is strictly assigned to the ROOT volume.", volume.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (diskOffering.getTags() != null) {
|
if (diskOffering.getTags() != null) {
|
||||||
if (!com.cloud.utils.StringUtils.areTagsEqual(diskOffering.getTags(), newDiskOffering.getTags())) {
|
if (!com.cloud.utils.StringUtils.areTagsEqual(diskOffering.getTags(), newDiskOffering.getTags())) {
|
||||||
throw new InvalidParameterValueException("The tags on the new and old disk offerings must match.");
|
throw new InvalidParameterValueException("The tags on the new and old disk offerings must match.");
|
||||||
@ -1038,7 +1069,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
_configMgr.checkDiskOfferingAccess(_accountMgr.getActiveAccountById(volume.getAccountId()), newDiskOffering, _dcDao.findById(volume.getDataCenterId()));
|
_configMgr.checkDiskOfferingAccess(_accountMgr.getActiveAccountById(volume.getAccountId()), newDiskOffering, _dcDao.findById(volume.getDataCenterId()));
|
||||||
|
|
||||||
if (newDiskOffering.getDiskSize() > 0 && DiskOfferingVO.Type.Service.equals(newDiskOffering.getType())) {
|
if (newDiskOffering.getDiskSize() > 0 && !newDiskOffering.isComputeOnly()) {
|
||||||
newSize = newDiskOffering.getDiskSize();
|
newSize = newDiskOffering.getDiskSize();
|
||||||
} else if (newDiskOffering.isCustomized()) {
|
} else if (newDiskOffering.isCustomized()) {
|
||||||
newSize = cmd.getSize();
|
newSize = cmd.getSize();
|
||||||
@ -1056,9 +1087,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
newSize = newDiskOffering.getDiskSize();
|
newSize = newDiskOffering.getDiskSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
Long instanceId = volume.getInstanceId();
|
|
||||||
VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(instanceId);
|
|
||||||
checkIfVolumeIsRootAndVmIsRunning(newSize, volume, vmInstanceVO);
|
checkIfVolumeIsRootAndVmIsRunning(newSize, volume, vmInstanceVO);
|
||||||
|
|
||||||
if (newDiskOffering.isCustomizedIops() != null && newDiskOffering.isCustomizedIops()) {
|
if (newDiskOffering.isCustomizedIops() != null && newDiskOffering.isCustomizedIops()) {
|
||||||
@ -1250,7 +1278,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
|
|
||||||
private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long newSize, Long newMinIops, Long newMaxIops, Integer newHypervisorSnapshotReserve, Long newDiskOfferingId,
|
private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long newSize, Long newMinIops, Long newMaxIops, Integer newHypervisorSnapshotReserve, Long newDiskOfferingId,
|
||||||
boolean shrinkOk) {
|
boolean shrinkOk) {
|
||||||
final VolumeVO volume = _volsDao.findById(volumeId);
|
final VolumeVO volume = _volsDao.findById(volumeId);
|
||||||
UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
|
UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
|
||||||
StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
|
StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
|
||||||
@ -1355,6 +1383,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
|
|
||||||
_volsDao.update(volume.getId(), volume);
|
_volsDao.update(volume.getId(), volume);
|
||||||
|
if (userVm != null) {
|
||||||
|
UserVmDetailVO userVmDetailVO = userVmDetailsDao.findDetail(userVm.getId(), VmDetailConstants.ROOT_DISK_SIZE);
|
||||||
|
if (userVmDetailVO != null) {
|
||||||
|
userVmDetailVO.setValue(String.valueOf(newSize/ GiB_TO_BYTES));
|
||||||
|
userVmDetailsDao.update(userVmDetailVO.getId(), userVmDetailVO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Update resource count for the account on primary storage resource */
|
/* Update resource count for the account on primary storage resource */
|
||||||
if (!shrinkOk) {
|
if (!shrinkOk) {
|
||||||
@ -1602,6 +1637,349 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_CHANGE_DISK_OFFERING, eventDescription = "Changing disk offering of a volume")
|
||||||
|
public Volume changeDiskOfferingForVolume(ChangeOfferingForVolumeCmd cmd) throws ResourceAllocationException {
|
||||||
|
Long newSize = cmd.getSize();
|
||||||
|
Long newMinIops = cmd.getMinIops();
|
||||||
|
Long newMaxIops = cmd.getMaxIops();
|
||||||
|
Long newDiskOfferingId = cmd.getNewDiskOfferingId();
|
||||||
|
boolean shrinkOk = cmd.isShrinkOk();
|
||||||
|
boolean autoMigrateVolume = cmd.getAutoMigrate();
|
||||||
|
|
||||||
|
VolumeVO volume = _volsDao.findById(cmd.getId());
|
||||||
|
if (volume == null) {
|
||||||
|
throw new InvalidParameterValueException("No such volume");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Does the caller have authority to act on this volume? */
|
||||||
|
_accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
|
||||||
|
|
||||||
|
return changeDiskOfferingForVolumeInternal(volume, newDiskOfferingId, newSize, newMinIops, newMaxIops, autoMigrateVolume, shrinkOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Volume changeDiskOfferingForVolumeInternal(VolumeVO volume, Long newDiskOfferingId, Long newSize, Long newMinIops, Long newMaxIops, boolean autoMigrateVolume, boolean shrinkOk) throws ResourceAllocationException {
|
||||||
|
DiskOfferingVO existingDiskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
|
||||||
|
DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(newDiskOfferingId);
|
||||||
|
Integer newHypervisorSnapshotReserve = null;
|
||||||
|
|
||||||
|
boolean volumeMigrateRequired = false;
|
||||||
|
boolean volumeResizeRequired = false;
|
||||||
|
|
||||||
|
// VALIDATIONS
|
||||||
|
Long updateNewSize[] = {newSize};
|
||||||
|
Long updateNewMinIops[] = {newMinIops};
|
||||||
|
Long updateNewMaxIops[] = {newMaxIops};
|
||||||
|
Integer updateNewHypervisorSnapshotReserve[] = {newHypervisorSnapshotReserve};
|
||||||
|
validateVolumeResizeWithNewDiskOfferingAndLoad(volume, existingDiskOffering, newDiskOffering, updateNewSize, updateNewMinIops, updateNewMaxIops, updateNewHypervisorSnapshotReserve);
|
||||||
|
newSize = updateNewSize[0];
|
||||||
|
newMinIops = updateNewMinIops[0];
|
||||||
|
newMaxIops = updateNewMaxIops[0];
|
||||||
|
newHypervisorSnapshotReserve = updateNewHypervisorSnapshotReserve[0];
|
||||||
|
long currentSize = volume.getSize();
|
||||||
|
validateVolumeResizeWithSize(volume, currentSize, newSize, shrinkOk);
|
||||||
|
|
||||||
|
/* If this volume has never been beyond allocated state, short circuit everything and simply update the database. */
|
||||||
|
// We need to publish this event to usage_volume table
|
||||||
|
if (volume.getState() == Volume.State.Allocated) {
|
||||||
|
s_logger.debug(String.format("Volume %s is in the allocated state, but has never been created. Simply updating database with new size and IOPS.", volume.getUuid()));
|
||||||
|
|
||||||
|
volume.setSize(newSize);
|
||||||
|
volume.setMinIops(newMinIops);
|
||||||
|
volume.setMaxIops(newMaxIops);
|
||||||
|
volume.setHypervisorSnapshotReserve(newHypervisorSnapshotReserve);
|
||||||
|
|
||||||
|
if (newDiskOffering != null) {
|
||||||
|
volume.setDiskOfferingId(newDiskOfferingId);
|
||||||
|
}
|
||||||
|
|
||||||
|
_volsDao.update(volume.getId(), volume);
|
||||||
|
if (currentSize != newSize) {
|
||||||
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
||||||
|
volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
|
||||||
|
}
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentSize != newSize || newMaxIops != volume.getMaxIops() || newMinIops != volume.getMinIops()) {
|
||||||
|
volumeResizeRequired = true;
|
||||||
|
validateVolumeReadyStateAndHypervisorChecks(volume, currentSize, newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
StoragePoolVO existingStoragePool = _storagePoolDao.findById(volume.getPoolId());
|
||||||
|
|
||||||
|
Pair<List<? extends StoragePool>, List<? extends StoragePool>> poolsPair = managementService.listStoragePoolsForMigrationOfVolumeInternal(volume.getId(), newDiskOffering.getId(), newSize, newMinIops, newMaxIops, true);
|
||||||
|
List<? extends StoragePool> suitableStoragePools = poolsPair.second();
|
||||||
|
|
||||||
|
if (!suitableStoragePools.stream().anyMatch(p -> (p.getId() == existingStoragePool.getId()))) {
|
||||||
|
volumeMigrateRequired = true;
|
||||||
|
if (!autoMigrateVolume) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Failed to change offering for volume %s since automigrate is set to false but volume needs to migrated", volume.getUuid()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!volumeMigrateRequired && !volumeResizeRequired) {
|
||||||
|
_volsDao.updateDiskOffering(volume.getId(), newDiskOffering.getId());
|
||||||
|
volume = _volsDao.findById(volume.getId());
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volumeMigrateRequired) {
|
||||||
|
if (CollectionUtils.isEmpty(poolsPair.first()) && CollectionUtils.isEmpty(poolsPair.second())) {
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Volume change offering operation failed for volume ID: %s as no suitable pool(s) found for migrating to support new disk offering", volume.getUuid()));
|
||||||
|
}
|
||||||
|
Collections.shuffle(suitableStoragePools);
|
||||||
|
MigrateVolumeCmd migrateVolumeCmd = new MigrateVolumeCmd(volume.getId(), suitableStoragePools.get(0).getId(), newDiskOffering.getId(), true);
|
||||||
|
try {
|
||||||
|
volume = (VolumeVO) migrateVolume(migrateVolumeCmd);
|
||||||
|
if (volume == null) {
|
||||||
|
throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume ID: %s migration failed to storage pool %s", volume.getUuid(), suitableStoragePools.get(0).getId()));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume ID: %s migration failed to storage pool %s due to %s", volume.getUuid(), suitableStoragePools.get(0).getId(), e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volumeResizeRequired) {
|
||||||
|
// refresh volume data
|
||||||
|
volume = _volsDao.findById(volume.getId());
|
||||||
|
try {
|
||||||
|
volume = resizeVolumeInternal(volume, newDiskOffering, currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, shrinkOk);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (volumeMigrateRequired) {
|
||||||
|
s_logger.warn(String.format("Volume change offering operation succeeded for volume ID: %s but volume resize operation failed, so please try resize volume operation separately", volume.getUuid()));
|
||||||
|
} else {
|
||||||
|
throw new CloudRuntimeException(String.format("Volume change offering operation failed for volume ID: %s due to resize volume operation failed", volume.getUuid()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
private VolumeVO resizeVolumeInternal(VolumeVO volume, DiskOfferingVO newDiskOffering, Long currentSize, Long newSize, Long newMinIops, Long newMaxIops, Integer newHypervisorSnapshotReserve, boolean shrinkOk) throws ResourceAllocationException {
|
||||||
|
UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
|
||||||
|
HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId());
|
||||||
|
|
||||||
|
if (userVm != null) {
|
||||||
|
if (volume.getVolumeType().equals(Volume.Type.ROOT) && userVm.getPowerState() != VirtualMachine.PowerState.PowerOff && hypervisorType == HypervisorType.VMware) {
|
||||||
|
s_logger.error(" For ROOT volume resize VM should be in Power Off state.");
|
||||||
|
throw new InvalidParameterValueException("VM current state is : " + userVm.getPowerState() + ". But VM should be in " + VirtualMachine.PowerState.PowerOff + " state.");
|
||||||
|
}
|
||||||
|
// serialize VM operation
|
||||||
|
AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
||||||
|
|
||||||
|
if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
|
||||||
|
// avoid re-entrance
|
||||||
|
|
||||||
|
VmWorkJobVO placeHolder = null;
|
||||||
|
|
||||||
|
placeHolder = createPlaceHolderWork(userVm.getId());
|
||||||
|
|
||||||
|
try {
|
||||||
|
return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve,
|
||||||
|
newDiskOffering != null ? newDiskOffering.getId() : null, shrinkOk);
|
||||||
|
} finally {
|
||||||
|
_workJobDao.expunge(placeHolder.getId());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Outcome<Volume> outcome = resizeVolumeThroughJobQueue(userVm.getId(), volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve,
|
||||||
|
newDiskOffering != null ? newDiskOffering.getId() : null, shrinkOk);
|
||||||
|
|
||||||
|
try {
|
||||||
|
outcome.get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException("Operation was interrupted", e);
|
||||||
|
} catch (java.util.concurrent.ExecutionException e) {
|
||||||
|
throw new RuntimeException("Execution exception", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
|
||||||
|
|
||||||
|
if (jobResult != null) {
|
||||||
|
if (jobResult instanceof ConcurrentOperationException) {
|
||||||
|
throw (ConcurrentOperationException)jobResult;
|
||||||
|
} else if (jobResult instanceof ResourceAllocationException) {
|
||||||
|
throw (ResourceAllocationException)jobResult;
|
||||||
|
} else if (jobResult instanceof RuntimeException) {
|
||||||
|
throw (RuntimeException)jobResult;
|
||||||
|
} else if (jobResult instanceof Throwable) {
|
||||||
|
throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
|
||||||
|
} else if (jobResult instanceof Long) {
|
||||||
|
return _volsDao.findById((Long)jobResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, newDiskOffering != null ? newDiskOffering.getId() : null,
|
||||||
|
shrinkOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateVolumeReadyStateAndHypervisorChecks(VolumeVO volume, long currentSize, Long newSize) {
|
||||||
|
// checking if there are any ongoing snapshots on the volume which is to be resized
|
||||||
|
List<SnapshotVO> ongoingSnapshots = _snapshotDao.listByStatus(volume.getId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
|
||||||
|
if (ongoingSnapshots.size() > 0) {
|
||||||
|
throw new CloudRuntimeException("There is/are unbacked up snapshot(s) on this volume, resize volume is not permitted, please try again later.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only works for KVM/XenServer/VMware (or "Any") for now, and volumes with 'None' since they're just allocated in DB */
|
||||||
|
HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId());
|
||||||
|
|
||||||
|
if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.XenServer
|
||||||
|
&& hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Any
|
||||||
|
&& hypervisorType != HypervisorType.None) {
|
||||||
|
throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support volume resize");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volume.getState() != Volume.State.Ready && volume.getState() != Volume.State.Allocated) {
|
||||||
|
throw new InvalidParameterValueException("Volume should be in ready or allocated state before attempting a resize. Volume " + volume.getUuid() + " is in state " + volume.getState() + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hypervisorType.equals(HypervisorType.VMware) && newSize < currentSize) {
|
||||||
|
throw new InvalidParameterValueException("VMware doesn't support shrinking volume from larger size: " + currentSize + " GB to a smaller size: " + newSize + " GB");
|
||||||
|
}
|
||||||
|
|
||||||
|
UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
|
||||||
|
if (userVm != null) {
|
||||||
|
if (volume.getVolumeType().equals(Volume.Type.ROOT) && userVm.getPowerState() != VirtualMachine.PowerState.PowerOff && hypervisorType == HypervisorType.VMware) {
|
||||||
|
s_logger.error(" For ROOT volume resize VM should be in Power Off state.");
|
||||||
|
throw new InvalidParameterValueException("VM current state is : " + userVm.getPowerState() + ". But VM should be in " + VirtualMachine.PowerState.PowerOff + " state.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateVolumeResizeWithNewDiskOfferingAndLoad(VolumeVO volume, DiskOfferingVO existingDiskOffering, DiskOfferingVO newDiskOffering, Long[] newSize, Long[] newMinIops, Long[] newMaxIops, Integer[] newHypervisorSnapshotReserve) {
|
||||||
|
if (newDiskOffering.getRemoved() != null) {
|
||||||
|
throw new InvalidParameterValueException("Requested disk offering has been removed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newDiskOffering.getId() == existingDiskOffering.getId()) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Volume %s already have the new disk offering %s provided", volume.getUuid(), existingDiskOffering.getUuid()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingDiskOffering.getDiskSizeStrictness() != newDiskOffering.getDiskSizeStrictness()) {
|
||||||
|
throw new InvalidParameterValueException("Disk offering size strictness does not match with new disk offering");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MatchStoragePoolTagsWithDiskOffering.valueIn(volume.getDataCenterId())) {
|
||||||
|
if (!doesNewDiskOfferingHasTagsAsOldDiskOffering(existingDiskOffering, newDiskOffering)) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Selected disk offering %s does not have tags as in existing disk offering of volume %s", existingDiskOffering.getUuid(), volume.getUuid()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Long instanceId = volume.getInstanceId();
|
||||||
|
VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(instanceId);
|
||||||
|
if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
|
||||||
|
ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(vmInstanceVO.getServiceOfferingId());
|
||||||
|
if (serviceOffering != null && serviceOffering.getDiskOfferingStrictness()) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Cannot resize ROOT volume [%s] with new disk offering since existing disk offering is strictly assigned to the ROOT volume.", volume.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_configMgr.checkDiskOfferingAccess(_accountMgr.getActiveAccountById(volume.getAccountId()), newDiskOffering, _dcDao.findById(volume.getDataCenterId()));
|
||||||
|
|
||||||
|
if (newDiskOffering.getDiskSize() > 0 && !newDiskOffering.isComputeOnly()) {
|
||||||
|
newSize[0] = (Long) newDiskOffering.getDiskSize();
|
||||||
|
} else if (newDiskOffering.isCustomized()) {
|
||||||
|
if (newSize[0] == null) {
|
||||||
|
throw new InvalidParameterValueException("The new disk offering requires that a size be specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert from GiB to bytes
|
||||||
|
newSize[0] = newSize[0] << 30;
|
||||||
|
} else {
|
||||||
|
if (newSize[0] != null) {
|
||||||
|
throw new InvalidParameterValueException("You cannot pass in a custom disk size to a non-custom disk offering.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newDiskOffering.isComputeOnly() && newDiskOffering.getDiskSize() == 0) {
|
||||||
|
newSize[0] = volume.getSize();
|
||||||
|
} else {
|
||||||
|
newSize[0] = newDiskOffering.getDiskSize();
|
||||||
|
}
|
||||||
|
if (newDiskOffering.isCustomizedIops() != null && newDiskOffering.isCustomizedIops()) {
|
||||||
|
newMinIops[0] = newMinIops[0] != null ? newMinIops[0] : volume.getMinIops();
|
||||||
|
newMaxIops[0] = newMaxIops[0] != null ? newMaxIops[0] : volume.getMaxIops();
|
||||||
|
|
||||||
|
validateIops(newMinIops[0], newMaxIops[0], volume.getPoolType());
|
||||||
|
} else {
|
||||||
|
newMinIops[0] = newDiskOffering.getMinIops();
|
||||||
|
newMaxIops[0] = newDiskOffering.getMaxIops();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the hypervisor snapshot reserve value is null, it must remain null (currently only KVM uses null and null is all KVM uses for a value here)
|
||||||
|
newHypervisorSnapshotReserve[0] = volume.getHypervisorSnapshotReserve() != null ? newDiskOffering.getHypervisorSnapshotReserve() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingDiskOffering.getDiskSizeStrictness() && !(volume.getSize().equals(newSize[0]))) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Resize volume for %s is not allowed since disk offering's size is fixed", volume.getName()));
|
||||||
|
}
|
||||||
|
checkIfVolumeIsRootAndVmIsRunning(newSize[0], volume, vmInstanceVO);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateVolumeResizeWithSize(VolumeVO volume, long currentSize, Long newSize, boolean shrinkOk) throws ResourceAllocationException {
|
||||||
|
|
||||||
|
// if the caller is looking to change the size of the volume
|
||||||
|
if (currentSize != newSize) {
|
||||||
|
if (volume.getInstanceId() != null) {
|
||||||
|
// Check that VM to which this volume is attached does not have VM snapshots
|
||||||
|
if (_vmSnapshotDao.findByVm(volume.getInstanceId()).size() > 0) {
|
||||||
|
throw new InvalidParameterValueException("A volume that is attached to a VM with any VM snapshots cannot be resized.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!validateVolumeSizeRange(newSize)) {
|
||||||
|
throw new InvalidParameterValueException("Requested size out of range");
|
||||||
|
}
|
||||||
|
|
||||||
|
Long storagePoolId = volume.getPoolId();
|
||||||
|
|
||||||
|
if (storagePoolId != null) {
|
||||||
|
StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
|
||||||
|
|
||||||
|
if (storagePoolVO.isManaged()) {
|
||||||
|
Long instanceId = volume.getInstanceId();
|
||||||
|
|
||||||
|
if (instanceId != null) {
|
||||||
|
VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(instanceId);
|
||||||
|
|
||||||
|
if (vmInstanceVO.getHypervisorType() == HypervisorType.KVM && vmInstanceVO.getState() != State.Stopped) {
|
||||||
|
throw new CloudRuntimeException("This kind of KVM disk cannot be resized while it is connected to a VM that's not in the Stopped state.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Let's make certain they (think they) know what they're doing if they
|
||||||
|
* want to shrink by forcing them to provide the shrinkok parameter.
|
||||||
|
* This will be checked again at the hypervisor level where we can see
|
||||||
|
* the actual disk size.
|
||||||
|
*/
|
||||||
|
if (currentSize > newSize) {
|
||||||
|
if (volume != null && ImageFormat.QCOW2.equals(volume.getFormat()) && !Volume.State.Allocated.equals(volume.getState())) {
|
||||||
|
String message = "Unable to shrink volumes of type QCOW2";
|
||||||
|
s_logger.warn(message);
|
||||||
|
throw new InvalidParameterValueException(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentSize > newSize && !shrinkOk) {
|
||||||
|
throw new InvalidParameterValueException("Going from existing size of " + currentSize + " to size of " + newSize + " would shrink the volume."
|
||||||
|
+ "Need to sign off by supplying the shrinkok parameter with value of true.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newSize > currentSize) {
|
||||||
|
/* Check resource limit for this account on primary storage resource */
|
||||||
|
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, volume.isDisplayVolume(),
|
||||||
|
new Long(newSize - currentSize).longValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true)
|
||||||
public Volume attachVolumeToVM(AttachVolumeCmd command) {
|
public Volume attachVolumeToVM(AttachVolumeCmd command) {
|
||||||
@ -2396,6 +2774,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
throw new InvalidParameterValueException("Cannot migrate volume " + vol + "to the destination storage pool " + destPool.getName() + " as the storage pool is in maintenance mode.");
|
throw new InvalidParameterValueException("Cannot migrate volume " + vol + "to the destination storage pool " + destPool.getName() + " as the storage pool is in maintenance mode.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
|
||||||
|
if (diskOffering == null) {
|
||||||
|
throw new CloudRuntimeException("volume '" + vol.getUuid() + "', has no diskoffering. Migration target cannot be checked.");
|
||||||
|
}
|
||||||
String poolUuid = destPool.getUuid();
|
String poolUuid = destPool.getUuid();
|
||||||
if (destPool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
|
if (destPool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
|
||||||
DataCenter dc = _entityMgr.findById(DataCenter.class, vol.getDataCenterId());
|
DataCenter dc = _entityMgr.findById(DataCenter.class, vol.getDataCenterId());
|
||||||
@ -2408,16 +2790,15 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
throw new CloudRuntimeException("Storage pool " + destPool.getName() + " is not suitable to migrate volume " + vol.getName());
|
throw new CloudRuntimeException("Storage pool " + destPool.getName() + " is not suitable to migrate volume " + vol.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!storageMgr.storagePoolHasEnoughSpace(Collections.singletonList(vol), destPool)) {
|
HypervisorType hypervisorType = _volsDao.getHypervisorType(volumeId);
|
||||||
|
DiskProfile diskProfile = new DiskProfile(vol, diskOffering, hypervisorType);
|
||||||
|
Pair<Volume, DiskProfile> volumeDiskProfilePair = new Pair<>(vol, diskProfile);
|
||||||
|
if (!storageMgr.storagePoolHasEnoughSpace(Collections.singletonList(volumeDiskProfilePair), destPool)) {
|
||||||
throw new CloudRuntimeException("Storage pool " + destPool.getName() + " does not have enough space to migrate volume " + vol.getName());
|
throw new CloudRuntimeException("Storage pool " + destPool.getName() + " does not have enough space to migrate volume " + vol.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// OfflineVmwareMigration: check storage tags on disk(offering)s in comparison to destination storage pool
|
// OfflineVmwareMigration: check storage tags on disk(offering)s in comparison to destination storage pool
|
||||||
// OfflineVmwareMigration: if no match return a proper error now
|
// OfflineVmwareMigration: if no match return a proper error now
|
||||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
|
|
||||||
if (diskOffering == null) {
|
|
||||||
throw new CloudRuntimeException("volume '" + vol.getUuid() + "', has no diskoffering. Migration target cannot be checked.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (liveMigrateVolume && State.Running.equals(vm.getState()) &&
|
if (liveMigrateVolume && State.Running.equals(vm.getState()) &&
|
||||||
destPool.getClusterId() != null && srcClusterId != null) {
|
destPool.getClusterId() != null && srcClusterId != null) {
|
||||||
@ -2444,10 +2825,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HypervisorType hypervisorType = _volsDao.getHypervisorType(volumeId);
|
|
||||||
if (hypervisorType.equals(HypervisorType.VMware)) {
|
if (hypervisorType.equals(HypervisorType.VMware)) {
|
||||||
try {
|
try {
|
||||||
boolean isStoragePoolStoragepolicyComplaince = storageMgr.isStoragePoolCompliantWithStoragePolicy(Arrays.asList(vol), destPool);
|
boolean isStoragePoolStoragepolicyComplaince = storageMgr.isStoragePoolCompliantWithStoragePolicy(Arrays.asList(volumeDiskProfilePair), destPool);
|
||||||
if (!isStoragePoolStoragepolicyComplaince) {
|
if (!isStoragePoolStoragepolicyComplaince) {
|
||||||
throw new CloudRuntimeException(String.format("Storage pool %s is not storage policy compliance with the volume %s", poolUuid, vol.getUuid()));
|
throw new CloudRuntimeException(String.format("Storage pool %s is not storage policy compliance with the volume %s", poolUuid, vol.getUuid()));
|
||||||
}
|
}
|
||||||
@ -2458,6 +2838,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
DiskOfferingVO newDiskOffering = retrieveAndValidateNewDiskOffering(cmd);
|
DiskOfferingVO newDiskOffering = retrieveAndValidateNewDiskOffering(cmd);
|
||||||
validateConditionsToReplaceDiskOfferingOfVolume(vol, newDiskOffering, destPool);
|
validateConditionsToReplaceDiskOfferingOfVolume(vol, newDiskOffering, destPool);
|
||||||
|
|
||||||
if (vm != null) {
|
if (vm != null) {
|
||||||
// serialize VM operation
|
// serialize VM operation
|
||||||
AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
||||||
@ -2517,13 +2898,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
* If all checks pass, we move forward returning the disk offering object.
|
* If all checks pass, we move forward returning the disk offering object.
|
||||||
*/
|
*/
|
||||||
private DiskOfferingVO retrieveAndValidateNewDiskOffering(MigrateVolumeCmd cmd) {
|
private DiskOfferingVO retrieveAndValidateNewDiskOffering(MigrateVolumeCmd cmd) {
|
||||||
String newDiskOfferingUuid = cmd.getNewDiskOfferingUuid();
|
Long newDiskOfferingId = cmd.getNewDiskOfferingId();
|
||||||
if (StringUtils.isBlank(newDiskOfferingUuid)) {
|
if (newDiskOfferingId == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
DiskOfferingVO newDiskOffering = _diskOfferingDao.findByUuid(newDiskOfferingUuid);
|
DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(newDiskOfferingId);
|
||||||
if (newDiskOffering == null) {
|
if (newDiskOffering == null) {
|
||||||
throw new InvalidParameterValueException(String.format("The disk offering informed is not valid [id=%s].", newDiskOfferingUuid));
|
throw new InvalidParameterValueException(String.format("The disk offering informed is not valid [id=%s].", newDiskOfferingId));
|
||||||
}
|
}
|
||||||
if (newDiskOffering.getRemoved() != null) {
|
if (newDiskOffering.getRemoved() != null) {
|
||||||
throw new InvalidParameterValueException(String.format("We cannot assign a removed disk offering [id=%s] to a volume. ", newDiskOffering.getUuid()));
|
throw new InvalidParameterValueException(String.format("We cannot assign a removed disk offering [id=%s] to a volume. ", newDiskOffering.getUuid()));
|
||||||
@ -2535,6 +2916,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
zone = _dcDao.findById(volume.getDataCenterId());
|
zone = _dcDao.findById(volume.getDataCenterId());
|
||||||
}
|
}
|
||||||
_accountMgr.checkAccess(caller, newDiskOffering, zone);
|
_accountMgr.checkAccess(caller, newDiskOffering, zone);
|
||||||
|
DiskOfferingVO currentDiskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
|
||||||
|
if (VolumeApiServiceImpl.MatchStoragePoolTagsWithDiskOffering.valueIn(zone.getId()) && !doesNewDiskOfferingHasTagsAsOldDiskOffering(currentDiskOffering, newDiskOffering)) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Existing disk offering storage tags of the volume %s does not contain in the new disk offering %s ", volume.getUuid(), newDiskOffering.getUuid()));
|
||||||
|
}
|
||||||
return newDiskOffering;
|
return newDiskOffering;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2554,12 +2939,25 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((destPool.isShared() && newDiskOffering.isUseLocalStorage()) || destPool.isLocal() && newDiskOffering.isShared()) {
|
if ((destPool.isShared() && newDiskOffering.isUseLocalStorage()) || destPool.isLocal() && newDiskOffering.isShared()) {
|
||||||
throw new InvalidParameterValueException("You cannot move the volume to a shared storage and assing a disk offering for local storage and vice versa.");
|
throw new InvalidParameterValueException("You cannot move the volume to a shared storage and assign a disk offering for local storage and vice versa.");
|
||||||
}
|
}
|
||||||
if (!doesTargetStorageSupportDiskOffering(destPool, newDiskOffering)) {
|
if (!doesTargetStorageSupportDiskOffering(destPool, newDiskOffering)) {
|
||||||
throw new InvalidParameterValueException(String.format("Target Storage [id=%s] tags [%s] does not match new disk offering [id=%s] tags [%s].", destPool.getUuid(),
|
throw new InvalidParameterValueException(String.format("Migration failed: target pool [%s, tags:%s] has no matching tags for volume [%s, uuid:%s, tags:%s]", destPool.getName(),
|
||||||
getStoragePoolTags(destPool), newDiskOffering.getUuid(), newDiskOffering.getTags()));
|
getStoragePoolTags(destPool), volume.getName(), volume.getUuid(), newDiskOffering.getTags()));
|
||||||
}
|
}
|
||||||
|
if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
|
||||||
|
VMInstanceVO vm = null;
|
||||||
|
if (volume.getInstanceId() != null) {
|
||||||
|
vm = _vmInstanceDao.findById(volume.getInstanceId());
|
||||||
|
}
|
||||||
|
if (vm != null) {
|
||||||
|
ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(vm.getServiceOfferingId());
|
||||||
|
if (serviceOffering != null && serviceOffering.getDiskOfferingStrictness()) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Disk offering cannot be changed to the volume %s since existing disk offering is strictly associated with the volume", volume.getUuid()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (volume.getSize() != newDiskOffering.getDiskSize()) {
|
if (volume.getSize() != newDiskOffering.getDiskSize()) {
|
||||||
DiskOfferingVO oldDiskOffering = this._diskOfferingDao.findById(volume.getDiskOfferingId());
|
DiskOfferingVO oldDiskOffering = this._diskOfferingDao.findById(volume.getDiskOfferingId());
|
||||||
s_logger.warn(String.format(
|
s_logger.warn(String.format(
|
||||||
@ -2621,6 +3019,18 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
return CollectionUtils.isSubCollection(Arrays.asList(newDiskOfferingTagsAsStringArray), Arrays.asList(storageTagsAsStringArray));
|
return CollectionUtils.isSubCollection(Arrays.asList(newDiskOfferingTagsAsStringArray), Arrays.asList(storageTagsAsStringArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean doesNewDiskOfferingHasTagsAsOldDiskOffering(DiskOfferingVO oldDO, DiskOfferingVO newDO) {
|
||||||
|
String[] oldDOStorageTags = oldDO.getTagsArray();
|
||||||
|
String[] newDOStorageTags = newDO.getTagsArray();
|
||||||
|
if (oldDOStorageTags.length == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (newDOStorageTags.length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return CollectionUtils.isSubCollection(Arrays.asList(oldDOStorageTags), Arrays.asList(newDOStorageTags));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the storage pool tags as a {@link String}. If the storage pool does not have tags we return a null value.
|
* Retrieves the storage pool tags as a {@link String}. If the storage pool does not have tags we return a null value.
|
||||||
*/
|
*/
|
||||||
@ -3651,7 +4061,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Outcome<Volume> resizeVolumeThroughJobQueue(final Long vmId, final long volumeId, final long currentSize, final long newSize, final Long newMinIops, final Long newMaxIops,
|
public Outcome<Volume> resizeVolumeThroughJobQueue(final Long vmId, final long volumeId, final long currentSize, final long newSize, final Long newMinIops, final Long newMaxIops,
|
||||||
final Integer newHypervisorSnapshotReserve, final Long newServiceOfferingId, final boolean shrinkOk) {
|
final Integer newHypervisorSnapshotReserve, final Long newServiceOfferingId, final boolean shrinkOk) {
|
||||||
final CallContext context = CallContext.current();
|
final CallContext context = CallContext.current();
|
||||||
final User callingUser = context.getCallingUser();
|
final User callingUser = context.getCallingUser();
|
||||||
final Account callingAccount = context.getCallingAccount();
|
final Account callingAccount = context.getCallingAccount();
|
||||||
@ -3745,7 +4155,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Outcome<Snapshot> takeVolumeSnapshotThroughJobQueue(final Long vmId, final Long volumeId, final Long policyId, final Long snapshotId, final Long accountId, final boolean quiesceVm,
|
public Outcome<Snapshot> takeVolumeSnapshotThroughJobQueue(final Long vmId, final Long volumeId, final Long policyId, final Long snapshotId, final Long accountId, final boolean quiesceVm,
|
||||||
final Snapshot.LocationType locationType, final boolean asyncBackup) {
|
final Snapshot.LocationType locationType, final boolean asyncBackup) {
|
||||||
|
|
||||||
final CallContext context = CallContext.current();
|
final CallContext context = CallContext.current();
|
||||||
final User callingUser = context.getCallingUser();
|
final User callingUser = context.getCallingUser();
|
||||||
@ -3852,6 +4262,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigKey<?>[] getConfigKeys() {
|
public ConfigKey<?>[] getConfigKeys() {
|
||||||
return new ConfigKey<?>[] {ConcurrentMigrationsThresholdPerDatastore, AllowUserExpungeRecoverVolume};
|
return new ConfigKey<?>[] {ConcurrentMigrationsThresholdPerDatastore, AllowUserExpungeRecoverVolume, MatchStoragePoolTagsWithDiskOffering};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -932,30 +932,38 @@ public class DatabaseConfig {
|
|||||||
} else {
|
} else {
|
||||||
useLocalStorage = false;
|
useLocalStorage = false;
|
||||||
}
|
}
|
||||||
|
DiskOfferingVO diskOfferingVO = new DiskOfferingVO(name, displayText, provisioningType, false, null, false, false, true);
|
||||||
|
|
||||||
ServiceOfferingVO serviceOffering =
|
ServiceOfferingVO serviceOffering =
|
||||||
new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText,
|
new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText,
|
||||||
provisioningType, useLocalStorage, false, null, false, null, false);
|
false, null, false);
|
||||||
|
|
||||||
Long bytesReadRate = Long.parseLong(_currentObjectParams.get("bytesReadRate"));
|
Long bytesReadRate = Long.parseLong(_currentObjectParams.get("bytesReadRate"));
|
||||||
if ((bytesReadRate != null) && (bytesReadRate > 0))
|
if ((bytesReadRate != null) && (bytesReadRate > 0))
|
||||||
serviceOffering.setBytesReadRate(bytesReadRate);
|
diskOfferingVO.setBytesReadRate(bytesReadRate);
|
||||||
Long bytesWriteRate = Long.parseLong(_currentObjectParams.get("bytesWriteRate"));
|
Long bytesWriteRate = Long.parseLong(_currentObjectParams.get("bytesWriteRate"));
|
||||||
if ((bytesWriteRate != null) && (bytesWriteRate > 0))
|
if ((bytesWriteRate != null) && (bytesWriteRate > 0))
|
||||||
serviceOffering.setBytesWriteRate(bytesWriteRate);
|
diskOfferingVO.setBytesWriteRate(bytesWriteRate);
|
||||||
Long iopsReadRate = Long.parseLong(_currentObjectParams.get("iopsReadRate"));
|
Long iopsReadRate = Long.parseLong(_currentObjectParams.get("iopsReadRate"));
|
||||||
if ((iopsReadRate != null) && (iopsReadRate > 0))
|
if ((iopsReadRate != null) && (iopsReadRate > 0))
|
||||||
serviceOffering.setIopsReadRate(iopsReadRate);
|
diskOfferingVO.setIopsReadRate(iopsReadRate);
|
||||||
Long iopsWriteRate = Long.parseLong(_currentObjectParams.get("iopsWriteRate"));
|
Long iopsWriteRate = Long.parseLong(_currentObjectParams.get("iopsWriteRate"));
|
||||||
if ((iopsWriteRate != null) && (iopsWriteRate > 0))
|
if ((iopsWriteRate != null) && (iopsWriteRate > 0))
|
||||||
serviceOffering.setIopsWriteRate(iopsWriteRate);
|
diskOfferingVO.setIopsWriteRate(iopsWriteRate);
|
||||||
|
|
||||||
ServiceOfferingDaoImpl dao = ComponentContext.inject(ServiceOfferingDaoImpl.class);
|
DiskOfferingDaoImpl DiskOfferinDao = ComponentContext.inject(DiskOfferingDaoImpl.class);
|
||||||
try {
|
try {
|
||||||
dao.persist(serviceOffering);
|
DiskOfferinDao.persist(diskOfferingVO);
|
||||||
|
} catch (Exception e) {
|
||||||
|
s_logger.error("error creating disk offering", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceOffering.setDiskOfferingId(diskOfferingVO.getId());
|
||||||
|
ServiceOfferingDaoImpl serviceOfferingDao = ComponentContext.inject(ServiceOfferingDaoImpl.class);
|
||||||
|
try {
|
||||||
|
serviceOfferingDao.persist(serviceOffering);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s_logger.error("error creating service offering", e);
|
s_logger.error("error creating service offering", e);
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
String insertSql = "INSERT INTO `cloud`.`service_offering` (id, name, cpu, ram_size, speed, nw_rate, mc_rate, created, ha_enabled, mirrored, display_text, guest_ip_type, use_local_storage) " +
|
String insertSql = "INSERT INTO `cloud`.`service_offering` (id, name, cpu, ram_size, speed, nw_rate, mc_rate, created, ha_enabled, mirrored, display_text, guest_ip_type, use_local_storage) " +
|
||||||
|
|||||||
@ -84,6 +84,7 @@ import org.apache.cloudstack.api.command.user.vm.UpdateVmNicIpCmd;
|
|||||||
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
|
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
|
||||||
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
|
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
|
||||||
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
|
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
|
||||||
|
import org.apache.cloudstack.api.command.user.volume.ChangeOfferingForVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
|
||||||
import org.apache.cloudstack.backup.Backup;
|
import org.apache.cloudstack.backup.Backup;
|
||||||
import org.apache.cloudstack.backup.BackupManager;
|
import org.apache.cloudstack.backup.BackupManager;
|
||||||
@ -1115,57 +1116,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
_accountMgr.checkAccess(caller, null, true, vmInstance);
|
_accountMgr.checkAccess(caller, null, true, vmInstance);
|
||||||
|
|
||||||
// Check resource limits for CPU and Memory.
|
upgradeStoppedVirtualMachine(vmId, svcOffId, cmd.getDetails());
|
||||||
Map<String, String> customParameters = cmd.getDetails();
|
|
||||||
ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId);
|
|
||||||
if (newServiceOffering.getState() == DiskOffering.State.Inactive) {
|
|
||||||
throw new InvalidParameterValueException(String.format("Unable to upgrade virtual machine %s with an inactive service offering %s", vmInstance.getUuid(), newServiceOffering.getUuid()));
|
|
||||||
}
|
|
||||||
if (newServiceOffering.isDynamic()) {
|
|
||||||
newServiceOffering.setDynamicFlag(true);
|
|
||||||
validateCustomParameters(newServiceOffering, cmd.getDetails());
|
|
||||||
newServiceOffering = _offeringDao.getComputeOffering(newServiceOffering, customParameters);
|
|
||||||
} else {
|
|
||||||
validateOfferingMaxResource(newServiceOffering);
|
|
||||||
}
|
|
||||||
|
|
||||||
ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
|
|
||||||
|
|
||||||
int newCpu = newServiceOffering.getCpu();
|
|
||||||
int newMemory = newServiceOffering.getRamSize();
|
|
||||||
int currentCpu = currentServiceOffering.getCpu();
|
|
||||||
int currentMemory = currentServiceOffering.getRamSize();
|
|
||||||
|
|
||||||
Account owner = _accountMgr.getActiveAccountById(vmInstance.getAccountId());
|
|
||||||
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
|
||||||
if (newCpu > currentCpu) {
|
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, newCpu - currentCpu);
|
|
||||||
}
|
|
||||||
if (newMemory > currentMemory) {
|
|
||||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, newMemory - currentMemory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the specified service offering ID is valid
|
|
||||||
_itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
|
|
||||||
|
|
||||||
resizeRootVolumeOfVmWithNewOffering(vmInstance, newServiceOffering);
|
|
||||||
|
|
||||||
_itMgr.upgradeVmDb(vmId, newServiceOffering, currentServiceOffering);
|
|
||||||
|
|
||||||
// Increment or decrement CPU and Memory count accordingly.
|
|
||||||
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
|
||||||
if (newCpu > currentCpu) {
|
|
||||||
_resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
|
|
||||||
} else if (currentCpu > newCpu) {
|
|
||||||
_resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.cpu, new Long(currentCpu - newCpu));
|
|
||||||
}
|
|
||||||
if (newMemory > currentMemory) {
|
|
||||||
_resourceLimitMgr.incrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory));
|
|
||||||
} else if (currentMemory > newMemory) {
|
|
||||||
_resourceLimitMgr.decrementResourceCount(owner.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate usage event for VM upgrade
|
// Generate usage event for VM upgrade
|
||||||
UserVmVO userVm = _vmDao.findById(vmId);
|
UserVmVO userVm = _vmDao.findById(vmId);
|
||||||
@ -1230,19 +1181,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
|
|
||||||
private UserVm upgradeStoppedVirtualMachine(Long vmId, Long svcOffId, Map<String, String> customParameters) throws ResourceAllocationException {
|
private UserVm upgradeStoppedVirtualMachine(Long vmId, Long svcOffId, Map<String, String> customParameters) throws ResourceAllocationException {
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
|
||||||
|
|
||||||
// Verify input parameters
|
|
||||||
//UserVmVO vmInstance = _vmDao.findById(vmId);
|
|
||||||
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
|
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
|
||||||
if (vmInstance == null) {
|
|
||||||
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
|
|
||||||
}
|
|
||||||
|
|
||||||
_accountMgr.checkAccess(caller, null, true, vmInstance);
|
|
||||||
|
|
||||||
// Check resource limits for CPU and Memory.
|
// Check resource limits for CPU and Memory.
|
||||||
ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId);
|
ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId);
|
||||||
|
if (newServiceOffering.getState() == ServiceOffering.State.Inactive) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Unable to upgrade virtual machine %s with an inactive service offering %s", vmInstance.getUuid(), newServiceOffering.getUuid()));
|
||||||
|
}
|
||||||
if (newServiceOffering.isDynamic()) {
|
if (newServiceOffering.isDynamic()) {
|
||||||
newServiceOffering.setDynamicFlag(true);
|
newServiceOffering.setDynamicFlag(true);
|
||||||
validateCustomParameters(newServiceOffering, customParameters);
|
validateCustomParameters(newServiceOffering, customParameters);
|
||||||
@ -1252,6 +1197,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
|
ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
|
||||||
|
|
||||||
|
validateDiskOfferingChecks(currentServiceOffering, newServiceOffering);
|
||||||
|
|
||||||
int newCpu = newServiceOffering.getCpu();
|
int newCpu = newServiceOffering.getCpu();
|
||||||
int newMemory = newServiceOffering.getRamSize();
|
int newMemory = newServiceOffering.getRamSize();
|
||||||
int currentCpu = currentServiceOffering.getCpu();
|
int currentCpu = currentServiceOffering.getCpu();
|
||||||
@ -1271,29 +1218,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
_itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
|
_itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
|
||||||
|
|
||||||
// Check if the new service offering can be applied to vm instance
|
// Check if the new service offering can be applied to vm instance
|
||||||
ServiceOffering newSvcOffering = _offeringDao.findById(svcOffId);
|
_accountMgr.checkAccess(owner, newServiceOffering, _dcDao.findById(vmInstance.getDataCenterId()));
|
||||||
_accountMgr.checkAccess(owner, newSvcOffering, _dcDao.findById(vmInstance.getDataCenterId()));
|
|
||||||
|
|
||||||
DiskOfferingVO newRootDiskOffering = _diskOfferingDao.findById(newServiceOffering.getId());
|
// resize and migrate the root volume if required
|
||||||
|
DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(newServiceOffering.getDiskOfferingId());
|
||||||
List<VolumeVO> vols = _volsDao.findReadyAndAllocatedRootVolumesByInstance(vmInstance.getId());
|
changeDiskOfferingForRootVolume(vmId, newDiskOffering, customParameters);
|
||||||
|
|
||||||
for (final VolumeVO rootVolumeOfVm : vols) {
|
|
||||||
DiskOfferingVO currentRootDiskOffering = _diskOfferingDao.findById(rootVolumeOfVm.getDiskOfferingId());
|
|
||||||
|
|
||||||
ResizeVolumeCmd resizeVolumeCmd = prepareResizeVolumeCmd(rootVolumeOfVm, currentRootDiskOffering, newRootDiskOffering);
|
|
||||||
|
|
||||||
if (rootVolumeOfVm.getDiskOfferingId() != newRootDiskOffering.getId()) {
|
|
||||||
rootVolumeOfVm.setDiskOfferingId(newRootDiskOffering.getId());
|
|
||||||
_volsDao.update(rootVolumeOfVm.getId(), rootVolumeOfVm);
|
|
||||||
}
|
|
||||||
HypervisorType hypervisorType = _volsDao.getHypervisorType(rootVolumeOfVm.getId());
|
|
||||||
if (HypervisorType.Simulator != hypervisorType) {
|
|
||||||
_volumeService.resizeVolume(resizeVolumeCmd);
|
|
||||||
} else if (newRootDiskOffering.getDiskSize() > 0 && currentRootDiskOffering.getDiskSize() != newRootDiskOffering.getDiskSize()) {
|
|
||||||
throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support volume resize");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_itMgr.upgradeVmDb(vmId, newServiceOffering, currentServiceOffering);
|
_itMgr.upgradeVmDb(vmId, newServiceOffering, currentServiceOffering);
|
||||||
|
|
||||||
@ -1349,19 +1278,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
return resizeVolumeCmd;
|
return resizeVolumeCmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resizeRootVolumeOfVmWithNewOffering(VMInstanceVO vmInstance, ServiceOfferingVO newServiceOffering)
|
|
||||||
throws ResourceAllocationException {
|
|
||||||
DiskOfferingVO newROOTDiskOffering = _diskOfferingDao.findById(newServiceOffering.getId());
|
|
||||||
List<VolumeVO> vols = _volsDao.findReadyAndAllocatedRootVolumesByInstance(vmInstance.getId());
|
|
||||||
|
|
||||||
for (final VolumeVO rootVolumeOfVm : vols) {
|
|
||||||
rootVolumeOfVm.setDiskOfferingId(newROOTDiskOffering.getId());
|
|
||||||
ResizeVolumeCmd resizeVolumeCmd = new ResizeVolumeCmd(rootVolumeOfVm.getId(), newROOTDiskOffering.getMinIops(), newROOTDiskOffering.getMaxIops());
|
|
||||||
_volumeService.resizeVolume(resizeVolumeCmd);
|
|
||||||
_volsDao.update(rootVolumeOfVm.getId(), rootVolumeOfVm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_NIC_CREATE, eventDescription = "Creating Nic", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_NIC_CREATE, eventDescription = "Creating Nic", async = true)
|
||||||
public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, CloudRuntimeException {
|
public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, CloudRuntimeException {
|
||||||
@ -1920,7 +1836,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
// Verify input parameters
|
// Verify input parameters
|
||||||
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
|
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
|
||||||
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
|
_accountMgr.checkAccess(caller, null, true, vmInstance);
|
||||||
if (vmInstance != null) {
|
if (vmInstance != null) {
|
||||||
if (vmInstance.getState().equals(State.Stopped)) {
|
if (vmInstance.getState().equals(State.Stopped)) {
|
||||||
upgradeStoppedVirtualMachine(vmId, newServiceOfferingId, customParameters);
|
upgradeStoppedVirtualMachine(vmId, newServiceOfferingId, customParameters);
|
||||||
@ -1971,6 +1888,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
throw new InvalidParameterValueException("Unable to Scale VM: since dynamic scaling enabled flag is not same for new service offering and old service offering");
|
throw new InvalidParameterValueException("Unable to Scale VM: since dynamic scaling enabled flag is not same for new service offering and old service offering");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validateDiskOfferingChecks(currentServiceOffering, newServiceOffering);
|
||||||
|
|
||||||
int newCpu = newServiceOffering.getCpu();
|
int newCpu = newServiceOffering.getCpu();
|
||||||
int newMemory = newServiceOffering.getRamSize();
|
int newMemory = newServiceOffering.getRamSize();
|
||||||
int newSpeed = newServiceOffering.getSpeed();
|
int newSpeed = newServiceOffering.getSpeed();
|
||||||
@ -2066,7 +1985,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
_itMgr.findHostAndMigrate(vmInstance.getUuid(), newServiceOfferingId, customParameters, excludes);
|
_itMgr.findHostAndMigrate(vmInstance.getUuid(), newServiceOfferingId, customParameters, excludes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #3 scale the vm now
|
// #3 resize or migrate the root volume if required
|
||||||
|
DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(newServiceOffering.getDiskOfferingId());
|
||||||
|
changeDiskOfferingForRootVolume(vmId, newDiskOffering, customParameters);
|
||||||
|
|
||||||
|
// #4 scale the vm now
|
||||||
vmInstance = _vmInstanceDao.findById(vmId);
|
vmInstance = _vmInstanceDao.findById(vmId);
|
||||||
_itMgr.reConfigureVm(vmInstance.getUuid(), currentServiceOffering, newServiceOffering, customParameters, existingHostHasCapacity);
|
_itMgr.reConfigureVm(vmInstance.getUuid(), currentServiceOffering, newServiceOffering, customParameters, existingHostHasCapacity);
|
||||||
success = true;
|
success = true;
|
||||||
@ -2090,6 +2013,51 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateDiskOfferingChecks(ServiceOfferingVO currentServiceOffering, ServiceOfferingVO newServiceOffering) {
|
||||||
|
if (currentServiceOffering.getDiskOfferingStrictness() != newServiceOffering.getDiskOfferingStrictness()) {
|
||||||
|
throw new InvalidParameterValueException("Unable to Scale VM, since disk offering strictness flag is not same for new service offering and old service offering");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentServiceOffering.getDiskOfferingStrictness() && currentServiceOffering.getDiskOfferingId() != newServiceOffering.getDiskOfferingId()) {
|
||||||
|
throw new InvalidParameterValueException("Unable to Scale VM, since disk offering id associated with the old service offering is not same for new service offering");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeDiskOfferingForRootVolume(Long vmId, DiskOfferingVO newDiskOffering, Map<String, String> customParameters) throws ResourceAllocationException {
|
||||||
|
|
||||||
|
List<VolumeVO> vols = _volsDao.findReadyAndAllocatedRootVolumesByInstance(vmId);
|
||||||
|
|
||||||
|
for (final VolumeVO rootVolumeOfVm : vols) {
|
||||||
|
DiskOfferingVO currentRootDiskOffering = _diskOfferingDao.findById(rootVolumeOfVm.getDiskOfferingId());
|
||||||
|
HypervisorType hypervisorType = _volsDao.getHypervisorType(rootVolumeOfVm.getId());
|
||||||
|
if (HypervisorType.Simulator != hypervisorType) {
|
||||||
|
Long minIopsInNewDiskOffering = null;
|
||||||
|
Long maxIopsInNewDiskOffering = null;
|
||||||
|
boolean autoMigrate = false;
|
||||||
|
boolean shrinkOk = false;
|
||||||
|
if (customParameters.containsKey(ApiConstants.MIN_IOPS)) {
|
||||||
|
minIopsInNewDiskOffering = Long.parseLong(customParameters.get(ApiConstants.MIN_IOPS));
|
||||||
|
}
|
||||||
|
if (customParameters.containsKey(ApiConstants.MAX_IOPS)) {
|
||||||
|
minIopsInNewDiskOffering = Long.parseLong(customParameters.get(ApiConstants.MAX_IOPS));
|
||||||
|
}
|
||||||
|
if (customParameters.containsKey(ApiConstants.AUTO_MIGRATE)) {
|
||||||
|
autoMigrate = Boolean.parseBoolean(customParameters.get(ApiConstants.AUTO_MIGRATE));
|
||||||
|
}
|
||||||
|
if (customParameters.containsKey(ApiConstants.SHRINK_OK)) {
|
||||||
|
shrinkOk = Boolean.parseBoolean(customParameters.get(ApiConstants.SHRINK_OK));
|
||||||
|
}
|
||||||
|
ChangeOfferingForVolumeCmd changeOfferingForVolumeCmd = new ChangeOfferingForVolumeCmd(rootVolumeOfVm.getId(), newDiskOffering.getId(), minIopsInNewDiskOffering, maxIopsInNewDiskOffering, autoMigrate, shrinkOk);
|
||||||
|
Volume result = _volumeService.changeDiskOfferingForVolume(changeOfferingForVolumeCmd);
|
||||||
|
if (result == null) {
|
||||||
|
throw new CloudRuntimeException("Failed to change disk offering of the root volume");
|
||||||
|
}
|
||||||
|
} else if (newDiskOffering.getDiskSize() > 0 && currentRootDiskOffering.getDiskSize() != newDiskOffering.getDiskSize()) {
|
||||||
|
throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support volume resize");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HashMap<Long, VmStatsEntry> getVirtualMachineStatistics(long hostId, String hostName, List<Long> vmIds) throws CloudRuntimeException {
|
public HashMap<Long, VmStatsEntry> getVirtualMachineStatistics(long hostId, String hostName, List<Long> vmIds) throws CloudRuntimeException {
|
||||||
HashMap<Long, VmStatsEntry> vmStatsById = new HashMap<Long, VmStatsEntry>();
|
HashMap<Long, VmStatsEntry> vmStatsById = new HashMap<Long, VmStatsEntry>();
|
||||||
@ -2258,7 +2226,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
Long offeringId = null;
|
Long offeringId = null;
|
||||||
if (diskOfferingId != null) {
|
if (diskOfferingId != null) {
|
||||||
DiskOfferingVO offering = _diskOfferingDao.findById(diskOfferingId);
|
DiskOfferingVO offering = _diskOfferingDao.findById(diskOfferingId);
|
||||||
if (offering != null && (offering.getType() == DiskOfferingVO.Type.Disk)) {
|
if (offering != null && !offering.isComputeOnly()) {
|
||||||
offeringId = offering.getId();
|
offeringId = offering.getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3433,7 +3401,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
|
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
|
||||||
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
|
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
|
||||||
Map<String, String> customParametes, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
|
Map<String, String> customParametes, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
|
||||||
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
|
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
|
||||||
StorageUnavailableException, ResourceAllocationException {
|
StorageUnavailableException, ResourceAllocationException {
|
||||||
|
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
@ -3482,7 +3450,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod,
|
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod,
|
||||||
userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParametes, customId, dhcpOptionMap,
|
userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParametes, customId, dhcpOptionMap,
|
||||||
dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled, null);
|
dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled, null, overrideDiskOfferingId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3492,7 +3460,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
|
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
|
||||||
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
|
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
|
||||||
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
|
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
|
||||||
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled) throws InsufficientCapacityException, ConcurrentOperationException,
|
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId) throws InsufficientCapacityException, ConcurrentOperationException,
|
||||||
ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
|
ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
|
||||||
|
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
@ -3593,7 +3561,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod,
|
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod,
|
||||||
userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParameters, customId, dhcpOptionMap, dataDiskTemplateToDiskOfferingMap,
|
userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParameters, customId, dhcpOptionMap, dataDiskTemplateToDiskOfferingMap,
|
||||||
userVmOVFProperties, dynamicScalingEnabled, null);
|
userVmOVFProperties, dynamicScalingEnabled, null, overrideDiskOfferingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -3602,7 +3570,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
|
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
|
||||||
String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayvm, String keyboard, List<Long> affinityGroupIdList,
|
String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayvm, String keyboard, List<Long> affinityGroupIdList,
|
||||||
Map<String, String> customParametrs, String customId, Map<String, Map<Integer, String>> dhcpOptionsMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
Map<String, String> customParametrs, String customId, Map<String, Map<Integer, String>> dhcpOptionsMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
||||||
Map<String, String> userVmOVFPropertiesMap, boolean dynamicScalingEnabled, String type) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
|
Map<String, String> userVmOVFPropertiesMap, boolean dynamicScalingEnabled, String type, Long overrideDiskOfferingId) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
|
||||||
StorageUnavailableException, ResourceAllocationException {
|
StorageUnavailableException, ResourceAllocationException {
|
||||||
|
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
@ -3654,7 +3622,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, httpmethod, userData,
|
return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, httpmethod, userData,
|
||||||
sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, customParametrs, customId, dhcpOptionsMap,
|
sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, customParametrs, customId, dhcpOptionsMap,
|
||||||
dataDiskTemplateToDiskOfferingMap, userVmOVFPropertiesMap, dynamicScalingEnabled, type);
|
dataDiskTemplateToDiskOfferingMap, userVmOVFPropertiesMap, dynamicScalingEnabled, type, overrideDiskOfferingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NetworkVO getNetworkToAddToNetworkList(VirtualMachineTemplate template, Account owner, HypervisorType hypervisor,
|
private NetworkVO getNetworkToAddToNetworkList(VirtualMachineTemplate template, Account owner, HypervisorType hypervisor,
|
||||||
@ -3773,7 +3741,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
String sshKeyPair, HypervisorType hypervisor, Account caller, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean isDisplayVm, String keyboard,
|
String sshKeyPair, HypervisorType hypervisor, Account caller, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean isDisplayVm, String keyboard,
|
||||||
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
|
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
|
||||||
Map<Long, DiskOffering> datadiskTemplateToDiskOfferringMap,
|
Map<Long, DiskOffering> datadiskTemplateToDiskOfferringMap,
|
||||||
Map<String, String> userVmOVFPropertiesMap, boolean dynamicScalingEnabled, String type) throws InsufficientCapacityException, ResourceUnavailableException,
|
Map<String, String> userVmOVFPropertiesMap, boolean dynamicScalingEnabled, String type, Long overrideDiskOfferingId) throws InsufficientCapacityException, ResourceUnavailableException,
|
||||||
ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException {
|
ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException {
|
||||||
|
|
||||||
_accountMgr.checkAccess(caller, null, true, owner);
|
_accountMgr.checkAccess(caller, null, true, owner);
|
||||||
@ -3834,23 +3802,28 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
// check if account/domain is with in resource limits to create a new vm
|
// check if account/domain is with in resource limits to create a new vm
|
||||||
boolean isIso = Storage.ImageFormat.ISO == template.getFormat();
|
boolean isIso = Storage.ImageFormat.ISO == template.getFormat();
|
||||||
|
|
||||||
long size = configureCustomRootDiskSize(customParameters, template, hypervisorType, offering);
|
Long rootDiskOfferingId = offering.getDiskOfferingId();
|
||||||
|
if (isIso) {
|
||||||
if (diskOfferingId != null) {
|
if (diskOfferingId == null) {
|
||||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(rootDiskOfferingId);
|
||||||
if (diskOffering != null && diskOffering.isCustomized()) {
|
if (diskOffering.isComputeOnly()) {
|
||||||
if (diskSize == null) {
|
throw new InvalidParameterValueException("Installing from ISO requires a disk offering to be specified for the root disk.");
|
||||||
throw new InvalidParameterValueException("This disk offering requires a custom size specified");
|
|
||||||
}
|
}
|
||||||
Long customDiskOfferingMaxSize = VolumeOrchestrationService.CustomDiskOfferingMaxSize.value();
|
} else {
|
||||||
Long customDiskOfferingMinSize = VolumeOrchestrationService.CustomDiskOfferingMinSize.value();
|
rootDiskOfferingId = diskOfferingId;
|
||||||
if ((diskSize < customDiskOfferingMinSize) || (diskSize > customDiskOfferingMaxSize)) {
|
diskOfferingId = null;
|
||||||
throw new InvalidParameterValueException("VM Creation failed. Volume size: " + diskSize + "GB is out of allowed range. Max: " + customDiskOfferingMaxSize
|
|
||||||
+ " Min:" + customDiskOfferingMinSize);
|
|
||||||
}
|
|
||||||
size += diskSize * GiB_TO_BYTES;
|
|
||||||
}
|
}
|
||||||
size += _diskOfferingDao.findById(diskOfferingId).getDiskSize();
|
}
|
||||||
|
if (!offering.getDiskOfferingStrictness() && overrideDiskOfferingId != null) {
|
||||||
|
rootDiskOfferingId = overrideDiskOfferingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiskOfferingVO rootdiskOffering = _diskOfferingDao.findById(rootDiskOfferingId);
|
||||||
|
long size = configureCustomRootDiskSize(customParameters, template, hypervisorType, rootdiskOffering);
|
||||||
|
|
||||||
|
if (!isIso && diskOfferingId != null) {
|
||||||
|
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
|
||||||
|
size += verifyAndGetDiskSize(diskOffering, diskSize);
|
||||||
}
|
}
|
||||||
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
|
||||||
resourceLimitCheck(owner, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
resourceLimitCheck(owner, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
||||||
@ -4137,7 +4110,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
|
|
||||||
UserVmVO vm = commitUserVm(zone, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, caller, isDisplayVm, keyboard, accountId, userId, offering,
|
UserVmVO vm = commitUserVm(zone, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, caller, isDisplayVm, keyboard, accountId, userId, offering,
|
||||||
isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters, dhcpOptionMap,
|
isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters, dhcpOptionMap,
|
||||||
datadiskTemplateToDiskOfferringMap, userVmOVFPropertiesMap, dynamicScalingEnabled, type);
|
datadiskTemplateToDiskOfferringMap, userVmOVFPropertiesMap, dynamicScalingEnabled, type, rootDiskOfferingId);
|
||||||
|
|
||||||
// Assign instance to the group
|
// Assign instance to the group
|
||||||
try {
|
try {
|
||||||
@ -4161,6 +4134,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long verifyAndGetDiskSize(DiskOfferingVO diskOffering, Long diskSize) {
|
||||||
|
long size = 0l;
|
||||||
|
if (diskOffering != null && diskOffering.isCustomized() && !diskOffering.isComputeOnly()) {
|
||||||
|
if (diskSize == null) {
|
||||||
|
throw new InvalidParameterValueException("This disk offering requires a custom size specified");
|
||||||
|
}
|
||||||
|
Long customDiskOfferingMaxSize = VolumeOrchestrationService.CustomDiskOfferingMaxSize.value();
|
||||||
|
Long customDiskOfferingMinSize = VolumeOrchestrationService.CustomDiskOfferingMinSize.value();
|
||||||
|
if ((diskSize < customDiskOfferingMinSize) || (diskSize > customDiskOfferingMaxSize)) {
|
||||||
|
throw new InvalidParameterValueException("VM Creation failed. Volume size: " + diskSize + "GB is out of allowed range. Max: " + customDiskOfferingMaxSize
|
||||||
|
+ " Min:" + customDiskOfferingMinSize);
|
||||||
|
}
|
||||||
|
size += diskSize * GiB_TO_BYTES;
|
||||||
|
}
|
||||||
|
size += diskOffering.getDiskSize();
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkIfDynamicScalingCanBeEnabled(VirtualMachine vm, ServiceOffering offering, VirtualMachineTemplate template, Long zoneId) {
|
public boolean checkIfDynamicScalingCanBeEnabled(VirtualMachine vm, ServiceOffering offering, VirtualMachineTemplate template, Long zoneId) {
|
||||||
boolean canEnableDynamicScaling = (vm != null ? vm.isDynamicallyScalable() : true) && offering.isDynamicScalingEnabled() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zoneId);
|
boolean canEnableDynamicScaling = (vm != null ? vm.isDynamicallyScalable() : true) && offering.isDynamicScalingEnabled() && template.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(zoneId);
|
||||||
@ -4175,10 +4166,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
* Configures the Root disk size via User`s custom parameters.
|
* Configures the Root disk size via User`s custom parameters.
|
||||||
* If the Service Offering has the Root Disk size field configured then the User`s root disk custom parameter is overwritten by the service offering.
|
* If the Service Offering has the Root Disk size field configured then the User`s root disk custom parameter is overwritten by the service offering.
|
||||||
*/
|
*/
|
||||||
protected long configureCustomRootDiskSize(Map<String, String> customParameters, VMTemplateVO template, HypervisorType hypervisorType, ServiceOfferingVO serviceOffering) {
|
protected long configureCustomRootDiskSize(Map<String, String> customParameters, VMTemplateVO template, HypervisorType hypervisorType, DiskOfferingVO rootDiskOffering) {
|
||||||
verifyIfHypervisorSupportsRootdiskSizeOverride(hypervisorType);
|
verifyIfHypervisorSupportsRootdiskSizeOverride(hypervisorType);
|
||||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(serviceOffering.getId());
|
long rootDiskSizeInBytes = verifyAndGetDiskSize(rootDiskOffering, NumbersUtil.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE), -1));
|
||||||
long rootDiskSizeInBytes = diskOffering.getDiskSize();
|
|
||||||
if (rootDiskSizeInBytes > 0) { //if the size at DiskOffering is not zero then the Service Offering had it configured, it holds priority over the User custom size
|
if (rootDiskSizeInBytes > 0) { //if the size at DiskOffering is not zero then the Service Offering had it configured, it holds priority over the User custom size
|
||||||
long rootDiskSizeInGiB = rootDiskSizeInBytes / GiB_TO_BYTES;
|
long rootDiskSizeInGiB = rootDiskSizeInBytes / GiB_TO_BYTES;
|
||||||
customParameters.put(VmDetailConstants.ROOT_DISK_SIZE, String.valueOf(rootDiskSizeInGiB));
|
customParameters.put(VmDetailConstants.ROOT_DISK_SIZE, String.valueOf(rootDiskSizeInGiB));
|
||||||
@ -4249,12 +4239,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
final long accountId, final long userId, final ServiceOffering offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap<String, List<NicProfile>> networkNicMap,
|
final long accountId, final long userId, final ServiceOffering offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap<String, List<NicProfile>> networkNicMap,
|
||||||
final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map<String, String> customParameters,
|
final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map<String, String> customParameters,
|
||||||
final Map<String, Map<Integer, String>> extraDhcpOptionMap, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
final Map<String, Map<Integer, String>> extraDhcpOptionMap, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
||||||
final Map<String, String> userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState, final boolean dynamicScalingEnabled, String type) throws InsufficientCapacityException {
|
final Map<String, String> userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState, final boolean dynamicScalingEnabled, String type, final Long rootDiskOfferingId) throws InsufficientCapacityException {
|
||||||
return Transaction.execute(new TransactionCallbackWithException<UserVmVO, InsufficientCapacityException>() {
|
return Transaction.execute(new TransactionCallbackWithException<UserVmVO, InsufficientCapacityException>() {
|
||||||
@Override
|
@Override
|
||||||
public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException {
|
public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException {
|
||||||
UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, template.getGuestOSId(), offering.isOfferHA(),
|
UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, template.getGuestOSId(), offering.isOfferHA(),
|
||||||
offering.getLimitCpuUse(), owner.getDomainId(), owner.getId(), userId, offering.getId(), userData, hostName, diskOfferingId);
|
offering.getLimitCpuUse(), owner.getDomainId(), owner.getId(), userId, offering.getId(), userData, hostName);
|
||||||
vm.setUuid(uuidName);
|
vm.setUuid(uuidName);
|
||||||
vm.setDynamicallyScalable(dynamicScalingEnabled);
|
vm.setDynamicallyScalable(dynamicScalingEnabled);
|
||||||
|
|
||||||
@ -4370,15 +4360,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
computeTags.add(offering.getHostTag());
|
computeTags.add(offering.getHostTag());
|
||||||
|
|
||||||
List<String> rootDiskTags = new ArrayList<String>();
|
List<String> rootDiskTags = new ArrayList<String>();
|
||||||
rootDiskTags.add(offering.getTags());
|
DiskOfferingVO rootDiskOfferingVO = _diskOfferingDao.findById(rootDiskOfferingId);
|
||||||
|
rootDiskTags.add(rootDiskOfferingVO.getTags());
|
||||||
|
|
||||||
if (isIso) {
|
if (isIso) {
|
||||||
_orchSrvc.createVirtualMachineFromScratch(vm.getUuid(), Long.toString(owner.getAccountId()), vm.getIsoId().toString(), hostName, displayName,
|
_orchSrvc.createVirtualMachineFromScratch(vm.getUuid(), Long.toString(owner.getAccountId()), vm.getIsoId().toString(), hostName, displayName,
|
||||||
hypervisorType.name(), guestOSCategory.getName(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags,
|
hypervisorType.name(), guestOSCategory.getName(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags,
|
||||||
networkNicMap, plan, extraDhcpOptionMap);
|
networkNicMap, plan, extraDhcpOptionMap, rootDiskOfferingId);
|
||||||
} else {
|
} else {
|
||||||
_orchSrvc.createVirtualMachine(vm.getUuid(), Long.toString(owner.getAccountId()), Long.toString(template.getId()), hostName, displayName, hypervisorType.name(),
|
_orchSrvc.createVirtualMachine(vm.getUuid(), Long.toString(owner.getAccountId()), Long.toString(template.getId()), hostName, displayName, hypervisorType.name(),
|
||||||
offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan, rootDiskSize, extraDhcpOptionMap, dataDiskTemplateToDiskOfferingMap);
|
offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan, rootDiskSize, extraDhcpOptionMap,
|
||||||
|
dataDiskTemplateToDiskOfferingMap, diskOfferingId, rootDiskOfferingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
@ -4444,13 +4436,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
final long accountId, final long userId, final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap<String, List<NicProfile>> networkNicMap,
|
final long accountId, final long userId, final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap<String, List<NicProfile>> networkNicMap,
|
||||||
final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map<String, String> customParameters, final Map<String,
|
final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map<String, String> customParameters, final Map<String,
|
||||||
Map<Integer, String>> extraDhcpOptionMap, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
Map<Integer, String>> extraDhcpOptionMap, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
|
||||||
Map<String, String> userVmOVFPropertiesMap, final boolean dynamicScalingEnabled, String type) throws InsufficientCapacityException {
|
Map<String, String> userVmOVFPropertiesMap, final boolean dynamicScalingEnabled, String type, final Long rootDiskOfferingId) throws InsufficientCapacityException {
|
||||||
return commitUserVm(false, zone, null, null, template, hostName, displayName, owner,
|
return commitUserVm(false, zone, null, null, template, hostName, displayName, owner,
|
||||||
diskOfferingId, diskSize, userData, caller, isDisplayVm, keyboard,
|
diskOfferingId, diskSize, userData, caller, isDisplayVm, keyboard,
|
||||||
accountId, userId, offering, isIso, sshPublicKey, networkNicMap,
|
accountId, userId, offering, isIso, sshPublicKey, networkNicMap,
|
||||||
id, instanceName, uuidName, hypervisorType, customParameters,
|
id, instanceName, uuidName, hypervisorType, customParameters,
|
||||||
extraDhcpOptionMap, dataDiskTemplateToDiskOfferingMap,
|
extraDhcpOptionMap, dataDiskTemplateToDiskOfferingMap,
|
||||||
userVmOVFPropertiesMap, null, dynamicScalingEnabled, type);
|
userVmOVFPropertiesMap, null, dynamicScalingEnabled, type, rootDiskOfferingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validateRootDiskResize(final HypervisorType hypervisorType, Long rootDiskSize, VMTemplateVO templateVO, UserVmVO vm, final Map<String, String> customParameters) throws InvalidParameterValueException
|
public void validateRootDiskResize(final HypervisorType hypervisorType, Long rootDiskSize, VMTemplateVO templateVO, UserVmVO vm, final Map<String, String> customParameters) throws InvalidParameterValueException
|
||||||
@ -5585,12 +5577,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
|
|
||||||
Long serviceOfferingId = cmd.getServiceOfferingId();
|
Long serviceOfferingId = cmd.getServiceOfferingId();
|
||||||
|
Long overrideDiskOfferingId = cmd.getOverrideDiskOfferingId();
|
||||||
|
|
||||||
ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
|
ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
|
||||||
if (serviceOffering == null) {
|
if (serviceOffering == null) {
|
||||||
throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
|
throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (serviceOffering.getDiskOfferingStrictness() && overrideDiskOfferingId != null) {
|
||||||
|
throw new InvalidParameterValueException(String.format("Cannot override disk offering id %d since provided service offering is strictly mapped to its disk offering", overrideDiskOfferingId));
|
||||||
|
}
|
||||||
|
|
||||||
if (!serviceOffering.isDynamic()) {
|
if (!serviceOffering.isDynamic()) {
|
||||||
for(String detail: cmd.getDetails().keySet()) {
|
for(String detail: cmd.getDetails().keySet()) {
|
||||||
if(detail.equalsIgnoreCase(VmDetailConstants.CPU_NUMBER) || detail.equalsIgnoreCase(VmDetailConstants.CPU_SPEED) || detail.equalsIgnoreCase(VmDetailConstants.MEMORY)) {
|
if(detail.equalsIgnoreCase(VmDetailConstants.CPU_NUMBER) || detail.equalsIgnoreCase(VmDetailConstants.CPU_SPEED) || detail.equalsIgnoreCase(VmDetailConstants.MEMORY)) {
|
||||||
@ -5617,7 +5614,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd.getDetails().get("rootdisksize") != null) {
|
if (cmd.getDetails().get("rootdisksize") != null) {
|
||||||
throw new InvalidParameterValueException("Overriding root disk size isn't supported for VMs deployed from defploy as-is templates");
|
throw new InvalidParameterValueException("Overriding root disk size isn't supported for VMs deployed from deploy as-is templates");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bootmode and boottype are not supported on VMWare dpeloy-as-is templates (since 4.15)
|
// Bootmode and boottype are not supported on VMWare dpeloy-as-is templates (since 4.15)
|
||||||
@ -5633,11 +5630,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
if (diskOffering == null) {
|
if (diskOffering == null) {
|
||||||
throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingId);
|
throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingId);
|
||||||
}
|
}
|
||||||
|
if (diskOffering.isComputeOnly()) {
|
||||||
|
throw new InvalidParameterValueException(String.format("The disk offering id %d provided is directly mapped to a service offering, please provide an individual disk offering", diskOfferingId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!zone.isLocalStorageEnabled()) {
|
if (!zone.isLocalStorageEnabled()) {
|
||||||
if (serviceOffering.isUseLocalStorage()) {
|
DiskOffering diskOfferingMappedInServiceOffering = _entityMgr.findById(DiskOffering.class, serviceOffering.getDiskOfferingId());
|
||||||
throw new InvalidParameterValueException("Zone is not configured to use local storage but service offering " + serviceOffering.getName() + " uses it");
|
if (diskOfferingMappedInServiceOffering.isUseLocalStorage()) {
|
||||||
|
throw new InvalidParameterValueException("Zone is not configured to use local storage but disk offering " + diskOfferingMappedInServiceOffering.getName() + " mapped in service offering uses it");
|
||||||
}
|
}
|
||||||
if (diskOffering != null && diskOffering.isUseLocalStorage()) {
|
if (diskOffering != null && diskOffering.isUseLocalStorage()) {
|
||||||
throw new InvalidParameterValueException("Zone is not configured to use local storage but disk offering " + diskOffering.getName() + " uses it");
|
throw new InvalidParameterValueException("Zone is not configured to use local storage but disk offering " + diskOffering.getName() + " uses it");
|
||||||
@ -5680,14 +5681,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
vm = createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(cmd), owner, name, displayName, diskOfferingId,
|
vm = createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(cmd), owner, name, displayName, diskOfferingId,
|
||||||
size , group , cmd.getHypervisor(), cmd.getHttpMethod(), userData , sshKeyPairName , cmd.getIpToNetworkMap(), addrs, displayVm , keyboard , cmd.getAffinityGroupIdList(),
|
size , group , cmd.getHypervisor(), cmd.getHttpMethod(), userData , sshKeyPairName , cmd.getIpToNetworkMap(), addrs, displayVm , keyboard , cmd.getAffinityGroupIdList(),
|
||||||
cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(),
|
cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(),
|
||||||
dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled);
|
dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled, overrideDiskOfferingId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (zone.isSecurityGroupEnabled()) {
|
if (zone.isSecurityGroupEnabled()) {
|
||||||
vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, getSecurityGroupIdList(cmd), owner, name,
|
vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, getSecurityGroupIdList(cmd), owner, name,
|
||||||
displayName, diskOfferingId, size, group, cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard,
|
displayName, diskOfferingId, size, group, cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard,
|
||||||
cmd.getAffinityGroupIdList(), cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(),
|
cmd.getAffinityGroupIdList(), cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(),
|
||||||
dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled);
|
dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled, overrideDiskOfferingId);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (cmd.getSecurityGroupIdList() != null && !cmd.getSecurityGroupIdList().isEmpty()) {
|
if (cmd.getSecurityGroupIdList() != null && !cmd.getSecurityGroupIdList().isEmpty()) {
|
||||||
@ -5695,7 +5696,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
vm = createAdvancedVirtualMachine(zone, serviceOffering, template, networkIds, owner, name, displayName, diskOfferingId, size, group,
|
vm = createAdvancedVirtualMachine(zone, serviceOffering, template, networkIds, owner, name, displayName, diskOfferingId, size, group,
|
||||||
cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard, cmd.getAffinityGroupIdList(), cmd.getDetails(),
|
cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard, cmd.getAffinityGroupIdList(), cmd.getDetails(),
|
||||||
cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled, null);
|
cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled, null, overrideDiskOfferingId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check if this templateId has a child ISO
|
// check if this templateId has a child ISO
|
||||||
@ -6655,7 +6656,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId());
|
HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId());
|
||||||
if (hypervisorType.equals(HypervisorType.VMware)) {
|
if (hypervisorType.equals(HypervisorType.VMware)) {
|
||||||
try {
|
try {
|
||||||
boolean isStoragePoolStoragepolicyCompliance = storageManager.isStoragePoolCompliantWithStoragePolicy(Arrays.asList(volume), pool);
|
DiskOffering diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
|
||||||
|
DiskProfile diskProfile = new DiskProfile(volume, diskOffering, _volsDao.getHypervisorType(volume.getId()));
|
||||||
|
Pair<Volume, DiskProfile> volumeDiskProfilePair = new Pair<>(volume, diskProfile);
|
||||||
|
boolean isStoragePoolStoragepolicyCompliance = storageManager.isStoragePoolCompliantWithStoragePolicy(Arrays.asList(volumeDiskProfilePair), pool);
|
||||||
if (!isStoragePoolStoragepolicyCompliance) {
|
if (!isStoragePoolStoragepolicyCompliance) {
|
||||||
throw new CloudRuntimeException(String.format("Storage pool %s is not storage policy compliance with the volume %s", pool.getUuid(), volume.getUuid()));
|
throw new CloudRuntimeException(String.format("Storage pool %s is not storage policy compliance with the volume %s", pool.getUuid(), volume.getUuid()));
|
||||||
}
|
}
|
||||||
@ -7829,7 +7833,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
null, null, userData, caller, isDisplayVm, keyboard,
|
null, null, userData, caller, isDisplayVm, keyboard,
|
||||||
accountId, userId, serviceOffering, template.getFormat().equals(ImageFormat.ISO), sshPublicKey, null,
|
accountId, userId, serviceOffering, template.getFormat().equals(ImageFormat.ISO), sshPublicKey, null,
|
||||||
id, instanceName, uuidName, hypervisorType, customParameters,
|
id, instanceName, uuidName, hypervisorType, customParameters,
|
||||||
null, null, null, powerState, dynamicScalingEnabled, null);
|
null, null, null, powerState, dynamicScalingEnabled, null, serviceOffering.getDiskOfferingId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -95,6 +95,7 @@ import com.cloud.serializer.GsonHelper;
|
|||||||
import com.cloud.server.ManagementService;
|
import com.cloud.server.ManagementService;
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
import com.cloud.storage.GuestOS;
|
import com.cloud.storage.GuestOS;
|
||||||
import com.cloud.storage.GuestOSHypervisor;
|
import com.cloud.storage.GuestOSHypervisor;
|
||||||
import com.cloud.storage.Snapshot;
|
import com.cloud.storage.Snapshot;
|
||||||
@ -392,16 +393,6 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
return volumeApiService.doesTargetStorageSupportDiskOffering(pool, diskOffering.getTags());
|
return volumeApiService.doesTargetStorageSupportDiskOffering(pool, diskOffering.getTags());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean storagePoolSupportsServiceOffering(StoragePool pool, ServiceOffering serviceOffering) {
|
|
||||||
if (pool == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (serviceOffering == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return volumeApiService.doesTargetStorageSupportDiskOffering(pool, serviceOffering.getTags());
|
|
||||||
}
|
|
||||||
|
|
||||||
private ServiceOfferingVO getUnmanagedInstanceServiceOffering(final UnmanagedInstanceTO instance, ServiceOfferingVO serviceOffering, final Account owner, final DataCenter zone, final Map<String, String> details)
|
private ServiceOfferingVO getUnmanagedInstanceServiceOffering(final UnmanagedInstanceTO instance, ServiceOfferingVO serviceOffering, final Account owner, final DataCenter zone, final Map<String, String> details)
|
||||||
throws ServerApiException, PermissionDeniedException, ResourceAllocationException {
|
throws ServerApiException, PermissionDeniedException, ResourceAllocationException {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
@ -560,9 +551,6 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
if (diskOffering != null && !migrateAllowed && !storagePoolSupportsDiskOffering(storagePool, diskOffering)) {
|
if (diskOffering != null && !migrateAllowed && !storagePoolSupportsDiskOffering(storagePool, diskOffering)) {
|
||||||
throw new InvalidParameterValueException(String.format("Disk offering: %s is not compatible with storage pool: %s of unmanaged disk: %s", diskOffering.getUuid(), storagePool.getUuid(), disk.getDiskId()));
|
throw new InvalidParameterValueException(String.format("Disk offering: %s is not compatible with storage pool: %s of unmanaged disk: %s", diskOffering.getUuid(), storagePool.getUuid(), disk.getDiskId()));
|
||||||
}
|
}
|
||||||
if (serviceOffering != null && !migrateAllowed && !storagePoolSupportsServiceOffering(storagePool, serviceOffering)) {
|
|
||||||
throw new InvalidParameterValueException(String.format("Service offering: %s is not compatible with storage pool: %s of unmanaged disk: %s", serviceOffering.getUuid(), storagePool.getUuid(), disk.getDiskId()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkUnmanagedDiskAndOfferingForImport(List<UnmanagedInstanceTO.Disk> disks, final Map<String, Long> diskOfferingMap, final Account owner, final DataCenter zone, final Cluster cluster, final boolean migrateAllowed)
|
private void checkUnmanagedDiskAndOfferingForImport(List<UnmanagedInstanceTO.Disk> disks, final Map<String, Long> diskOfferingMap, final Account owner, final DataCenter zone, final Cluster cluster, final boolean migrateAllowed)
|
||||||
@ -811,14 +799,11 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
boolean poolSupportsOfferings = storagePoolSupportsDiskOffering(diskProfileStoragePool.second(), dOffering);
|
boolean poolSupportsOfferings = storagePoolSupportsDiskOffering(diskProfileStoragePool.second(), dOffering);
|
||||||
if (poolSupportsOfferings && profile.getType() == Volume.Type.ROOT) {
|
|
||||||
poolSupportsOfferings = storagePoolSupportsServiceOffering(diskProfileStoragePool.second(), serviceOffering);
|
|
||||||
}
|
|
||||||
if (poolSupportsOfferings) {
|
if (poolSupportsOfferings) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LOGGER.debug(String.format("Volume %s needs to be migrated", volumeVO.getUuid()));
|
LOGGER.debug(String.format("Volume %s needs to be migrated", volumeVO.getUuid()));
|
||||||
Pair<List<? extends StoragePool>, List<? extends StoragePool>> poolsPair = managementService.listStoragePoolsForMigrationOfVolume(profile.getVolumeId());
|
Pair<List<? extends StoragePool>, List<? extends StoragePool>> poolsPair = managementService.listStoragePoolsForMigrationOfVolumeInternal(profile.getVolumeId(), null, null, null, null, false);
|
||||||
if (CollectionUtils.isEmpty(poolsPair.first()) && CollectionUtils.isEmpty(poolsPair.second())) {
|
if (CollectionUtils.isEmpty(poolsPair.first()) && CollectionUtils.isEmpty(poolsPair.second())) {
|
||||||
cleanupFailedImportVM(vm);
|
cleanupFailedImportVM(vm);
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("VM import failed for unmanaged vm: %s during volume ID: %s migration as no suitable pool(s) found", userVm.getInstanceName(), volumeVO.getUuid()));
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("VM import failed for unmanaged vm: %s during volume ID: %s migration as no suitable pool(s) found", userVm.getInstanceName(), volumeVO.getUuid()));
|
||||||
@ -828,9 +813,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
if (CollectionUtils.isNotEmpty(storagePools)) {
|
if (CollectionUtils.isNotEmpty(storagePools)) {
|
||||||
for (StoragePool pool : storagePools) {
|
for (StoragePool pool : storagePools) {
|
||||||
if (diskProfileStoragePool.second().getId() != pool.getId() &&
|
if (diskProfileStoragePool.second().getId() != pool.getId() &&
|
||||||
storagePoolSupportsDiskOffering(pool, dOffering) &&
|
storagePoolSupportsDiskOffering(pool, dOffering)
|
||||||
(!profile.getType().equals(Volume.Type.ROOT) ||
|
) {
|
||||||
profile.getType().equals(Volume.Type.ROOT) && storagePoolSupportsServiceOffering(pool, serviceOffering))) {
|
|
||||||
storagePool = pool;
|
storagePool = pool;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -841,9 +825,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
storagePools = poolsPair.first();
|
storagePools = poolsPair.first();
|
||||||
for (StoragePool pool : storagePools) {
|
for (StoragePool pool : storagePools) {
|
||||||
if (diskProfileStoragePool.second().getId() != pool.getId() &&
|
if (diskProfileStoragePool.second().getId() != pool.getId() &&
|
||||||
storagePoolSupportsDiskOffering(pool, dOffering) &&
|
storagePoolSupportsDiskOffering(pool, dOffering)
|
||||||
(!profile.getType().equals(Volume.Type.ROOT) ||
|
) {
|
||||||
profile.getType().equals(Volume.Type.ROOT) && storagePoolSupportsServiceOffering(pool, serviceOffering))) {
|
|
||||||
storagePool = pool;
|
storagePool = pool;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1021,7 +1004,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||||||
if (details.containsKey("maxIops")) {
|
if (details.containsKey("maxIops")) {
|
||||||
maxIops = Long.parseLong(details.get("maxIops"));
|
maxIops = Long.parseLong(details.get("maxIops"));
|
||||||
}
|
}
|
||||||
diskProfileStoragePoolList.add(importDisk(rootDisk, userVm, cluster, serviceOffering, Volume.Type.ROOT, String.format("ROOT-%d", userVm.getId()),
|
DiskOfferingVO diskOffering = diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
|
||||||
|
diskProfileStoragePoolList.add(importDisk(rootDisk, userVm, cluster, diskOffering, Volume.Type.ROOT, String.format("ROOT-%d", userVm.getId()),
|
||||||
(rootDisk.getCapacity() / Resource.ResourceType.bytesToGiB), minIops, maxIops,
|
(rootDisk.getCapacity() / Resource.ResourceType.bytesToGiB), minIops, maxIops,
|
||||||
template, owner, null));
|
template, owner, null));
|
||||||
for (UnmanagedInstanceTO.Disk disk : dataDisks) {
|
for (UnmanagedInstanceTO.Disk disk : dataDisks) {
|
||||||
|
|||||||
@ -23,6 +23,8 @@ import java.util.Map;
|
|||||||
import com.cloud.network.dao.NetworkDetailVO;
|
import com.cloud.network.dao.NetworkDetailVO;
|
||||||
import com.cloud.network.dao.NetworkDetailsDao;
|
import com.cloud.network.dao.NetworkDetailsDao;
|
||||||
import com.cloud.network.router.VirtualRouter;
|
import com.cloud.network.router.VirtualRouter;
|
||||||
|
import com.cloud.storage.DiskOfferingVO;
|
||||||
|
import com.cloud.storage.dao.DiskOfferingDao;
|
||||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
@ -89,6 +91,7 @@ public class RouterDeploymentDefinition {
|
|||||||
protected VirtualRouterProviderDao vrProviderDao;
|
protected VirtualRouterProviderDao vrProviderDao;
|
||||||
protected NetworkOfferingDao networkOfferingDao;
|
protected NetworkOfferingDao networkOfferingDao;
|
||||||
protected ServiceOfferingDao serviceOfferingDao;
|
protected ServiceOfferingDao serviceOfferingDao;
|
||||||
|
protected DiskOfferingDao diskOfferingDao;
|
||||||
protected IpAddressManager ipAddrMgr;
|
protected IpAddressManager ipAddrMgr;
|
||||||
protected VMInstanceDao vmDao;
|
protected VMInstanceDao vmDao;
|
||||||
protected HostPodDao podDao;
|
protected HostPodDao podDao;
|
||||||
@ -405,8 +408,9 @@ public class RouterDeploymentDefinition {
|
|||||||
logger.debug("Verifying router service offering with uuid : " + offeringUuid);
|
logger.debug("Verifying router service offering with uuid : " + offeringUuid);
|
||||||
ServiceOfferingVO serviceOffering = serviceOfferingDao.findByUuid(offeringUuid);
|
ServiceOfferingVO serviceOffering = serviceOfferingDao.findByUuid(offeringUuid);
|
||||||
if (serviceOffering != null && serviceOffering.isSystemUse()) {
|
if (serviceOffering != null && serviceOffering.isSystemUse()) {
|
||||||
|
DiskOfferingVO diskOffering = diskOfferingDao.findById(serviceOffering.getDiskOfferingId());
|
||||||
boolean isLocalStorage = ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dest.getDataCenter().getId());
|
boolean isLocalStorage = ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dest.getDataCenter().getId());
|
||||||
if (isLocalStorage == serviceOffering.isUseLocalStorage()) {
|
if (isLocalStorage == diskOffering.isUseLocalStorage()) {
|
||||||
logger.debug(String.format("Service offering %s (uuid: %s) will be used on virtual router", serviceOffering.getName(), serviceOffering.getUuid()));
|
logger.debug(String.format("Service offering %s (uuid: %s) will be used on virtual router", serviceOffering.getName(), serviceOffering.getUuid()));
|
||||||
serviceOfferingId = serviceOffering.getId();
|
serviceOfferingId = serviceOffering.getId();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -98,7 +98,6 @@ import com.cloud.resource.ResourceManager;
|
|||||||
import com.cloud.org.Grouping.AllocationState;
|
import com.cloud.org.Grouping.AllocationState;
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
||||||
import com.cloud.storage.Storage.ProvisioningType;
|
|
||||||
import com.cloud.storage.StorageManager;
|
import com.cloud.storage.StorageManager;
|
||||||
import com.cloud.storage.dao.DiskOfferingDao;
|
import com.cloud.storage.dao.DiskOfferingDao;
|
||||||
import com.cloud.storage.dao.GuestOSCategoryDao;
|
import com.cloud.storage.dao.GuestOSCategoryDao;
|
||||||
@ -213,8 +212,7 @@ public class DeploymentPlanningManagerImplTest {
|
|||||||
public void dataCenterAvoidTest() throws InsufficientServerCapacityException, AffinityConflictException {
|
public void dataCenterAvoidTest() throws InsufficientServerCapacityException, AffinityConflictException {
|
||||||
ServiceOfferingVO svcOffering =
|
ServiceOfferingVO svcOffering =
|
||||||
new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm",
|
new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm",
|
||||||
ProvisioningType.THIN, false, false, null, false, VirtualMachine.Type.User,
|
false, VirtualMachine.Type.User, null, "FirstFitPlanner", true, false);
|
||||||
null, "FirstFitPlanner", true);
|
|
||||||
Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering);
|
Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering);
|
||||||
|
|
||||||
DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
|
DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
|
||||||
@ -228,8 +226,7 @@ public class DeploymentPlanningManagerImplTest {
|
|||||||
public void plannerCannotHandleTest() throws InsufficientServerCapacityException, AffinityConflictException {
|
public void plannerCannotHandleTest() throws InsufficientServerCapacityException, AffinityConflictException {
|
||||||
ServiceOfferingVO svcOffering =
|
ServiceOfferingVO svcOffering =
|
||||||
new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm",
|
new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm",
|
||||||
ProvisioningType.THIN, false, false, null, false, VirtualMachine.Type.User,
|
false, VirtualMachine.Type.User, null, "UserDispersingPlanner", true, false);
|
||||||
null, "UserDispersingPlanner", true);
|
|
||||||
Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering);
|
Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering);
|
||||||
|
|
||||||
DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
|
DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
|
||||||
@ -244,8 +241,7 @@ public class DeploymentPlanningManagerImplTest {
|
|||||||
public void emptyClusterListTest() throws InsufficientServerCapacityException, AffinityConflictException {
|
public void emptyClusterListTest() throws InsufficientServerCapacityException, AffinityConflictException {
|
||||||
ServiceOfferingVO svcOffering =
|
ServiceOfferingVO svcOffering =
|
||||||
new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm",
|
new ServiceOfferingVO("testOffering", 1, 512, 500, 1, 1, false, false, false, "test dpm",
|
||||||
ProvisioningType.THIN, false, false, null, false, VirtualMachine.Type.User,
|
false, VirtualMachine.Type.User, null, "FirstFitPlanner", true, false);
|
||||||
null, "FirstFitPlanner", true);
|
|
||||||
Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering);
|
Mockito.when(vmProfile.getServiceOffering()).thenReturn(svcOffering);
|
||||||
|
|
||||||
DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
|
DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
|
||||||
|
|||||||
@ -95,7 +95,6 @@ import com.cloud.offerings.dao.NetworkOfferingDao;
|
|||||||
import com.cloud.resource.ResourceManager;
|
import com.cloud.resource.ResourceManager;
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.storage.Storage.ProvisioningType;
|
|
||||||
import com.cloud.storage.VMTemplateVO;
|
import com.cloud.storage.VMTemplateVO;
|
||||||
import com.cloud.storage.dao.GuestOSDao;
|
import com.cloud.storage.dao.GuestOSDao;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
@ -336,10 +335,6 @@ public class VirtualRouterElementTest {
|
|||||||
/* multicastRateMbps */ 0,
|
/* multicastRateMbps */ 0,
|
||||||
/* offerHA */ false,
|
/* offerHA */ false,
|
||||||
"displayText",
|
"displayText",
|
||||||
ProvisioningType.THIN,
|
|
||||||
/* useLocalStorage */ false,
|
|
||||||
/* recreatable */ false,
|
|
||||||
"tags",
|
|
||||||
/* systemUse */ false,
|
/* systemUse */ false,
|
||||||
VirtualMachine.Type.DomainRouter,
|
VirtualMachine.Type.DomainRouter,
|
||||||
/* defaultUse */ false);
|
/* defaultUse */ false);
|
||||||
|
|||||||
@ -37,6 +37,8 @@ import java.util.concurrent.ExecutionException;
|
|||||||
|
|
||||||
import com.cloud.api.query.dao.ServiceOfferingJoinDao;
|
import com.cloud.api.query.dao.ServiceOfferingJoinDao;
|
||||||
import com.cloud.api.query.vo.ServiceOfferingJoinVO;
|
import com.cloud.api.query.vo.ServiceOfferingJoinVO;
|
||||||
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||||
@ -158,6 +160,8 @@ public class VolumeApiServiceImplTest {
|
|||||||
private VMTemplateDao templateDao;
|
private VMTemplateDao templateDao;
|
||||||
@Mock
|
@Mock
|
||||||
private ServiceOfferingJoinDao serviceOfferingJoinDao;
|
private ServiceOfferingJoinDao serviceOfferingJoinDao;
|
||||||
|
@Mock
|
||||||
|
private ServiceOfferingDao serviceOfferingDao;
|
||||||
|
|
||||||
private DetachVolumeCmd detachCmd = new DetachVolumeCmd();
|
private DetachVolumeCmd detachCmd = new DetachVolumeCmd();
|
||||||
private Class<?> _detachCmdClass = detachCmd.getClass();
|
private Class<?> _detachCmdClass = detachCmd.getClass();
|
||||||
@ -213,7 +217,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
VolumeVO volumeOfRunningVm = new VolumeVO("root", 1L, 1L, 1L, 1L, 1L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
|
VolumeVO volumeOfRunningVm = new VolumeVO("root", 1L, 1L, 1L, 1L, 1L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
|
||||||
when(volumeDaoMock.findById(1L)).thenReturn(volumeOfRunningVm);
|
when(volumeDaoMock.findById(1L)).thenReturn(volumeOfRunningVm);
|
||||||
|
|
||||||
UserVmVO runningVm = new UserVmVO(1L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
|
UserVmVO runningVm = new UserVmVO(1L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm");
|
||||||
runningVm.setState(State.Running);
|
runningVm.setState(State.Running);
|
||||||
runningVm.setDataCenterId(1L);
|
runningVm.setDataCenterId(1L);
|
||||||
when(userVmDaoMock.findById(1L)).thenReturn(runningVm);
|
when(userVmDaoMock.findById(1L)).thenReturn(runningVm);
|
||||||
@ -223,13 +227,13 @@ public class VolumeApiServiceImplTest {
|
|||||||
volumeOfStoppedVm.setPoolId(1L);
|
volumeOfStoppedVm.setPoolId(1L);
|
||||||
when(volumeDaoMock.findById(2L)).thenReturn(volumeOfStoppedVm);
|
when(volumeDaoMock.findById(2L)).thenReturn(volumeOfStoppedVm);
|
||||||
|
|
||||||
UserVmVO stoppedVm = new UserVmVO(2L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
|
UserVmVO stoppedVm = new UserVmVO(2L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm");
|
||||||
stoppedVm.setState(State.Stopped);
|
stoppedVm.setState(State.Stopped);
|
||||||
stoppedVm.setDataCenterId(1L);
|
stoppedVm.setDataCenterId(1L);
|
||||||
when(userVmDaoMock.findById(2L)).thenReturn(stoppedVm);
|
when(userVmDaoMock.findById(2L)).thenReturn(stoppedVm);
|
||||||
|
|
||||||
// volume of hyperV vm id=3
|
// volume of hyperV vm id=3
|
||||||
UserVmVO hyperVVm = new UserVmVO(3L, "vm", "vm", 1, HypervisorType.Hyperv, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
|
UserVmVO hyperVVm = new UserVmVO(3L, "vm", "vm", 1, HypervisorType.Hyperv, 1L, false, false, 1L, 1L, 1, 1L, null, "vm");
|
||||||
hyperVVm.setState(State.Stopped);
|
hyperVVm.setState(State.Stopped);
|
||||||
hyperVVm.setDataCenterId(1L);
|
hyperVVm.setDataCenterId(1L);
|
||||||
when(userVmDaoMock.findById(3L)).thenReturn(hyperVVm);
|
when(userVmDaoMock.findById(3L)).thenReturn(hyperVVm);
|
||||||
@ -285,7 +289,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
when(volumeDaoMock.findById(7L)).thenReturn(managedVolume1);
|
when(volumeDaoMock.findById(7L)).thenReturn(managedVolume1);
|
||||||
|
|
||||||
// vm having root volume
|
// vm having root volume
|
||||||
UserVmVO vmHavingRootVolume = new UserVmVO(4L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
|
UserVmVO vmHavingRootVolume = new UserVmVO(4L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm");
|
||||||
vmHavingRootVolume.setState(State.Stopped);
|
vmHavingRootVolume.setState(State.Stopped);
|
||||||
vmHavingRootVolume.setDataCenterId(1L);
|
vmHavingRootVolume.setDataCenterId(1L);
|
||||||
when(userVmDaoMock.findById(4L)).thenReturn(vmHavingRootVolume);
|
when(userVmDaoMock.findById(4L)).thenReturn(vmHavingRootVolume);
|
||||||
@ -570,6 +574,27 @@ public class VolumeApiServiceImplTest {
|
|||||||
@Test
|
@Test
|
||||||
public void validateConditionsToReplaceDiskOfferingOfVolumeTestRootVolume() {
|
public void validateConditionsToReplaceDiskOfferingOfVolumeTestRootVolume() {
|
||||||
Mockito.lenient().when(volumeVoMock.getVolumeType()).thenReturn(Type.ROOT);
|
Mockito.lenient().when(volumeVoMock.getVolumeType()).thenReturn(Type.ROOT);
|
||||||
|
Mockito.doReturn(vmInstanceMockId).when(volumeVoMock).getInstanceId();
|
||||||
|
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||||
|
when(_vmInstanceDao.findById(anyLong())).thenReturn(vm);
|
||||||
|
when(vm.getServiceOfferingId()).thenReturn(1L);
|
||||||
|
ServiceOfferingVO serviceOfferingVO = Mockito.mock(ServiceOfferingVO.class);
|
||||||
|
serviceOfferingVO.setDiskOfferingStrictness(false);
|
||||||
|
when(serviceOfferingDao.findById(anyLong())).thenReturn(serviceOfferingVO);
|
||||||
|
|
||||||
|
volumeApiServiceImpl.validateConditionsToReplaceDiskOfferingOfVolume(volumeVoMock, newDiskOfferingMock, storagePoolMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void validateConditionsToReplaceDiskOfferingOfVolumeTestRootVolumeWithDiskOfferingStrictnessTrue() {
|
||||||
|
Mockito.lenient().when(volumeVoMock.getVolumeType()).thenReturn(Type.ROOT);
|
||||||
|
Mockito.doReturn(vmInstanceMockId).when(volumeVoMock).getInstanceId();
|
||||||
|
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||||
|
when(_vmInstanceDao.findById(anyLong())).thenReturn(vm);
|
||||||
|
when(vm.getServiceOfferingId()).thenReturn(1L);
|
||||||
|
ServiceOfferingVO serviceOfferingVO = Mockito.mock(ServiceOfferingVO.class);
|
||||||
|
when(serviceOfferingDao.findById(anyLong())).thenReturn(serviceOfferingVO);
|
||||||
|
when(serviceOfferingVO.getDiskOfferingStrictness()).thenReturn(true);
|
||||||
|
|
||||||
volumeApiServiceImpl.validateConditionsToReplaceDiskOfferingOfVolume(volumeVoMock, newDiskOfferingMock, storagePoolMock);
|
volumeApiServiceImpl.validateConditionsToReplaceDiskOfferingOfVolume(volumeVoMock, newDiskOfferingMock, storagePoolMock);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,7 +72,6 @@ import com.cloud.offering.ServiceOffering;
|
|||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.storage.GuestOSVO;
|
import com.cloud.storage.GuestOSVO;
|
||||||
import com.cloud.storage.Storage;
|
|
||||||
import com.cloud.storage.dao.GuestOSDao;
|
import com.cloud.storage.dao.GuestOSDao;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
@ -96,9 +95,6 @@ public class UserVmManagerImplTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private DiskOfferingDao diskOfferingDao;
|
private DiskOfferingDao diskOfferingDao;
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ServiceOfferingVO serviceOfferingVO;
|
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private DataCenterDao _dcDao;
|
private DataCenterDao _dcDao;
|
||||||
@Mock
|
@Mock
|
||||||
@ -223,8 +219,9 @@ public class UserVmManagerImplTest {
|
|||||||
boolean ha = false;
|
boolean ha = false;
|
||||||
boolean useLocalStorage = false;
|
boolean useLocalStorage = false;
|
||||||
|
|
||||||
ServiceOfferingVO serviceOffering = new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText, Storage.ProvisioningType.THIN, useLocalStorage, false, null, false, null,
|
ServiceOfferingVO serviceOffering = new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText, false, null,
|
||||||
false);
|
false);
|
||||||
|
serviceOffering.setDiskOfferingId(1l);
|
||||||
return serviceOffering;
|
return serviceOffering;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,16 +468,13 @@ public class UserVmManagerImplTest {
|
|||||||
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
|
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
|
||||||
Mockito.when(template.getId()).thenReturn(1l);
|
Mockito.when(template.getId()).thenReturn(1l);
|
||||||
Mockito.when(template.getSize()).thenReturn(99L * GiB_TO_BYTES);
|
Mockito.when(template.getSize()).thenReturn(99L * GiB_TO_BYTES);
|
||||||
ServiceOfferingVO offering = Mockito.mock(ServiceOfferingVO.class);
|
|
||||||
Mockito.when(offering.getId()).thenReturn(1l);
|
|
||||||
Mockito.when(templateDao.findById(Mockito.anyLong())).thenReturn(template);
|
Mockito.when(templateDao.findById(Mockito.anyLong())).thenReturn(template);
|
||||||
|
|
||||||
DiskOfferingVO diskfferingVo = Mockito.mock(DiskOfferingVO.class);
|
DiskOfferingVO diskfferingVo = Mockito.mock(DiskOfferingVO.class);
|
||||||
Mockito.when(diskOfferingDao.findById(Mockito.anyLong())).thenReturn(diskfferingVo);
|
|
||||||
|
|
||||||
Mockito.when(diskfferingVo.getDiskSize()).thenReturn(offeringRootDiskSize);
|
Mockito.when(diskfferingVo.getDiskSize()).thenReturn(offeringRootDiskSize);
|
||||||
|
|
||||||
long rootDiskSize = userVmManagerImpl.configureCustomRootDiskSize(customParameters, template, Hypervisor.HypervisorType.KVM, offering);
|
long rootDiskSize = userVmManagerImpl.configureCustomRootDiskSize(customParameters, template, Hypervisor.HypervisorType.KVM, diskfferingVo);
|
||||||
|
|
||||||
Assert.assertEquals(expectedRootDiskSize, rootDiskSize);
|
Assert.assertEquals(expectedRootDiskSize, rootDiskSize);
|
||||||
Mockito.verify(userVmManagerImpl, Mockito.times(timesVerifyIfHypervisorSupports)).verifyIfHypervisorSupportsRootdiskSizeOverride(Mockito.any());
|
Mockito.verify(userVmManagerImpl, Mockito.times(timesVerifyIfHypervisorSupports)).verifyIfHypervisorSupportsRootdiskSizeOverride(Mockito.any());
|
||||||
|
|||||||
@ -97,7 +97,6 @@ import com.cloud.offerings.NetworkOfferingVO;
|
|||||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
import com.cloud.storage.Storage;
|
|
||||||
import com.cloud.storage.VMTemplateVO;
|
import com.cloud.storage.VMTemplateVO;
|
||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
@ -452,7 +451,7 @@ public class UserVmManagerTest {
|
|||||||
boolean ha = false;
|
boolean ha = false;
|
||||||
boolean useLocalStorage = false;
|
boolean useLocalStorage = false;
|
||||||
|
|
||||||
ServiceOfferingVO serviceOffering = new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText, Storage.ProvisioningType.THIN, useLocalStorage, false, null, false, null,
|
ServiceOfferingVO serviceOffering = new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText, false, null,
|
||||||
false);
|
false);
|
||||||
return serviceOffering;
|
return serviceOffering;
|
||||||
}
|
}
|
||||||
@ -517,7 +516,7 @@ public class UserVmManagerTest {
|
|||||||
AccountVO newAccount = new AccountVO("testaccount", 1, "networkdomain", (short)1, UUID.randomUUID().toString());
|
AccountVO newAccount = new AccountVO("testaccount", 1, "networkdomain", (short)1, UUID.randomUUID().toString());
|
||||||
newAccount.setId(2L);
|
newAccount.setId(2L);
|
||||||
|
|
||||||
UserVmVO vm = new UserVmVO(10L, "test", "test", 1L, HypervisorType.Any, 1L, false, false, 1L, 1L, 1, 5L, "test", "test", 1L);
|
UserVmVO vm = new UserVmVO(10L, "test", "test", 1L, HypervisorType.Any, 1L, false, false, 1L, 1L, 1, 5L, "test", "test");
|
||||||
vm.setState(VirtualMachine.State.Stopped);
|
vm.setState(VirtualMachine.State.Stopped);
|
||||||
when(_vmDao.findById(anyLong())).thenReturn(vm);
|
when(_vmDao.findById(anyLong())).thenReturn(vm);
|
||||||
|
|
||||||
|
|||||||
@ -48,7 +48,7 @@ public class UserVmDaoImplTest extends TestCase {
|
|||||||
// Persist the data.
|
// Persist the data.
|
||||||
UserVmVO vo =
|
UserVmVO vo =
|
||||||
new UserVmVO(vmId, instanceName, displayName, templateId, hypervisor, guestOsId, haEnabled, limitCpuUse, domainId, accountId, 1, serviceOfferingId, userdata,
|
new UserVmVO(vmId, instanceName, displayName, templateId, hypervisor, guestOsId, haEnabled, limitCpuUse, domainId, accountId, 1, serviceOfferingId, userdata,
|
||||||
name, diskOfferingId);
|
name);
|
||||||
dao.persist(vo);
|
dao.persist(vo);
|
||||||
|
|
||||||
vo = dao.findById(vmId);
|
vo = dao.findById(vmId);
|
||||||
|
|||||||
@ -205,7 +205,7 @@ public class AffinityApiUnitTest {
|
|||||||
@Test(expected = InvalidParameterValueException.class)
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
public void updateAffinityGroupVMRunning() throws ResourceInUseException {
|
public void updateAffinityGroupVMRunning() throws ResourceInUseException {
|
||||||
|
|
||||||
UserVmVO vm = new UserVmVO(10L, "test", "test", 101L, HypervisorType.Any, 21L, false, false, domainId, 200L, 1, 5L, "", "test", 1L);
|
UserVmVO vm = new UserVmVO(10L, "test", "test", 101L, HypervisorType.Any, 21L, false, false, domainId, 200L, 1, 5L, "", "test");
|
||||||
vm.setState(VirtualMachine.State.Running);
|
vm.setState(VirtualMachine.State.Running);
|
||||||
when(_vmDao.findById(10L)).thenReturn(vm);
|
when(_vmDao.findById(10L)).thenReturn(vm);
|
||||||
|
|
||||||
|
|||||||
@ -270,7 +270,7 @@ public class AffinityGroupServiceImplTest {
|
|||||||
@Test(expected = InvalidParameterValueException.class)
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
public void updateAffinityGroupVMRunning() throws ResourceInUseException {
|
public void updateAffinityGroupVMRunning() throws ResourceInUseException {
|
||||||
when(_acctMgr.finalizeOwner((Account)anyObject(), anyString(), anyLong(), anyLong())).thenReturn(acct);
|
when(_acctMgr.finalizeOwner((Account)anyObject(), anyString(), anyLong(), anyLong())).thenReturn(acct);
|
||||||
UserVmVO vm = new UserVmVO(10L, "test", "test", 101L, HypervisorType.Any, 21L, false, false, DOMAIN_ID, 200L, 1, 5L, "", "test", 1L);
|
UserVmVO vm = new UserVmVO(10L, "test", "test", 101L, HypervisorType.Any, 21L, false, false, DOMAIN_ID, 200L, 1, 5L, "", "test");
|
||||||
vm.setState(VirtualMachine.State.Running);
|
vm.setState(VirtualMachine.State.Running);
|
||||||
when(_vmDao.findById(10L)).thenReturn(vm);
|
when(_vmDao.findById(10L)).thenReturn(vm);
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,6 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import com.cloud.storage.Storage;
|
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
|
||||||
@ -32,8 +31,8 @@ public class ServiceOfferingVOTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
offeringCustom = new ServiceOfferingVO("custom", null, null, 500, 10, 10, false, "custom", Storage.ProvisioningType.THIN, false, false, "", false, VirtualMachine.Type.User, false);
|
offeringCustom = new ServiceOfferingVO("custom", null, null, 500, 10, 10, false, "custom", false, VirtualMachine.Type.User, false);
|
||||||
offering = new ServiceOfferingVO("normal", 1, 1000, 500, 10, 10, false, "normal", Storage.ProvisioningType.THIN, false, false, "", false, VirtualMachine.Type.User, false);
|
offering = new ServiceOfferingVO("normal", 1, 1000, 500, 10, 10, false, "normal", false, VirtualMachine.Type.User, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test restoreVm when VM state not in running/stopped case
|
// Test restoreVm when VM state not in running/stopped case
|
||||||
|
|||||||
@ -266,13 +266,13 @@ public class UnmanagedVMsManagerImplTest {
|
|||||||
when(templateDao.findByName(Mockito.anyString())).thenReturn(template);
|
when(templateDao.findByName(Mockito.anyString())).thenReturn(template);
|
||||||
ServiceOfferingVO serviceOffering = Mockito.mock(ServiceOfferingVO.class);
|
ServiceOfferingVO serviceOffering = Mockito.mock(ServiceOfferingVO.class);
|
||||||
when(serviceOffering.getId()).thenReturn(1L);
|
when(serviceOffering.getId()).thenReturn(1L);
|
||||||
when(serviceOffering.getTags()).thenReturn("");
|
|
||||||
when(serviceOffering.isDynamic()).thenReturn(false);
|
when(serviceOffering.isDynamic()).thenReturn(false);
|
||||||
when(serviceOffering.getCpu()).thenReturn(instance.getCpuCores());
|
when(serviceOffering.getCpu()).thenReturn(instance.getCpuCores());
|
||||||
when(serviceOffering.getRamSize()).thenReturn(instance.getMemory());
|
when(serviceOffering.getRamSize()).thenReturn(instance.getMemory());
|
||||||
when(serviceOffering.getSpeed()).thenReturn(instance.getCpuSpeed());
|
when(serviceOffering.getSpeed()).thenReturn(instance.getCpuSpeed());
|
||||||
when(serviceOfferingDao.findById(Mockito.anyLong())).thenReturn(serviceOffering);
|
when(serviceOfferingDao.findById(Mockito.anyLong())).thenReturn(serviceOffering);
|
||||||
DiskOfferingVO diskOfferingVO = Mockito.mock(DiskOfferingVO.class);
|
DiskOfferingVO diskOfferingVO = Mockito.mock(DiskOfferingVO.class);
|
||||||
|
when(diskOfferingVO.getTags()).thenReturn("");
|
||||||
when(diskOfferingVO.isCustomized()).thenReturn(false);
|
when(diskOfferingVO.isCustomized()).thenReturn(false);
|
||||||
when(diskOfferingVO.getDiskSize()).thenReturn(Long.MAX_VALUE);
|
when(diskOfferingVO.getDiskSize()).thenReturn(Long.MAX_VALUE);
|
||||||
when(diskOfferingDao.findById(Mockito.anyLong())).thenReturn(diskOfferingVO);
|
when(diskOfferingDao.findById(Mockito.anyLong())).thenReturn(diskOfferingVO);
|
||||||
|
|||||||
@ -25,6 +25,7 @@ from marvin.lib.utils import (isAlmostEqual,
|
|||||||
cleanup_resources,
|
cleanup_resources,
|
||||||
random_gen)
|
random_gen)
|
||||||
from marvin.lib.base import (ServiceOffering,
|
from marvin.lib.base import (ServiceOffering,
|
||||||
|
DiskOffering,
|
||||||
Account,
|
Account,
|
||||||
VirtualMachine)
|
VirtualMachine)
|
||||||
from marvin.lib.common import (list_service_offering,
|
from marvin.lib.common import (list_service_offering,
|
||||||
@ -338,17 +339,17 @@ class TestServiceOfferings(cloudstackTestCase):
|
|||||||
cls.apiclient,
|
cls.apiclient,
|
||||||
cls.services["service_offerings"]["tiny"]
|
cls.services["service_offerings"]["tiny"]
|
||||||
)
|
)
|
||||||
template = get_test_template(
|
cls.template = get_test_template(
|
||||||
cls.apiclient,
|
cls.apiclient,
|
||||||
cls.zone.id,
|
cls.zone.id,
|
||||||
cls.hypervisor
|
cls.hypervisor
|
||||||
)
|
)
|
||||||
if template == FAILED:
|
if cls.template == FAILED:
|
||||||
assert False, "get_test_template() failed to return template"
|
assert False, "get_test_template() failed to return template"
|
||||||
|
|
||||||
# Set Zones and disk offerings
|
# Set Zones and disk offerings
|
||||||
cls.services["small"]["zoneid"] = cls.zone.id
|
cls.services["small"]["zoneid"] = cls.zone.id
|
||||||
cls.services["small"]["template"] = template.id
|
cls.services["small"]["template"] = cls.template.id
|
||||||
|
|
||||||
|
|
||||||
# Create VMs, NAT Rules etc
|
# Create VMs, NAT Rules etc
|
||||||
@ -614,6 +615,204 @@ class TestServiceOfferings(cloudstackTestCase):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true")
|
||||||
|
def test_05_disk_offering_strictness_true(self):
|
||||||
|
"""Test to see change service offering is not possible when disk offering strictness is set to true
|
||||||
|
"""
|
||||||
|
# Validate the following
|
||||||
|
# 1. Create service offering linked a disk offering and disk offering strictness is true
|
||||||
|
# 2. Create a VM with that service offering
|
||||||
|
# 3. Create another service offering with a different disk offering
|
||||||
|
# 4. Try change service offering for VM and it will fail since disk offering strictness is true (not allowed to change the disk offering)
|
||||||
|
|
||||||
|
if self.hypervisor.lower() == "lxc":
|
||||||
|
self.skipTest("Skipping this test for {} due to bug CS-38153".format(self.hypervisor))
|
||||||
|
offering_data = {
|
||||||
|
'displaytext': 'TestDiskOfferingStrictnessTrue',
|
||||||
|
'cpuspeed': 512,
|
||||||
|
'cpunumber': 2,
|
||||||
|
'name': 'TestDiskOfferingStrictnessTrue',
|
||||||
|
'memory': 1024,
|
||||||
|
'diskofferingstrictness': True
|
||||||
|
}
|
||||||
|
|
||||||
|
self.serviceOfferingWithDiskOfferingStrictnessTrue = ServiceOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
offering_data,
|
||||||
|
)
|
||||||
|
self._cleanup.append(self.serviceOfferingWithDiskOfferingStrictnessTrue)
|
||||||
|
|
||||||
|
self.virtual_machine_with_diskoffering_strictness_true = VirtualMachine.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.services["small"],
|
||||||
|
accountid=self.account.name,
|
||||||
|
domainid=self.account.domainid,
|
||||||
|
serviceofferingid=self.serviceOfferingWithDiskOfferingStrictnessTrue.id,
|
||||||
|
mode=self.services["mode"]
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.virtual_machine_with_diskoffering_strictness_true.stop(self.apiclient)
|
||||||
|
|
||||||
|
timeout = self.services["timeout"]
|
||||||
|
|
||||||
|
while True:
|
||||||
|
time.sleep(self.services["sleep"])
|
||||||
|
|
||||||
|
# Ensure that VM is in stopped state
|
||||||
|
list_vm_response = list_virtual_machines(
|
||||||
|
self.apiclient,
|
||||||
|
id=self.virtual_machine_with_diskoffering_strictness_true.id
|
||||||
|
)
|
||||||
|
|
||||||
|
if isinstance(list_vm_response, list):
|
||||||
|
vm = list_vm_response[0]
|
||||||
|
if vm.state == 'Stopped':
|
||||||
|
self.debug("VM state: %s" % vm.state)
|
||||||
|
break
|
||||||
|
|
||||||
|
if timeout == 0:
|
||||||
|
raise Exception(
|
||||||
|
"Failed to stop VM (ID: %s) in change service offering" % vm.id)
|
||||||
|
|
||||||
|
timeout = timeout - 1
|
||||||
|
except Exception as e:
|
||||||
|
self.fail("Failed to stop VM: %s" % e)
|
||||||
|
|
||||||
|
offering_data = {
|
||||||
|
'displaytext': 'TestDiskOfferingStrictnessTrue2',
|
||||||
|
'cpuspeed': 1000,
|
||||||
|
'cpunumber': 2,
|
||||||
|
'name': 'TestDiskOfferingStrictnessTrue2',
|
||||||
|
'memory': 1024,
|
||||||
|
'diskofferingstrictness': True
|
||||||
|
}
|
||||||
|
|
||||||
|
self.serviceOfferingWithDiskOfferingStrictnessTrue2 = ServiceOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
offering_data,
|
||||||
|
)
|
||||||
|
self._cleanup.append(self.serviceOfferingWithDiskOfferingStrictnessTrue2)
|
||||||
|
cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd()
|
||||||
|
cmd.id = self.virtual_machine_with_diskoffering_strictness_true.id
|
||||||
|
cmd.serviceofferingid = self.serviceOfferingWithDiskOfferingStrictnessTrue2.id
|
||||||
|
|
||||||
|
with self.assertRaises(Exception) as e:
|
||||||
|
self.apiclient.changeServiceForVirtualMachine(cmd)
|
||||||
|
self.debug("Upgrade VM with new service offering having different disk offering operation failed as expected with exception: %s" %
|
||||||
|
e.exception)
|
||||||
|
return
|
||||||
|
|
||||||
|
@attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true")
|
||||||
|
def test_06_disk_offering_strictness_false(self):
|
||||||
|
"""Test to see change service offering is possible when disk offering strictness is set to false
|
||||||
|
"""
|
||||||
|
# Validate the following
|
||||||
|
# 1. Create service offering linked a disk offering and disk offering strictness is false
|
||||||
|
# 2. Create a VM with that service offering
|
||||||
|
# 3. Create another service offering with a different disk offering and disk offering strictness is false
|
||||||
|
# 4. Try change service offering for VM should succeed
|
||||||
|
|
||||||
|
if self.hypervisor.lower() == "lxc":
|
||||||
|
self.skipTest("Skipping this test for {} due to bug CS-38153".format(self.hypervisor))
|
||||||
|
|
||||||
|
offering_data = {
|
||||||
|
'displaytext': 'TestDiskOfferingStrictnessFalse',
|
||||||
|
'cpuspeed': 512,
|
||||||
|
'cpunumber': 2,
|
||||||
|
'name': 'TestDiskOfferingStrictnessFalse',
|
||||||
|
'memory': 1024,
|
||||||
|
'diskofferingstrictness': False
|
||||||
|
}
|
||||||
|
|
||||||
|
self.serviceOfferingWithDiskOfferingStrictnessFalse = ServiceOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
offering_data,
|
||||||
|
)
|
||||||
|
self._cleanup.append(self.serviceOfferingWithDiskOfferingStrictnessFalse)
|
||||||
|
|
||||||
|
self.virtual_machine_with_diskoffering_strictness_false = VirtualMachine.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.services["small"],
|
||||||
|
accountid=self.account.name,
|
||||||
|
domainid=self.account.domainid,
|
||||||
|
serviceofferingid=self.serviceOfferingWithDiskOfferingStrictnessFalse.id,
|
||||||
|
mode=self.services["mode"]
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.virtual_machine_with_diskoffering_strictness_false.stop(self.apiclient)
|
||||||
|
|
||||||
|
timeout = self.services["timeout"]
|
||||||
|
|
||||||
|
while True:
|
||||||
|
time.sleep(self.services["sleep"])
|
||||||
|
|
||||||
|
# Ensure that VM is in stopped state
|
||||||
|
list_vm_response = list_virtual_machines(
|
||||||
|
self.apiclient,
|
||||||
|
id=self.virtual_machine_with_diskoffering_strictness_false.id
|
||||||
|
)
|
||||||
|
|
||||||
|
if isinstance(list_vm_response, list):
|
||||||
|
vm = list_vm_response[0]
|
||||||
|
if vm.state == 'Stopped':
|
||||||
|
self.debug("VM state: %s" % vm.state)
|
||||||
|
break
|
||||||
|
|
||||||
|
if timeout == 0:
|
||||||
|
raise Exception(
|
||||||
|
"Failed to stop VM (ID: %s) in change service offering" % vm.id)
|
||||||
|
|
||||||
|
timeout = timeout - 1
|
||||||
|
except Exception as e:
|
||||||
|
self.fail("Failed to stop VM: %s" % e)
|
||||||
|
|
||||||
|
self.disk_offering2 = DiskOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.services["disk_offering"],
|
||||||
|
)
|
||||||
|
self._cleanup.append(self.disk_offering2)
|
||||||
|
offering_data = {
|
||||||
|
'displaytext': 'TestDiskOfferingStrictnessFalse2',
|
||||||
|
'cpuspeed': 1000,
|
||||||
|
'cpunumber': 2,
|
||||||
|
'name': 'TestDiskOfferingStrictnessFalse2',
|
||||||
|
'memory': 1024,
|
||||||
|
'diskofferingstrictness': False,
|
||||||
|
'diskofferingid': self.disk_offering2.id
|
||||||
|
}
|
||||||
|
|
||||||
|
self.serviceOfferingWithDiskOfferingStrictnessFalse2 = ServiceOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
offering_data,
|
||||||
|
)
|
||||||
|
self._cleanup.append(self.serviceOfferingWithDiskOfferingStrictnessFalse2)
|
||||||
|
cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd()
|
||||||
|
cmd.id = self.virtual_machine_with_diskoffering_strictness_false.id
|
||||||
|
cmd.serviceofferingid = self.serviceOfferingWithDiskOfferingStrictnessFalse2.id
|
||||||
|
self.apiclient.changeServiceForVirtualMachine(cmd)
|
||||||
|
|
||||||
|
list_vm_response = VirtualMachine.list(
|
||||||
|
self.apiclient,
|
||||||
|
id=self.virtual_machine_with_diskoffering_strictness_false.id
|
||||||
|
)
|
||||||
|
|
||||||
|
vm_response = list_vm_response[0]
|
||||||
|
self.assertEqual(
|
||||||
|
vm_response.id,
|
||||||
|
self.virtual_machine_with_diskoffering_strictness_false.id,
|
||||||
|
"Check virtual machine ID of upgraded VM"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
vm_response.serviceofferingid,
|
||||||
|
self.serviceOfferingWithDiskOfferingStrictnessFalse2.id,
|
||||||
|
"Check service offering of the VM"
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
class TestCpuCapServiceOfferings(cloudstackTestCase):
|
class TestCpuCapServiceOfferings(cloudstackTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|||||||
@ -606,38 +606,6 @@ class TestVolumes(cloudstackTestCase):
|
|||||||
with self.assertRaises(Exception):
|
with self.assertRaises(Exception):
|
||||||
self.apiClient.resizeVolume(cmd)
|
self.apiClient.resizeVolume(cmd)
|
||||||
|
|
||||||
# Ok, now let's try and resize a volume that is not custom.
|
|
||||||
cmd.id = self.volume.id
|
|
||||||
cmd.diskofferingid = self.services['diskofferingid']
|
|
||||||
cmd.size = 4
|
|
||||||
|
|
||||||
self.debug(
|
|
||||||
"Attaching volume (ID: %s) to VM (ID: %s)" % (
|
|
||||||
self.volume.id,
|
|
||||||
self.virtual_machine.id)
|
|
||||||
)
|
|
||||||
# attach the volume
|
|
||||||
self.virtual_machine.attach_volume(self.apiClient, self.volume)
|
|
||||||
self.attached = True
|
|
||||||
# stop the vm if it is on xenserver
|
|
||||||
hosts = Host.list(self.apiClient, id=self.virtual_machine.hostid)
|
|
||||||
self.assertTrue(isinstance(hosts, list))
|
|
||||||
self.assertTrue(len(hosts) > 0)
|
|
||||||
self.debug("Found %s host" % hosts[0].hypervisor)
|
|
||||||
|
|
||||||
if hosts[0].hypervisor == "XenServer":
|
|
||||||
self.virtual_machine.stop(self.apiClient)
|
|
||||||
elif hosts[0].hypervisor.lower() == "hyperv":
|
|
||||||
self.skipTest("Resize Volume is unsupported on Hyper-V")
|
|
||||||
|
|
||||||
# Attempting to resize it should throw an exception, as we're using a non
|
|
||||||
# customisable disk offering, therefore our size parameter should be ignored
|
|
||||||
with self.assertRaises(Exception):
|
|
||||||
self.apiClient.resizeVolume(cmd)
|
|
||||||
|
|
||||||
if hosts[0].hypervisor == "XenServer":
|
|
||||||
self.virtual_machine.start(self.apiClient)
|
|
||||||
time.sleep(30)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
|
@attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
|
||||||
@ -758,6 +726,67 @@ class TestVolumes(cloudstackTestCase):
|
|||||||
time.sleep(30)
|
time.sleep(30)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
|
||||||
|
def test_12_resize_volume_with_only_size_parameter(self):
|
||||||
|
"""Test resize a volume by providing only size parameter, disk offering id is not mandatory"""
|
||||||
|
# Verify the size is the new size is what we wanted it to be.
|
||||||
|
self.debug(
|
||||||
|
"Attaching volume (ID: %s) to VM (ID: %s)" % (
|
||||||
|
self.volume.id,
|
||||||
|
self.virtual_machine.id
|
||||||
|
))
|
||||||
|
|
||||||
|
self.virtual_machine.attach_volume(self.apiClient, self.volume)
|
||||||
|
self.attached = True
|
||||||
|
hosts = Host.list(self.apiClient, id=self.virtual_machine.hostid)
|
||||||
|
self.assertTrue(isinstance(hosts, list))
|
||||||
|
self.assertTrue(len(hosts) > 0)
|
||||||
|
self.debug("Found %s host" % hosts[0].hypervisor)
|
||||||
|
|
||||||
|
if hosts[0].hypervisor == "XenServer":
|
||||||
|
self.virtual_machine.stop(self.apiClient)
|
||||||
|
elif hosts[0].hypervisor.lower() == "hyperv":
|
||||||
|
self.skipTest("Resize Volume is unsupported on Hyper-V")
|
||||||
|
|
||||||
|
# resize the data disk
|
||||||
|
self.debug("Resize Volume ID: %s" % self.volume.id)
|
||||||
|
|
||||||
|
cmd = resizeVolume.resizeVolumeCmd()
|
||||||
|
cmd.id = self.volume.id
|
||||||
|
cmd.size = 20
|
||||||
|
|
||||||
|
self.apiClient.resizeVolume(cmd)
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
success = False
|
||||||
|
while count < 3:
|
||||||
|
list_volume_response = Volume.list(
|
||||||
|
self.apiClient,
|
||||||
|
id=self.volume.id,
|
||||||
|
type='DATADISK'
|
||||||
|
)
|
||||||
|
for vol in list_volume_response:
|
||||||
|
if vol.id == self.volume.id and int(vol.size) == (20 * (1024 ** 3)) and vol.state == 'Ready':
|
||||||
|
success = True
|
||||||
|
if success:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
time.sleep(10)
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
success,
|
||||||
|
True,
|
||||||
|
"Check if the data volume resized appropriately"
|
||||||
|
)
|
||||||
|
|
||||||
|
# start the vm if it is on xenserver
|
||||||
|
|
||||||
|
if hosts[0].hypervisor == "XenServer":
|
||||||
|
self.virtual_machine.start(self.apiClient)
|
||||||
|
time.sleep(30)
|
||||||
|
return
|
||||||
|
|
||||||
@attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
|
@attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
|
||||||
def test_09_delete_detached_volume(self):
|
def test_09_delete_detached_volume(self):
|
||||||
"""Delete a Volume unattached to an VM
|
"""Delete a Volume unattached to an VM
|
||||||
|
|||||||
@ -2305,6 +2305,12 @@ class ServiceOffering:
|
|||||||
if "dynamicscalingenabled" in services:
|
if "dynamicscalingenabled" in services:
|
||||||
cmd.dynamicscalingenabled = services["dynamicscalingenabled"]
|
cmd.dynamicscalingenabled = services["dynamicscalingenabled"]
|
||||||
|
|
||||||
|
if "diskofferingstrictness" in services:
|
||||||
|
cmd.diskofferingstrictness = services["diskofferingstrictness"]
|
||||||
|
|
||||||
|
if "diskofferingid" in services:
|
||||||
|
cmd.diskofferingid = services["diskofferingid"]
|
||||||
|
|
||||||
# Service Offering private to that domain
|
# Service Offering private to that domain
|
||||||
if domainid:
|
if domainid:
|
||||||
cmd.domainid = domainid
|
cmd.domainid = domainid
|
||||||
|
|||||||
@ -470,6 +470,7 @@
|
|||||||
"label.asyncbackup": "Async Backup",
|
"label.asyncbackup": "Async Backup",
|
||||||
"label.authentication.method": "Authentication Method",
|
"label.authentication.method": "Authentication Method",
|
||||||
"label.authentication.sshkey": "System SSH Key",
|
"label.authentication.sshkey": "System SSH Key",
|
||||||
|
"label.automigrate.volume": "Auto migrate volume to another storage pool if required",
|
||||||
"label.author.email": "Author e-mail",
|
"label.author.email": "Author e-mail",
|
||||||
"label.author.name": "Author name",
|
"label.author.name": "Author name",
|
||||||
"label.auto.assign": "Automatically assign",
|
"label.auto.assign": "Automatically assign",
|
||||||
@ -558,6 +559,7 @@
|
|||||||
"label.change.ip.addess": "Change IP Address",
|
"label.change.ip.addess": "Change IP Address",
|
||||||
"label.change.ipaddress": "Change IP address for NIC",
|
"label.change.ipaddress": "Change IP address for NIC",
|
||||||
"label.change.service.offering": "Change service offering",
|
"label.change.service.offering": "Change service offering",
|
||||||
|
"label.change.offering.for.volume": "Change disk offering for the volume",
|
||||||
"label.change.value": "Change value",
|
"label.change.value": "Change value",
|
||||||
"label.character": "Character",
|
"label.character": "Character",
|
||||||
"label.chassis": "Chassis",
|
"label.chassis": "Chassis",
|
||||||
@ -863,6 +865,9 @@
|
|||||||
"label.duration.in.sec": "Duration (in sec)",
|
"label.duration.in.sec": "Duration (in sec)",
|
||||||
"label.dynamicscalingenabled": "Dynamic Scaling Enabled",
|
"label.dynamicscalingenabled": "Dynamic Scaling Enabled",
|
||||||
"label.dynamicscalingenabled.tooltip": "VM can dynamically scale only when dynamic scaling is enabled on template, service offering and global setting",
|
"label.dynamicscalingenabled.tooltip": "VM can dynamically scale only when dynamic scaling is enabled on template, service offering and global setting",
|
||||||
|
"label.diskofferingstrictness": "Disk Offering Strictness",
|
||||||
|
"label.disksizestrictness": "Disk Size Strictness",
|
||||||
|
"label.computeonly.offering": "Compute only Disk Offering",
|
||||||
"label.edit": "Edit",
|
"label.edit": "Edit",
|
||||||
"label.edit.acl.list": "Edit ACL List",
|
"label.edit.acl.list": "Edit ACL List",
|
||||||
"label.edit.acl.rule": "Edit ACL rule",
|
"label.edit.acl.rule": "Edit ACL rule",
|
||||||
@ -1440,6 +1445,7 @@
|
|||||||
"label.migrate.to.host": "Migrate to host",
|
"label.migrate.to.host": "Migrate to host",
|
||||||
"label.migrate.to.storage": "Migrate to storage",
|
"label.migrate.to.storage": "Migrate to storage",
|
||||||
"label.migrate.volume": "Migrate Volume",
|
"label.migrate.volume": "Migrate Volume",
|
||||||
|
"message.migrate.volume.tooltip": "Volume can be migrated to any suitable storage pool. Admin has to choose the appropriate disk offering to replace, that supports the new storage pool",
|
||||||
"label.migrate.volume.newdiskoffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
|
"label.migrate.volume.newdiskoffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
|
||||||
"label.migrate.volume.to.primary.storage": "Migrate volume to another primary storage",
|
"label.migrate.volume.to.primary.storage": "Migrate volume to another primary storage",
|
||||||
"label.migrate.with.storage": "Migrate with storage",
|
"label.migrate.with.storage": "Migrate with storage",
|
||||||
@ -1607,6 +1613,8 @@
|
|||||||
"label.override.rootdisk.size": "Override Root Disk Size",
|
"label.override.rootdisk.size": "Override Root Disk Size",
|
||||||
"label.overrideguesttraffic": "Override Guest-Traffic",
|
"label.overrideguesttraffic": "Override Guest-Traffic",
|
||||||
"label.overridepublictraffic": "Override Public-Traffic",
|
"label.overridepublictraffic": "Override Public-Traffic",
|
||||||
|
"label.override.diskoffering": "Override Disk Offering",
|
||||||
|
"label.override.root.diskoffering": "Override Root Disk Offering",
|
||||||
"label.ovf.properties": "vApp Properties",
|
"label.ovf.properties": "vApp Properties",
|
||||||
"label.ovm3cluster": "Native Clustering",
|
"label.ovm3cluster": "Native Clustering",
|
||||||
"label.ovm3networklabel": "OVM3 Traffic Label",
|
"label.ovm3networklabel": "OVM3 Traffic Label",
|
||||||
@ -2675,6 +2683,10 @@
|
|||||||
"message.basic.mode.desc": "Choose this network model if you do <b>*<u>not</u>*</b> want to enable any VLAN support. All virtual instances created under this network model will be assigned an IP directly from the network and security groups are used to provide security and segregation.",
|
"message.basic.mode.desc": "Choose this network model if you do <b>*<u>not</u>*</b> want to enable any VLAN support. All virtual instances created under this network model will be assigned an IP directly from the network and security groups are used to provide security and segregation.",
|
||||||
"message.certificate.upload.processing": "Certificate upload in progress",
|
"message.certificate.upload.processing": "Certificate upload in progress",
|
||||||
"message.change.offering.confirm": "Please confirm that you wish to change the service offering of this virtual instance.",
|
"message.change.offering.confirm": "Please confirm that you wish to change the service offering of this virtual instance.",
|
||||||
|
"message.confirm.change.offering.for.volume": "Please confirm that you want to change disk offering for the volume",
|
||||||
|
"message.change.offering.for.volume.failed": "Change offering for the volume failed",
|
||||||
|
"message.change.offering.for.volume.processing": "Changing offering for the volume...",
|
||||||
|
"message.change.offering.for.volume": "Successfully changed offering for the volume",
|
||||||
"message.change.password": "Please change your password",
|
"message.change.password": "Please change your password",
|
||||||
"message.cluster.dedicated": "Cluster Dedicated",
|
"message.cluster.dedicated": "Cluster Dedicated",
|
||||||
"message.cluster.dedication.released": "Cluster dedication released",
|
"message.cluster.dedication.released": "Cluster dedication released",
|
||||||
|
|||||||
@ -31,7 +31,7 @@ export default {
|
|||||||
params: { isrecursive: 'true' },
|
params: { isrecursive: 'true' },
|
||||||
columns: ['name', 'displaytext', 'cpunumber', 'cpuspeed', 'memory', 'domain', 'zone', 'order'],
|
columns: ['name', 'displaytext', 'cpunumber', 'cpuspeed', 'memory', 'domain', 'zone', 'order'],
|
||||||
details: () => {
|
details: () => {
|
||||||
var fields = ['name', 'id', 'displaytext', 'offerha', 'provisioningtype', 'storagetype', 'iscustomized', 'iscustomizediops', 'limitcpuuse', 'cpunumber', 'cpuspeed', 'memory', 'hosttags', 'storagetags', 'domain', 'zone', 'created', 'dynamicscalingenabled']
|
var fields = ['name', 'id', 'displaytext', 'offerha', 'provisioningtype', 'storagetype', 'iscustomized', 'iscustomizediops', 'limitcpuuse', 'cpunumber', 'cpuspeed', 'memory', 'hosttags', 'tags', 'storagetags', 'domain', 'zone', 'created', 'dynamicscalingenabled', 'diskofferingstrictness']
|
||||||
if (store.getters.apis.createServiceOffering &&
|
if (store.getters.apis.createServiceOffering &&
|
||||||
store.getters.apis.createServiceOffering.params.filter(x => x.name === 'storagepolicy').length > 0) {
|
store.getters.apis.createServiceOffering.params.filter(x => x.name === 'storagepolicy').length > 0) {
|
||||||
fields.splice(6, 0, 'vspherestoragepolicy')
|
fields.splice(6, 0, 'vspherestoragepolicy')
|
||||||
@ -101,7 +101,7 @@ export default {
|
|||||||
permission: ['listServiceOfferings', 'listInfrastructure'],
|
permission: ['listServiceOfferings', 'listInfrastructure'],
|
||||||
params: { issystem: 'true', isrecursive: 'true' },
|
params: { issystem: 'true', isrecursive: 'true' },
|
||||||
columns: ['name', 'systemvmtype', 'cpunumber', 'cpuspeed', 'memory', 'storagetype', 'order'],
|
columns: ['name', 'systemvmtype', 'cpunumber', 'cpuspeed', 'memory', 'storagetype', 'order'],
|
||||||
details: ['name', 'id', 'displaytext', 'systemvmtype', 'provisioningtype', 'storagetype', 'iscustomized', 'limitcpuuse', 'cpunumber', 'cpuspeed', 'memory', 'hosttags', 'tags', 'domain', 'zone', 'created', 'dynamicscalingenabled'],
|
details: ['name', 'id', 'displaytext', 'systemvmtype', 'provisioningtype', 'storagetype', 'iscustomized', 'limitcpuuse', 'cpunumber', 'cpuspeed', 'memory', 'hosttags', 'tags', 'domain', 'zone', 'created', 'dynamicscalingenabled', 'diskofferingstrictness'],
|
||||||
actions: [{
|
actions: [{
|
||||||
api: 'createServiceOffering',
|
api: 'createServiceOffering',
|
||||||
icon: 'plus',
|
icon: 'plus',
|
||||||
@ -141,7 +141,7 @@ export default {
|
|||||||
params: { isrecursive: 'true' },
|
params: { isrecursive: 'true' },
|
||||||
columns: ['name', 'displaytext', 'disksize', 'domain', 'zone', 'order'],
|
columns: ['name', 'displaytext', 'disksize', 'domain', 'zone', 'order'],
|
||||||
details: () => {
|
details: () => {
|
||||||
var fields = ['name', 'id', 'displaytext', 'disksize', 'provisioningtype', 'storagetype', 'iscustomized', 'iscustomizediops', 'tags', 'domain', 'zone', 'created']
|
var fields = ['name', 'id', 'displaytext', 'disksize', 'provisioningtype', 'storagetype', 'iscustomized', 'disksizestrictness', 'iscustomizediops', 'tags', 'domain', 'zone', 'created']
|
||||||
if (store.getters.apis.createDiskOffering &&
|
if (store.getters.apis.createDiskOffering &&
|
||||||
store.getters.apis.createDiskOffering.params.filter(x => x.name === 'storagepolicy').length > 0) {
|
store.getters.apis.createDiskOffering.params.filter(x => x.name === 'storagepolicy').length > 0) {
|
||||||
fields.splice(6, 0, 'vspherestoragepolicy')
|
fields.splice(6, 0, 'vspherestoragepolicy')
|
||||||
|
|||||||
@ -197,6 +197,17 @@ export default {
|
|||||||
popup: true,
|
popup: true,
|
||||||
component: () => import('@/views/storage/MigrateVolume.vue')
|
component: () => import('@/views/storage/MigrateVolume.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
api: 'changeOfferingForVolume',
|
||||||
|
icon: 'swap',
|
||||||
|
docHelp: 'adminguide/storage.html#id2',
|
||||||
|
label: 'label.change.offering.for.volume',
|
||||||
|
args: ['id', 'diskofferingid', 'size', 'miniops', 'maxiops', 'automigrate'],
|
||||||
|
dataView: true,
|
||||||
|
show: (record, store) => { return ['Allocated', 'Ready'].includes(record.state) && ['Admin'].includes(store.userInfo.roletype) },
|
||||||
|
popup: true,
|
||||||
|
component: () => import('@/views/storage/ChangeOfferingForVolume.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
api: 'extractVolume',
|
api: 'extractVolume',
|
||||||
icon: 'cloud-download',
|
icon: 'cloud-download',
|
||||||
|
|||||||
@ -148,8 +148,9 @@
|
|||||||
<span>
|
<span>
|
||||||
{{ $t('label.override.rootdisk.size') }}
|
{{ $t('label.override.rootdisk.size') }}
|
||||||
<a-switch
|
<a-switch
|
||||||
:default-checked="showRootDiskSizeChanger && rootDiskSizeFixed > 0"
|
:default-checked="this.showRootDiskSizeChanger && rootDiskSizeFixed > 0"
|
||||||
:disabled="rootDiskSizeFixed > 0 || template.deployasis"
|
:checked="this.showRootDiskSizeChanger"
|
||||||
|
:disabled="rootDiskSizeFixed > 0 || template.deployasis || this.showOverrideDiskOfferingOption"
|
||||||
@change="val => { this.showRootDiskSizeChanger = val }"
|
@change="val => { this.showRootDiskSizeChanger = val }"
|
||||||
style="margin-left: 10px;"/>
|
style="margin-left: 10px;"/>
|
||||||
<div v-if="template.deployasis"> {{ this.$t('message.deployasis') }} </div>
|
<div v-if="template.deployasis"> {{ this.$t('message.deployasis') }} </div>
|
||||||
@ -273,6 +274,65 @@
|
|||||||
<a-input v-decorator="['memory']"/>
|
<a-input v-decorator="['memory']"/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</span>
|
</span>
|
||||||
|
<span v-if="tabKey!=='isoid'">
|
||||||
|
{{ $t('label.override.root.diskoffering') }}
|
||||||
|
<a-switch
|
||||||
|
v-decorator="['this.showOverrideDiskOfferingOption']"
|
||||||
|
:checked="serviceOffering && !serviceOffering.diskofferingstrictness && this.showOverrideDiskOfferingOption"
|
||||||
|
:disabled="(serviceOffering && serviceOffering.diskofferingstrictness)"
|
||||||
|
@change="val => { updateOverrideRootDiskShowParam(val) }"
|
||||||
|
style="margin-left: 10px;"/>
|
||||||
|
</span>
|
||||||
|
<span v-if="tabKey!=='isoid' && serviceOffering && !serviceOffering.diskofferingstrictness">
|
||||||
|
<a-step
|
||||||
|
:status="zoneSelected ? 'process' : 'wait'"
|
||||||
|
v-if="!template.deployasis && template.childtemplates && template.childtemplates.length > 0" >
|
||||||
|
<template slot="description">
|
||||||
|
<div v-if="zoneSelected">
|
||||||
|
<multi-disk-selection
|
||||||
|
:items="template.childtemplates"
|
||||||
|
:diskOfferings="options.diskOfferings"
|
||||||
|
:zoneId="zoneId"
|
||||||
|
@select-multi-disk-offering="updateMultiDiskOffering($event)" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-step>
|
||||||
|
<a-step
|
||||||
|
v-else
|
||||||
|
:status="zoneSelected ? 'process' : 'wait'">
|
||||||
|
<template slot="description">
|
||||||
|
<div v-if="zoneSelected">
|
||||||
|
<disk-offering-selection
|
||||||
|
v-if="showOverrideDiskOfferingOption"
|
||||||
|
:items="options.diskOfferings"
|
||||||
|
:row-count="rowCount.diskOfferings"
|
||||||
|
:zoneId="zoneId"
|
||||||
|
:value="overrideDiskOffering ? overrideDiskOffering.id : ''"
|
||||||
|
:loading="loading.diskOfferings"
|
||||||
|
:preFillContent="dataPreFill"
|
||||||
|
:isIsoSelected="tabKey==='isoid'"
|
||||||
|
:isRootDiskOffering="true"
|
||||||
|
@on-selected-root-disk-size="onSelectRootDiskSize"
|
||||||
|
@select-disk-offering-item="($event) => updateOverrideDiskOffering($event)"
|
||||||
|
@handle-search-filter="($event) => handleSearchFilter('diskOfferings', $event)"
|
||||||
|
></disk-offering-selection>
|
||||||
|
<disk-size-selection
|
||||||
|
v-if="overrideDiskOffering && (overrideDiskOffering.iscustomized || overrideDiskOffering.iscustomizediops)"
|
||||||
|
input-decorator="rootdisksize"
|
||||||
|
:preFillContent="dataPreFill"
|
||||||
|
:minDiskSize="dataPreFill.minrootdisksize"
|
||||||
|
:rootDiskSelected="overrideDiskOffering"
|
||||||
|
:isCustomized="overrideDiskOffering.iscustomized"
|
||||||
|
@handler-error="handlerError"
|
||||||
|
@update-disk-size="updateFieldValue"
|
||||||
|
@update-root-disk-iops-value="updateIOPSValue"/>
|
||||||
|
<a-form-item class="form-item-hidden">
|
||||||
|
<a-input v-decorator="['rootdisksize']"/>
|
||||||
|
</a-form-item>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-step>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-step>
|
</a-step>
|
||||||
@ -819,6 +879,7 @@ export default {
|
|||||||
networksAdd: [],
|
networksAdd: [],
|
||||||
zone: {},
|
zone: {},
|
||||||
sshKeyPair: {},
|
sshKeyPair: {},
|
||||||
|
overrideDiskOffering: {},
|
||||||
templateFilter: [
|
templateFilter: [
|
||||||
'featured',
|
'featured',
|
||||||
'community',
|
'community',
|
||||||
@ -839,10 +900,12 @@ export default {
|
|||||||
dataPreFill: {},
|
dataPreFill: {},
|
||||||
showDetails: false,
|
showDetails: false,
|
||||||
showRootDiskSizeChanger: false,
|
showRootDiskSizeChanger: false,
|
||||||
|
showOverrideDiskOfferingOption: false,
|
||||||
securitygroupids: [],
|
securitygroupids: [],
|
||||||
rootDiskSizeFixed: 0,
|
rootDiskSizeFixed: 0,
|
||||||
error: false,
|
error: false,
|
||||||
diskSelected: {},
|
diskSelected: {},
|
||||||
|
rootDiskSelected: {},
|
||||||
diskIOpsMin: 0,
|
diskIOpsMin: 0,
|
||||||
diskIOpsMax: 0,
|
diskIOpsMax: 0,
|
||||||
minIops: 0,
|
minIops: 0,
|
||||||
@ -1092,7 +1155,7 @@ export default {
|
|||||||
return this.diskSelected?.iscustomizediops || false
|
return this.diskSelected?.iscustomizediops || false
|
||||||
},
|
},
|
||||||
isCustomizedIOPS () {
|
isCustomizedIOPS () {
|
||||||
return this.serviceOffering?.iscustomizediops || false
|
return this.rootDiskSelected?.iscustomizediops || this.serviceOffering?.iscustomizediops || false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -1126,7 +1189,25 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.serviceOffering = _.find(this.options.serviceOfferings, (option) => option.id === instanceConfig.computeofferingid)
|
this.serviceOffering = _.find(this.options.serviceOfferings, (option) => option.id === instanceConfig.computeofferingid)
|
||||||
this.diskOffering = _.find(this.options.diskOfferings, (option) => option.id === instanceConfig.diskofferingid)
|
if (this.serviceOffering?.diskofferingid) {
|
||||||
|
if (iso) {
|
||||||
|
this.diskOffering = _.find(this.options.diskOfferings, (option) => option.id === this.serviceOffering.diskofferingid)
|
||||||
|
} else {
|
||||||
|
instanceConfig.overridediskofferingid = this.serviceOffering.diskofferingid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!iso && this.diskSelected) {
|
||||||
|
this.diskOffering = _.find(this.options.diskOfferings, (option) => option.id === instanceConfig.diskofferingid)
|
||||||
|
}
|
||||||
|
if (this.rootDiskSelected?.id) {
|
||||||
|
instanceConfig.overridediskofferingid = this.rootDiskSelected.id
|
||||||
|
}
|
||||||
|
console.log('overrided value ' + instanceConfig.overridediskofferingid)
|
||||||
|
if (instanceConfig.overridediskofferingid) {
|
||||||
|
this.overrideDiskOffering = _.find(this.options.diskOfferings, (option) => option.id === instanceConfig.overridediskofferingid)
|
||||||
|
} else {
|
||||||
|
this.overrideDiskOffering = null
|
||||||
|
}
|
||||||
this.zone = _.find(this.options.zones, (option) => option.id === instanceConfig.zoneid)
|
this.zone = _.find(this.options.zones, (option) => option.id === instanceConfig.zoneid)
|
||||||
this.affinityGroups = _.filter(this.options.affinityGroups, (option) => _.includes(instanceConfig.affinitygroupids, option.id))
|
this.affinityGroups = _.filter(this.options.affinityGroups, (option) => _.includes(instanceConfig.affinitygroupids, option.id))
|
||||||
this.networks = _.filter(this.options.networks, (option) => _.includes(instanceConfig.networkids, option.id))
|
this.networks = _.filter(this.options.networks, (option) => _.includes(instanceConfig.networkids, option.id))
|
||||||
@ -1244,6 +1325,7 @@ export default {
|
|||||||
})
|
})
|
||||||
this.form.getFieldDecorator('computeofferingid', { initialValue: undefined, preserve: true })
|
this.form.getFieldDecorator('computeofferingid', { initialValue: undefined, preserve: true })
|
||||||
this.form.getFieldDecorator('diskofferingid', { initialValue: undefined, preserve: true })
|
this.form.getFieldDecorator('diskofferingid', { initialValue: undefined, preserve: true })
|
||||||
|
this.form.getFieldDecorator('overridediskofferingid', { initialValue: undefined, preserve: true })
|
||||||
this.form.getFieldDecorator('multidiskoffering', { initialValue: undefined, preserve: true })
|
this.form.getFieldDecorator('multidiskoffering', { initialValue: undefined, preserve: true })
|
||||||
this.form.getFieldDecorator('affinitygroupids', { initialValue: [], preserve: true })
|
this.form.getFieldDecorator('affinitygroupids', { initialValue: [], preserve: true })
|
||||||
this.form.getFieldDecorator('networkids', { initialValue: [], preserve: true })
|
this.form.getFieldDecorator('networkids', { initialValue: [], preserve: true })
|
||||||
@ -1369,6 +1451,14 @@ export default {
|
|||||||
getImg (image) {
|
getImg (image) {
|
||||||
return 'data:image/png;charset=utf-8;base64, ' + image
|
return 'data:image/png;charset=utf-8;base64, ' + image
|
||||||
},
|
},
|
||||||
|
updateOverrideRootDiskShowParam (val) {
|
||||||
|
if (val) {
|
||||||
|
this.showRootDiskSizeChanger = false
|
||||||
|
} else {
|
||||||
|
this.rootDiskSelected = null
|
||||||
|
}
|
||||||
|
this.showOverrideDiskOfferingOption = val
|
||||||
|
},
|
||||||
async fetchDataByZone (zoneId) {
|
async fetchDataByZone (zoneId) {
|
||||||
this.fillValue('zoneid')
|
this.fillValue('zoneid')
|
||||||
this.options.zones = await this.fetchZones(zoneId)
|
this.options.zones = await this.fetchZones(zoneId)
|
||||||
@ -1503,6 +1593,17 @@ export default {
|
|||||||
diskofferingid: id
|
diskofferingid: id
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
updateOverrideDiskOffering (id) {
|
||||||
|
if (id === '0') {
|
||||||
|
this.form.setFieldsValue({
|
||||||
|
overridediskofferingid: undefined
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.form.setFieldsValue({
|
||||||
|
overridediskofferingid: id
|
||||||
|
})
|
||||||
|
},
|
||||||
updateMultiDiskOffering (value) {
|
updateMultiDiskOffering (value) {
|
||||||
this.form.setFieldsValue({
|
this.form.setFieldsValue({
|
||||||
multidiskoffering: value
|
multidiskoffering: value
|
||||||
@ -1634,7 +1735,8 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
deployVmData.templateid = values.isoid
|
deployVmData.templateid = values.isoid
|
||||||
}
|
}
|
||||||
if (this.showRootDiskSizeChanger && values.rootdisksize && values.rootdisksize > 0) {
|
|
||||||
|
if (values.rootdisksize && values.rootdisksize > 0) {
|
||||||
deployVmData.rootdisksize = values.rootdisksize
|
deployVmData.rootdisksize = values.rootdisksize
|
||||||
} else if (this.rootDiskSizeFixed > 0) {
|
} else if (this.rootDiskSizeFixed > 0) {
|
||||||
deployVmData.rootdisksize = this.rootDiskSizeFixed
|
deployVmData.rootdisksize = this.rootDiskSizeFixed
|
||||||
@ -1661,6 +1763,9 @@ export default {
|
|||||||
if (this.selectedTemplateConfiguration) {
|
if (this.selectedTemplateConfiguration) {
|
||||||
deployVmData['details[0].configurationId'] = this.selectedTemplateConfiguration.id
|
deployVmData['details[0].configurationId'] = this.selectedTemplateConfiguration.id
|
||||||
}
|
}
|
||||||
|
if (!this.serviceOffering.diskofferingstrictness && values.overridediskofferingid) {
|
||||||
|
deployVmData.overridediskofferingid = values.overridediskofferingid
|
||||||
|
}
|
||||||
if (this.isCustomizedIOPS) {
|
if (this.isCustomizedIOPS) {
|
||||||
deployVmData['details[0].minIops'] = this.minIops
|
deployVmData['details[0].minIops'] = this.minIops
|
||||||
deployVmData['details[0].maxIops'] = this.maxIops
|
deployVmData['details[0].maxIops'] = this.maxIops
|
||||||
@ -2222,6 +2327,9 @@ export default {
|
|||||||
onSelectDiskSize (rowSelected) {
|
onSelectDiskSize (rowSelected) {
|
||||||
this.diskSelected = rowSelected
|
this.diskSelected = rowSelected
|
||||||
},
|
},
|
||||||
|
onSelectRootDiskSize (rowSelected) {
|
||||||
|
this.rootDiskSelected = rowSelected
|
||||||
|
},
|
||||||
updateIOPSValue (input, value) {
|
updateIOPSValue (input, value) {
|
||||||
this[input] = value
|
this[input] = value
|
||||||
},
|
},
|
||||||
|
|||||||
@ -48,6 +48,14 @@
|
|||||||
@update-compute-cpuspeed="updateFieldValue"
|
@update-compute-cpuspeed="updateFieldValue"
|
||||||
@update-compute-memory="updateFieldValue" />
|
@update-compute-memory="updateFieldValue" />
|
||||||
|
|
||||||
|
<a-form-item :label="$t('label.automigrate.volume')">
|
||||||
|
<tooltip-label slot="label" :title="$t('label.automigrate.volume')" :tooltip="apiParams.automigrate.description"/>
|
||||||
|
<a-switch
|
||||||
|
v-decorator="['autoMigrate']"
|
||||||
|
:checked="autoMigrate"
|
||||||
|
@change="val => { autoMigrate = val }"/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
<div :span="24" class="action-button">
|
<div :span="24" class="action-button">
|
||||||
<a-button @click="closeAction">{{ this.$t('label.cancel') }}</a-button>
|
<a-button @click="closeAction">{{ this.$t('label.cancel') }}</a-button>
|
||||||
<a-button :loading="loading" ref="submit" type="primary" @click="handleSubmit">{{ this.$t('label.ok') }}</a-button>
|
<a-button :loading="loading" ref="submit" type="primary" @click="handleSubmit">{{ this.$t('label.ok') }}</a-button>
|
||||||
@ -78,6 +86,7 @@ export default {
|
|||||||
offeringsMap: {},
|
offeringsMap: {},
|
||||||
offerings: [],
|
offerings: [],
|
||||||
selectedOffering: {},
|
selectedOffering: {},
|
||||||
|
autoMigrate: true,
|
||||||
total: 0,
|
total: 0,
|
||||||
params: { id: this.resource.id },
|
params: { id: this.resource.id },
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -86,6 +95,10 @@ export default {
|
|||||||
memoryKey: 'details[0].memory'
|
memoryKey: 'details[0].memory'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
beforeCreate () {
|
||||||
|
this.form = this.$form.createForm(this)
|
||||||
|
this.apiParams = this.$getApiParams('scaleVirtualMachine')
|
||||||
|
},
|
||||||
created () {
|
created () {
|
||||||
this.fetchData({
|
this.fetchData({
|
||||||
keyword: '',
|
keyword: '',
|
||||||
@ -145,6 +158,7 @@ export default {
|
|||||||
|
|
||||||
this.params.serviceofferingid = id
|
this.params.serviceofferingid = id
|
||||||
this.selectedOffering = this.offeringsMap[id]
|
this.selectedOffering = this.offeringsMap[id]
|
||||||
|
this.params.automigrate = this.autoMigrate
|
||||||
},
|
},
|
||||||
updateFieldValue (name, value) {
|
updateFieldValue (name, value) {
|
||||||
this.params[name] = value
|
this.params[name] = value
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-card>
|
<a-card v-if="isCustomized">
|
||||||
<a-col>
|
<a-col>
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-col :md="colContraned" :lg="colContraned" v-if="isCustomized">
|
<a-col :md="colContraned" :lg="colContraned" v-if="isCustomized">
|
||||||
|
|||||||
@ -97,6 +97,10 @@ export default {
|
|||||||
isIsoSelected: {
|
isIsoSelected: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
isRootDiskOffering: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@ -163,6 +167,7 @@ export default {
|
|||||||
value (newValue, oldValue) {
|
value (newValue, oldValue) {
|
||||||
if (newValue && newValue !== oldValue) {
|
if (newValue && newValue !== oldValue) {
|
||||||
this.selectedRowKeys = [newValue]
|
this.selectedRowKeys = [newValue]
|
||||||
|
this.onSelectRow(this.selectedRowKeys)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
items (newData, oldData) {
|
items (newData, oldData) {
|
||||||
@ -202,7 +207,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
initDataItem () {
|
initDataItem () {
|
||||||
this.dataItems = []
|
this.dataItems = []
|
||||||
if (this.options.page === 1 && !this.isIsoSelected) {
|
if (this.options.page === 1 && !this.isIsoSelected && !this.isRootDiskOffering) {
|
||||||
this.dataItems.push({
|
this.dataItems.push({
|
||||||
id: '0',
|
id: '0',
|
||||||
name: this.$t('label.noselect'),
|
name: this.$t('label.noselect'),
|
||||||
@ -250,6 +255,7 @@ export default {
|
|||||||
this.selectedRowKeys = [record.key]
|
this.selectedRowKeys = [record.key]
|
||||||
this.$emit('select-disk-offering-item', record.key)
|
this.$emit('select-disk-offering-item', record.key)
|
||||||
this.$emit('on-selected-disk-size', this.diskSelected)
|
this.$emit('on-selected-disk-size', this.diskSelected)
|
||||||
|
this.$emit('on-selected-root-disk-size', this.diskSelected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-row :span="24" :style="{ marginTop: '20px' }">
|
<a-row :span="24" :style="{ marginTop: '20px' }">
|
||||||
<a-col :span="isCustomizedDiskIOps ? 8 : 24" v-if="isCustomized">
|
<a-col :span="isCustomizedDiskIOps || isCustomizedIOps ? 8 : 24" v-if="isCustomized">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="inputDecorator === 'rootdisksize' ? $t('label.root.disk.size') : $t('label.disksize')"
|
:label="inputDecorator === 'rootdisksize' ? $t('label.root.disk.size') : $t('label.disksize')"
|
||||||
class="form-item">
|
class="form-item">
|
||||||
@ -32,13 +32,13 @@
|
|||||||
<p v-if="error" style="color: red"> {{ $t(error) }} </p>
|
<p v-if="error" style="color: red"> {{ $t(error) }} </p>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8" v-if="isCustomizedDiskIOps">
|
<a-col :span="8" v-if="isCustomizedDiskIOps || isCustomizedIOps">
|
||||||
<a-form-item :label="$t('label.diskiopsmin')">
|
<a-form-item :label="$t('label.diskiopsmin')">
|
||||||
<a-input-number v-model="minIOps" @change="updateDiskIOps" />
|
<a-input-number v-model="minIOps" @change="updateDiskIOps" />
|
||||||
<p v-if="errorMinIOps" style="color: red"> {{ $t(errorMinIOps) }} </p>
|
<p v-if="errorMinIOps" style="color: red"> {{ $t(errorMinIOps) }} </p>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8" v-if="isCustomizedDiskIOps">
|
<a-col :span="8" v-if="isCustomizedDiskIOps || isCustomizedIOps">
|
||||||
<a-form-item :label="$t('label.diskiopsmax')">
|
<a-form-item :label="$t('label.diskiopsmax')">
|
||||||
<a-input-number v-model="maxIOps" @change="updateDiskIOps" />
|
<a-input-number v-model="maxIOps" @change="updateDiskIOps" />
|
||||||
<p v-if="errorMaxIOps" style="color: red"> {{ $t(errorMaxIOps) }} </p>
|
<p v-if="errorMaxIOps" style="color: red"> {{ $t(errorMaxIOps) }} </p>
|
||||||
@ -67,6 +67,10 @@ export default {
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => {}
|
default: () => {}
|
||||||
},
|
},
|
||||||
|
rootDiskSelected: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
},
|
||||||
isCustomized: {
|
isCustomized: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
@ -83,6 +87,9 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
isCustomizedDiskIOps () {
|
isCustomizedDiskIOps () {
|
||||||
return this.diskSelected?.iscustomizediops || false
|
return this.diskSelected?.iscustomizediops || false
|
||||||
|
},
|
||||||
|
isCustomizedIOps () {
|
||||||
|
return this.rootDiskSelected?.iscustomizediops || false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@ -143,6 +150,8 @@ export default {
|
|||||||
}
|
}
|
||||||
this.$emit('update-iops-value', 'diskIOpsMin', this.minIOps)
|
this.$emit('update-iops-value', 'diskIOpsMin', this.minIOps)
|
||||||
this.$emit('update-iops-value', 'diskIOpsMax', this.maxIOps)
|
this.$emit('update-iops-value', 'diskIOpsMax', this.maxIOps)
|
||||||
|
this.$emit('update-root-disk-iops-value', 'minIops', this.minIOps)
|
||||||
|
this.$emit('update-root-disk-iops-value', 'maxIops', this.maxIOps)
|
||||||
this.$emit('handler-error', false)
|
this.$emit('handler-error', false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,60 +56,6 @@
|
|||||||
<a-select-option key="secondarystoragevm">{{ $t('label.secondary.storage.vm') }}</a-select-option>
|
<a-select-option key="secondarystoragevm">{{ $t('label.secondary.storage.vm') }}</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item>
|
|
||||||
<tooltip-label slot="label" :title="$t('label.storagetype')" :tooltip="apiParams.storagetype.description"/>
|
|
||||||
<a-radio-group
|
|
||||||
v-decorator="['storagetype', {
|
|
||||||
initialValue: storageType
|
|
||||||
}]"
|
|
||||||
buttonStyle="solid"
|
|
||||||
@change="selected => { handleStorageTypeChange(selected.target.value) }">
|
|
||||||
<a-radio-button value="shared">
|
|
||||||
{{ $t('label.shared') }}
|
|
||||||
</a-radio-button>
|
|
||||||
<a-radio-button value="local">
|
|
||||||
{{ $t('label.local') }}
|
|
||||||
</a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item>
|
|
||||||
<tooltip-label slot="label" :title="$t('label.provisioningtype')" :tooltip="apiParams.provisioningtype.description"/>
|
|
||||||
<a-radio-group
|
|
||||||
v-decorator="['provisioningtype', {
|
|
||||||
initialValue: provisioningType
|
|
||||||
}]"
|
|
||||||
buttonStyle="solid"
|
|
||||||
@change="selected => { handleProvisioningTypeChange(selected.target.value) }">
|
|
||||||
<a-radio-button value="thin">
|
|
||||||
{{ $t('label.provisioningtype.thin') }}
|
|
||||||
</a-radio-button>
|
|
||||||
<a-radio-button value="sparse">
|
|
||||||
{{ $t('label.provisioningtype.sparse') }}
|
|
||||||
</a-radio-button>
|
|
||||||
<a-radio-button value="fat">
|
|
||||||
{{ $t('label.provisioningtype.fat') }}
|
|
||||||
</a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item>
|
|
||||||
<tooltip-label slot="label" :title="$t('label.cachemode')" :tooltip="apiParams.cachemode.description"/>
|
|
||||||
<a-radio-group
|
|
||||||
v-decorator="['cachemode', {
|
|
||||||
initialValue: cacheMode
|
|
||||||
}]"
|
|
||||||
buttonStyle="solid"
|
|
||||||
@change="selected => { handleCacheModeChange(selected.target.value) }">
|
|
||||||
<a-radio-button value="none">
|
|
||||||
{{ $t('label.nodiskcache') }}
|
|
||||||
</a-radio-button>
|
|
||||||
<a-radio-button value="writeback">
|
|
||||||
{{ $t('label.writeback') }}
|
|
||||||
</a-radio-button>
|
|
||||||
<a-radio-button value="writethrough">
|
|
||||||
{{ $t('label.writethrough') }}
|
|
||||||
</a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item :label="$t('label.offeringtype')" v-show="!isSystem">
|
<a-form-item :label="$t('label.offeringtype')" v-show="!isSystem">
|
||||||
<a-radio-group
|
<a-radio-group
|
||||||
v-decorator="['offeringtype', {
|
v-decorator="['offeringtype', {
|
||||||
@ -205,6 +151,14 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-row :gutter="12">
|
<a-row :gutter="12">
|
||||||
|
<a-col :md="12" :lg="12">
|
||||||
|
<a-form-item v-if="isAdmin()">
|
||||||
|
<tooltip-label slot="label" :title="$t('label.hosttags')" :tooltip="apiParams.hosttags.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['hosttags', {}]"
|
||||||
|
:placeholder="apiParams.hosttags.description"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
<a-col :md="12" :lg="12">
|
<a-col :md="12" :lg="12">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<tooltip-label slot="label" :title="$t('label.networkrate')" :tooltip="apiParams.networkrate.description"/>
|
<tooltip-label slot="label" :title="$t('label.networkrate')" :tooltip="apiParams.networkrate.description"/>
|
||||||
@ -213,97 +167,7 @@
|
|||||||
:placeholder="apiParams.networkrate.description"/>
|
:placeholder="apiParams.networkrate.description"/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :md="12" :lg="12">
|
|
||||||
<a-form-item v-if="apiParams.rootdisksize">
|
|
||||||
<tooltip-label slot="label" :title="$t('label.root.disk.size')" :tooltip="apiParams.rootdisksize.description"/>
|
|
||||||
<a-input
|
|
||||||
v-decorator="['rootdisksize', { rules: [naturalNumberRule] }]"
|
|
||||||
:placeholder="apiParams.rootdisksize.description"/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-form-item :label="$t('label.qostype')">
|
|
||||||
<a-radio-group
|
|
||||||
v-decorator="['qostype', {
|
|
||||||
initialValue: qosType
|
|
||||||
}]"
|
|
||||||
buttonStyle="solid"
|
|
||||||
@change="selected => { handleQosTypeChange(selected.target.value) }">
|
|
||||||
<a-radio-button value="">
|
|
||||||
{{ $t('label.none') }}
|
|
||||||
</a-radio-button>
|
|
||||||
<a-radio-button value="hypervisor">
|
|
||||||
{{ $t('label.hypervisor') }}
|
|
||||||
</a-radio-button>
|
|
||||||
<a-radio-button value="storage">
|
|
||||||
{{ $t('label.storage') }}
|
|
||||||
</a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
</a-form-item>
|
|
||||||
<a-row :gutter="12" v-if="qosType === 'hypervisor'">
|
|
||||||
<a-col :md="12" :lg="12">
|
|
||||||
<a-form-item>
|
|
||||||
<tooltip-label slot="label" :title="$t('label.diskbytesreadrate')" :tooltip="apiParams.bytesreadrate.description"/>
|
|
||||||
<a-input
|
|
||||||
v-decorator="['diskbytesreadrate', { rules: [naturalNumberRule] }]"
|
|
||||||
:placeholder="apiParams.bytesreadrate.description"/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :md="12" :lg="12">
|
|
||||||
<a-form-item>
|
|
||||||
<tooltip-label slot="label" :title="$t('label.diskbyteswriterate')" :tooltip="apiParams.byteswriterate.description"/>
|
|
||||||
<a-input
|
|
||||||
v-decorator="['diskbyteswriterate', { rules: [naturalNumberRule] }]"
|
|
||||||
:placeholder="apiParams.byteswriterate.description"/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
<a-row :gutter="12" v-if="qosType === 'hypervisor'">
|
|
||||||
<a-col :md="12" :lg="12">
|
|
||||||
<a-form-item>
|
|
||||||
<tooltip-label slot="label" :title="$t('label.diskiopsreadrate')" :tooltip="apiParams.iopsreadrate.description"/>
|
|
||||||
<a-input
|
|
||||||
v-decorator="['diskiopsreadrate', { rules: [naturalNumberRule] }]"
|
|
||||||
:placeholder="apiParams.iopsreadrate.description"/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :md="12" :lg="12">
|
|
||||||
<a-form-item>
|
|
||||||
<tooltip-label slot="label" :title="$t('label.diskiopswriterate')" :tooltip="apiParams.iopswriterate.description"/>
|
|
||||||
<a-input
|
|
||||||
v-decorator="['diskiopswriterate', { rules: [naturalNumberRule] }]"
|
|
||||||
:placeholder="apiParams.iopswriterate.description"/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
<a-form-item v-if="!isSystem && qosType === 'storage'">
|
|
||||||
<tooltip-label slot="label" :title="$t('label.iscustomizeddiskiops')" :tooltip="apiParams.customizediops.description"/>
|
|
||||||
<a-switch v-decorator="['iscustomizeddiskiops', {initialValue: isCustomizedDiskIops}]" :defaultChecked="isCustomizedDiskIops" @change="val => { isCustomizedDiskIops = val }" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-row :gutter="12" v-if="qosType === 'storage' && !isCustomizedDiskIops">
|
|
||||||
<a-col :md="12" :lg="12">
|
|
||||||
<a-form-item>
|
|
||||||
<tooltip-label slot="label" :title="$t('label.diskiopsmin')" :tooltip="apiParams.miniops.description"/>
|
|
||||||
<a-input
|
|
||||||
v-decorator="['diskiopsmin', { rules: [naturalNumberRule] }]"
|
|
||||||
:placeholder="apiParams.miniops.description"/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :md="12" :lg="12">
|
|
||||||
<a-form-item>
|
|
||||||
<tooltip-label slot="label" :title="$t('label.diskiopsmax')" :tooltip="apiParams.maxiops.description"/>
|
|
||||||
<a-input
|
|
||||||
v-decorator="['diskiopsmax', { rules: [naturalNumberRule] }]"
|
|
||||||
:placeholder="apiParams.maxiops.description"/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
<a-form-item v-if="!isSystem && qosType === 'storage'">
|
|
||||||
<tooltip-label slot="label" :title="$t('label.hypervisorsnapshotreserve')" :tooltip="apiParams.hypervisorsnapshotreserve.description"/>
|
|
||||||
<a-input
|
|
||||||
v-decorator="['hypervisorsnapshotreserve', { rules: [naturalNumberRule] }]"
|
|
||||||
:placeholder="apiParams.hypervisorsnapshotreserve.description"/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-row :gutter="12">
|
<a-row :gutter="12">
|
||||||
<a-col :md="12" :lg="12">
|
<a-col :md="12" :lg="12">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
@ -318,36 +182,6 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-row :gutter="12">
|
|
||||||
<a-col :md="12" :lg="12">
|
|
||||||
<a-form-item v-if="isAdmin()">
|
|
||||||
<tooltip-label slot="label" :title="$t('label.hosttags')" :tooltip="apiParams.hosttags.description"/>
|
|
||||||
<a-input
|
|
||||||
v-decorator="['hosttags', {}]"
|
|
||||||
:placeholder="apiParams.hosttags.description"/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :md="12" :lg="12">
|
|
||||||
<a-form-item v-if="isAdmin()">
|
|
||||||
<tooltip-label slot="label" :title="$t('label.storagetags')" :tooltip="apiParams.tags.description"/>
|
|
||||||
<a-select
|
|
||||||
mode="tags"
|
|
||||||
v-decorator="['storagetags', {}]"
|
|
||||||
showSearch
|
|
||||||
optionFilterProp="children"
|
|
||||||
:filterOption="(input, option) => {
|
|
||||||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
||||||
}"
|
|
||||||
:loading="storageTagLoading"
|
|
||||||
:placeholder="apiParams.tags.description"
|
|
||||||
v-if="isAdmin()">
|
|
||||||
<a-select-option v-for="opt in storageTags" :key="opt">
|
|
||||||
{{ opt }}
|
|
||||||
</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
<a-row :gutter="12">
|
<a-row :gutter="12">
|
||||||
<a-col :md="12" :lg="12">
|
<a-col :md="12" :lg="12">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
@ -491,7 +325,7 @@
|
|||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="'listVsphereStoragePolicies' in $store.getters.apis && storagePolicies !== null">
|
<a-form-item v-if="'listVsphereStoragePolicies' in $store.getters.apis && storagePolicies !== null">
|
||||||
<tooltip-label slot="label" :title="$t('label.vmware.storage.polic')" :tooltip="apiParams.storagepolicy.description"/>
|
<tooltip-label slot="label" :title="$t('label.vmware.storage.policy')" :tooltip="apiParams.storagepolicy.description"/>
|
||||||
<a-select
|
<a-select
|
||||||
v-decorator="['storagepolicy']"
|
v-decorator="['storagepolicy']"
|
||||||
:placeholder="apiParams.storagepolicy.description"
|
:placeholder="apiParams.storagepolicy.description"
|
||||||
@ -505,6 +339,222 @@
|
|||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<span slot="label">
|
||||||
|
{{ $t('label.computeonly.offering') }}
|
||||||
|
</span>
|
||||||
|
<a-switch v-decorator="['computeonly', {initialValue: computeonly}]" :checked="computeonly" @change="val => { computeonly = val }"/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-card>
|
||||||
|
<span v-if="computeonly">
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.storagetype')" :tooltip="apiParams.storagetype.description"/>
|
||||||
|
<a-radio-group
|
||||||
|
v-decorator="['storagetype', {
|
||||||
|
initialValue: storageType
|
||||||
|
}]"
|
||||||
|
buttonStyle="solid"
|
||||||
|
@change="selected => { handleStorageTypeChange(selected.target.value) }">
|
||||||
|
<a-radio-button value="shared">
|
||||||
|
{{ $t('label.shared') }}
|
||||||
|
</a-radio-button>
|
||||||
|
<a-radio-button value="local">
|
||||||
|
{{ $t('label.local') }}
|
||||||
|
</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.provisioningtype')" :tooltip="apiParams.provisioningtype.description"/>
|
||||||
|
<a-radio-group
|
||||||
|
v-decorator="['provisioningtype', {
|
||||||
|
initialValue: provisioningType
|
||||||
|
}]"
|
||||||
|
buttonStyle="solid"
|
||||||
|
@change="selected => { handleProvisioningTypeChange(selected.target.value) }">
|
||||||
|
<a-radio-button value="thin">
|
||||||
|
{{ $t('label.provisioningtype.thin') }}
|
||||||
|
</a-radio-button>
|
||||||
|
<a-radio-button value="sparse">
|
||||||
|
{{ $t('label.provisioningtype.sparse') }}
|
||||||
|
</a-radio-button>
|
||||||
|
<a-radio-button value="fat">
|
||||||
|
{{ $t('label.provisioningtype.fat') }}
|
||||||
|
</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.cachemode')" :tooltip="apiParams.cachemode.description"/>
|
||||||
|
<a-radio-group
|
||||||
|
v-decorator="['cachemode', {
|
||||||
|
initialValue: cacheMode
|
||||||
|
}]"
|
||||||
|
buttonStyle="solid"
|
||||||
|
@change="selected => { handleCacheModeChange(selected.target.value) }">
|
||||||
|
<a-radio-button value="none">
|
||||||
|
{{ $t('label.nodiskcache') }}
|
||||||
|
</a-radio-button>
|
||||||
|
<a-radio-button value="writeback">
|
||||||
|
{{ $t('label.writeback') }}
|
||||||
|
</a-radio-button>
|
||||||
|
<a-radio-button value="writethrough">
|
||||||
|
{{ $t('label.writethrough') }}
|
||||||
|
</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item :label="$t('label.qostype')">
|
||||||
|
<a-radio-group
|
||||||
|
v-decorator="['qostype', {
|
||||||
|
initialValue: qosType
|
||||||
|
}]"
|
||||||
|
buttonStyle="solid"
|
||||||
|
@change="selected => { handleQosTypeChange(selected.target.value) }">
|
||||||
|
<a-radio-button value="">
|
||||||
|
{{ $t('label.none') }}
|
||||||
|
</a-radio-button>
|
||||||
|
<a-radio-button value="hypervisor">
|
||||||
|
{{ $t('label.hypervisor') }}
|
||||||
|
</a-radio-button>
|
||||||
|
<a-radio-button value="storage">
|
||||||
|
{{ $t('label.storage') }}
|
||||||
|
</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
<a-row :gutter="12" v-if="qosType === 'hypervisor'">
|
||||||
|
<a-col :md="12" :lg="12">
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.diskbytesreadrate')" :tooltip="apiParams.bytesreadrate.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['diskbytesreadrate', { rules: [naturalNumberRule] }]"
|
||||||
|
:placeholder="apiParams.bytesreadrate.description"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :md="12" :lg="12">
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.diskbyteswriterate')" :tooltip="apiParams.byteswriterate.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['diskbyteswriterate', { rules: [naturalNumberRule] }]"
|
||||||
|
:placeholder="apiParams.byteswriterate.description"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<a-row :gutter="12" v-if="qosType === 'hypervisor'">
|
||||||
|
<a-col :md="12" :lg="12">
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.diskiopsreadrate')" :tooltip="apiParams.iopsreadrate.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['diskiopsreadrate', { rules: [naturalNumberRule] }]"
|
||||||
|
:placeholder="apiParams.iopsreadrate.description"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :md="12" :lg="12">
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.diskiopswriterate')" :tooltip="apiParams.iopswriterate.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['diskiopswriterate', { rules: [naturalNumberRule] }]"
|
||||||
|
:placeholder="apiParams.iopswriterate.description"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<a-form-item v-if="!isSystem && qosType === 'storage'">
|
||||||
|
<tooltip-label slot="label" :title="$t('label.iscustomizeddiskiops')" :tooltip="apiParams.customizediops.description"/>
|
||||||
|
<a-switch v-decorator="['iscustomizeddiskiops', {initialValue: isCustomizedDiskIops}]" :defaultChecked="isCustomizedDiskIops" @change="val => { isCustomizedDiskIops = val }" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-row :gutter="12" v-if="qosType === 'storage' && !isCustomizedDiskIops">
|
||||||
|
<a-col :md="12" :lg="12">
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.diskiopsmin')" :tooltip="apiParams.miniops.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['diskiopsmin', { rules: [naturalNumberRule] }]"
|
||||||
|
:placeholder="apiParams.miniops.description"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :md="12" :lg="12">
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.diskiopsmax')" :tooltip="apiParams.maxiops.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['diskiopsmax', { rules: [naturalNumberRule] }]"
|
||||||
|
:placeholder="apiParams.maxiops.description"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<a-form-item v-if="!isSystem && qosType === 'storage'">
|
||||||
|
<tooltip-label slot="label" :title="$t('label.hypervisorsnapshotreserve')" :tooltip="apiParams.hypervisorsnapshotreserve.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['hypervisorsnapshotreserve', { rules: [naturalNumberRule] }]"
|
||||||
|
:placeholder="apiParams.hypervisorsnapshotreserve.description"/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-row :gutter="12">
|
||||||
|
<a-col :md="12" :lg="12">
|
||||||
|
<a-form-item v-if="apiParams.rootdisksize">
|
||||||
|
<tooltip-label slot="label" :title="$t('label.root.disk.size')" :tooltip="apiParams.rootdisksize.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['rootdisksize', { rules: [naturalNumberRule] }]"
|
||||||
|
:placeholder="apiParams.rootdisksize.description"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :md="12" :lg="12">
|
||||||
|
<a-form-item v-if="isAdmin()">
|
||||||
|
<tooltip-label slot="label" :title="$t('label.storagetags')" :tooltip="apiParams.tags.description"/>
|
||||||
|
<a-select
|
||||||
|
mode="tags"
|
||||||
|
v-decorator="['storagetags', {}]"
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="children"
|
||||||
|
:filterOption="(input, option) => {
|
||||||
|
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}"
|
||||||
|
:loading="storageTagLoading"
|
||||||
|
:placeholder="apiParams.tags.description"
|
||||||
|
v-if="isAdmin()">
|
||||||
|
<a-select-option v-for="opt in storageTags" :key="opt">
|
||||||
|
{{ opt }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</span>
|
||||||
|
<span v-if="!computeonly">
|
||||||
|
<a-form-item>
|
||||||
|
<a-button type="primary" @click="addDiskOffering()"> {{ $t('label.add.disk.offering') }} </a-button>
|
||||||
|
<a-modal
|
||||||
|
:visible="showDiskOfferingModal"
|
||||||
|
:title="$t('label.add.disk.offering')"
|
||||||
|
:footer="null"
|
||||||
|
centered
|
||||||
|
:closable="true"
|
||||||
|
@cancel="closeDiskOfferingModal"
|
||||||
|
width="auto">
|
||||||
|
<add-disk-offering @close-action="closeDiskOfferingModal()" @publish-disk-offering-id="($event) => updateSelectedDiskOffering($event)"/>
|
||||||
|
</a-modal>
|
||||||
|
<br /><br />
|
||||||
|
<a-form-item :label="$t('label.disk.offerings')">
|
||||||
|
<a-select
|
||||||
|
v-decorator="['diskofferingid', {
|
||||||
|
initialValue: selectedDiskOfferingId,
|
||||||
|
rules: [{ required: true, message: `${this.$t('message.error.select')}` }]}]"
|
||||||
|
:loading="loading"
|
||||||
|
:placeholder="$t('label.diskoffering')">
|
||||||
|
<a-select-option
|
||||||
|
v-for="(offering, index) in diskOfferings"
|
||||||
|
:value="offering.id"
|
||||||
|
:key="index">
|
||||||
|
{{ offering.displaytext || offering.name }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form-item>
|
||||||
|
</span>
|
||||||
|
<a-form-item>
|
||||||
|
<span slot="label">
|
||||||
|
{{ $t('label.diskofferingstrictness') }}
|
||||||
|
<a-tooltip :title="apiParams.diskofferingstrictness.description">
|
||||||
|
<a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</span>
|
||||||
|
<a-switch v-decorator="['diskofferingstrictness', {initialValue: diskofferingstrictness}]" :checked="diskofferingstrictness" @change="val => { diskofferingstrictness = val }"/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-card>
|
||||||
</a-form>
|
</a-form>
|
||||||
<div :span="24" class="action-button">
|
<div :span="24" class="action-button">
|
||||||
<a-button @click="closeAction">{{ this.$t('label.cancel') }}</a-button>
|
<a-button @click="closeAction">{{ this.$t('label.cancel') }}</a-button>
|
||||||
@ -516,6 +566,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { api } from '@/api'
|
import { api } from '@/api'
|
||||||
|
import AddDiskOffering from '@/views/offering/AddDiskOffering'
|
||||||
import { isAdmin } from '@/role'
|
import { isAdmin } from '@/role'
|
||||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||||
@ -523,6 +574,7 @@ import TooltipLabel from '@/components/widgets/TooltipLabel'
|
|||||||
export default {
|
export default {
|
||||||
name: 'AddServiceOffering',
|
name: 'AddServiceOffering',
|
||||||
components: {
|
components: {
|
||||||
|
AddDiskOffering,
|
||||||
ResourceIcon,
|
ResourceIcon,
|
||||||
TooltipLabel
|
TooltipLabel
|
||||||
},
|
},
|
||||||
@ -568,6 +620,7 @@ export default {
|
|||||||
plannerModeVisible: false,
|
plannerModeVisible: false,
|
||||||
plannerMode: '',
|
plannerMode: '',
|
||||||
selectedGpu: '',
|
selectedGpu: '',
|
||||||
|
showDiskOfferingModal: false,
|
||||||
gpuTypes: [
|
gpuTypes: [
|
||||||
{
|
{
|
||||||
value: '',
|
value: '',
|
||||||
@ -588,7 +641,12 @@ export default {
|
|||||||
vGpuVisible: false,
|
vGpuVisible: false,
|
||||||
vGpuTypes: [],
|
vGpuTypes: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
dynamicscalingenabled: true
|
dynamicscalingenabled: true,
|
||||||
|
diskofferingstrictness: false,
|
||||||
|
computeonly: true,
|
||||||
|
diskOfferingLoading: false,
|
||||||
|
diskOfferings: [],
|
||||||
|
selectedDiskOfferingId: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeCreate () {
|
beforeCreate () {
|
||||||
@ -620,6 +678,32 @@ export default {
|
|||||||
this.fetchStorageTagData()
|
this.fetchStorageTagData()
|
||||||
this.fetchDeploymentPlannerData()
|
this.fetchDeploymentPlannerData()
|
||||||
}
|
}
|
||||||
|
this.fetchDiskOfferings()
|
||||||
|
},
|
||||||
|
addDiskOffering () {
|
||||||
|
this.showDiskOfferingModal = true
|
||||||
|
},
|
||||||
|
fetchDiskOfferings () {
|
||||||
|
this.diskOfferingLoading = true
|
||||||
|
api('listDiskOfferings', {
|
||||||
|
listall: true
|
||||||
|
}).then(json => {
|
||||||
|
this.diskOfferings = json.listdiskofferingsresponse.diskoffering || []
|
||||||
|
if (this.selectedDiskOfferingId === '') {
|
||||||
|
this.selectedDiskOfferingId = this.diskOfferings[0].id || ''
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.diskOfferingLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
updateSelectedDiskOffering (id) {
|
||||||
|
if (id) {
|
||||||
|
this.selectedDiskOfferingId = id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closeDiskOfferingModal () {
|
||||||
|
this.fetchDiskOfferings()
|
||||||
|
this.showDiskOfferingModal = false
|
||||||
},
|
},
|
||||||
isAdmin () {
|
isAdmin () {
|
||||||
return isAdmin()
|
return isAdmin()
|
||||||
@ -751,7 +835,11 @@ export default {
|
|||||||
customized: values.offeringtype !== 'fixed',
|
customized: values.offeringtype !== 'fixed',
|
||||||
offerha: values.offerha === true,
|
offerha: values.offerha === true,
|
||||||
limitcpuuse: values.limitcpuuse === true,
|
limitcpuuse: values.limitcpuuse === true,
|
||||||
dynamicscalingenabled: values.dynamicscalingenabled
|
dynamicscalingenabled: values.dynamicscalingenabled,
|
||||||
|
diskofferingstrictness: values.diskofferingstrictness
|
||||||
|
}
|
||||||
|
if (values.diskofferingid) {
|
||||||
|
params.diskofferingid = values.diskofferingid
|
||||||
}
|
}
|
||||||
|
|
||||||
// custom fields (begin)
|
// custom fields (begin)
|
||||||
|
|||||||
@ -74,6 +74,15 @@
|
|||||||
</a-radio-button>
|
</a-radio-button>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<span slot="label">
|
||||||
|
{{ $t('label.disksizestrictness') }}
|
||||||
|
<a-tooltip :title="apiParams.disksizestrictness.description">
|
||||||
|
<a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</span>
|
||||||
|
<a-switch v-decorator="['disksizestrictness', { initialValue: this.disksizestrictness }]" :checked="this.disksizestrictness" @change="val => { this.disksizestrictness = val }" />
|
||||||
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<tooltip-label slot="label" :title="$t('label.customdisksize')" :tooltip="apiParams.customized.description"/>
|
<tooltip-label slot="label" :title="$t('label.customdisksize')" :tooltip="apiParams.customized.description"/>
|
||||||
<a-switch v-decorator="['customdisksize', { initialValue: isCustomDiskSize }]" :checked="isCustomDiskSize" @change="val => { isCustomDiskSize = val }" />
|
<a-switch v-decorator="['customdisksize', { initialValue: isCustomDiskSize }]" :checked="isCustomDiskSize" @change="val => { isCustomDiskSize = val }" />
|
||||||
@ -379,7 +388,8 @@ export default {
|
|||||||
domainLoading: false,
|
domainLoading: false,
|
||||||
zones: [],
|
zones: [],
|
||||||
zoneLoading: false,
|
zoneLoading: false,
|
||||||
loading: false
|
loading: false,
|
||||||
|
disksizestrictness: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeCreate () {
|
beforeCreate () {
|
||||||
@ -501,7 +511,8 @@ export default {
|
|||||||
storageType: values.storagetype,
|
storageType: values.storagetype,
|
||||||
cacheMode: values.writecachetype,
|
cacheMode: values.writecachetype,
|
||||||
provisioningType: values.provisioningtype,
|
provisioningType: values.provisioningtype,
|
||||||
customized: values.customdisksize
|
customized: values.customdisksize,
|
||||||
|
disksizestrictness: values.disksizestrictness
|
||||||
}
|
}
|
||||||
if (values.customdisksize !== true) {
|
if (values.customdisksize !== true) {
|
||||||
params.disksize = values.disksize
|
params.disksize = values.disksize
|
||||||
@ -568,6 +579,7 @@ export default {
|
|||||||
params.storagepolicy = values.storagepolicy
|
params.storagepolicy = values.storagepolicy
|
||||||
}
|
}
|
||||||
api('createDiskOffering', params).then(json => {
|
api('createDiskOffering', params).then(json => {
|
||||||
|
this.$emit('publish-disk-offering-id', json?.creatediskofferingresponse?.diskoffering?.id)
|
||||||
this.$message.success(`${this.$t('message.disk.offering.created')} ${values.name}`)
|
this.$message.success(`${this.$t('message.disk.offering.created')} ${values.name}`)
|
||||||
this.$emit('refresh-data')
|
this.$emit('refresh-data')
|
||||||
this.closeAction()
|
this.closeAction()
|
||||||
|
|||||||
246
ui/src/views/storage/ChangeOfferingForVolume.vue
Normal file
246
ui/src/views/storage/ChangeOfferingForVolume.vue
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
// Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
// or more contributor license agreements. See the NOTICE file
|
||||||
|
// distributed with this work for additional information
|
||||||
|
// regarding copyright ownership. The ASF licenses this file
|
||||||
|
// to you under the Apache License, Version 2.0 (the
|
||||||
|
// "License"); you may not use this file except in compliance
|
||||||
|
// with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing,
|
||||||
|
// software distributed under the License is distributed on an
|
||||||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
// KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations
|
||||||
|
// under the License.
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-form
|
||||||
|
class="form"
|
||||||
|
:form="form"
|
||||||
|
@submit="submitChangeOfferingForVolume"
|
||||||
|
v-ctrl-enter="submitChangeOfferingForVolume"
|
||||||
|
layout="vertical">
|
||||||
|
<a-form-item>
|
||||||
|
<a-alert type="warning">
|
||||||
|
<span slot="message" v-html="$t('message.confirm.change.offering.for.volume')" />
|
||||||
|
</a-alert>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.diskofferingid')" :tooltip="apiParams.diskofferingid.description || 'Disk Offering'"/>
|
||||||
|
<a-select
|
||||||
|
v-decorator="['diskofferingid', {
|
||||||
|
initialValue: selectedDiskOfferingId,
|
||||||
|
rules: [{ required: true, message: $t('message.error.select') }]}]"
|
||||||
|
:loading="loading"
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="children"
|
||||||
|
:filterOption="(input, option) => {
|
||||||
|
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}"
|
||||||
|
@change="id => onChangeDiskOffering(id)">
|
||||||
|
<a-select-option
|
||||||
|
v-for="(offering, index) in diskOfferings"
|
||||||
|
:value="offering.id"
|
||||||
|
:key="index">
|
||||||
|
{{ offering.displaytext || offering.name }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<span v-if="customDiskOffering">
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.sizegb')" :tooltip="apiParams.size.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['size', {
|
||||||
|
rules: [{ required: true, message: $t('message.error.custom.disk.size') }]}]"
|
||||||
|
:placeholder="$t('label.disksize')"/>
|
||||||
|
</a-form-item>
|
||||||
|
</span>
|
||||||
|
<span v-if="isCustomizedDiskIOps">
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.miniops')" :tooltip="apiParams.miniops.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['miniops', {
|
||||||
|
rules: [{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (value && (isNaN(value) || value <= 0)) {
|
||||||
|
callback(this.$t('message.error.number'))
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}]"
|
||||||
|
:placeholder="this.$t('label.miniops')"/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<tooltip-label slot="label" :title="$t('label.maxiops')" :tooltip="apiParams.maxiops.description"/>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['maxiops', {
|
||||||
|
rules: [{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (value && (isNaN(value) || value <= 0)) {
|
||||||
|
callback(this.$t('message.error.number'))
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}]"
|
||||||
|
:placeholder="this.$t('label.maxiops')"/>
|
||||||
|
</a-form-item>
|
||||||
|
</span>
|
||||||
|
<a-form-item :label="$t('label.automigrate.volume')">
|
||||||
|
<tooltip-label slot="label" :title="$t('label.automigrate.volume')" :tooltip="apiParams.automigrate.description"/>
|
||||||
|
<a-switch
|
||||||
|
v-decorator="['autoMigrate']"
|
||||||
|
:checked="autoMigrate"
|
||||||
|
@change="val => { autoMigrate = val }"/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item :label="$t('label.shrinkok')">
|
||||||
|
<a-switch
|
||||||
|
v-decorator="['shrinkOk']"
|
||||||
|
:checked="shrinkOk"
|
||||||
|
@change="val => { shrinkOk = val }"/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-divider />
|
||||||
|
<div class="actions">
|
||||||
|
<a-button @click="closeModal">
|
||||||
|
{{ $t('label.cancel') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button type="primary" @click="submitChangeOfferingForVolume">
|
||||||
|
{{ $t('label.ok') }}
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { api } from '@/api'
|
||||||
|
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ChangeOfferingForVolume',
|
||||||
|
props: {
|
||||||
|
resource: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
TooltipLabel
|
||||||
|
},
|
||||||
|
inject: ['parentFetchData'],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
diskOfferings: [],
|
||||||
|
autoMigrate: true,
|
||||||
|
shrinkOk: false,
|
||||||
|
selectedDiskOfferingId: null,
|
||||||
|
size: null,
|
||||||
|
customDiskOffering: false,
|
||||||
|
loading: false,
|
||||||
|
isCustomizedDiskIOps: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeCreate () {
|
||||||
|
this.form = this.$form.createForm(this)
|
||||||
|
this.apiParams = this.$getApiParams('changeOfferingForVolume')
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.fetchDiskOfferings()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchDiskOfferings () {
|
||||||
|
api('listDiskOfferings', {
|
||||||
|
volumeid: this.resource.id,
|
||||||
|
listall: true
|
||||||
|
}).then(response => {
|
||||||
|
this.diskOfferings = response.listdiskofferingsresponse.diskoffering
|
||||||
|
if (this.diskOfferings) {
|
||||||
|
this.selectedDiskOfferingId = this.diskOfferings[0].id
|
||||||
|
this.customDiskOffering = this.diskOfferings[0].iscustomized || false
|
||||||
|
this.isCustomizedDiskIOps = this.diskOfferings[0]?.iscustomizediops || false
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
this.$notifyError(error)
|
||||||
|
this.closeModal()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
closeModal () {
|
||||||
|
this.$parent.$parent.close()
|
||||||
|
},
|
||||||
|
submitChangeOfferingForVolume () {
|
||||||
|
if (this.loading) return
|
||||||
|
this.form.validateFields((err, values) => {
|
||||||
|
if (err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.loading = true
|
||||||
|
const params = {}
|
||||||
|
params.diskofferingid = values.diskofferingid
|
||||||
|
params.id = this.resource.id
|
||||||
|
params.automigrate = values.autoMigrate
|
||||||
|
params.shrinkok = values.shrinkOk
|
||||||
|
if (values.size) {
|
||||||
|
params.size = values.size
|
||||||
|
}
|
||||||
|
if (values.miniops) {
|
||||||
|
params.miniops = values.miniops
|
||||||
|
}
|
||||||
|
if (values.maxiops) {
|
||||||
|
params.maxiops = values.maxiops
|
||||||
|
}
|
||||||
|
api('changeOfferingForVolume', params).then(response => {
|
||||||
|
this.$pollJob({
|
||||||
|
jobId: response.changeofferingforvolumeresponse.jobid,
|
||||||
|
successMessage: this.$t('message.change.offering.for.volume'),
|
||||||
|
successMethod: () => {
|
||||||
|
this.parentFetchData()
|
||||||
|
},
|
||||||
|
errorMessage: this.$t('message.change.offering.for.volume.failed'),
|
||||||
|
errorMethod: () => {
|
||||||
|
this.parentFetchData()
|
||||||
|
},
|
||||||
|
loadingMessage: this.$t('message.change.offering.for.volume.processing'),
|
||||||
|
catchMessage: this.$t('error.fetching.async.job.result'),
|
||||||
|
catchMethod: () => {
|
||||||
|
this.parentFetchData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.closeModal()
|
||||||
|
this.parentFetchData()
|
||||||
|
}).catch(error => {
|
||||||
|
this.$notifyError(error)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onChangeDiskOffering (id) {
|
||||||
|
const offering = this.diskOfferings.filter(x => x.id === id)
|
||||||
|
this.customDiskOffering = offering[0]?.iscustomized || false
|
||||||
|
this.isCustomizedDiskIOps = offering[0]?.iscustomizediops || false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.change-offering-for-volume-container {
|
||||||
|
width: 85vw;
|
||||||
|
|
||||||
|
@media (min-width: 760px) {
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 20px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user