mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-2987 Ensure XStools to be there in template inorder to enable dynamic scaling of vm
CLOUDSTACK-3042 - handle Scaling up of vm memory/CPU based on the presence of XS tools in the template This also takes care of updation of VM after XS tools are installed in the vm and set memory values accordingly to support dynamic scaling after stop start of VM Signed-off-by: Abhinandan Prateek <aprateek@apache.org>
This commit is contained in:
parent
e420c3be8c
commit
7b6b8d7a07
|
|
@ -92,4 +92,6 @@ public interface VirtualMachineTemplate extends ControlledEntity, Identity, Inte
|
|||
|
||||
String getTemplateTag();
|
||||
Map getDetails();
|
||||
|
||||
Boolean isDynamicallyScalable();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,6 +158,8 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
|
|||
}
|
||||
}
|
||||
|
||||
public static final String IsDynamicScalingEnabled = "enable.dynamic.scaling";
|
||||
|
||||
public enum Event {
|
||||
CreateRequested,
|
||||
StartRequested,
|
||||
|
|
|
|||
|
|
@ -509,6 +509,7 @@ public class ApiConstants {
|
|||
public static final String DEPLOYMENT_PLANNER = "deploymentplanner";
|
||||
public static final String ACL_ID = "aclid";
|
||||
public static final String NUMBER = "number";
|
||||
public static final String IS_DYNAMICALLY_SCALABLE = "isdynamicallyscalable";
|
||||
|
||||
public enum HostDetails {
|
||||
all, capacity, events, stats, min;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
|
|||
@Parameter(name=ApiConstants.SORT_KEY, type=CommandType.INTEGER, description="sort key of the template, integer")
|
||||
private Integer sortKey;
|
||||
|
||||
@Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE, type = CommandType.BOOLEAN, description = "true if template/ISO contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
|
||||
private Boolean isDynamicallyScalable;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -89,4 +92,8 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
|
|||
public Integer getSortKey() {
|
||||
return sortKey;
|
||||
}
|
||||
|
||||
public Boolean isDynamicallyScalable() {
|
||||
return isDynamicallyScalable;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,9 @@ public class RegisterIsoCmd extends BaseCmd {
|
|||
description="Image store uuid")
|
||||
private String imageStoreUuid;
|
||||
|
||||
@Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE, type = CommandType.BOOLEAN, description = "true if iso contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
|
||||
protected Boolean isDynamicallyScalable;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -149,6 +152,10 @@ public class RegisterIsoCmd extends BaseCmd {
|
|||
return this.imageStoreUuid;
|
||||
}
|
||||
|
||||
public Boolean isDynamicallyScalable() {
|
||||
return isDynamicallyScalable == null ? false : isDynamicallyScalable;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -118,6 +118,9 @@ public class RegisterTemplateCmd extends BaseCmd {
|
|||
@Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="Template details in key/value pairs.")
|
||||
protected Map details;
|
||||
|
||||
@Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE, type = CommandType.BOOLEAN, description = "true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
|
||||
protected Boolean isDynamicallyScalable;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -208,6 +211,10 @@ public class RegisterTemplateCmd extends BaseCmd {
|
|||
return params;
|
||||
}
|
||||
|
||||
public Boolean isDynamicallyScalable() {
|
||||
return isDynamicallyScalable == null ? false : isDynamicallyScalable;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@ public class UpdateVMCmd extends BaseCmd{
|
|||
@Parameter(name=ApiConstants.DISPLAY_VM, type=CommandType.BOOLEAN, description="an optional field, whether to the display the vm to the end user or not.")
|
||||
private Boolean displayVm;
|
||||
|
||||
@Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE, type = CommandType.BOOLEAN, description = "true if VM contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
|
||||
protected Boolean isDynamicallyScalable;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -95,6 +98,10 @@ public class UpdateVMCmd extends BaseCmd{
|
|||
return displayVm;
|
||||
}
|
||||
|
||||
public Boolean isDynamicallyScalable() {
|
||||
return isDynamicallyScalable;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -139,6 +139,9 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe
|
|||
@SerializedName(ApiConstants.SSHKEY_ENABLED) @Param(description="true if template is sshkey enabled, false otherwise")
|
||||
private Boolean sshKeyEnabled;
|
||||
|
||||
@SerializedName(ApiConstants.IS_DYNAMICALLY_SCALABLE) @Param(description="true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
|
||||
private Boolean isDynamicallyScalable;
|
||||
|
||||
@Override
|
||||
public String getObjectId() {
|
||||
return this.getId();
|
||||
|
|
@ -296,4 +299,8 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe
|
|||
this.sshKeyEnabled = sshKeyEnabled;
|
||||
}
|
||||
|
||||
public void setDynamicallyScalable(boolean isDynamicallyScalable) {
|
||||
this.isDynamicallyScalable = isDynamicallyScalable;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,6 +189,9 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp
|
|||
@SerializedName(ApiConstants.DISPLAY_VM) @Param(description="an optional field whether to the display the vm to the end user or not.")
|
||||
private Boolean displayVm;
|
||||
|
||||
@SerializedName(ApiConstants.IS_DYNAMICALLY_SCALABLE) @Param(description="true if vm contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory.")
|
||||
private Boolean isDynamicallyScalable;
|
||||
|
||||
public UserVmResponse(){
|
||||
securityGroupList = new LinkedHashSet<SecurityGroupResponse>();
|
||||
nics = new LinkedHashSet<NicResponse>();
|
||||
|
|
@ -432,4 +435,8 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp
|
|||
this.affinityGroupList.add(affinityGroup);
|
||||
}
|
||||
|
||||
public void setDynamicallyScalable(boolean isDynamicallyScalable) {
|
||||
this.isDynamicallyScalable = isDynamicallyScalable;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ public class ScaleVmCommand extends Command {
|
|||
}
|
||||
|
||||
public ScaleVmCommand(String vmName, int cpus,
|
||||
Integer minSpeed, Integer maxSpeed, long minRam, long maxRam, boolean limitCpuUse) {
|
||||
Integer minSpeed, Integer maxSpeed, long minRam, long maxRam, boolean limitCpuUse, boolean isDynamicallyScalable) {
|
||||
super();
|
||||
this.vmName = vmName;
|
||||
this.cpus = cpus;
|
||||
|
|
@ -50,6 +50,7 @@ public class ScaleVmCommand extends Command {
|
|||
this.minRam = minRam;
|
||||
this.maxRam = maxRam;
|
||||
this.vm = new VirtualMachineTO(1L, vmName, null, cpus, minSpeed, maxSpeed, minRam, maxRam, null, null, false, limitCpuUse, null);
|
||||
vm.setEnableDynamicallyScaleVm(isDynamicallyScalable);
|
||||
/*vm.setName(vmName);
|
||||
vm.setCpus(cpus);
|
||||
vm.setRam(minRam, maxRam);*/
|
||||
|
|
|
|||
|
|
@ -148,6 +148,9 @@ public class VMTemplateVO implements VirtualMachineTemplate, StateObject<Templat
|
|||
@Transient
|
||||
Map details;
|
||||
|
||||
@Column(name = "dynamically_scalable")
|
||||
protected boolean dynamicallyScalable;
|
||||
|
||||
@Override
|
||||
public String getUniqueName() {
|
||||
return uniqueName;
|
||||
|
|
@ -171,12 +174,13 @@ public class VMTemplateVO implements VirtualMachineTemplate, StateObject<Templat
|
|||
this.state = TemplateState.Allocated;
|
||||
}
|
||||
|
||||
public VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hyperType, String templateTag, Map details, boolean sshKeyEnabled) {
|
||||
public VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hyperType, String templateTag, Map details, boolean sshKeyEnabled, boolean isDynamicallyScalable) {
|
||||
this(id, name, format, isPublic, featured, isExtractable, type, url, requiresHvm, bits, accountId, cksum, displayText, enablePassword, guestOSId, bootable, hyperType, details);
|
||||
this.templateTag = templateTag;
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.state = TemplateState.Allocated;
|
||||
this.enableSshKey = sshKeyEnabled;
|
||||
this.dynamicallyScalable = isDynamicallyScalable;
|
||||
}
|
||||
|
||||
public VMTemplateVO(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, TemplateType type, String url, Date created, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable, HypervisorType hyperType) {
|
||||
|
|
@ -530,5 +534,13 @@ public class VMTemplateVO implements VirtualMachineTemplate, StateObject<Templat
|
|||
this.updated = updated;
|
||||
}
|
||||
|
||||
public void setDynamicallyScalable(boolean dynamicallyScalable) {
|
||||
this.dynamicallyScalable = dynamicallyScalable;
|
||||
}
|
||||
|
||||
public Boolean isDynamicallyScalable() {
|
||||
return this.dynamicallyScalable;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
|
|||
@Enumerated(value=EnumType.STRING)
|
||||
protected HypervisorType hypervisorType;
|
||||
|
||||
|
||||
/*
|
||||
@Column(name="tags")
|
||||
protected String tags;
|
||||
|
|
|
|||
|
|
@ -101,6 +101,12 @@ public class TemplateEntityImpl implements TemplateEntity {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isDynamicallyScalable() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addDetail(String name, String value) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import com.cloud.storage.dao.GuestOSDao;
|
|||
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VirtualMachineProfileImpl;
|
||||
|
||||
@Local(value=HypervisorGuru.class)
|
||||
public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru {
|
||||
|
|
|
|||
|
|
@ -680,6 +680,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
throw new CloudRuntimeException("Unable to scale the vm: " + vmName + " as DMC - Dynamic memory control is not enabled for the XenServer:" + _host.uuid + " ,check your license and hypervisor version.");
|
||||
}
|
||||
|
||||
if(!vmSpec.isEnableDynamicallyScaleVm()) {
|
||||
throw new CloudRuntimeException("Unable to Scale the vm: " + vmName + "as vm does not have xs tools to support dynamic scaling");
|
||||
}
|
||||
|
||||
// stop vm which is running on this host or is in halted state
|
||||
Iterator<VM> iter = vms.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ public class XenServer56FP1Resource extends XenServer56Resource {
|
|||
vmr.actionsAfterCrash = Types.OnCrashBehaviour.DESTROY;
|
||||
vmr.actionsAfterShutdown = Types.OnNormalExit.DESTROY;
|
||||
|
||||
Map<String, String> details = vmSpec.getDetails();
|
||||
if (isDmcEnabled(conn, host) && vmSpec.isEnableDynamicallyScaleVm()) {
|
||||
//scaling is allowed
|
||||
vmr.memoryStaticMin = mem_128m; //128MB
|
||||
|
|
|
|||
|
|
@ -1306,6 +1306,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
response.setTags(tagResponses);
|
||||
|
||||
response.setObjectName("iso");
|
||||
response.setDynamicallyScalable(result.isDynamicallyScalable());
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
@ -1520,6 +1521,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
templateResponse.setTags(tagResponses);
|
||||
|
||||
templateResponse.setObjectName("template");
|
||||
templateResponse.setDynamicallyScalable(template.isDynamicallyScalable());
|
||||
responses.add(templateResponse);
|
||||
return responses;
|
||||
}
|
||||
|
|
@ -1545,6 +1547,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
isoResponse.setChecksum(iso.getChecksum());
|
||||
isoResponse.setPasswordEnabled(false);
|
||||
isoResponse.setDetails(iso.getDetails());
|
||||
isoResponse.setDynamicallyScalable(iso.isDynamicallyScalable());
|
||||
|
||||
// add account ID and name
|
||||
Account owner = ApiDBUtils.findAccountById(iso.getAccountId());
|
||||
|
|
@ -1721,6 +1724,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
isoResponse.setPublic(iso.isPublicTemplate());
|
||||
isoResponse.setChecksum(iso.getChecksum());
|
||||
isoResponse.setDetails(iso.getDetails());
|
||||
isoResponse.setDynamicallyScalable(iso.isDynamicallyScalable());
|
||||
|
||||
// TODO: implement
|
||||
GuestOS os = ApiDBUtils.findGuestOSById(iso.getGuestOSId());
|
||||
|
|
|
|||
|
|
@ -249,6 +249,11 @@ public class UserVmJoinDaoImpl extends GenericDaoBase<UserVmJoinVO, Long> implem
|
|||
}
|
||||
|
||||
userVmResponse.setObjectName(objectName);
|
||||
if (userVm.isDynamicallyScalable() == null) {
|
||||
userVmResponse.setDynamicallyScalable(false);
|
||||
} else {
|
||||
userVmResponse.setDynamicallyScalable(userVm.isDynamicallyScalable());
|
||||
}
|
||||
|
||||
return userVmResponse;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -391,6 +391,9 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity {
|
|||
@Column(name="uuid")
|
||||
private String uuid;
|
||||
|
||||
@Column(name="dynamically_scalable")
|
||||
private boolean isDynamicallyScalable;
|
||||
|
||||
public UserVmJoinVO() {
|
||||
}
|
||||
|
||||
|
|
@ -1717,5 +1720,13 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity {
|
|||
return affinityGroupDescription;
|
||||
}
|
||||
|
||||
public Boolean isDynamicallyScalable() {
|
||||
return isDynamicallyScalable;
|
||||
}
|
||||
|
||||
public void setDynamicallyScalable(boolean isDynamicallyScalable) {
|
||||
this.isDynamicallyScalable = isDynamicallyScalable;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ import com.cloud.configuration.Config;
|
|||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.server.ConfigurationServer;
|
||||
import com.cloud.storage.dao.VMTemplateDetailsDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.NicVO;
|
||||
|
|
@ -37,6 +39,7 @@ import com.cloud.vm.VirtualMachine;
|
|||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.NicSecondaryIpDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru {
|
||||
|
|
@ -47,7 +50,6 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
|||
@Inject NicSecondaryIpDao _nicSecIpDao;
|
||||
@Inject ConfigurationServer _configServer;
|
||||
|
||||
|
||||
protected HypervisorGuruBase() {
|
||||
super();
|
||||
}
|
||||
|
|
@ -120,15 +122,18 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
|||
if(detailsInVm != null) {
|
||||
details.putAll(detailsInVm);
|
||||
}
|
||||
if (details.get(VirtualMachine.IsDynamicScalingEnabled) == null || details.get(VirtualMachine.IsDynamicScalingEnabled).isEmpty()) {
|
||||
to. setEnableDynamicallyScaleVm(false);
|
||||
} else {
|
||||
// check if XStools/VMWare tools are present in the VM and dynamic scaling feature is enabled (per zone/global)
|
||||
to.setEnableDynamicallyScaleVm(details.get(VirtualMachine.IsDynamicScalingEnabled).equals("true") && Boolean.parseBoolean(_configServer.getConfigValue(Config.EnableDynamicallyScaleVm.key(), Config.ConfigurationParameterScope.zone.toString(), vm.getDataCenterId())));
|
||||
}
|
||||
to.setDetails(details);
|
||||
|
||||
// Workaround to make sure the TO has the UUID we need for Niciri integration
|
||||
VMInstanceVO vmInstance = _virtualMachineDao.findById(to.getId());
|
||||
to.setUuid(vmInstance.getUuid());
|
||||
|
||||
//
|
||||
to.setEnableDynamicallyScaleVm(Boolean.parseBoolean(_configServer.getConfigValue(Config.EnableDynamicallyScaleVm.key(), Config.ConfigurationParameterScope.zone.toString(), vm.getDataCenterId())));
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1877,6 +1877,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
Boolean passwordEnabled = cmd.isPasswordEnabled();
|
||||
Boolean bootable = cmd.isBootable();
|
||||
Integer sortKey = cmd.getSortKey();
|
||||
Boolean isDynamicallyScalable = cmd.isDynamicallyScalable();
|
||||
Account account = UserContext.current().getCaller();
|
||||
|
||||
// verify that template exists
|
||||
|
|
@ -1898,7 +1899,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
_accountMgr.checkAccess(account, AccessType.ModifyEntry, true, template);
|
||||
|
||||
boolean updateNeeded = !(name == null && displayText == null && format == null && guestOSId == null && passwordEnabled == null
|
||||
&& bootable == null && sortKey == null);
|
||||
&& bootable == null && sortKey == null && isDynamicallyScalable == null);
|
||||
if (!updateNeeded) {
|
||||
return template;
|
||||
}
|
||||
|
|
@ -1947,6 +1948,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
template.setBootable(bootable);
|
||||
}
|
||||
|
||||
if (isDynamicallyScalable != null) {
|
||||
template.setDynamicallyScalable(isDynamicallyScalable);
|
||||
}
|
||||
|
||||
_templateDao.update(id, template);
|
||||
|
||||
return _templateDao.findById(id);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ public class TemplateProfile {
|
|||
String templateTag;
|
||||
Long imageStoreId;
|
||||
Map details;
|
||||
Boolean isDynamicallyScalable;
|
||||
|
||||
public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm,
|
||||
String url, Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId,
|
||||
|
|
@ -84,11 +85,12 @@ public class TemplateProfile {
|
|||
public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm,
|
||||
String url, Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId,
|
||||
HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, String templateTag, Map details, Boolean sshKeyEnabled,
|
||||
Long imageStoreId) {
|
||||
Long imageStoreId, Boolean isDynamicallyScalable) {
|
||||
this(templateId, userId, name, displayText, bits, passwordEnabled, requiresHvm, url, isPublic, featured, isExtractable, format, guestOsId, zoneId,
|
||||
hypervisorType, accountName, domainId, accountId, chksum, bootable, details, sshKeyEnabled);
|
||||
this.templateTag = templateTag;
|
||||
this.imageStoreId = imageStoreId;
|
||||
this.isDynamicallyScalable = isDynamicallyScalable;
|
||||
}
|
||||
|
||||
public Long getTemplateId() {
|
||||
|
|
@ -258,4 +260,12 @@ public class TemplateProfile {
|
|||
public Long getImageStoreId() {
|
||||
return this.imageStoreId;
|
||||
}
|
||||
|
||||
public Boolean IsDynamicallyScalable() {
|
||||
return this.isDynamicallyScalable;
|
||||
}
|
||||
|
||||
public void setScalabe(Boolean isDynamicallyScalabe) {
|
||||
this.isDynamicallyScalable = isDynamicallyScalabe;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,5 +69,5 @@ public interface TemplateAdapter extends Adapter {
|
|||
public TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits,
|
||||
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
|
||||
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType,
|
||||
String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshKeyEnabled, String imageStoreUuid) throws ResourceAllocationException;
|
||||
String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshKeyEnabled, String imageStoreUuid, Boolean isDynamicallyScalable) throws ResourceAllocationException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,14 +104,14 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
|
|||
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType,
|
||||
String accountName, Long domainId, String chksum, Boolean bootable, Map details) throws ResourceAllocationException {
|
||||
return prepare(isIso, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, format, guestOSId, zoneId, hypervisorType,
|
||||
chksum, bootable, null, null, details, false, null);
|
||||
chksum, bootable, null, null, details, false, null, false);
|
||||
}
|
||||
|
||||
public TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits,
|
||||
Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured,
|
||||
Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType,
|
||||
String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshkeyEnabled,
|
||||
String imageStoreUuid) throws ResourceAllocationException {
|
||||
String imageStoreUuid, Boolean isDynamicallyScalable) throws ResourceAllocationException {
|
||||
//Long accountId = null;
|
||||
// parameters verification
|
||||
|
||||
|
|
@ -226,7 +226,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
|
|||
Long id = _tmpltDao.getNextInSequence(Long.class, "id");
|
||||
UserContext.current().setEventDetails("Id: " +id+ " name: " + name);
|
||||
return new TemplateProfile(id, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic,
|
||||
featured, isExtractable, imgfmt, guestOSId, zoneId, hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, templateTag, details, sshkeyEnabled, imageStoreId);
|
||||
featured, isExtractable, imgfmt, guestOSId, zoneId, hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, templateTag, details, sshkeyEnabled, imageStoreId, isDynamicallyScalable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -241,7 +241,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
|
|||
return prepare(false, UserContext.current().getCallerUserId(), cmd.getTemplateName(), cmd.getDisplayText(),
|
||||
cmd.getBits(), cmd.isPasswordEnabled(), cmd.getRequiresHvm(), cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(),
|
||||
cmd.isExtractable(), cmd.getFormat(), cmd.getOsTypeId(), cmd.getZoneId(), HypervisorType.getType(cmd.getHypervisor()),
|
||||
cmd.getChecksum(), true, cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled(), cmd.getImageStoreUuid());
|
||||
cmd.getChecksum(), true, cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled(), cmd.getImageStoreUuid(), cmd.isDynamicallyScalable());
|
||||
}
|
||||
|
||||
public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException {
|
||||
|
|
@ -252,7 +252,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
|
|||
|
||||
return prepare(true, UserContext.current().getCallerUserId(), cmd.getIsoName(), cmd.getDisplayText(), 64, false,
|
||||
true, cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), ImageFormat.ISO.toString(), cmd.getOsTypeId(),
|
||||
cmd.getZoneId(), HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null, owner, null, false, cmd.getImageStoreUuid());
|
||||
cmd.getZoneId(), HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null, owner, null, false, cmd.getImageStoreUuid(), cmd.isDynamicallyScalable());
|
||||
}
|
||||
|
||||
protected VMTemplateVO persistTemplate(TemplateProfile profile) {
|
||||
|
|
@ -261,7 +261,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
|
|||
profile.getFeatured(), profile.getIsExtractable(), TemplateType.USER, profile.getUrl(), profile.getRequiresHVM(),
|
||||
profile.getBits(), profile.getAccountId(), profile.getCheckSum(), profile.getDisplayText(),
|
||||
profile.getPasswordEnabled(), profile.getGuestOsId(), profile.getBootable(), profile.getHypervisorType(), profile.getTemplateTag(),
|
||||
profile.getDetails(), profile.getSshKeyEnabled());
|
||||
profile.getDetails(), profile.getSshKeyEnabled(), profile.IsDynamicallyScalable());
|
||||
|
||||
template.setImageDataStoreId(profile.getImageStoreId());
|
||||
if (zoneId == null || zoneId.longValue() == -1) {
|
||||
|
|
|
|||
|
|
@ -1709,6 +1709,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
Long id = cmd.getId();
|
||||
Long osTypeId = cmd.getOsTypeId();
|
||||
String userData = cmd.getUserData();
|
||||
Boolean isDynamicallyScalable = cmd.isDynamicallyScalable();
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
// Input validation
|
||||
|
|
@ -1796,6 +1797,17 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
}
|
||||
}
|
||||
|
||||
if (isDynamicallyScalable != null) {
|
||||
UserVmDetailVO vmDetailVO = _vmDetailsDao.findDetail(vm.getId(), VirtualMachine.IsDynamicScalingEnabled);
|
||||
if (vmDetailVO == null) {
|
||||
vmDetailVO = new UserVmDetailVO(vm.getId(), VirtualMachine.IsDynamicScalingEnabled, isDynamicallyScalable.toString());
|
||||
_vmDetailsDao.persist(vmDetailVO);
|
||||
} else {
|
||||
vmDetailVO.setValue(isDynamicallyScalable.toString());
|
||||
_vmDetailsDao.update(vmDetailVO.getId(), vmDetailVO);
|
||||
}
|
||||
}
|
||||
|
||||
_vmDao.updateVM(id, displayName, ha, osTypeId, userData, isDisplayVmEnabled);
|
||||
|
||||
if (updateUserdata) {
|
||||
|
|
@ -2684,6 +2696,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
owner.getDomainId(), owner.getId(), offering.getId(), userData,
|
||||
hostName, diskOfferingId);
|
||||
vm.setUuid(uuidName);
|
||||
vm.setDetail(VirtualMachine.IsDynamicScalingEnabled, template.isDynamicallyScalable().toString());
|
||||
|
||||
if (sshPublicKey != null) {
|
||||
vm.setDetail("SSH.PublicKey", sshPublicKey);
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||
import com.cloud.utils.exception.ExecutionException;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.vm.UserVmDetailVO;
|
||||
import com.cloud.vm.ItWorkVO.Step;
|
||||
import com.cloud.vm.VirtualMachine.Event;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
|
|
@ -3230,14 +3231,23 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
@Override
|
||||
public VMInstanceVO reConfigureVm(VMInstanceVO vm , ServiceOffering oldServiceOffering, boolean reconfiguringOnExistingHost) throws ResourceUnavailableException, ConcurrentOperationException {
|
||||
|
||||
UserVmDetailVO vmDetailVO = _uservmDetailsDao.findDetail(vm.getId(), VirtualMachine.IsDynamicScalingEnabled);
|
||||
Boolean isDynamicallyScalable;
|
||||
if (vmDetailVO == null) {
|
||||
isDynamicallyScalable = false;
|
||||
} else {
|
||||
isDynamicallyScalable = (vmDetailVO.getValue()).equals("true");
|
||||
}
|
||||
|
||||
long newServiceofferingId = vm.getServiceOfferingId();
|
||||
ServiceOffering newServiceOffering = _configMgr.getServiceOffering(newServiceofferingId);
|
||||
HostVO hostVo = _hostDao.findById(vm.hostId);
|
||||
HostVO hostVo = _hostDao.findById(vm.getHostId());
|
||||
|
||||
Float memoryOvercommitRatio = Float.parseFloat(_configServer.getConfigValue(Config.MemOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), hostVo.getClusterId()));
|
||||
Float cpuOvercommitRatio = Float.parseFloat(_configServer.getConfigValue(Config.CPUOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), hostVo.getClusterId()));
|
||||
long minMemory = (long) (newServiceOffering.getRamSize()/memoryOvercommitRatio);
|
||||
ScaleVmCommand reconfigureCmd = new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(),
|
||||
(int) (newServiceOffering.getSpeed()/cpuOvercommitRatio), newServiceOffering.getSpeed(), minMemory * 1024 * 1024, newServiceOffering.getRamSize() * 1024 * 1024, newServiceOffering.getLimitCpuUse());
|
||||
(int) (newServiceOffering.getSpeed()/cpuOvercommitRatio), newServiceOffering.getSpeed(), minMemory * 1024 * 1024, newServiceOffering.getRamSize() * 1024 * 1024, newServiceOffering.getLimitCpuUse(), isDynamicallyScalable);
|
||||
|
||||
Long dstHostId = vm.getHostId();
|
||||
ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Running, vm.getType(), vm.getId());
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ import com.cloud.user.dao.AccountDao;
|
|||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
|
||||
import com.cloud.utils.Pair;
|
||||
|
|
@ -160,12 +160,15 @@ public class VirtualMachineManagerImplTest {
|
|||
ConfigurationServer _configServer;
|
||||
@Mock
|
||||
HostVO hostVO;
|
||||
@Mock
|
||||
UserVmDetailVO _vmDetailVO;
|
||||
|
||||
@Mock ClusterDao _clusterDao;
|
||||
@Mock HostPodDao _podDao;
|
||||
@Mock DataCenterDao _dcDao;
|
||||
@Mock DiskOfferingDao _diskOfferingDao;
|
||||
@Mock PrimaryDataStoreDao _storagePoolDao;
|
||||
@Mock UserVmDetailsDao _vmDetailsDao;
|
||||
@Mock StoragePoolHostDao _poolHostDao;
|
||||
@Mock NetworkManager _networkMgr;
|
||||
@Mock HypervisorGuruManager _hvGuruMgr;
|
||||
|
|
@ -206,6 +209,7 @@ public class VirtualMachineManagerImplTest {
|
|||
_vmMgr._vmSnapshotMgr = _vmSnapshotMgr;
|
||||
_vmMgr._vmDao = _vmInstanceDao;
|
||||
_vmMgr._configServer = _configServer;
|
||||
_vmMgr._uservmDetailsDao = _vmDetailsDao;
|
||||
|
||||
when(_vmMock.getId()).thenReturn(314l);
|
||||
when(_vmInstance.getId()).thenReturn(1L);
|
||||
|
|
@ -244,14 +248,20 @@ public class VirtualMachineManagerImplTest {
|
|||
DeployDestination dest = new DeployDestination(null, null, null, _host);
|
||||
long l = 1L;
|
||||
|
||||
doReturn(3L).when(_vmInstance).getId();
|
||||
when(_vmDetailsDao.findDetail(3L, VirtualMachine.IsDynamicScalingEnabled)).thenReturn(_vmDetailVO);
|
||||
doReturn("true").when(_vmDetailVO).getValue();
|
||||
when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance);
|
||||
ServiceOfferingVO newServiceOffering = getSvcoffering(512);
|
||||
when(_hostDao.findById(_vmInstance.hostId)).thenReturn(hostVO);
|
||||
doReturn(1L).when(_vmInstance).getHostId();
|
||||
doReturn(hostVO).when(_hostDao).findById(1L);
|
||||
doReturn(1L).when(_vmInstance).getDataCenterId();
|
||||
doReturn(1L).when(hostVO).getClusterId();
|
||||
when(_configServer.getConfigValue(Config.EnableDynamicallyScaleVm.key(), Config.ConfigurationParameterScope.zone.toString(), 1L)).thenReturn("true");
|
||||
when(_configServer.getConfigValue(Config.MemOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), 1L)).thenReturn("1.0");
|
||||
when(_configServer.getConfigValue(Config.CPUOverprovisioningFactor.key(), Config.ConfigurationParameterScope.cluster.toString(), 1L)).thenReturn("1.0");
|
||||
ScaleVmCommand reconfigureCmd = new ScaleVmCommand("myVmName", newServiceOffering.getCpu(),
|
||||
newServiceOffering.getSpeed(), newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse());
|
||||
newServiceOffering.getSpeed(), newServiceOffering.getSpeed(), newServiceOffering.getRamSize(), newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse(), true);
|
||||
Answer answer = new ScaleVmAnswer(reconfigureCmd, true, "details");
|
||||
when(_agentMgr.send(2l, reconfigureCmd)).thenReturn(null);
|
||||
_vmMgr.reConfigureVm(_vmInstance, getSvcoffering(256), false);
|
||||
|
|
|
|||
|
|
@ -1518,7 +1518,8 @@ CREATE VIEW `cloud`.`user_vm_view` AS
|
|||
affinity_group.id affinity_group_id,
|
||||
affinity_group.uuid affinity_group_uuid,
|
||||
affinity_group.name affinity_group_name,
|
||||
affinity_group.description affinity_group_description
|
||||
affinity_group.description affinity_group_description,
|
||||
vm_details.value dynamically_scalable
|
||||
|
||||
from
|
||||
`cloud`.`user_vm`
|
||||
|
|
@ -1579,10 +1580,13 @@ CREATE VIEW `cloud`.`user_vm_view` AS
|
|||
`cloud`.`async_job` ON async_job.instance_id = vm_instance.id
|
||||
and async_job.instance_type = 'VirtualMachine'
|
||||
and async_job.job_status = 0
|
||||
left join
|
||||
`cloud`.`affinity_group_vm_map` ON vm_instance.id = affinity_group_vm_map.instance_id
|
||||
left join
|
||||
`cloud`.`affinity_group` ON affinity_group_vm_map.affinity_group_id = affinity_group.id;
|
||||
left join
|
||||
`cloud`.`affinity_group_vm_map` ON vm_instance.id = affinity_group_vm_map.instance_id
|
||||
left join
|
||||
`cloud`.`affinity_group` ON affinity_group_vm_map.affinity_group_id = affinity_group.id
|
||||
left join
|
||||
`cloud`.`user_vm_details` vm_details ON vm_details.vm_id = vm_instance.id
|
||||
and vm_details.name = 'enable.dynamic.scaling';
|
||||
|
||||
DROP VIEW IF EXISTS `cloud`.`volume_view`;
|
||||
CREATE VIEW `cloud`.`volume_view` AS
|
||||
|
|
@ -1884,3 +1888,4 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'manag
|
|||
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'execute.in.sequence.hypervisor.commands', 'false', 'If set to true, StartCommand, StopCommand, CopyVolumeCommand, CreateCommand will be synchronized on the agent side. If set to false, these commands become asynchronous. Default value is false.');
|
||||
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'execute.in.sequence.network.element.commands', 'false', 'If set to true, DhcpEntryCommand, SavePasswordCommand, UserDataCommand, VmDataCommand will be synchronized on the agent side. If set to false, these commands become asynchronous. Default value is false.');
|
||||
|
||||
ALTER TABLE `cloud`.`vm_template` ADD COLUMN `dynamically_scalable` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory';
|
||||
|
|
|
|||
Loading…
Reference in New Issue