@Override public String reserveVirtualMachine( VMEntityVO vmEntityVO, String plannerToUse, DeploymentPlan planToDeploy, ExcludeList exclude) throws InsufficientCapacityException, ResourceUnavailableException { // call planner and get the deployDestination. // load vm instance and offerings and call virtualMachineManagerImpl // FIXME: profile should work on VirtualMachineEntity VMInstanceVO vm = _vmDao.findByUuid(vmEntityVO.getUuid()); VirtualMachineProfileImpl<VMInstanceVO> vmProfile = new VirtualMachineProfileImpl<VMInstanceVO>(vm); DataCenterDeployment plan = new DataCenterDeployment( vm.getDataCenterId(), vm.getPodIdToDeployIn(), null, null, null, null); if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) { plan = new DataCenterDeployment( planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId()); } List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vm.getId()); if (!vols.isEmpty()) { VolumeVO vol = vols.get(0); StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); if (!pool.isInMaintenance()) { long rootVolDcId = pool.getDataCenterId(); Long rootVolPodId = pool.getPodId(); Long rootVolClusterId = pool.getClusterId(); if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) { Long clusterIdSpecified = planToDeploy.getClusterId(); if (clusterIdSpecified != null && rootVolClusterId != null) { if (rootVolClusterId.longValue() != clusterIdSpecified.longValue()) { // cannot satisfy the plan passed in to the // planner throw new ResourceUnavailableException( "Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + vm, Cluster.class, clusterIdSpecified); } } plan = new DataCenterDeployment( planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), vol.getPoolId(), null, null); } else { plan = new DataCenterDeployment( rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId(), null, null); } } } DeploymentPlanner planner = ComponentContext.getComponent(plannerToUse); DeployDestination dest = null; if (planner.canHandle(vmProfile, plan, exclude)) { dest = planner.plan(vmProfile, plan, exclude); } if (dest != null) { // save destination with VMEntityVO VMReservationVO vmReservation = new VMReservationVO( vm.getId(), dest.getDataCenter().getId(), dest.getPod().getId(), dest.getCluster().getId(), dest.getHost().getId()); Map<Long, Long> volumeReservationMap = new HashMap<Long, Long>(); for (Volume vo : dest.getStorageForDisks().keySet()) { volumeReservationMap.put(vo.getId(), dest.getStorageForDisks().get(vo).getId()); } vmReservation.setVolumeReservation(volumeReservationMap); vmEntityVO.setVmReservation(vmReservation); _vmEntityDao.persist(vmEntityVO); return vmReservation.getUuid(); } else { throw new InsufficientServerCapacityException( "Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId()); } }
@Override @DB public void recalculateCapacity() { // FIXME: the right way to do this is to register a listener (see RouterStatsListener, // VMSyncListener) // for the vm sync state. The listener model has connects/disconnects to keep things in // sync much better // than this model right now, so when a VM is started, we update the amount allocated, // and when a VM // is stopped we updated the amount allocated, and when VM sync reports a changed state, // we update // the amount allocated. Hopefully it's limited to 3 entry points and will keep the // amount allocated // per host accurate. try { if (s_logger.isDebugEnabled()) { s_logger.debug("recalculating system capacity"); s_logger.debug("Executing cpu/ram capacity update"); } // Calculate CPU and RAM capacities // get all hosts...even if they are not in 'UP' state List<HostVO> hosts = _resourceMgr.listAllHostsInAllZonesByType(Host.Type.Routing); for (HostVO host : hosts) { _capacityMgr.updateCapacityForHost(host); } if (s_logger.isDebugEnabled()) { s_logger.debug("Done executing cpu/ram capacity update"); s_logger.debug("Executing storage capacity update"); } // Calculate storage pool capacity List<StoragePoolVO> storagePools = _storagePoolDao.listAll(); for (StoragePoolVO pool : storagePools) { long disk = 0l; Pair<Long, Long> sizes = _volumeDao.getCountAndTotalByPool(pool.getId()); disk = sizes.second(); if (pool.isShared()) { _storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, disk); } else { _storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_LOCAL_STORAGE, disk); } } if (s_logger.isDebugEnabled()) { s_logger.debug("Done executing storage capacity update"); s_logger.debug("Executing capacity updates public ip and Vlans"); } List<DataCenterVO> datacenters = _dcDao.listAll(); for (DataCenterVO datacenter : datacenters) { long dcId = datacenter.getId(); // NOTE // What happens if we have multiple vlans? Dashboard currently shows stats // with no filter based on a vlan // ideal way would be to remove out the vlan param, and filter only on dcId // implementing the same // Calculate new Public IP capacity for Virtual Network if (datacenter.getNetworkType() == NetworkType.Advanced) { createOrUpdateIpCapacity(dcId, null, CapacityVO.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP); } // Calculate new Public IP capacity for Direct Attached Network createOrUpdateIpCapacity(dcId, null, CapacityVO.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP); if (datacenter.getNetworkType() == NetworkType.Advanced) { // Calculate VLAN's capacity createOrUpdateVlanCapacity(dcId); } } if (s_logger.isDebugEnabled()) { s_logger.debug("Done capacity updates for public ip and Vlans"); s_logger.debug("Executing capacity updates for private ip"); } // Calculate new Private IP capacity List<HostPodVO> pods = _podDao.listAll(); for (HostPodVO pod : pods) { long podId = pod.getId(); long dcId = pod.getDataCenterId(); createOrUpdateIpCapacity(dcId, podId, CapacityVO.CAPACITY_TYPE_PRIVATE_IP); } if (s_logger.isDebugEnabled()) { s_logger.debug("Done executing capacity updates for private ip"); s_logger.debug("Done recalculating system capacity"); } } catch (Throwable t) { s_logger.error("Caught exception in recalculating capacity", t); } }