Merge branch 'master' into rbac
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/84a528fa Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/84a528fa Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/84a528fa Branch: refs/heads/rbac Commit: 84a528fad6979ed6745ad9eb9806d6b9a9fdb0f4 Parents: fa80c63 90c485e Author: Min Chen <[email protected]> Authored: Thu Mar 13 14:52:37 2014 -0700 Committer: Min Chen <[email protected]> Committed: Thu Mar 13 14:52:37 2014 -0700 ---------------------------------------------------------------------- api/src/com/cloud/domain/Domain.java | 3 - .../org/apache/cloudstack/api/ApiConstants.java | 2 +- .../org/apache/cloudstack/api/BaseListCmd.java | 2 +- .../api/command/user/vm/DeployVMCmd.java | 7 + .../api/command/user/vm/StartVMCmd.java | 11 +- .../src/com/cloud/vm/VirtualMachineManager.java | 2 +- .../cloud/entity/api/VirtualMachineEntity.java | 3 +- .../cloud/deploy/DeploymentPlanningManager.java | 4 +- .../com/cloud/vm/VirtualMachineManagerImpl.java | 20 +- .../src/com/cloud/vm/VmWorkStart.java | 12 +- .../cloud/entity/api/VMEntityManager.java | 3 +- .../cloud/entity/api/VMEntityManagerImpl.java | 19 +- .../entity/api/VirtualMachineEntityImpl.java | 4 +- .../security/dao/VmRulesetLogDaoImpl.java | 2 +- .../src/com/cloud/projects/ProjectVO.java | 5 + .../cloud/entity/api/db/VMReservationVO.java | 11 + .../jobs/impl/JobSerializerHelper.java | 5 +- .../mom/rabbitmq/RabbitMQEventBus.java | 18 +- .../lb/InternalLoadBalancerVMManagerImpl.java | 2 +- .../allocator/impl/FirstFitAllocator.java | 29 +-- .../dispatch/ParamGenericValidationWorker.java | 3 + .../src/com/cloud/dc/DedicatedResourceVO.java | 7 + .../deploy/DeploymentPlanningManagerImpl.java | 31 ++- .../src/com/cloud/deploy/FirstFitPlanner.java | 3 +- .../com/cloud/network/IpAddressManagerImpl.java | 4 +- .../cloud/network/as/AutoScaleManagerImpl.java | 4 +- .../com/cloud/server/ManagementServerImpl.java | 217 +------------------ server/src/com/cloud/vm/UserVmManager.java | 2 +- server/src/com/cloud/vm/UserVmManagerImpl.java | 35 ++- .../ParamGenericValidationWorkerTest.java | 24 ++ setup/db/db/schema-430to440.sql | 2 + 31 files changed, 175 insertions(+), 321 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/84a528fa/api/src/org/apache/cloudstack/api/ApiConstants.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/84a528fa/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/84a528fa/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java ---------------------------------------------------------------------- diff --cc api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java index 4e91c7b,f55aa59..13b7442 --- a/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java @@@ -16,18 -16,13 +16,19 @@@ // under the License. package org.apache.cloudstack.api.command.user.vm; - import org.apache.cloudstack.api.BaseAsyncVMCmd; +import org.apache.log4j.Logger; + +import org.apache.cloudstack.acl.IAMEntityType; + import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; + import org.apache.cloudstack.api.BaseAsyncVMCmd; import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.UserVmResponse; @@@ -70,6 -68,6 +74,7 @@@ public class StartVMCmd extends BaseAsy // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// ++ @Override public Long getId() { return id; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/84a528fa/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java ---------------------------------------------------------------------- diff --cc server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java index c1f336c,5312e15..9cbbb10 --- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java @@@ -1,57 -1,56 +1,56 @@@ -// 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 com.cloud.deploy; - -import java.util.ArrayList; +// 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 com.cloud.deploy; + +import java.util.ArrayList; import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; +import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.List; +import java.util.Map; import java.util.Set; -import java.util.Timer; -import java.util.TreeSet; - -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.affinity.AffinityGroupProcessor; -import org.apache.cloudstack.affinity.AffinityGroupService; +import java.util.Timer; +import java.util.TreeSet; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + - import org.apache.log4j.Logger; - +import org.apache.cloudstack.affinity.AffinityGroupProcessor; +import org.apache.cloudstack.affinity.AffinityGroupService; import org.apache.cloudstack.affinity.AffinityGroupVMMapVO; -import org.apache.cloudstack.affinity.AffinityGroupVO; -import org.apache.cloudstack.affinity.dao.AffinityGroupDao; -import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; -import org.apache.cloudstack.engine.cloud.entity.api.db.VMReservationVO; -import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMReservationDao; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.cloudstack.framework.messagebus.MessageBus; -import org.apache.cloudstack.framework.messagebus.MessageSubscriber; -import org.apache.cloudstack.managed.context.ManagedContextTimerTask; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.cloudstack.utils.identity.ManagementServerNode; +import org.apache.cloudstack.affinity.AffinityGroupVO; +import org.apache.cloudstack.affinity.dao.AffinityGroupDao; +import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; +import org.apache.cloudstack.engine.cloud.entity.api.db.VMReservationVO; +import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMReservationDao; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.messagebus.MessageBus; +import org.apache.cloudstack.framework.messagebus.MessageSubscriber; +import org.apache.cloudstack.managed.context.ManagedContextTimerTask; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.utils.identity.ManagementServerNode; + import org.apache.log4j.Logger; - + import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; @@@ -230,99 -229,94 +229,94 @@@ public class DeploymentPlanningManagerI public void setPlanners(List<DeploymentPlanner> planners) { _planners = planners; - } + } + + protected List<AffinityGroupProcessor> _affinityProcessors; - protected List<AffinityGroupProcessor> _affinityProcessors; + public List<AffinityGroupProcessor> getAffinityGroupProcessors() { + return _affinityProcessors; + } - public List<AffinityGroupProcessor> getAffinityGroupProcessors() { - return _affinityProcessors; - } - - public void setAffinityGroupProcessors(List<AffinityGroupProcessor> affinityProcessors) { + public void setAffinityGroupProcessors(List<AffinityGroupProcessor> affinityProcessors) { _affinityProcessors = affinityProcessors; - } - - @Override + } + + @Override public DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids, DeploymentPlanner planner) throws InsufficientServerCapacityException, AffinityConflictException { - - // call affinitygroup chain - VirtualMachine vm = vmProfile.getVirtualMachine(); - long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId()); + + // call affinitygroup chain + VirtualMachine vm = vmProfile.getVirtualMachine(); + long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId()); DataCenter dc = _dcDao.findById(vm.getDataCenterId()); - - if (vmGroupCount > 0) { - for (AffinityGroupProcessor processor : _affinityProcessors) { - processor.process(vmProfile, plan, avoids); - } + + if (vmGroupCount > 0) { + for (AffinityGroupProcessor processor : _affinityProcessors) { + processor.process(vmProfile, plan, avoids); + } + } + + if (vm.getType() == VirtualMachine.Type.User) { + checkForNonDedicatedResources(vmProfile, dc, avoids); } - - if (vm.getType() == VirtualMachine.Type.User) { - checkForNonDedicatedResources(vmProfile, dc, avoids); - } - if (s_logger.isDebugEnabled()) { + if (s_logger.isDebugEnabled()) { s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid()); - } - - // call planners + } + + // call planners //DataCenter dc = _dcDao.findById(vm.getDataCenterId()); - // check if datacenter is in avoid set - if (avoids.shouldAvoid(dc)) { - if (s_logger.isDebugEnabled()) { + // check if datacenter is in avoid set + if (avoids.shouldAvoid(dc)) { + if (s_logger.isDebugEnabled()) { s_logger.debug("DataCenter id = '" + dc.getId() + "' provided is in avoid set, DeploymentPlanner cannot allocate the VM, returning."); - } - return null; - } - - ServiceOffering offering = vmProfile.getServiceOffering(); + } + return null; + } + + ServiceOffering offering = vmProfile.getServiceOffering(); if(planner == null){ - String plannerName = offering.getDeploymentPlanner(); - if (plannerName == null) { - if (vm.getHypervisorType() == HypervisorType.BareMetal) { - plannerName = "BareMetalPlanner"; - } else { - plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key()); - } - } + String plannerName = offering.getDeploymentPlanner(); + if (plannerName == null) { + if (vm.getHypervisorType() == HypervisorType.BareMetal) { + plannerName = "BareMetalPlanner"; + } else { + plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key()); + } + } - for (DeploymentPlanner plannerInList : _planners) { - if (plannerName.equals(plannerInList.getName())) { - planner = plannerInList; - break; - } - } + planner = getDeploymentPlannerByName(plannerName); } - - int cpu_requested = offering.getCpu() * offering.getSpeed(); - long ram_requested = offering.getRamSize() * 1024L * 1024L; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("DeploymentPlanner allocation algorithm: " + planner); - + + int cpu_requested = offering.getCpu() * offering.getSpeed(); + long ram_requested = offering.getRamSize() * 1024L * 1024L; + + if (s_logger.isDebugEnabled()) { + s_logger.debug("DeploymentPlanner allocation algorithm: " + planner); + s_logger.debug("Trying to allocate a host and storage pools from dc:" + plan.getDataCenterId() + ", pod:" + plan.getPodId() + ",cluster:" + plan.getClusterId() + ", requested cpu: " + cpu_requested + ", requested ram: " + ram_requested); - + s_logger.debug("Is ROOT volume READY (pool already allocated)?: " + (plan.getPoolId() != null ? "Yes" : "No")); - } - + } + String haVmTag = (String)vmProfile.getParameter(VirtualMachineProfile.Param.HaTag); - - if (plan.getHostId() != null && haVmTag == null) { - Long hostIdSpecified = plan.getHostId(); - if (s_logger.isDebugEnabled()) { + + if (plan.getHostId() != null && haVmTag == null) { + Long hostIdSpecified = plan.getHostId(); + if (s_logger.isDebugEnabled()) { s_logger.debug("DeploymentPlan has host_id specified, choosing this host and making no checks on this host: " + hostIdSpecified); - } - HostVO host = _hostDao.findById(hostIdSpecified); - if (host == null) { - s_logger.debug("The specified host cannot be found"); - } else if (avoids.shouldAvoid(host)) { - s_logger.debug("The specified host is in avoid set"); - } else { - if (s_logger.isDebugEnabled()) { + } + HostVO host = _hostDao.findById(hostIdSpecified); + if (host == null) { + s_logger.debug("The specified host cannot be found"); + } else if (avoids.shouldAvoid(host)) { + s_logger.debug("The specified host is in avoid set"); + } else { + if (s_logger.isDebugEnabled()) { s_logger.debug("Looking for suitable pools for this host under zone: " + host.getDataCenterId() + ", pod: " + host.getPodId() + ", cluster: " + host.getClusterId()); - } - - // search for storage under the zone, pod, cluster of the host. + } + + // search for storage under the zone, pod, cluster of the host. DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), hostIdSpecified, plan.getPoolId(), null, plan.getReservationContext()); @@@ -440,100 -434,114 +434,114 @@@ } else { s_logger.debug("The last host of this VM is not UP or is not enabled, host status is: " + host.getStatus().name() + ", host resource state is: " + host.getResourceState()); - } - } - s_logger.debug("Cannot choose the last host to deploy this VM "); - } - - DeployDestination dest = null; - List<Long> clusterList = null; - - if (planner != null && planner.canHandle(vmProfile, plan, avoids)) { - while (true) { - if (planner instanceof DeploymentClusterPlanner) { - + } + } + s_logger.debug("Cannot choose the last host to deploy this VM "); + } + + DeployDestination dest = null; + List<Long> clusterList = null; + + if (planner != null && planner.canHandle(vmProfile, plan, avoids)) { + while (true) { - + if (planner instanceof DeploymentClusterPlanner) { + ExcludeList plannerAvoidInput = new ExcludeList(avoids.getDataCentersToAvoid(), avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(), - avoids.getPoolsToAvoid()); - + avoids.getPoolsToAvoid()); + clusterList = ((DeploymentClusterPlanner)planner).orderClusters(vmProfile, plan, avoids); - - if (clusterList != null && !clusterList.isEmpty()) { - // planner refactoring. call allocators to list hosts + + 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()); - - resetAvoidSet(plannerAvoidOutput, plannerAvoidInput); - + avoids.getPoolsToAvoid()); + + resetAvoidSet(plannerAvoidOutput, plannerAvoidInput); + dest = checkClustersforDestination(clusterList, vmProfile, plan, avoids, dc, getPlannerUsage(planner, vmProfile, plan, avoids), 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 { - // find another host - seems some concurrent - // deployment picked it up for dedicated access - continue; - } - } else { - return null; - } - } - } - } - - return dest; - } - + 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 { + // find another host - seems some concurrent + // deployment picked it up for dedicated access + continue; + } + } else { + return null; + } + } + } + } + + return dest; + } + + @Override + public DeploymentPlanner getDeploymentPlannerByName(String plannerName) { + if (plannerName != null) { + for (DeploymentPlanner plannerInList : _planners) { + if (plannerName != null) { + } + if (plannerName.equalsIgnoreCase(plannerInList.getName())) { + return plannerInList; + } + } + } + + return null; + } + private void checkForNonDedicatedResources(VirtualMachineProfile vmProfile, DataCenter dc, ExcludeList avoids) { - boolean isExplicit = false; - VirtualMachine vm = vmProfile.getVirtualMachine(); - - // check if zone is dedicated. if yes check if vm owner has acess to it. - DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(dc.getId()); - if (dedicatedZone != null && !_accountMgr.isRootAdmin(vmProfile.getOwner().getType())) { - long accountDomainId = vmProfile.getOwner().getDomainId(); - long accountId = vmProfile.getOwner().getAccountId(); - - // If a zone is dedicated to an account then all hosts in this zone - // will be explicitly dedicated to - // that account. So there won't be any shared hosts in the zone, the - // only way to deploy vms from that - // account will be to use explicit dedication affinity group. - if (dedicatedZone.getAccountId() != null) { - if (dedicatedZone.getAccountId().equals(accountId)) { - return; - } else { + boolean isExplicit = false; + VirtualMachine vm = vmProfile.getVirtualMachine(); + + // check if zone is dedicated. if yes check if vm owner has acess to it. + DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(dc.getId()); + if (dedicatedZone != null && !_accountMgr.isRootAdmin(vmProfile.getOwner().getId())) { + long accountDomainId = vmProfile.getOwner().getDomainId(); + long accountId = vmProfile.getOwner().getAccountId(); + + // If a zone is dedicated to an account then all hosts in this zone + // will be explicitly dedicated to + // that account. So there won't be any shared hosts in the zone, the + // only way to deploy vms from that + // account will be to use explicit dedication affinity group. + if (dedicatedZone.getAccountId() != null) { + if (dedicatedZone.getAccountId().equals(accountId)) { + return; + } else { throw new CloudRuntimeException("Failed to deploy VM, Zone " + dc.getName() + " not available for the user account " + vmProfile.getOwner()); - } - } - - // if zone is dedicated to a domain. Check owner's access to the - // domain level dedication group + } + } + + // if zone is dedicated to a domain. Check owner's access to the + // domain level dedication group if (!_affinityGroupService.isAffinityGroupAvailableInDomain(dedicatedZone.getAffinityGroupId(), accountDomainId)) { throw new CloudRuntimeException("Failed to deploy VM, Zone " + dc.getName() + " not available for the user domain " + vmProfile.getOwner()); - } - - } - - // check affinity group of type Explicit dedication exists. If No put + } + + } + + // check affinity group of type Explicit dedication exists. If No put // dedicated pod/cluster/host in avoid list List<AffinityGroupVMMapVO> vmGroupMappings = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), "ExplicitDedication"); @@@ -1302,111 -1310,114 +1310,114 @@@ avoid.getPoolsToAvoid().addAll(poolsToAvoidOutput); } - if (suitableVolumeStoragePools.isEmpty()) { - s_logger.debug("No suitable pools found"); - } - - return new Pair<Map<Volume, List<StoragePool>>, List<Volume>>(suitableVolumeStoragePools, readyAndReusedVolumes); - } - - private boolean isEnabledForAllocation(long zoneId, Long podId, Long clusterId) { - // Check if the zone exists in the system - DataCenterVO zone = _dcDao.findById(zoneId); - if (zone != null && Grouping.AllocationState.Disabled == zone.getAllocationState()) { - s_logger.info("Zone is currently disabled, cannot allocate to this zone: " + zoneId); - return false; - } - - Pod pod = _podDao.findById(podId); - if (pod != null && Grouping.AllocationState.Disabled == pod.getAllocationState()) { - s_logger.info("Pod is currently disabled, cannot allocate to this pod: " + podId); - return false; - } - - Cluster cluster = _clusterDao.findById(clusterId); - if (cluster != null && Grouping.AllocationState.Disabled == cluster.getAllocationState()) { - s_logger.info("Cluster is currently disabled, cannot allocate to this cluster: " + clusterId); - return false; - } - - return true; - } - - private boolean isRootAdmin(ReservationContext reservationContext) { - if (reservationContext != null) { - if (reservationContext.getAccount() != null) { - return _accountMgr.isRootAdmin(reservationContext.getAccount().getType()); - } else { - return false; - } - } - return false; - } - - @DB - @Override + if (suitableVolumeStoragePools.isEmpty()) { + s_logger.debug("No suitable pools found"); + } + + return new Pair<Map<Volume, List<StoragePool>>, List<Volume>>(suitableVolumeStoragePools, readyAndReusedVolumes); + } + + private boolean isEnabledForAllocation(long zoneId, Long podId, Long clusterId) { + // Check if the zone exists in the system + DataCenterVO zone = _dcDao.findById(zoneId); + if (zone != null && Grouping.AllocationState.Disabled == zone.getAllocationState()) { + s_logger.info("Zone is currently disabled, cannot allocate to this zone: " + zoneId); + return false; + } + + Pod pod = _podDao.findById(podId); + if (pod != null && Grouping.AllocationState.Disabled == pod.getAllocationState()) { + s_logger.info("Pod is currently disabled, cannot allocate to this pod: " + podId); + return false; + } + + Cluster cluster = _clusterDao.findById(clusterId); + if (cluster != null && Grouping.AllocationState.Disabled == cluster.getAllocationState()) { + s_logger.info("Cluster is currently disabled, cannot allocate to this cluster: " + clusterId); + return false; + } + + return true; + } + + private boolean isRootAdmin(ReservationContext reservationContext) { + if (reservationContext != null) { + if (reservationContext.getAccount() != null) { + return _accountMgr.isRootAdmin(reservationContext.getAccount().getId()); + } else { + return false; + } + } + return false; + } + + @DB + @Override - public String finalizeReservation(final DeployDestination plannedDestination, final VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids) + public String finalizeReservation(final DeployDestination plannedDestination, final VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids, final DeploymentPlanner planner) - throws InsufficientServerCapacityException, AffinityConflictException { - - final VirtualMachine vm = vmProfile.getVirtualMachine(); - final long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId()); - - return Transaction.execute(new TransactionCallback<String>() { - @Override - public String doInTransaction(TransactionStatus status) { - boolean saveReservation = true; - - if (vmGroupCount > 0) { - List<Long> groupIds = _affinityGroupVMMapDao.listAffinityGroupIdsByVmId(vm.getId()); - SearchCriteria<AffinityGroupVO> criteria = _affinityGroupDao.createSearchCriteria(); - criteria.addAnd("id", SearchCriteria.Op.IN, groupIds.toArray(new Object[groupIds.size()])); - List<AffinityGroupVO> groups = _affinityGroupDao.lockRows(criteria, null, true); - - for (AffinityGroupProcessor processor : _affinityProcessors) { - if (!processor.check(vmProfile, plannedDestination)) { - saveReservation = false; - break; - } - } - } - - if (saveReservation) { + throws InsufficientServerCapacityException, AffinityConflictException { + + final VirtualMachine vm = vmProfile.getVirtualMachine(); + final long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId()); + + return Transaction.execute(new TransactionCallback<String>() { + @Override + public String doInTransaction(TransactionStatus status) { + boolean saveReservation = true; + + if (vmGroupCount > 0) { + List<Long> groupIds = _affinityGroupVMMapDao.listAffinityGroupIdsByVmId(vm.getId()); + SearchCriteria<AffinityGroupVO> criteria = _affinityGroupDao.createSearchCriteria(); + criteria.addAnd("id", SearchCriteria.Op.IN, groupIds.toArray(new Object[groupIds.size()])); + List<AffinityGroupVO> groups = _affinityGroupDao.lockRows(criteria, null, true); + + for (AffinityGroupProcessor processor : _affinityProcessors) { + if (!processor.check(vmProfile, plannedDestination)) { + saveReservation = false; + break; + } + } + } + + if (saveReservation) { VMReservationVO vmReservation = new VMReservationVO(vm.getId(), plannedDestination.getDataCenter().getId(), plannedDestination.getPod().getId(), plannedDestination.getCluster() .getId(), plannedDestination.getHost().getId()); + if (planner != null) { + vmReservation.setDeploymentPlanner(planner.getName()); + } - Map<Long, Long> volumeReservationMap = new HashMap<Long, Long>(); - - if (vm.getHypervisorType() != HypervisorType.BareMetal) { - for (Volume vo : plannedDestination.getStorageForDisks().keySet()) { - volumeReservationMap.put(vo.getId(), plannedDestination.getStorageForDisks().get(vo).getId()); - } - vmReservation.setVolumeReservation(volumeReservationMap); - } - _reservationDao.persist(vmReservation); - return vmReservation.getUuid(); - } - - return null; - } - }); - } - - @Override + Map<Long, Long> volumeReservationMap = new HashMap<Long, Long>(); + + if (vm.getHypervisorType() != HypervisorType.BareMetal) { + for (Volume vo : plannedDestination.getStorageForDisks().keySet()) { + volumeReservationMap.put(vo.getId(), plannedDestination.getStorageForDisks().get(vo).getId()); + } + vmReservation.setVolumeReservation(volumeReservationMap); + } + _reservationDao.persist(vmReservation); + return vmReservation.getUuid(); + } + + return null; + } + }); + } + + @Override public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) { - return true; - } - - @Override + return true; + } + + @Override public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) { - if (!status) { - return false; - } - if ((oldState == State.Starting) && (newState != State.Starting)) { - // cleanup all VM reservation entries - SearchCriteria<VMReservationVO> sc = _reservationDao.createSearchCriteria(); - sc.addAnd("vmId", SearchCriteria.Op.EQ, vo.getId()); - _reservationDao.expunge(sc); - } - return true; - } -} + if (!status) { + return false; + } + if ((oldState == State.Starting) && (newState != State.Starting)) { + // cleanup all VM reservation entries + SearchCriteria<VMReservationVO> sc = _reservationDao.createSearchCriteria(); + sc.addAnd("vmId", SearchCriteria.Op.EQ, vo.getId()); + _reservationDao.expunge(sc); + } + return true; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/84a528fa/server/src/com/cloud/deploy/FirstFitPlanner.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/84a528fa/server/src/com/cloud/network/IpAddressManagerImpl.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/84a528fa/server/src/com/cloud/network/as/AutoScaleManagerImpl.java ---------------------------------------------------------------------- diff --cc server/src/com/cloud/network/as/AutoScaleManagerImpl.java index 755fc54,61b7f4b..99189fe --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@@ -1375,18 -1366,18 +1375,18 @@@ public class AutoScaleManagerImpl<Type return sdf.format(current); } - private boolean startNewVM(final long vmId) { + private boolean startNewVM(long vmId) { try { CallContext.current().setEventDetails("Vm Id: " + vmId); - _userVmManager.startVirtualMachine(vmId, null, null); - } catch (ResourceUnavailableException ex) { + _userVmManager.startVirtualMachine(vmId, null, null, null); + } catch (final ResourceUnavailableException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); - } catch (final ConcurrentOperationException ex) { + } catch (ConcurrentOperationException ex) { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); - } catch (final InsufficientCapacityException ex) { - final StringBuilder message = new StringBuilder(ex.getMessage()); + } catch (InsufficientCapacityException ex) { + StringBuilder message = new StringBuilder(ex.getMessage()); if (ex instanceof InsufficientServerCapacityException) { if (((InsufficientServerCapacityException)ex).isAffinityApplied()) { message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them"); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/84a528fa/server/src/com/cloud/server/ManagementServerImpl.java ---------------------------------------------------------------------- diff --cc server/src/com/cloud/server/ManagementServerImpl.java index 09823d7,2b63ae9..073cf47 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@@ -40,11 -40,7 +40,10 @@@ import javax.crypto.spec.SecretKeySpec import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + import org.apache.cloudstack.acl.ControlledEntity; - import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.affinity.AffinityGroupProcessor; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.api.ApiConstants; @@@ -735,10 -723,7 +726,9 @@@ public class ManagementServerImpl exten @Inject private UserVmManager _userVmMgr; @Inject + private AccountService _accountService; + @Inject private ServiceOfferingDao _offeringDao; - @Inject private DeploymentPlanningManager _dpMgr; @@@ -1708,210 -1692,108 +1697,6 @@@ return new Pair<List<? extends Configuration>, Integer>(result.first(), result.second()); } -- /* TODO: this method should go away. Keep here just in case that our latest refactoring using template_store_ref missed anything -- * in handling Swift or S3. -- private Set<Pair<Long, Long>> listTemplates(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, -- Boolean bootable, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, -- List<Account> permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags, String zoneType) { -- -- VMTemplateVO template = null; -- if (templateId != null) { -- template = _templateDao.findById(templateId); -- if (template == null) { -- throw new InvalidParameterValueException("Please specify a valid template ID."); -- }// If ISO requested then it should be ISO. -- if (isIso && template.getFormat() != ImageFormat.ISO) { -- s_logger.error("Template Id " + templateId + " is not an ISO"); -- InvalidParameterValueException ex = new InvalidParameterValueException("Specified Template Id is not an ISO"); -- ex.addProxyObject(template.getUuid(), "templateId"); -- throw ex; -- }// If ISO not requested then it shouldn't be an ISO. -- if (!isIso && template.getFormat() == ImageFormat.ISO) { -- s_logger.error("Incorrect format of the template id " + templateId); -- InvalidParameterValueException ex = new InvalidParameterValueException("Incorrect format " + template.getFormat() -- + " of the specified template id"); -- ex.addProxyObject(template.getUuid(), "templateId"); -- throw ex; -- } -- } -- -- DomainVO domain = null; -- if (!permittedAccounts.isEmpty()) { -- domain = _domainDao.findById(permittedAccounts.get(0).getDomainId()); -- } else { -- domain = _domainDao.findById(DomainVO.ROOT_DOMAIN); -- } -- -- List<HypervisorType> hypers = null; -- if (!isIso) { -- hypers = _resourceMgr.listAvailHypervisorInZone(null, null); -- } -- Set<Pair<Long, Long>> templateZonePairSet = new HashSet<Pair<Long, Long>>(); -- if (_swiftMgr.isSwiftEnabled()) { -- if (template == null) { -- templateZonePairSet = _templateDao.searchSwiftTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, -- startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller, tags); -- Set<Pair<Long, Long>> templateZonePairSet2 = new HashSet<Pair<Long, Long>>(); -- templateZonePairSet2 = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, -- startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller, listProjectResourcesCriteria, tags, zoneType); -- -- for (Pair<Long, Long> tmpltPair : templateZonePairSet2) { -- if (!templateZonePairSet.contains(new Pair<Long, Long>(tmpltPair.first(), -1L))) { -- templateZonePairSet.add(tmpltPair); -- } -- } -- -- } else { -- // if template is not public, perform permission check here -- if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { -- Account owner = _accountMgr.getAccount(template.getAccountId()); -- _accountMgr.checkAccess(caller, null, true, owner); -- } -- templateZonePairSet.add(new Pair<Long, Long>(template.getId(), zoneId)); -- } -- } else if (_s3Mgr.isS3Enabled()) { -- if (template == null) { -- templateZonePairSet = _templateDao.searchSwiftTemplates(name, keyword, templateFilter, isIso, -- hypers, bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, -- permittedAccounts, caller, tags); -- Set<Pair<Long, Long>> templateZonePairSet2 = new HashSet<Pair<Long, Long>>(); -- templateZonePairSet2 = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, -- bootable, domain, pageSize, startIndex, zoneId, hyperType, onlyReady, showDomr, -- permittedAccounts, caller, listProjectResourcesCriteria, tags, zoneType); -- -- for (Pair<Long, Long> tmpltPair : templateZonePairSet2) { -- if (!templateZonePairSet.contains(new Pair<Long, Long>(tmpltPair.first(), -1L))) { -- templateZonePairSet.add(tmpltPair); -- } -- } -- } else { -- // if template is not public, perform permission check here -- if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { -- Account owner = _accountMgr.getAccount(template.getAccountId()); -- _accountMgr.checkAccess(caller, null, true, owner); -- } -- templateZonePairSet.add(new Pair<Long, Long>(template.getId(), zoneId)); -- } -- } else { -- if (template == null) { -- templateZonePairSet = _templateDao.searchTemplates(name, keyword, templateFilter, isIso, hypers, bootable, domain, pageSize, -- startIndex, zoneId, hyperType, onlyReady, showDomr, permittedAccounts, caller, listProjectResourcesCriteria, tags, zoneType); -- } else { -- // if template is not public, perform permission check here -- if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { -- Account owner = _accountMgr.getAccount(template.getAccountId()); -- _accountMgr.checkAccess(caller, null, true, owner); -- } -- templateZonePairSet.add(new Pair<Long, Long>(template.getId(), zoneId)); -- } -- } -- -- return templateZonePairSet; -- } -- */ -- - private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) { - Long id = cmd.getId(); - String name = cmd.getTemplateName(); - String displayText = cmd.getDisplayText(); - String format = cmd.getFormat(); - Long guestOSId = cmd.getOsTypeId(); - Boolean passwordEnabled = cmd.isPasswordEnabled(); - Boolean bootable = cmd.isBootable(); - Integer sortKey = cmd.getSortKey(); - Boolean isDynamicallyScalable = cmd.isDynamicallyScalable(); - Boolean isRoutingTemplate = cmd.isRoutingType(); - Account account = CallContext.current().getCallingAccount(); - - // verify that template exists - VMTemplateVO template = _templateDao.findById(id); - if (template == null || template.getRemoved() != null) { - InvalidParameterValueException ex = new InvalidParameterValueException("unable to find template/iso with specified id"); - ex.addProxyObject(id.toString(), "templateId"); - throw ex; - } - - // Don't allow to modify system template - if (id.equals(Long.valueOf(1))) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id"); - ex.addProxyObject(template.getUuid(), "templateId"); - throw ex; - } - - // do a permission check - _accountMgr.checkAccess(account, AccessType.OperateEntry, true, template); - - if(cmd.isRoutingType() != null){ - if (!_accountService.isRootAdmin(account.getId())) { - throw new PermissionDeniedException("Parameter isrouting can only be specified by a Root Admin, permission denied"); - } - } - boolean updateNeeded = !(name == null && displayText == null && format == null && guestOSId == null && passwordEnabled == null && bootable == null && sortKey == null - && isDynamicallyScalable == null && isRoutingTemplate == null); - if (!updateNeeded) { - return template; - } - - template = _templateDao.createForUpdate(id); - - if (name != null) { - template.setName(name); - } - - if (displayText != null) { - template.setDisplayText(displayText); - } - - if (sortKey != null) { - template.setSortKey(sortKey); - } - - ImageFormat imageFormat = null; - if (format != null) { - try { - imageFormat = ImageFormat.valueOf(format.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new InvalidParameterValueException("Image format: " + format + " is incorrect. Supported formats are " + EnumUtils.listValues(ImageFormat.values())); - } - - template.setFormat(imageFormat); - } - - if (guestOSId != null) { - GuestOSVO guestOS = _guestOSDao.findById(guestOSId); - - if (guestOS == null) { - throw new InvalidParameterValueException("Please specify a valid guest OS ID."); - } else { - template.setGuestOSId(guestOSId); - } - } - - if (passwordEnabled != null) { - template.setEnablePassword(passwordEnabled); - } - - if (bootable != null) { - template.setBootable(bootable); - } - - if (isDynamicallyScalable != null) { - template.setDynamicallyScalable(isDynamicallyScalable); - } - - if (isRoutingTemplate != null) { - if (isRoutingTemplate) { - template.setTemplateType(TemplateType.ROUTING); - } else { - template.setTemplateType(TemplateType.USER); - } - } - - _templateDao.update(id, template); - - return _templateDao.findById(id); - } - @Override public Pair<List<? extends IpAddress>, Integer> searchForIPAddresses(ListPublicIpAddressesCmd cmd) { Object keyword = cmd.getKeyword(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/84a528fa/server/src/com/cloud/vm/UserVmManager.java ---------------------------------------------------------------------- diff --cc server/src/com/cloud/vm/UserVmManager.java index 0e48414,11b110f..afe1002 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@@ -88,7 -92,23 +88,7 @@@ public interface UserVmManager extends boolean expunge(UserVmVO vm, long callerUserId, Account caller); - Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams) - /** - * Obtains a list of virtual machines by the specified search criteria. - * Can search by: "userId", "name", "state", "dataCenterId", "podId", "hostId" - * @param c - * @param caller TODO - * @param domainId TODO - * @param isRecursive TODO - * @param permittedAccounts TODO - * @param listAll TODO - * @param listProjectResourcesCriteria TODO - * @param tags TODO - * @return List of UserVMs + count - */ - Pair<List<UserVmJoinVO>, Integer> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List<Long> permittedAccounts, boolean listAll, - ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags); - + Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map<String, String> customParameters) throws ResourceUnavailableException, http://git-wip-us.apache.org/repos/asf/cloudstack/blob/84a528fa/server/src/com/cloud/vm/UserVmManagerImpl.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/84a528fa/setup/db/db/schema-430to440.sql ----------------------------------------------------------------------
