@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 protected List<StoragePool> select( DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { List<StoragePool> suitablePools = new ArrayList<StoragePool>(); s_logger.debug("LocalStoragePoolAllocator trying to find storage pool to fit the vm"); if (!dskCh.useLocalStorage()) { return suitablePools; } // data disk and host identified from deploying vm (attach volume case) if (dskCh.getType() == Volume.Type.DATADISK && plan.getHostId() != null) { List<StoragePoolHostVO> hostPools = _poolHostDao.listByHostId(plan.getHostId()); for (StoragePoolHostVO hostPool : hostPools) { StoragePoolVO pool = _storagePoolDao.findById(hostPool.getPoolId()); if (pool != null && pool.isLocal()) { StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); if (filter(avoid, pol, dskCh, plan)) { s_logger.debug( "Found suitable local storage pool " + pool.getId() + ", adding to list"); suitablePools.add(pol); } else { avoid.addPool(pool.getId()); } } if (suitablePools.size() == returnUpTo) { break; } } } else { if (plan.getPodId() == null) { // zone wide primary storage deployment return null; } List<StoragePoolVO> availablePools = _storagePoolDao.findLocalStoragePoolsByTags( plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), dskCh.getTags()); for (StoragePoolVO pool : availablePools) { if (suitablePools.size() == returnUpTo) { break; } StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); if (filter(avoid, pol, dskCh, plan)) { suitablePools.add(pol); } else { avoid.addPool(pool.getId()); } } // add remaining pools in cluster, that did not match tags, to avoid // set List<StoragePoolVO> allPools = _storagePoolDao.findLocalStoragePoolsByTags( plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), null); allPools.removeAll(availablePools); for (StoragePoolVO pool : allPools) { avoid.addPool(pool.getId()); } } if (s_logger.isDebugEnabled()) { s_logger.debug( "LocalStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools"); } return suitablePools; }