http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef22b42b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java index 252cf8a..cdd46ce 100644 --- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java @@ -30,6 +30,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; 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; @@ -66,6 +67,7 @@ import com.cloud.deploy.dao.PlannerHostReservationDao; import com.cloud.exception.AffinityConflictException; import com.cloud.exception.ConnectionException; import com.cloud.exception.InsufficientServerCapacityException; +import com.cloud.exception.PermissionDeniedException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; @@ -133,6 +135,8 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy @Inject protected AffinityGroupVMMapDao _affinityGroupVMMapDao; @Inject + AffinityGroupService _affinityGroupService; + @Inject DataCenterDao _dcDao; @Inject PlannerHostReservationDao _plannerHostReserveDao; @@ -215,7 +219,9 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } } - checkForNonDedicatedResources(vmProfile, dc, avoids); + if (vm.getType() == VirtualMachine.Type.User) { + checkForNonDedicatedResources(vmProfile, dc, avoids); + } if (s_logger.isDebugEnabled()) { s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid()); @@ -444,20 +450,48 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy private void checkForNonDedicatedResources(VirtualMachineProfile vmProfile, DataCenter dc, ExcludeList avoids) { boolean isExplicit = false; - VirtualMachine vm = vmProfile.getVirtualMachine(); - // check affinity group of type Explicit dedication exists + 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) { + 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 (!_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 + // dedicated pod/cluster/host in avoid list List<AffinityGroupVMMapVO> vmGroupMappings = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), "ExplicitDedication"); if (vmGroupMappings != null && !vmGroupMappings.isEmpty()){ isExplicit = true; } - if (!isExplicit && vm.getType() == VirtualMachine.Type.User) { + if (!isExplicit) { //add explicitly dedicated resources in avoidList - DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(dc.getId()); - if (dedicatedZone != null && dedicatedZone.getDomainId() != null) { - throw new CloudRuntimeException("Failed to deploy VM. Zone " + dc.getName() + " is dedicated . Please use Explicit Dedication Affinity Group"); - } List<Long> allPodsInDc = _podDao.listAllPods(dc.getId()); List<Long> allDedicatedPods = _dedicatedDao.listAllPods();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef22b42b/server/src/com/cloud/vm/UserVmManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 1ce3f20..53211e1 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2503,20 +2503,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir + zone.getId()); } - boolean isExplicit = false; - // check affinity group type Explicit dedication - if (affinityGroupIdList != null) { - for (Long affinityGroupId : affinityGroupIdList) { - AffinityGroupVO ag = _affinityGroupDao.findById(affinityGroupId); - String agType = ag.getType(); - if (agType.equals("ExplicitDedication")) { - isExplicit = true; - } - } - } // check if zone is dedicated DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(zone.getId()); - if (isExplicit && dedicatedZone != null) { + if (dedicatedZone != null) { DomainVO domain = _domainDao.findById(dedicatedZone.getDomainId()); if (domain == null) { throw new CloudRuntimeException("Unable to find the domain " http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef22b42b/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java ---------------------------------------------------------------------- diff --git a/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java b/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java index 06c04cb..c6f1b92 100644 --- a/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java +++ b/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java @@ -140,6 +140,7 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro ControlledEntity.ACLType aclType = null; Account owner = null; + boolean domainLevel = false; if (account != null && domainId != null) { @@ -166,6 +167,7 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro // domain level group, owner is SYSTEM. owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); aclType = ControlledEntity.ACLType.Domain; + domainLevel = true; } else { owner = caller; @@ -176,6 +178,10 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro throw new InvalidParameterValueException("Unable to create affinity group, a group with name " + affinityGroupName + " already exisits."); } + if (domainLevel && _affinityGroupDao.findDomainLevelGroupByName(domainId, affinityGroupName) != null) { + throw new InvalidParameterValueException("Unable to create affinity group, a group with name " + + affinityGroupName + " already exisits under the domain."); + } Transaction txn = Transaction.currentTxn(); txn.start(); @@ -185,7 +191,9 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro _affinityGroupDao.persist(group); if (domainId != null && aclType == ACLType.Domain) { - AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), domainId, false); + boolean subDomainAccess = false; + subDomainAccess = processor.subDomainAccess(); + AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), domainId, subDomainAccess); _affinityGroupDomainMapDao.persist(domainMap); } @@ -251,6 +259,12 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro _affinityGroupVMMapDao.remove(sc); } + // call processor to handle the group delete + AffinityGroupProcessor processor = getAffinityGroupProcessorForType(group.getType()); + if (processor != null) { + processor.handleDeleteGroup(group); + } + _affinityGroupDao.expunge(affinityGroupId); txn.commit(); @@ -324,8 +338,9 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro if (componentMap.size() > 0) { for (Entry<String, AffinityGroupProcessor> entry : componentMap.entrySet()) { AffinityGroupProcessor processor = entry.getValue(); - if (processor.isAdminControlledGroup() && !_accountMgr.isRootAdmin(caller.getType())) { - continue; + if (processor.isAdminControlledGroup()) { + continue; // we dont list the type if this group can be + // created only as an admin/system operation. } types.add(processor.getType()); } @@ -469,6 +484,15 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro return false; } + private AffinityGroupProcessor getAffinityGroupProcessorForType(String affinityGroupType) { + for (AffinityGroupProcessor processor : _affinityProcessors) { + if (affinityGroupType != null && affinityGroupType.equals(processor.getType())) { + return processor; + } + } + return null; + } + @Override public boolean isAffinityGroupAvailableInDomain(long affinityGroupId, long domainId) { Long groupDomainId = null; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ef22b42b/setup/db/db/schema-410to420.sql ---------------------------------------------------------------------- diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index ba9932f..5887caa 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -447,6 +447,7 @@ CREATE TABLE `cloud`.`dedicated_resources` ( `host_id` bigint unsigned COMMENT 'host id', `domain_id` bigint unsigned COMMENT 'domain id of the domain to which resource is dedicated', `account_id` bigint unsigned COMMENT 'account id of the account to which resource is dedicated', + `affinity_group_id` bigint unsigned NOT NULL COMMENT 'affinity group id associated', PRIMARY KEY (`id`), CONSTRAINT `fk_dedicated_resources__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `cloud`.`data_center`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_dedicated_resources__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `cloud`.`host_pod_ref`(`id`), @@ -454,8 +455,10 @@ CREATE TABLE `cloud`.`dedicated_resources` ( CONSTRAINT `fk_dedicated_resources__host_id` FOREIGN KEY (`host_id`) REFERENCES `cloud`.`host`(`id`), CONSTRAINT `fk_dedicated_resources__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`), CONSTRAINT `fk_dedicated_resources__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`), + CONSTRAINT `fk_dedicated_resources__affinity_group_id` FOREIGN KEY (`affinity_group_id`) REFERENCES `affinity_group`(`id`) ON DELETE CASCADE, INDEX `i_dedicated_resources_domain_id`(`domain_id`), INDEX `i_dedicated_resources_account_id`(`account_id`), + INDEX `i_dedicated_resources_affinity_group_id`(`affinity_group_id`), CONSTRAINT `uc_dedicated_resources__uuid` UNIQUE (`uuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -486,9 +489,6 @@ ALTER TABLE `cloud`.`event` ADD COLUMN `archived` tinyint(1) unsigned NOT NULL D INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'alert.purge.interval', '86400', 'The interval (in seconds) to wait before running the alert purge thread'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'alert.purge.delay', '0', 'Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts'); -INSERT INTO `cloud`.`dedicated_resources` (`data_center_id`, `domain_id`) SELECT `id`, `domain_id` FROM `cloud`.`data_center` WHERE `domain_id` IS NOT NULL; -UPDATE `cloud`.`data_center` SET `domain_id` = NULL WHERE `domain_id` IS NOT NULL; - DROP VIEW IF EXISTS `cloud`.`event_view`; CREATE VIEW `cloud`.`event_view` AS select
