Bug 9534 : implement CPU cap

Introducing new boolean flag in service offering to restrict the user VM's CPU utilization to what service offering it is entitled for.
This commit is contained in:
Murali Reddy 2011-04-27 13:42:24 +05:30
parent 7960a499dc
commit c12ccbd06f
14 changed files with 92 additions and 17 deletions

View File

@ -39,13 +39,14 @@ public class VirtualMachineTO {
String[] bootupScripts; String[] bootupScripts;
boolean rebootOnCrash; boolean rebootOnCrash;
boolean enableHA; boolean enableHA;
boolean limitCpuUse;
String vncPassword; String vncPassword;
Map<String, String> params; Map<String, String> params;
VolumeTO[] disks; VolumeTO[] disks;
NicTO[] nics; NicTO[] nics;
public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader, String os, boolean enableHA, String vncPassword) { public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader, String os, boolean enableHA, boolean limitCpuUse, String vncPassword) {
this.id = id; this.id = id;
this.name = instanceName; this.name = instanceName;
this.type = type; this.type = type;
@ -56,6 +57,7 @@ public class VirtualMachineTO {
this.bootloader = bootloader; this.bootloader = bootloader;
this.os = os; this.os = os;
this.enableHA = enableHA; this.enableHA = enableHA;
this.limitCpuUse = limitCpuUse;
this.vncPassword = vncPassword; this.vncPassword = vncPassword;
} }
@ -102,6 +104,10 @@ public class VirtualMachineTO {
return speed; return speed;
} }
public boolean getLimitCpuUse() {
return limitCpuUse;
}
public long getMinRam() { public long getMinRam() {
return minRam; return minRam;
} }

View File

@ -98,6 +98,7 @@ public class ApiConstants {
public static final String JOB_STATUS = "jobstatus"; public static final String JOB_STATUS = "jobstatus";
public static final String LASTNAME = "lastname"; public static final String LASTNAME = "lastname";
public static final String LEVEL = "level"; public static final String LEVEL = "level";
public static final String LIMIT_CPU_USE = "limitcpuuse";
public static final String LOCK = "lock"; public static final String LOCK = "lock";
public static final String LUN = "lun"; public static final String LUN = "lun";
public static final String MAX = "max"; public static final String MAX = "max";

View File

@ -56,6 +56,9 @@ public class CreateServiceOfferingCmd extends BaseCmd {
@Parameter(name=ApiConstants.OFFER_HA, type=CommandType.BOOLEAN, description="the HA for the service offering") @Parameter(name=ApiConstants.OFFER_HA, type=CommandType.BOOLEAN, description="the HA for the service offering")
private Boolean offerHa; private Boolean offerHa;
@Parameter(name=ApiConstants.LIMIT_CPU_USE, type=CommandType.BOOLEAN, description="restrict the CPU usage to committed service offering")
private Boolean limitCpuUse;
@Parameter(name=ApiConstants.STORAGE_TYPE, type=CommandType.STRING, description="the storage type of the service offering. Values are local and shared.") @Parameter(name=ApiConstants.STORAGE_TYPE, type=CommandType.STRING, description="the storage type of the service offering. Values are local and shared.")
private String storageType; private String storageType;
@ -97,6 +100,10 @@ public class CreateServiceOfferingCmd extends BaseCmd {
return offerHa; return offerHa;
} }
public Boolean GetLimitCpuUse() {
return limitCpuUse;
}
public String getStorageType() { public String getStorageType() {
return storageType; return storageType;
} }

View File

@ -56,6 +56,11 @@ public interface ServiceOffering {
* @return Does this service plan offer HA? * @return Does this service plan offer HA?
*/ */
boolean getOfferHA(); boolean getOfferHA();
/**
* @return Does this service plan offer VM to use CPU resources beyond the service offering limits?
*/
boolean getLimitCpuUse();
/** /**
* @return the rate in megabits per sec to which a VM's network interface is throttled to * @return the rate in megabits per sec to which a VM's network interface is throttled to

View File

@ -236,7 +236,11 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, StateObject
* @return should HA be enabled for this machine? * @return should HA be enabled for this machine?
*/ */
public boolean isHaEnabled(); public boolean isHaEnabled();
/**
* @return should limit CPU usage to the service offering?
*/
public boolean limitCpuUse();
/** /**
* @return date when machine was created * @return date when machine was created
*/ */

View File

@ -80,12 +80,13 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
HypervisorType hypervisorType, HypervisorType hypervisorType,
long guestOsId, long guestOsId,
boolean haEnabled, boolean haEnabled,
boolean limitCpuUse,
long domainId, long domainId,
long accountId, long accountId,
long serviceOfferingId, long serviceOfferingId,
String userData, String userData,
String name) { String name) {
super(id, serviceOfferingId, name, instanceName, Type.User, templateId, hypervisorType, guestOsId, domainId, accountId, haEnabled); super(id, serviceOfferingId, name, instanceName, Type.User, templateId, hypervisorType, guestOsId, domainId, accountId, haEnabled, limitCpuUse);
this.userData = userData; this.userData = userData;
this.displayName = displayName != null ? displayName : null; this.displayName = displayName != null ? displayName : null;
this.details = new HashMap<String, String>(); this.details = new HashMap<String, String>();

View File

@ -107,7 +107,10 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
@Column(name="ha_enabled", updatable=true, nullable=true) @Column(name="ha_enabled", updatable=true, nullable=true)
protected boolean haEnabled; protected boolean haEnabled;
@Column(name="limit_cpu_use", updatable=true, nullable=true)
private boolean limitCpuUse;
@Column(name="update_count", updatable = true, nullable=false) @Column(name="update_count", updatable = true, nullable=false)
protected long updated; // This field should be updated everytime the state is updated. There's no set method in the vo object because it is done with in the dao code. protected long updated; // This field should be updated everytime the state is updated. There's no set method in the vo object because it is done with in the dao code.
@ -163,8 +166,25 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
this.domainId = domainId; this.domainId = domainId;
this.serviceOfferingId = serviceOfferingId; this.serviceOfferingId = serviceOfferingId;
this.hypervisorType = hypervisorType; this.hypervisorType = hypervisorType;
this.limitCpuUse = false;
} }
public VMInstanceVO(long id,
long serviceOfferingId,
String name,
String instanceName,
Type type,
Long vmTemplateId,
HypervisorType hypervisorType,
long guestOSId,
long domainId,
long accountId,
boolean haEnabled,
boolean limitResourceUse) {
this(id, serviceOfferingId, name, instanceName, type, vmTemplateId, hypervisorType, guestOSId, domainId, accountId, haEnabled);
this.limitCpuUse = limitResourceUse;
}
protected VMInstanceVO() { protected VMInstanceVO() {
} }
@ -330,8 +350,13 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
@Override @Override
public boolean isHaEnabled() { public boolean isHaEnabled() {
return haEnabled; return haEnabled;
} }
@Override
public boolean limitCpuUse() {
return limitCpuUse;
}
@Override @Override
public String getPrivateMacAddress() { public String getPrivateMacAddress() {
return privateMacAddress; return privateMacAddress;

View File

@ -70,7 +70,7 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
* @param hostTag * @param hostTag
* @return ID * @return ID
*/ */
ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, String tags, Long domainId, String hostTag); ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, boolean limitResourceUse, String tags, Long domainId, String hostTag);
/** /**
* Creates a new disk offering * Creates a new disk offering

View File

@ -1448,16 +1448,21 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
offerHA = false; offerHA = false;
} }
Boolean limitCpuUse = cmd.GetLimitCpuUse();
if (limitCpuUse == null) {
limitCpuUse = false;
}
return createServiceOffering(userId, cmd.getServiceOfferingName(), cpuNumber.intValue(), memory.intValue(), cpuSpeed.intValue(), cmd.getDisplayText(), localStorageRequired, offerHA, return createServiceOffering(userId, cmd.getServiceOfferingName(), cpuNumber.intValue(), memory.intValue(), cpuSpeed.intValue(), cmd.getDisplayText(), localStorageRequired, offerHA,
cmd.getTags(), cmd.getDomainId(), cmd.getHostTag()); limitCpuUse, cmd.getTags(), cmd.getDomainId(), cmd.getHostTag());
} }
@Override @Override
@ActionEvent(eventType = EventTypes.EVENT_SERVICE_OFFERING_CREATE, eventDescription = "creating service offering") @ActionEvent(eventType = EventTypes.EVENT_SERVICE_OFFERING_CREATE, eventDescription = "creating service offering")
public ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, String tags, public ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, boolean limitResourceUse, String tags,
Long domainId, String hostTag) { Long domainId, String hostTag) {
tags = cleanupTags(tags); tags = cleanupTags(tags);
ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, offerHA, displayText, localStorageRequired, false, tags, false, domainId, hostTag); ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, offerHA, limitResourceUse, displayText, localStorageRequired, false, tags, false, domainId, hostTag);
if ((offering = _serviceOfferingDao.persist(offering)) != null) { if ((offering = _serviceOfferingDao.persist(offering)) != null) {
UserContext.current().setEventDetails("Service offering id=" + offering.getId()); UserContext.current().setEventDetails("Service offering id=" + offering.getId());

View File

@ -60,7 +60,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
VirtualMachine vm = vmProfile.getVirtualMachine(); VirtualMachine vm = vmProfile.getVirtualMachine();
VirtualMachineTO to = new VirtualMachineTO(vm.getId(), vm.getInstanceName(), vm.getType(), offering.getCpu(), offering.getSpeed(), VirtualMachineTO to = new VirtualMachineTO(vm.getId(), vm.getInstanceName(), vm.getType(), offering.getCpu(), offering.getSpeed(),
offering.getRamSize() * 1024l * 1024l, offering.getRamSize() * 1024l * 1024l, null, null, vm.isHaEnabled(), vm.getVncPassword()); offering.getRamSize() * 1024l * 1024l, offering.getRamSize() * 1024l * 1024l, null, null, vm.isHaEnabled(), vm.limitCpuUse(), vm.getVncPassword());
to.setBootArgs(vmProfile.getBootArgs()); to.setBootArgs(vmProfile.getBootArgs());
List<NicProfile> nicProfiles = vmProfile.getNics(); List<NicProfile> nicProfiles = vmProfile.getNics();

View File

@ -84,7 +84,12 @@ public class ServiceOffering21VO extends DiskOffering21VO implements ServiceOffe
public boolean getOfferHA() { public boolean getOfferHA() {
return offerHA; return offerHA;
} }
@Override
public boolean getLimitCpuUse() {
return false;
}
public void setOfferHA(boolean offerHA) { public void setOfferHA(boolean offerHA) {
this.offerHA = offerHA; this.offerHA = offerHA;
} }

View File

@ -51,6 +51,9 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
@Column(name="ha_enabled") @Column(name="ha_enabled")
private boolean offerHA; private boolean offerHA;
@Column(name="limit_cpu_use")
private boolean limitCpuUse;
@Column(name="host_tag") @Column(name="host_tag")
private String hostTag; private String hostTag;
@ -65,10 +68,11 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
this.speed = speed; this.speed = speed;
this.rateMbps = rateMbps; this.rateMbps = rateMbps;
this.multicastRateMbps = multicastRateMbps; this.multicastRateMbps = multicastRateMbps;
this.offerHA = offerHA; this.offerHA = offerHA;
this.limitCpuUse = false;
} }
public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, Long domainId) { public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitCpuUse, String displayText, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, Long domainId) {
super(name, displayText, false, tags, recreatable, useLocalStorage, systemUse, true, domainId); super(name, displayText, false, tags, recreatable, useLocalStorage, systemUse, true, domainId);
this.cpu = cpu; this.cpu = cpu;
this.ramSize = ramSize; this.ramSize = ramSize;
@ -76,10 +80,11 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
this.rateMbps = rateMbps; this.rateMbps = rateMbps;
this.multicastRateMbps = multicastRateMbps; this.multicastRateMbps = multicastRateMbps;
this.offerHA = offerHA; this.offerHA = offerHA;
this.limitCpuUse = limitCpuUse;
} }
public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, Long domainId, String hostTag) { public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse, String displayText, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, Long domainId, String hostTag) {
this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, displayText, useLocalStorage, recreatable, tags, systemUse, domainId); this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, displayText, useLocalStorage, recreatable, tags, systemUse, domainId);
this.hostTag = hostTag; this.hostTag = hostTag;
} }
@ -91,6 +96,15 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
public void setOfferHA(boolean offerHA) { public void setOfferHA(boolean offerHA) {
this.offerHA = offerHA; this.offerHA = offerHA;
} }
@Override
public boolean getLimitCpuUse() {
return limitCpuUse;
}
public void setLimitResourceUse(boolean limitCpuUse) {
this.limitCpuUse = limitCpuUse;
}
@Override @Override
@Transient @Transient

View File

@ -2331,7 +2331,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
hypervisorType = template.getHypervisorType(); hypervisorType = template.getHypervisorType();
} }
UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, template.getGuestOSId(), offering.getOfferHA(), owner.getDomainId(), owner.getId(), UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, template.getGuestOSId(), offering.getOfferHA(), offering.getLimitCpuUse(), owner.getDomainId(), owner.getId(),
offering.getId(), userData, hostName); offering.getId(), userData, hostName);
if (sshPublicKey != null) { if (sshPublicKey != null) {

View File

@ -803,6 +803,7 @@ CREATE TABLE `cloud`.`vm_instance` (
`proxy_assign_time` DATETIME NULL COMMENT 'time when console proxy was assigned', `proxy_assign_time` DATETIME NULL COMMENT 'time when console proxy was assigned',
`vnc_password` varchar(255) NOT NULL COMMENT 'vnc password', `vnc_password` varchar(255) NOT NULL COMMENT 'vnc password',
`ha_enabled` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Should HA be enabled for this VM', `ha_enabled` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Should HA be enabled for this VM',
`limit_cpu_use` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Limit the cpu usage to service offering',
`update_count` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'date state was updated', `update_count` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'date state was updated',
`update_time` datetime COMMENT 'date the destroy was requested', `update_time` datetime COMMENT 'date the destroy was requested',
`created` datetime NOT NULL COMMENT 'date created', `created` datetime NOT NULL COMMENT 'date created',
@ -1108,6 +1109,7 @@ CREATE TABLE `cloud`.`service_offering` (
`nw_rate` smallint unsigned default 200 COMMENT 'network rate throttle mbits/s', `nw_rate` smallint unsigned default 200 COMMENT 'network rate throttle mbits/s',
`mc_rate` smallint unsigned default 10 COMMENT 'mcast rate throttle mbits/s', `mc_rate` smallint unsigned default 10 COMMENT 'mcast rate throttle mbits/s',
`ha_enabled` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Enable HA', `ha_enabled` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Enable HA',
`limit_cpu_use` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Limit the CPU usage to service offering',
`host_tag` varchar(255) COMMENT 'host tag specified by the service_offering', `host_tag` varchar(255) COMMENT 'host tag specified by the service_offering',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
CONSTRAINT `fk_service_offering__id` FOREIGN KEY (`id`) REFERENCES `disk_offering`(`id`) ON DELETE CASCADE CONSTRAINT `fk_service_offering__id` FOREIGN KEY (`id`) REFERENCES `disk_offering`(`id`) ON DELETE CASCADE