- Host reservation release process

- Make deployment_planner optional field in service offering, global config vm.deployment.planner
- Admin API to release host reservation
This commit is contained in:
Prachi Damle 2013-05-08 16:38:01 -07:00
parent 81d6da5ad7
commit 0e792eb938
20 changed files with 513 additions and 162 deletions

View File

@ -390,6 +390,8 @@ public class EventTypes {
public static final String EVENT_AFFINITY_GROUP_REMOVE = "AG.REMOVE";
public static final String EVENT_VM_AFFINITY_GROUP_UPDATE = "VM.AG.UPDATE";
public static final String EVENT_HOST_RESERVATION_RELEASE = "HOST.RESERVATION.RELEASE";
static {
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking
@ -690,6 +692,7 @@ public class EventTypes {
entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_UPDATE, AutoScaleVmGroup.class.getName());
entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_ENABLE, AutoScaleVmGroup.class.getName());
entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DISABLE, AutoScaleVmGroup.class.getName());
}
public static String getEntityForEvent (String eventName) {

View File

@ -100,11 +100,13 @@ public interface ResourceService {
Swift discoverSwift(AddSwiftCmd addSwiftCmd) throws DiscoveryException;
S3 discoverS3(AddS3Cmd cmd) throws DiscoveryException;
List<HypervisorType> getSupportedHypervisorTypes(long zoneId, boolean forVirtualRouter, Long podId);
Pair<List<? extends Swift>, Integer> listSwifts(ListSwiftsCmd cmd);
List<? extends S3> listS3s(ListS3sCmd cmd);
boolean releaseHostReservation(Long hostId);
}

View File

@ -0,0 +1,105 @@
// 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.admin.host;
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.ServerApiException;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.log4j.Logger;
import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
@APICommand(name = "releaseHostReservation", description = "Releases host reservation.", responseObject = SuccessResponse.class)
public class ReleaseHostReservationCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(ReleaseHostReservationCmd.class.getName());
private static final String s_name = "releasehostreservationresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=HostResponse.class,
required=true, description="the host ID")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
Account account = UserContext.current().getCaller();
if (account != null) {
return account.getId();
}
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public String getEventType() {
return EventTypes.EVENT_HOST_RESERVATION_RELEASE;
}
@Override
public String getEventDescription() {
return "releasing reservation for host: " + getId();
}
@Override
public AsyncJob.Type getInstanceType() {
return AsyncJob.Type.Host;
}
@Override
public Long getInstanceId() {
return getId();
}
@Override
public void execute(){
boolean result = _resourceService.releaseHostReservation(getId());
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release host reservation");
}
}
}

View File

@ -84,7 +84,7 @@ public class CreateServiceOfferingCmd extends BaseCmd {
@Parameter(name=ApiConstants.NETWORKRATE, type=CommandType.INTEGER, description="data transfer rate in megabits per second allowed. Supported only for non-System offering and system offerings having \"domainrouter\" systemvmtype")
private Integer networkRate;
@Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "The deployment planner heuristics used to deploy a VM of this offering, default \"FirstFitPlanner\".")
@Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "The deployment planner heuristics used to deploy a VM of this offering. If null, value of global config vm.deployment.planner is used")
private String deploymentPlanner;
/////////////////////////////////////////////////////

View File

@ -259,6 +259,7 @@ listHosts=3
findHostsForMigration=1
addSecondaryStorage=1
updateHostPassword=1
releaseHostReservation=1
#### volume commands
attachVolume=15

View File

@ -82,11 +82,14 @@ import com.cloud.utils.db.DB;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.fsm.StateListener;
import com.cloud.vm.UserVmDetailVO;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.UserVmDetailsDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.VMSnapshot;
import com.cloud.vm.snapshot.VMSnapshotVO;
@ -126,6 +129,8 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
protected VMSnapshotDao _vmSnapshotDao;
@Inject
protected UserVmDao _userVMDao;
@Inject
protected UserVmDetailsDao _userVmDetailsDao;
@Inject
ClusterDetailsDao _clusterDetailsDao;
@ -140,6 +145,8 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
@Inject
MessageBus _messageBus;
private static final String MESSAGE_RESERVED_CAPACITY_FREED_FLAG = "Message.ReservedCapacityFreed.Flag";
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
@ -561,9 +568,19 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
reservedMemory += so.getRamSize() * 1024L * 1024L;
reservedCpu += so.getCpu() * so.getSpeed();
} else {
// signal that the VM has been stopped for skip.counting.hours,
// signal if not done already, that the VM has been stopped for skip.counting.hours,
// hence capacity will not be reserved anymore.
_messageBus.publish(_name, "VM_ReservedCapacity_Free", PublishScope.LOCAL, vm);
UserVmDetailVO messageSentFlag = _userVmDetailsDao.findDetail(vm.getId(), MESSAGE_RESERVED_CAPACITY_FREED_FLAG);
if (messageSentFlag == null || !Boolean.valueOf(messageSentFlag.getValue())) {
_messageBus.publish(_name, "VM_ReservedCapacity_Free", PublishScope.LOCAL, vm);
if (vm.getType() == VirtualMachine.Type.User) {
UserVmVO userVM = _userVMDao.findById(vm.getId());
_userVMDao.loadDetails(userVM);
userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "true");
_userVMDao.saveDetails(userVM);
}
}
}
}
@ -700,6 +717,18 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
allocateVmCapacity(vm, fromLastHost);
}
if (newState == State.Stopped) {
if (vm.getType() == VirtualMachine.Type.User) {
UserVmVO userVM = _userVMDao.findById(vm.getId());
_userVMDao.loadDetails(userVM);
// free the message sent flag if it exists
userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "false");
_userVMDao.saveDetails(userVM);
}
}
return true;
}

View File

@ -214,6 +214,8 @@ public enum Config {
SecStorageProxy("Advanced", AgentManager.class, String.class, "secstorage.proxy", null, "http proxy used by ssvm, in http://username:password@proxyserver:port format", null),
AlertPurgeInterval("Advanced", ManagementServer.class, Integer.class, "alert.purge.interval", "86400", "The interval (in seconds) to wait before running the alert purge thread", null),
AlertPurgeDelay("Advanced", ManagementServer.class, Integer.class, "alert.purge.delay", "0", "Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts", null),
HostReservationReleasePeriod("Advanced", ManagementServer.class, Integer.class, "host.reservation.release.period", "300000", "The interval in milliseconds between host reservation release checks", null),
// LB HealthCheck Interval.
LBHealthCheck("Advanced", ManagementServer.class, String.class, "healthcheck.update.interval", "600",
@ -235,6 +237,7 @@ public enum Config {
ApplyAllocationAlgorithmToPods("Advanced", ManagementServer.class, Boolean.class, "apply.allocation.algorithm.to.pods", "false", "If true, deployment planner applies the allocation heuristics at pods first in the given datacenter during VM resource allocation", "true,false"),
VmUserDispersionWeight("Advanced", ManagementServer.class, Float.class, "vm.user.dispersion.weight", "1", "Weight for user dispersion heuristic (as a value between 0 and 1) applied to resource allocation during vm deployment. Weight for capacity heuristic will be (1 - weight of user dispersion)", null),
VmAllocationAlgorithm("Advanced", ManagementServer.class, String.class, "vm.allocation.algorithm", "random", "'random', 'firstfit', 'userdispersing', 'userconcentratedpod_random', 'userconcentratedpod_firstfit' : Order in which hosts within a cluster will be considered for VM/volume allocation.", null),
VmDeploymentPlanner("Advanced", ManagementServer.class, String.class, "vm.deployment.planner", "FirstFitPlanner", "'FirstFitPlanner', 'UserDispersingPlanner', 'UserConcentratedPodPlanner': DeploymentPlanner heuristic that will be used for VM deployment.", null),
EndpointeUrl("Advanced", ManagementServer.class, String.class, "endpointe.url", "http://localhost:8080/client/api", "Endpointe Url", null),
ElasticLoadBalancerEnabled("Advanced", ManagementServer.class, String.class, "network.loadbalancer.basiczone.elb.enabled", "false", "Whether the load balancing service is enabled for basic zones", "true,false"),
ElasticLoadBalancerNetwork("Advanced", ManagementServer.class, String.class, "network.loadbalancer.basiczone.elb.network", "guest", "Whether the elastic load balancing service public ips are taken from the public or guest network", "guest,public"),

View File

@ -21,7 +21,8 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeSet;
import javax.ejb.Local;
@ -29,7 +30,7 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
@ -41,9 +42,10 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.log4j.Logger;
import com.cloud.capacity.Capacity;
import com.cloud.capacity.CapacityManager;
import com.cloud.capacity.dao.CapacityDao;
import com.cloud.cluster.ManagementServerNode;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.ClusterDetailsDao;
@ -65,7 +67,6 @@ import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.security.SecurityGroupVO;
import com.cloud.offering.ServiceOffering;
import com.cloud.org.Cluster;
import com.cloud.org.Grouping;
@ -82,6 +83,7 @@ import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.user.AccountManager;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentContext;
@ -94,6 +96,7 @@ import com.cloud.vm.ReservationContext;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.agent.AgentManager;
@ -106,6 +109,7 @@ import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.agent.manager.allocator.HostAllocator;
@Local(value = { DeploymentPlanningManager.class })
public class DeploymentPlanningManagerImpl extends ManagerBase implements DeploymentPlanningManager, Manager, Listener {
@ -124,9 +128,14 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
DataCenterDao _dcDao;
@Inject
PlannerHostReservationDao _plannerHostReserveDao;
private int _vmCapacityReleaseInterval;
@Inject
MessageBus _messageBus;
private Timer _timer = null;
private long _hostReservationReleasePeriod = 60L * 60L * 1000L; // one hour by default
private static final long INITIAL_RESERVATION_RELEASE_CHECKER_DELAY = 30L * 1000L; // thirty seconds expressed in milliseconds
protected long _nodeId = -1;
protected List<StoragePoolAllocator> _storagePoolAllocators;
public List<StoragePoolAllocator> getStoragePoolAllocators() {
@ -212,7 +221,11 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
ServiceOffering offering = vmProfile.getServiceOffering();
DeploymentPlanner planner = ComponentContext.getComponent(offering.getDeploymentPlanner());
String plannerName = offering.getDeploymentPlanner();
if (plannerName == null) {
plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key());
}
DeploymentPlanner planner = ComponentContext.getComponent(plannerName);
int cpu_requested = offering.getCpu() * offering.getSpeed();
long ram_requested = offering.getRamSize() * 1024L * 1024L;
@ -352,58 +365,58 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
DeployDestination dest = null;
List<Long> clusterList = null;
if (offering != null && offering.getDeploymentPlanner() != null) {
if (planner != null && planner.canHandle(vmProfile, plan, avoids)) {
while (true) {
if (planner != null && planner.canHandle(vmProfile, plan, avoids)) {
while (true) {
if (planner instanceof DeploymentClusterPlanner) {
if (planner instanceof DeploymentClusterPlanner) {
ExcludeList PlannerAvoidInput = new ExcludeList(avoids.getDataCentersToAvoid(),
ExcludeList PlannerAvoidInput = new ExcludeList(avoids.getDataCentersToAvoid(),
avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
avoids.getPoolsToAvoid());
clusterList = ((DeploymentClusterPlanner) planner).orderClusters(vmProfile, plan, avoids);
if (clusterList != null && !clusterList.isEmpty()) {
// planner refactoring. call allocators to list hosts
ExcludeList PlannerAvoidOutput = new ExcludeList(avoids.getDataCentersToAvoid(),
avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
avoids.getPoolsToAvoid());
clusterList = ((DeploymentClusterPlanner) planner).orderClusters(vmProfile, plan, avoids);
resetAvoidSet(PlannerAvoidOutput, PlannerAvoidInput);
if (clusterList != null && !clusterList.isEmpty()) {
// planner refactoring. call allocators to list hosts
ExcludeList PlannerAvoidOutput = new ExcludeList(avoids.getDataCentersToAvoid(),
avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
avoids.getPoolsToAvoid());
dest = checkClustersforDestination(clusterList, vmProfile, plan, avoids, dc,
getPlannerUsage(planner), PlannerAvoidOutput);
if (dest != null) {
return dest;
}
// reset the avoid input to the planners
resetAvoidSet(avoids, PlannerAvoidOutput);
resetAvoidSet(PlannerAvoidOutput, PlannerAvoidInput);
dest = checkClustersforDestination(clusterList, vmProfile, plan, avoids, dc,
getPlannerUsage(planner), PlannerAvoidOutput);
if(dest != null){
return dest;
}
// reset the avoid input to the planners
resetAvoidSet(avoids, PlannerAvoidOutput);
} else {
return null;
}
} else {
dest = planner.plan(vmProfile, plan, avoids);
if (dest != null) {
long hostId = dest.getHost().getId();
avoids.addHost(dest.getHost().getId());
if (checkIfHostFitsPlannerUsage(hostId, DeploymentPlanner.PlannerResourceUsage.Shared)) {
// found destination
return dest;
} else {
return null;
// find another host - seems some concurrent
// deployment picked it up for dedicated access
continue;
}
} else {
dest = planner.plan(vmProfile, plan, avoids);
if (dest != null) {
long hostId = dest.getHost().getId();
avoids.addHost(dest.getHost().getId());
if (checkIfHostFitsPlannerUsage(hostId, DeploymentPlanner.PlannerResourceUsage.Shared)) {
// found destination
return dest;
} else {
// find another host - seems some concurrent deployment picked it up for dedicated access
continue;
}
}else{
return null;
}
return null;
}
}
}
}
return dest;
}
@ -495,36 +508,69 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
}
@DB
public void checkHostReservationRelease(VMInstanceVO vm) {
s_logger.debug("MessageBus message: host reserved capacity released for VM: " + vm.getLastHostId()
+ ", checking if host reservation can be released for host:" + vm.getLastHostId());
Long hostId = vm.getLastHostId();
public boolean checkHostReservationRelease(Long hostId) {
if (hostId != null) {
List<VMInstanceVO> vms = _vmInstanceDao.listUpByHostId(hostId);
if (vms.size() > 0) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot release reservation, Found " + vms.size() + " VMs Running on host " + hostId);
}
}
List<VMInstanceVO> vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId);
if (vmsByLastHostId.size() > 0) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot release reservation, Found " + vmsByLastHostId.size()
+ " VMs Stopped but reserved on host " + hostId);
}
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Host has no VMs, releasing the planner reservation");
}
PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
if (reservationEntry != null) {
long id = reservationEntry.getId();
if (reservationEntry != null && reservationEntry.getResourceUsage() != null) {
// check if any VMs are starting or running on this host
List<VMInstanceVO> vms = _vmInstanceDao.listUpByHostId(hostId);
if (vms.size() > 0) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot release reservation, Found " + vms.size() + " VMs Running on host "
+ hostId);
}
return false;
}
List<VMInstanceVO> vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId);
if (vmsByLastHostId.size() > 0) {
// check if any VMs are within skip.counting.hours, if yes
// we
// cannot release the host
for (VMInstanceVO stoppedVM : vmsByLastHostId) {
long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime()
.getTime()) / 1000;
if (secondsSinceLastUpdate < _vmCapacityReleaseInterval) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot release reservation, Found VM: " + stoppedVM
+ " Stopped but reserved on host " + hostId);
}
return false;
}
}
}
// check if any VMs are stopping on or migrating to this host
List<VMInstanceVO> vmsStoppingMigratingByHostId = _vmInstanceDao.findByHostInStates(hostId,
State.Stopping, State.Migrating, State.Starting);
if (vmsStoppingMigratingByHostId.size() > 0) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot release reservation, Found " + vms.size()
+ " VMs stopping/migrating on host " + hostId);
}
return false;
}
// check if any VMs are in starting state with no hostId set yet
// -
// just ignore host release to avoid race condition
List<VMInstanceVO> vmsStartingNoHost = _vmInstanceDao.listStartingWithNoHostId();
if (vmsStartingNoHost.size() > 0) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Cannot release reservation, Found " + vms.size()
+ " VMs starting as of now and no hostId yet stored");
}
return false;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Host has no VMs associated, releasing the planner reservation for host " + hostId);
}
long id = reservationEntry.getId();
final Transaction txn = Transaction.currentTxn();
try {
@ -533,11 +579,13 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true);
if (lockedEntry == null) {
s_logger.error("Unable to lock the host entry for reservation, host: " + hostId);
return false;
}
// check before updating
if (lockedEntry.getResourceUsage() != null) {
lockedEntry.setResourceUsage(null);
_plannerHostReserveDao.persist(lockedEntry);
return true;
}
} finally {
txn.commit();
@ -545,6 +593,32 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
}
}
return false;
}
class HostReservationReleaseChecker extends TimerTask {
@Override
public void run() {
try {
s_logger.debug("Checking if any host reservation can be released ... ");
checkHostReservations();
s_logger.debug("Done running HostReservationReleaseChecker ... ");
} catch (Throwable t) {
s_logger.error("Exception in HostReservationReleaseChecker", t);
}
}
}
private void checkHostReservations() {
List<PlannerHostReservationVO> reservedHosts = _plannerHostReserveDao.listAllReservedHosts();
for (PlannerHostReservationVO hostReservation : reservedHosts) {
HostVO host = _hostDao.findById(hostReservation.getHostId());
if (host != null && host.getManagementServerId() != null && host.getManagementServerId() == _nodeId) {
checkHostReservationRelease(hostReservation.getHostId());
}
}
}
@Override
@ -610,14 +684,45 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
_agentMgr.registerForHostEvents(this, true, false, true);
_messageBus.subscribe("VM_ReservedCapacity_Free", new MessageSubscriber() {
@Override
public void onPublishMessage(String senderAddress, String subject, Object vm) {
checkHostReservationRelease((VMInstanceVO) vm);
public void onPublishMessage(String senderAddress, String subject, Object obj) {
VMInstanceVO vm = ((VMInstanceVO) obj);
s_logger.debug("MessageBus message: host reserved capacity released for VM: " + vm.getLastHostId()
+ ", checking if host reservation can be released for host:" + vm.getLastHostId());
Long hostId = vm.getLastHostId();
checkHostReservationRelease(hostId);
}
});
_vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()),
3600);
String hostReservationReleasePeriod = _configDao.getValue(Config.HostReservationReleasePeriod.key());
if (hostReservationReleasePeriod != null) {
_hostReservationReleasePeriod = Long.parseLong(hostReservationReleasePeriod);
if (_hostReservationReleasePeriod <= 0)
_hostReservationReleasePeriod = Long.parseLong(Config.HostReservationReleasePeriod.getDefaultValue());
}
_timer = new Timer("HostReservationReleaseChecker");
_nodeId = ManagementServerNode.getManagementServerId();
return super.configure(name, params);
}
@Override
public boolean start() {
_timer.schedule(new HostReservationReleaseChecker(), INITIAL_RESERVATION_RELEASE_CHECKER_DELAY,
_hostReservationReleasePeriod);
return true;
}
@Override
public boolean stop() {
_timer.cancel();
return true;
}
// /refactoring planner methods
private DeployDestination checkClustersforDestination(List<Long> clusterList,
VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid,

View File

@ -106,6 +106,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPla
protected String _allocationAlgorithm = "random";
protected String _globalDeploymentPlanner = "FirstFitPlanner";
@Override
@ -483,12 +484,16 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPla
@Override
public boolean canHandle(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid) {
// check what the ServiceOffering says
// check what the ServiceOffering says. If null, check the global config
ServiceOffering offering = vm.getServiceOffering();
if (offering != null && offering.getDeploymentPlanner() != null) {
if (offering.getDeploymentPlanner().equals(this.getName())) {
return true;
}
} else {
if (_globalDeploymentPlanner != null && _globalDeploymentPlanner.equals(this._name)) {
return true;
}
}
return false;
}
@ -497,6 +502,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentClusterPla
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
super.configure(name, params);
_allocationAlgorithm = _configDao.getValue(Config.VmAllocationAlgorithm.key());
_globalDeploymentPlanner = _configDao.getValue(Config.VmDeploymentPlanner.key());
return true;
}

View File

@ -16,6 +16,8 @@
// under the License.
package com.cloud.deploy.dao;
import java.util.List;
import com.cloud.deploy.PlannerHostReservationVO;
import com.cloud.utils.db.GenericDao;
@ -23,4 +25,6 @@ public interface PlannerHostReservationDao extends GenericDao<PlannerHostReserva
PlannerHostReservationVO findByHostId(long hostId);
List<PlannerHostReservationVO> listAllReservedHosts();
}

View File

@ -16,6 +16,8 @@
// under the License.
package com.cloud.deploy.dao;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.Local;
import com.cloud.deploy.PlannerHostReservationVO;
@ -28,6 +30,7 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
PlannerHostReservationDao {
private SearchBuilder<PlannerHostReservationVO> _hostIdSearch;
private SearchBuilder<PlannerHostReservationVO> _reservedHostSearch;
public PlannerHostReservationDaoImpl() {
@ -38,6 +41,10 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
_hostIdSearch = createSearchBuilder();
_hostIdSearch.and("hostId", _hostIdSearch.entity().getHostId(), SearchCriteria.Op.EQ);
_hostIdSearch.done();
_reservedHostSearch = createSearchBuilder();
_reservedHostSearch.and("usage", _reservedHostSearch.entity().getResourceUsage(), SearchCriteria.Op.NNULL);
_reservedHostSearch.done();
}
@Override
@ -47,4 +54,10 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
return findOneBy(sc);
}
@Override
public List<PlannerHostReservationVO> listAllReservedHosts() {
SearchCriteria<PlannerHostReservationVO> sc = _reservedHostSearch.create();
return listBy(sc);
}
}

View File

@ -79,6 +79,10 @@ import com.cloud.dc.dao.ClusterVSMMapDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DataCenterIpAddressDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.deploy.PlannerHostReservationVO;
import com.cloud.deploy.dao.PlannerHostReservationDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.DiscoveryException;
import com.cloud.exception.InvalidParameterValueException;
@ -206,6 +210,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
protected HighAvailabilityManager _haMgr;
@Inject
protected StorageService _storageSvr;
@Inject
PlannerHostReservationDao _plannerHostReserveDao;
protected List<? extends Discoverer> _discoverers;
public List<? extends Discoverer> getDiscoverers() {
@ -2845,4 +2851,41 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
ResourceState.Enabled);
return sc.list();
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_HOST_RESERVATION_RELEASE, eventDescription = "releasing host reservation", async = true)
public boolean releaseHostReservation(Long hostId) {
Transaction txn = Transaction.currentTxn();
try {
txn.start();
PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
if (reservationEntry != null) {
long id = reservationEntry.getId();
PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true);
if (hostReservation == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Host reservation for host: " + hostId + " does not even exist. Release reservartion call is ignored.");
}
txn.rollback();
return false;
}
hostReservation.setResourceUsage(null);
_plannerHostReserveDao.persist(hostReservation);
txn.commit();
return true;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Host reservation for host: " + hostId
+ " does not even exist. Release reservartion call is ignored.");
}
return false;
} catch (CloudRuntimeException e) {
throw e;
} catch (Throwable t) {
s_logger.error("Unable to release host reservation for host: " + hostId, t);
txn.rollback();
return false;
}
}
}

View File

@ -2556,6 +2556,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
cmdList.add(UpdateVMAffinityGroupCmd.class);
cmdList.add(ListAffinityGroupTypesCmd.class);
cmdList.add(ListDeploymentPlannersCmd.class);
cmdList.add(ReleaseHostReservationCmd.class);
return cmdList;
}

View File

@ -69,7 +69,7 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
int sortKey;
@Column(name = "deployment_planner")
private String deploymentPlanner = "FirstFitPlanner";
private String deploymentPlanner = null;
protected ServiceOfferingVO() {
super();
@ -87,7 +87,6 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
this.volatileVm = false;
this.default_use = defaultUse;
this.vm_type = vm_type == null ? null : vm_type.toString().toLowerCase();
this.deploymentPlanner = "FirstFitPlanner";
}
public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitCpuUse, boolean volatileVm, String displayText, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vm_type, Long domainId) {
@ -101,13 +100,11 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
this.limitCpuUse = limitCpuUse;
this.volatileVm = volatileVm;
this.vm_type = vm_type == null ? null : vm_type.toString().toLowerCase();
this.deploymentPlanner = "FirstFitPlanner";
}
public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse, boolean volatileVm, String displayText, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vm_type, Long domainId, String hostTag) {
this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm, displayText, useLocalStorage, recreatable, tags, systemUse, vm_type, domainId);
this.hostTag = hostTag;
this.deploymentPlanner = "FirstFitPlanner";
}
public ServiceOfferingVO(String name, int cpu, int ramSize, int speed, Integer rateMbps, Integer multicastRateMbps,
@ -116,11 +113,7 @@ public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering
String hostTag, String deploymentPlanner) {
this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm,
displayText, useLocalStorage, recreatable, tags, systemUse, vm_type, domainId, hostTag);
if (deploymentPlanner != null) {
this.deploymentPlanner = deploymentPlanner;
} else {
this.deploymentPlanner = "FirstFitPlanner";
}
this.deploymentPlanner = deploymentPlanner;
}
@Override

View File

@ -67,7 +67,7 @@ public class Upgrade410to420 implements DbUpgrade {
updatePrimaryStore(conn);
addEgressFwRulesForSRXGuestNw(conn);
upgradeEIPNetworkOfferings(conn);
updateServiceOfferingDeploymentPlanner(conn);
updateGlobalDeploymentPlanner(conn);
}
private void updateSystemVmTemplates(Connection conn) {
@ -402,7 +402,7 @@ public class Upgrade410to420 implements DbUpgrade {
}
}
private void updateServiceOfferingDeploymentPlanner(Connection conn) {
private void updateGlobalDeploymentPlanner(Connection conn) {
PreparedStatement pstmt = null;
ResultSet rs = null;
@ -429,13 +429,13 @@ public class Upgrade410to420 implements DbUpgrade {
plannerName = "UserDispersingPlanner";
}
}
// update service offering with the planner name
pstmt = conn.prepareStatement("UPDATE `cloud`.`service_offering` set deployment_planner=?");
// update vm.deployment.planner global config
pstmt = conn.prepareStatement("UPDATE `cloud`.`configuration` set value=? where name = 'vm.deployment.planner'");
pstmt.setString(1, plannerName);
pstmt.executeUpdate();
}
} catch (SQLException e) {
throw new CloudRuntimeException("Unable to set deployment_planner for service offerings", e);
throw new CloudRuntimeException("Unable to set vm.deployment.planner global config", e);
} finally {
try {
if (rs != null) {

View File

@ -3066,6 +3066,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
// Get serviceOffering for Virtual Machine
ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId());
String plannerName = offering.getDeploymentPlanner();
if (plannerName == null) {
plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key());
}
String reservationId = vmEntity.reserve(plannerName, plan, new ExcludeList(), new Long(callerUser.getId()).toString());
vmEntity.deploy(reservationId, new Long(callerUser.getId()).toString(), params);

View File

@ -38,14 +38,14 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
* @return list of VMInstanceVO running on that host.
*/
List<VMInstanceVO> listByHostId(long hostId);
/**
* List VMs by zone ID
* @param zoneId
* @return list of VMInstanceVO in the specified zone
*/
List<VMInstanceVO> listByZoneId(long zoneId);
/**
* List VMs by pod ID
* @param podId
@ -59,32 +59,32 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
* @return list of VMInstanceVO in the specified zone, deployed from the specified template, that are not expunged
*/
public List<VMInstanceVO> listNonExpungedByZoneAndTemplate(long zoneId, long templateId);
/**
* Find vm instance with names like.
*
*
* @param name name that fits SQL like.
* @return list of VMInstanceVO
*/
List<VMInstanceVO> findVMInstancesLike(String name);
List<VMInstanceVO> findVMInTransition(Date time, State... states);
List<VMInstanceVO> listByTypes(VirtualMachine.Type... types);
VMInstanceVO findByIdTypes(long id, VirtualMachine.Type... types);
VMInstanceVO findVMByInstanceName(String name);
void updateProxyId(long id, Long proxyId, Date time);
List<VMInstanceVO> listByHostIdTypes(long hostid, VirtualMachine.Type... types);
List<VMInstanceVO> listUpByHostIdTypes(long hostid, VirtualMachine.Type... types);
List<VMInstanceVO> listByZoneIdAndType(long zoneId, VirtualMachine.Type type);
List<VMInstanceVO> listUpByHostId(Long hostId);
List<VMInstanceVO> listByLastHostId(Long hostId);
List<VMInstanceVO> listByTypeAndState(VirtualMachine.Type type, State state);
List<VMInstanceVO> listByAccountId(long accountId);
@ -92,9 +92,9 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
List<VMInstanceVO> listByClusterId(long clusterId); // this does not pull up VMs which are starting
List<VMInstanceVO> listLHByClusterId(long clusterId); // get all the VMs even starting one on this cluster
List<VMInstanceVO> listVmsMigratingFromHost(Long hostId);
public Long countRunningByHostId(long hostId);
Pair<List<Long>, Map<Long, Double>> listClusterIdsInZoneByVmCount(long zoneId, long accountId);
@ -106,7 +106,7 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
List<Long> listHostIdsByVmCount(long dcId, Long podId, Long clusterId, long accountId);
Long countRunningByAccount(long accountId);
List<VMInstanceVO> listNonRemovedVmsByTypeAndNetwork(long networkId, VirtualMachine.Type... types);
/**
@ -116,4 +116,8 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
*/
List<String> listDistinctHostNames(long networkId, VirtualMachine.Type... types);
List<VMInstanceVO> findByHostInStates(Long hostId, State... states);
List<VMInstanceVO> listStartingWithNoHostId();
}

View File

@ -5,7 +5,7 @@
// 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,
@ -83,30 +83,32 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
protected GenericSearchBuilder<VMInstanceVO, Long> CountRunningByAccount;
protected SearchBuilder<VMInstanceVO> NetworkTypeSearch;
protected GenericSearchBuilder<VMInstanceVO, String> DistinctHostNameSearch;
protected SearchBuilder<VMInstanceVO> HostAndStateSearch;
protected SearchBuilder<VMInstanceVO> StartingWithNoHostSearch;
@Inject ResourceTagDao _tagsDao;
@Inject NicDao _nicDao;
protected Attribute _updateTimeAttr;
private static final String ORDER_CLUSTERS_NUMBER_OF_VMS_FOR_ACCOUNT_PART1 =
private static final String ORDER_CLUSTERS_NUMBER_OF_VMS_FOR_ACCOUNT_PART1 =
"SELECT host.cluster_id, SUM(IF(vm.state='Running' AND vm.account_id = ?, 1, 0)) FROM `cloud`.`host` host LEFT JOIN `cloud`.`vm_instance` vm ON host.id = vm.host_id WHERE ";
private static final String ORDER_CLUSTERS_NUMBER_OF_VMS_FOR_ACCOUNT_PART2 =
" AND host.type = 'Routing' GROUP BY host.cluster_id ORDER BY 2 ASC ";
private static final String ORDER_PODS_NUMBER_OF_VMS_FOR_ACCOUNT = "SELECT pod.id, SUM(IF(vm.state='Running' AND vm.account_id = ?, 1, 0)) FROM `cloud`.`host_pod_ref` pod LEFT JOIN `cloud`.`vm_instance` vm ON pod.id = vm.pod_id WHERE pod.data_center_id = ? " +
" GROUP BY pod.id ORDER BY 2 ASC ";
private static final String ORDER_HOSTS_NUMBER_OF_VMS_FOR_ACCOUNT =
"SELECT host.id, SUM(IF(vm.state='Running' AND vm.account_id = ?, 1, 0)) FROM `cloud`.`host` host LEFT JOIN `cloud`.`vm_instance` vm ON host.id = vm.host_id WHERE host.data_center_id = ? " +
" AND host.pod_id = ? AND host.cluster_id = ? AND host.type = 'Routing' " +
" GROUP BY host.id ORDER BY 2 ASC ";
@Inject protected HostDao _hostDao;
public VMInstanceDaoImpl() {
}
@PostConstruct
protected void init() {
@ -114,14 +116,14 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
IdStatesSearch.and("id", IdStatesSearch.entity().getId(), Op.EQ);
IdStatesSearch.and("states", IdStatesSearch.entity().getState(), Op.IN);
IdStatesSearch.done();
VMClusterSearch = createSearchBuilder();
SearchBuilder<HostVO> hostSearch = _hostDao.createSearchBuilder();
VMClusterSearch.join("hostSearch", hostSearch, hostSearch.entity().getId(), VMClusterSearch.entity().getHostId(), JoinType.INNER);
hostSearch.and("clusterId", hostSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
VMClusterSearch.done();
LHVMClusterSearch = createSearchBuilder();
SearchBuilder<HostVO> hostSearch1 = _hostDao.createSearchBuilder();
LHVMClusterSearch.join("hostSearch1", hostSearch1, hostSearch1.entity().getId(), LHVMClusterSearch.entity().getLastHostId(), JoinType.INNER);
@ -129,7 +131,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
hostSearch1.and("clusterId", hostSearch1.entity().getClusterId(), SearchCriteria.Op.EQ);
LHVMClusterSearch.done();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("host", AllFieldsSearch.entity().getHostId(), Op.EQ);
AllFieldsSearch.and("lastHost", AllFieldsSearch.entity().getLastHostId(), Op.EQ);
@ -169,23 +171,23 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
IdTypesSearch.and("id", IdTypesSearch.entity().getId(), Op.EQ);
IdTypesSearch.and("types", IdTypesSearch.entity().getType(), Op.IN);
IdTypesSearch.done();
HostIdTypesSearch = createSearchBuilder();
HostIdTypesSearch.and("hostid", HostIdTypesSearch.entity().getHostId(), Op.EQ);
HostIdTypesSearch.and("types", HostIdTypesSearch.entity().getType(), Op.IN);
HostIdTypesSearch.done();
HostIdUpTypesSearch = createSearchBuilder();
HostIdUpTypesSearch.and("hostid", HostIdUpTypesSearch.entity().getHostId(), Op.EQ);
HostIdUpTypesSearch.and("types", HostIdUpTypesSearch.entity().getType(), Op.IN);
HostIdUpTypesSearch.and("states", HostIdUpTypesSearch.entity().getState(), Op.NIN);
HostIdUpTypesSearch.done();
HostUpSearch = createSearchBuilder();
HostUpSearch.and("host", HostUpSearch.entity().getHostId(), Op.EQ);
HostUpSearch.and("states", HostUpSearch.entity().getState(), Op.IN);
HostUpSearch.done();
InstanceNameSearch = createSearchBuilder();
InstanceNameSearch.and("instanceName", InstanceNameSearch.entity().getInstanceName(), Op.EQ);
InstanceNameSearch.done();
@ -194,21 +196,31 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
CountVirtualRoutersByAccount.select(null, Func.COUNT, null);
CountVirtualRoutersByAccount.and("account", CountVirtualRoutersByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
CountVirtualRoutersByAccount.and("type", CountVirtualRoutersByAccount.entity().getType(), SearchCriteria.Op.EQ);
CountVirtualRoutersByAccount.and("state", CountVirtualRoutersByAccount.entity().getState(), SearchCriteria.Op.NIN);
CountVirtualRoutersByAccount.and("state", CountVirtualRoutersByAccount.entity().getState(), SearchCriteria.Op.NIN);
CountVirtualRoutersByAccount.done();
CountRunningByHost = createSearchBuilder(Long.class);
CountRunningByHost.select(null, Func.COUNT, null);
CountRunningByHost.and("host", CountRunningByHost.entity().getHostId(), SearchCriteria.Op.EQ);
CountRunningByHost.and("state", CountRunningByHost.entity().getState(), SearchCriteria.Op.EQ);
CountRunningByHost.done();
CountRunningByHost.done();
CountRunningByAccount = createSearchBuilder(Long.class);
CountRunningByAccount.select(null, Func.COUNT, null);
CountRunningByAccount.and("account", CountRunningByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
CountRunningByAccount.and("state", CountRunningByAccount.entity().getState(), SearchCriteria.Op.EQ);
CountRunningByAccount.done();
CountRunningByAccount.done();
HostAndStateSearch = createSearchBuilder();
HostAndStateSearch.and("host", HostAndStateSearch.entity().getHostId(), Op.EQ);
HostAndStateSearch.and("states", HostAndStateSearch.entity().getState(), Op.IN);
HostAndStateSearch.done();
StartingWithNoHostSearch = createSearchBuilder();
StartingWithNoHostSearch.and("state", StartingWithNoHostSearch.entity().getState(), Op.EQ);
StartingWithNoHostSearch.and("host", StartingWithNoHostSearch.entity().getHostId(), Op.NULL);
StartingWithNoHostSearch.done();
_updateTimeAttr = _allAttributes.get("updateTime");
assert _updateTimeAttr != null : "Couldn't get this updateTime attribute";
}
@ -219,7 +231,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
sc.setParameters("account", accountId);
return listBy(sc);
}
@Override
public List<VMInstanceVO> findVMInstancesLike(String name) {
SearchCriteria<VMInstanceVO> sc = NameLikeSearch.create();
@ -234,7 +246,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
return listBy(sc);
}
@Override
public List<VMInstanceVO> listByZoneId(long zoneId) {
SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@ -242,7 +254,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
return listBy(sc);
}
@Override
public List<VMInstanceVO> listByPodId(long podId) {
SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@ -263,7 +275,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
sc.setJoinParameters("hostSearch1", "clusterId", clusterId);
return listBy(sc);
}
@Override
public List<VMInstanceVO> listByZoneIdAndType(long zoneId, VirtualMachine.Type type) {
SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@ -271,8 +283,8 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
sc.setParameters("type", type.toString());
return listBy(sc);
}
@Override
public List<VMInstanceVO> listNonExpungedByZoneAndTemplate(long zoneId, long templateId) {
SearchCriteria<VMInstanceVO> sc = ZoneTemplateNonExpungedSearch.create();
@ -310,7 +322,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging});
return listBy(sc);
}
@Override
public List<VMInstanceVO> listUpByHostId(Long hostId) {
SearchCriteria<VMInstanceVO> sc = HostUpSearch.create();
@ -318,14 +330,14 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
sc.setParameters("states", new Object[] {State.Starting, State.Running});
return listBy(sc);
}
@Override
public List<VMInstanceVO> listByTypes(Type... types) {
SearchCriteria<VMInstanceVO> sc = TypesSearch.create();
sc.setParameters("types", (Object[]) types);
return listBy(sc);
}
@Override
public List<VMInstanceVO> listByTypeAndState(VirtualMachine.Type type, State state) {
SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@ -348,7 +360,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
sc.setParameters("instanceName", name);
return findOneBy(sc);
}
@Override
public void updateProxyId(long id, Long proxyId, Date time) {
VMInstanceVO vo = createForUpdate();
@ -369,12 +381,12 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
@SuppressWarnings("unchecked")
Pair<Long, Long> hosts = (Pair<Long,Long>)opaque;
Long newHostId = hosts.second();
VMInstanceVO vmi = (VMInstanceVO)vm;
Long oldHostId = vmi.getHostId();
Long oldUpdated = vmi.getUpdated();
Date oldUpdateDate = vmi.getUpdateTime();
SearchCriteria<VMInstanceVO> sc = StateChangeSearch.create();
sc.setParameters("id", vmi.getId());
sc.setParameters("states", oldState);
@ -383,7 +395,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
vmi.incrUpdated();
UpdateBuilder ub = getUpdateBuilder(vmi);
ub.set(vmi, "state", newState);
ub.set(vmi, "hostId", newHostId);
ub.set(vmi, "podIdToDeployIn", vmi.getPodIdToDeployIn());
@ -393,7 +405,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
if (result == 0 && s_logger.isDebugEnabled()) {
VMInstanceVO vo = findByIdIncludingRemoved(vm.getId());
if (vo != null) {
StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
str.append(": DB Data={Host=").append(vo.getHostId()).append("; State=").append(vo.getState().toString()).append("; updated=").append(vo.getUpdated()).append("; time=").append(vo.getUpdateTime());
@ -407,7 +419,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
}
return result > 0;
}
@Override
public List<VMInstanceVO> listByLastHostId(Long hostId) {
SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@ -415,7 +427,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
sc.setParameters("state", State.Stopped);
return listBy(sc);
}
@Override
public Long countAllocatedVirtualRoutersForAccount(long accountId) {
SearchCriteria<Long> sc = CountVirtualRoutersByAccount.create();
@ -424,7 +436,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging});
return customSearch(sc, null).get(0);
}
@Override
public List<VMInstanceVO> listVmsMigratingFromHost(Long hostId) {
SearchCriteria<VMInstanceVO> sc = AllFieldsSearch.create();
@ -432,7 +444,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
sc.setParameters("state", State.Migrating);
return listBy(sc);
}
@Override
public Long countRunningByHostId(long hostId){
SearchCriteria<Long> sc = CountRunningByHost.create();
@ -455,7 +467,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
pstmt = txn.prepareAutoCloseStatement(sql.toString());
pstmt.setLong(1, accountId);
pstmt.setLong(2, zoneId);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
Long clusterId = rs.getLong(1);
@ -484,11 +496,11 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
pstmt = txn.prepareAutoCloseStatement(sql.toString());
pstmt.setLong(1, accountId);
pstmt.setLong(2, podId);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
Long clusterId = rs.getLong(1);
result.add(clusterId);
result.add(clusterId);
clusterVmCountMap.put(clusterId, rs.getDouble(2));
}
return new Pair<List<Long>, Map<Long, Double>>(result, clusterVmCountMap);
@ -511,11 +523,11 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
pstmt = txn.prepareAutoCloseStatement(sql);
pstmt.setLong(1, accountId);
pstmt.setLong(2, dataCenterId);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
Long podId = rs.getLong(1);
result.add(podId);
result.add(podId);
podVmCountMap.put(podId, rs.getDouble(2));
}
return new Pair<List<Long>, Map<Long, Double>>(result, podVmCountMap);
@ -523,7 +535,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
throw new CloudRuntimeException("DB Exception on: " + ORDER_PODS_NUMBER_OF_VMS_FOR_ACCOUNT, e);
} catch (Throwable e) {
throw new CloudRuntimeException("Caught: " + ORDER_PODS_NUMBER_OF_VMS_FOR_ACCOUNT, e);
}
}
}
@Override
@ -538,7 +550,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
pstmt.setLong(2, dcId);
pstmt.setLong(3, podId);
pstmt.setLong(4, clusterId);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
result.add(rs.getLong(1));
@ -548,9 +560,9 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
throw new CloudRuntimeException("DB Exception on: " + ORDER_PODS_NUMBER_OF_VMS_FOR_ACCOUNT, e);
} catch (Throwable e) {
throw new CloudRuntimeException("Caught: " + ORDER_PODS_NUMBER_OF_VMS_FOR_ACCOUNT, e);
}
}
}
@Override
public Long countRunningByAccount(long accountId){
SearchCriteria<Long> sc = CountRunningByAccount.create();
@ -558,18 +570,18 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
sc.setParameters("state", State.Running);
return customSearch(sc, null).get(0);
}
@Override
public List<VMInstanceVO> listNonRemovedVmsByTypeAndNetwork(long networkId, VirtualMachine.Type... types) {
if (NetworkTypeSearch == null) {
SearchBuilder<NicVO> nicSearch = _nicDao.createSearchBuilder();
nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
NetworkTypeSearch = createSearchBuilder();
NetworkTypeSearch.and("types", NetworkTypeSearch.entity().getType(), SearchCriteria.Op.IN);
NetworkTypeSearch.and("removed", NetworkTypeSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
NetworkTypeSearch.join("nicSearch", nicSearch, NetworkTypeSearch.entity().getId(),
NetworkTypeSearch.join("nicSearch", nicSearch, NetworkTypeSearch.entity().getId(),
nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
NetworkTypeSearch.done();
}
@ -577,27 +589,27 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
SearchCriteria<VMInstanceVO> sc = NetworkTypeSearch.create();
if (types != null && types.length != 0) {
sc.setParameters("types", (Object[]) types);
}
}
sc.setJoinParameters("nicSearch", "networkId", networkId);
return listBy(sc);
}
@Override
public List<String> listDistinctHostNames(long networkId, VirtualMachine.Type... types) {
if (DistinctHostNameSearch == null) {
SearchBuilder<NicVO> nicSearch = _nicDao.createSearchBuilder();
nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
DistinctHostNameSearch = createSearchBuilder(String.class);
DistinctHostNameSearch.selectField(DistinctHostNameSearch.entity().getHostName());
DistinctHostNameSearch.and("types", DistinctHostNameSearch.entity().getType(), SearchCriteria.Op.IN);
DistinctHostNameSearch.and("removed", DistinctHostNameSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
DistinctHostNameSearch.join("nicSearch", nicSearch, DistinctHostNameSearch.entity().getId(),
DistinctHostNameSearch.join("nicSearch", nicSearch, DistinctHostNameSearch.entity().getId(),
nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
DistinctHostNameSearch.done();
}
@ -605,12 +617,12 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
SearchCriteria<String> sc = DistinctHostNameSearch.create();
if (types != null && types.length != 0) {
sc.setParameters("types", (Object[]) types);
}
}
sc.setJoinParameters("nicSearch", "networkId", networkId);
return customSearch(sc, null);
}
@Override
@DB
public boolean remove(Long id) {
@ -625,4 +637,19 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
return result;
}
@Override
public List<VMInstanceVO> findByHostInStates(Long hostId, State... states) {
SearchCriteria<VMInstanceVO> sc = HostAndStateSearch.create();
sc.setParameters("host", hostId);
sc.setParameters("states", (Object[]) states);
return listBy(sc);
}
@Override
public List<VMInstanceVO> listStartingWithNoHostId() {
SearchCriteria<VMInstanceVO> sc = StartingWithNoHostSearch.create();
sc.setParameters("state", State.Starting);
return listBy(sc);
}
}

View File

@ -608,4 +608,10 @@ public class MockResourceManagerImpl extends ManagerBase implements ResourceMana
return null;
}
@Override
public boolean releaseHostReservation(Long hostId) {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -934,7 +934,10 @@ CREATE TABLE `cloud`.`op_host_planner_reservation` (
CONSTRAINT `fk_planner_reservation__cluster_id` FOREIGN KEY (`cluster_id`) REFERENCES `cloud`.`cluster`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `deployment_planner` varchar(255) NOT NULL DEFAULT 'FirstFitPlanner' COMMENT 'Planner heuristics used to deploy a VM of this offering';
ALTER TABLE `cloud`.`service_offering` ADD COLUMN `deployment_planner` varchar(255) COMMENT 'Planner heuristics used to deploy a VM of this offering; if null global config vm.deployment.planner is used';
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.deployment.planner', 'FirstFitPlanner', '[''FirstFitPlanner'', ''UserDispersingPlanner'', ''UserConcentratedPodPlanner'']: DeploymentPlanner heuristic that will be used for VM deployment.');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'host.reservation.release.period', '300000', 'The interval in milliseconds between host reservation release checks');
DROP VIEW IF EXISTS `cloud`.`service_offering_view`;
CREATE VIEW `cloud`.`service_offering_view` AS