You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by de...@apache.org on 2013/07/23 10:01:52 UTC

git commit: updated refs/heads/4.2 to e2f2bc5

Updated Branches:
  refs/heads/4.2 c319ba3ba -> e2f2bc5f0


CLOUDSTACK-3382. Alert should be raised if a vm is migrated from dedicated to non-dedicated resource and vice versa.
Alerts are generated for VM migration between:
1) Source host is dedicated and destination host is not.
2) Source host is not dedicated and destination host is dedicated.
3) Both hosts are dedicated to different accounts/domains


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e2f2bc5f
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e2f2bc5f
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e2f2bc5f

Branch: refs/heads/4.2
Commit: e2f2bc5f0bd49401847d5d4681fd7bc167575f9b
Parents: c319ba3
Author: Saksham Srivastava <sa...@citrix.com>
Authored: Tue Jul 23 13:19:23 2013 +0530
Committer: Devdeep Singh <de...@gmail.com>
Committed: Tue Jul 23 13:22:44 2013 +0530

----------------------------------------------------------------------
 .../deploy/dao/PlannerHostReservationDao.java   |   2 +
 .../dao/PlannerHostReservationDaoImpl.java      |  15 +-
 server/src/com/cloud/vm/UserVmManagerImpl.java  | 240 +++++++++++++++++--
 3 files changed, 237 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2f2bc5f/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java b/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java
index 69118f1..e60254b 100644
--- a/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java
+++ b/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java
@@ -27,4 +27,6 @@ public interface PlannerHostReservationDao extends GenericDao<PlannerHostReserva
 
     List<PlannerHostReservationVO> listAllReservedHosts();
 
+    List<PlannerHostReservationVO> listAllDedicatedHosts();
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2f2bc5f/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java b/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java
index 41e0964..06cdab2 100644
--- a/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java
+++ b/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java
@@ -20,6 +20,8 @@ import java.util.List;
 
 import javax.annotation.PostConstruct;
 import javax.ejb.Local;
+
+import com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage;
 import com.cloud.deploy.PlannerHostReservationVO;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.SearchBuilder;
@@ -31,6 +33,7 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
 
     private SearchBuilder<PlannerHostReservationVO> _hostIdSearch;
     private SearchBuilder<PlannerHostReservationVO> _reservedHostSearch;
+    private SearchBuilder<PlannerHostReservationVO> _dedicatedHostSearch;;
 
     public PlannerHostReservationDaoImpl() {
 
@@ -45,6 +48,10 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
         _reservedHostSearch = createSearchBuilder();
         _reservedHostSearch.and("usage", _reservedHostSearch.entity().getResourceUsage(), SearchCriteria.Op.NNULL);
         _reservedHostSearch.done();
+
+        _dedicatedHostSearch = createSearchBuilder();
+        _dedicatedHostSearch.and("usage", _dedicatedHostSearch.entity().getResourceUsage(), SearchCriteria.Op.EQ);
+        _dedicatedHostSearch.done();
     }
 
     @Override
@@ -60,4 +67,10 @@ public class PlannerHostReservationDaoImpl extends GenericDaoBase<PlannerHostRes
         return listBy(sc);
     }
 
-}
+    @Override
+    public List<PlannerHostReservationVO> listAllDedicatedHosts() {
+        SearchCriteria<PlannerHostReservationVO> sc = _dedicatedHostSearch.create();
+        sc.setParameters("usage", PlannerResourceUsage.Dedicated);
+        return listBy(sc);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2f2bc5f/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 9968690..0771233 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -33,10 +33,6 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import org.apache.commons.codec.binary.Base64;
-import org.apache.log4j.Logger;
-
-import com.cloud.server.ConfigurationServer;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import org.apache.cloudstack.affinity.AffinityGroupService;
@@ -68,6 +64,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.AgentManager.OnError;
@@ -111,6 +109,8 @@ import com.cloud.dc.dao.HostPodDao;
 import com.cloud.deploy.DataCenterDeployment;
 import com.cloud.deploy.DeployDestination;
 import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.deploy.PlannerHostReservationVO;
+import com.cloud.deploy.dao.PlannerHostReservationDao;
 import com.cloud.domain.DomainVO;
 import com.cloud.domain.dao.DomainDao;
 import com.cloud.event.ActionEvent;
@@ -178,9 +178,11 @@ import com.cloud.projects.Project.ListProjectResourcesCriteria;
 import com.cloud.projects.ProjectManager;
 import com.cloud.resource.ResourceManager;
 import com.cloud.resource.ResourceState;
+import com.cloud.server.ConfigurationServer;
 import com.cloud.server.Criteria;
 import com.cloud.service.ServiceOfferingVO;
 import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
 import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.GuestOSCategoryVO;
 import com.cloud.storage.GuestOSVO;
@@ -225,6 +227,7 @@ import com.cloud.user.dao.SSHKeyPairDao;
 import com.cloud.user.dao.UserDao;
 import com.cloud.user.dao.VmDiskStatisticsDao;
 import com.cloud.uservm.UserVm;
+import com.cloud.utils.DateUtil;
 import com.cloud.utils.Journal;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
@@ -422,11 +425,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
     ConfigurationServer _configServer;
     @Inject
     AffinityGroupService _affinityGroupService;
+    @Inject
+    PlannerHostReservationDao _plannerHostReservationDao;
+    @Inject
+    private ServiceOfferingDetailsDao serviceOfferingDetailsDao;
 
     protected ScheduledExecutorService _executor = null;
     protected int _expungeInterval;
     protected int _expungeDelay;
     protected boolean _dailyOrHourly = false;
+    private int capacityReleaseInterval;
 
     protected String _name;
     protected String _instance;
@@ -1428,6 +1436,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
 
         String workers = configs.get("expunge.workers");
         int wrks = NumbersUtil.parseInt(workers, 10);
+        capacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
 
         String time = configs.get("expunge.interval");
         _expungeInterval = NumbersUtil.parseInt(time, 86400);
@@ -3868,22 +3877,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
                             + destinationHost.getResourceState());
         }
 
-        HostVO srcHost = _hostDao.findById(srcHostId);
-        HostVO destHost = _hostDao.findById(destinationHost.getId());
-        //if srcHost is dedicated and destination Host is not
-        if (checkIfHostIsDedicated(srcHost) && !checkIfHostIsDedicated(destHost)) {
-            //raise an alert
-            String msg = "VM is migrated on a non-dedicated host " + destinationHost.getName();
-            _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
-        }
-        //if srcHost is non dedicated but destination Host is.
-        if (!checkIfHostIsDedicated(srcHost) && checkIfHostIsDedicated(destHost)) {
-            //raise an alert
-            String msg = "VM is migrated on a dedicated host " + destinationHost.getName();
-            _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
-        }
+        checkHostsDedication(vm, srcHostId, destinationHost.getId());
 
-        // call to core process
+         // call to core process
         DataCenterVO dcVO = _dcDao.findById(destinationHost.getDataCenterId());
         HostPodVO pod = _podDao.findById(destinationHost.getPodId());
         Cluster cluster = _clusterDao.findById(destinationHost.getClusterId());
@@ -3926,6 +3922,210 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
         }
     }
 
+    private Long accountOfDedicatedHost(HostVO host) {
+        long hostId = host.getId();
+        DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
+        DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
+        DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
+        if(dedicatedHost != null) {
+            return dedicatedHost.getAccountId();
+        }
+        if(dedicatedClusterOfHost != null) {
+            return dedicatedClusterOfHost.getAccountId();
+        }
+        if(dedicatedPodOfHost != null) {
+            return dedicatedPodOfHost.getAccountId();
+        }
+        return null;
+    }
+
+    private Long domainOfDedicatedHost(HostVO host) {
+        long hostId = host.getId();
+        DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
+        DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
+        DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
+        if(dedicatedHost != null) {
+            return dedicatedHost.getDomainId();
+        }
+        if(dedicatedClusterOfHost != null) {
+            return dedicatedClusterOfHost.getDomainId();
+        }
+        if(dedicatedPodOfHost != null) {
+            return dedicatedPodOfHost.getDomainId();
+        }
+        return null;
+    }
+
+    public void checkHostsDedication (VMInstanceVO vm, long srcHostId, long destHostId) {
+        HostVO srcHost = _hostDao.findById(srcHostId);
+        HostVO destHost = _hostDao.findById(destHostId);
+        boolean srcExplDedicated = checkIfHostIsDedicated(srcHost);
+        boolean destExplDedicated = checkIfHostIsDedicated(destHost);
+        //if srcHost is explicitly dedicated and destination Host is not
+        if (srcExplDedicated && !destExplDedicated) {
+            //raise an alert
+            String msg = "VM is being migrated from a explicitly dedicated host " + srcHost.getName() +" to non-dedicated host " + destHost.getName();
+            _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+            s_logger.warn(msg);
+        }
+        //if srcHost is non dedicated but destination Host is explicitly dedicated
+        if (!srcExplDedicated && destExplDedicated) {
+            //raise an alert
+            String msg = "VM is being migrated from a non dedicated host " + srcHost.getName() + " to a explicitly dedicated host "+ destHost.getName();
+            _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+            s_logger.warn(msg);
+        }
+
+        //if hosts are dedicated to different account/domains, raise an alert
+        if (srcExplDedicated && destExplDedicated) {
+            if((accountOfDedicatedHost(srcHost) != null) && (accountOfDedicatedHost(srcHost)!= accountOfDedicatedHost(destHost))) {
+                String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(srcHost) +
+                        " to host " + destHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(destHost);
+                _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+                s_logger.warn(msg);
+            }
+            if((domainOfDedicatedHost(srcHost) != null) && (domainOfDedicatedHost(srcHost)!= domainOfDedicatedHost(destHost))) {
+                String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(srcHost) +
+                        " to host " + destHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(destHost);
+                _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+                s_logger.warn(msg);
+            }
+        }
+
+        // Checks for implicitly dedicated hosts
+        ServiceOfferingVO deployPlanner = _offeringDao.findById(vm.getServiceOfferingId());
+        if(deployPlanner.getDeploymentPlanner() != null && deployPlanner.getDeploymentPlanner().equals("ImplicitDedicationPlanner")) {
+            //VM is deployed using implicit planner
+            long accountOfVm = vm.getAccountId();
+            String msg = "VM of account " + accountOfVm + " with implicit deployment planner being migrated to host " + destHost.getName();
+            //Get all vms on destination host
+            boolean emptyDestination = false;
+            List<VMInstanceVO> vmsOnDest= getVmsOnHost(destHostId);
+            if (vmsOnDest == null || vmsOnDest.isEmpty()) {
+                emptyDestination = true;
+            }
+
+            if (!emptyDestination) {
+                //Check if vm is deployed using strict implicit planner
+                if(!isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId())) {
+                    //Check if all vms on destination host are created using strict implicit mode
+                    if(!checkIfAllVmsCreatedInStrictMode(accountOfVm, vmsOnDest)) {
+                        msg = "VM of account " + accountOfVm + " with strict implicit deployment planner being migrated to host " + destHost.getName() +
+                                " not having all vms strict implicitly dedicated to account " + accountOfVm;
+                    }
+                } else {
+                    //If vm is deployed using preferred implicit planner, check if all vms on destination host must be
+                    //using implicit planner and must belong to same account
+                    for (VMInstanceVO vmsDest : vmsOnDest) {
+                        ServiceOfferingVO destPlanner = _offeringDao.findById(vmsDest.getServiceOfferingId());
+                        if (!((destPlanner.getDeploymentPlanner() != null && destPlanner.getDeploymentPlanner().equals("ImplicitDedicationPlanner")) &&
+                                vmsDest.getAccountId()==accountOfVm)) {
+                            msg = "VM of account " + accountOfVm + " with preffered implicit deployment planner being migrated to host " + destHost.getName() +
+                            " not having all vms implicitly dedicated to account " + accountOfVm;
+                        }
+                    }
+                }
+            }
+            _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+            s_logger.warn(msg);
+
+        } else {
+            //VM is not deployed using implicit planner, check if it migrated between dedicated hosts
+            List<PlannerHostReservationVO> reservedHosts = _plannerHostReservationDao.listAllDedicatedHosts();
+            boolean srcImplDedicated = false;
+            boolean destImplDedicated = false;
+            String msg = null;
+            for (PlannerHostReservationVO reservedHost : reservedHosts) {
+                if(reservedHost.getHostId() == srcHostId) {
+                    srcImplDedicated = true;
+                }
+                if(reservedHost.getHostId() == destHostId) {
+                    destImplDedicated = true;
+                }
+            }
+            if(srcImplDedicated) {
+                if(destImplDedicated){
+                    msg = "VM is being migrated from implicitly dedicated host " + srcHost.getName() + " to another implicitly dedicated host " + destHost.getName();
+                } else {
+                    msg = "VM is being migrated from implicitly dedicated host " + srcHost.getName() + " to shared host " + destHost.getName();
+                }
+                _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+                s_logger.warn(msg);
+            } else {
+                if (destImplDedicated) {
+                    msg = "VM is being migrated from shared host " + srcHost.getName() + " to implicitly dedicated host " + destHost.getName();
+                    _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+                    s_logger.warn(msg);
+                }
+            }
+        }
+    }
+
+    private List<VMInstanceVO> getVmsOnHost(long hostId) {
+        List<VMInstanceVO> vms =  _vmInstanceDao.listUpByHostId(hostId);
+        List<VMInstanceVO> vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId);
+        if (vmsByLastHostId.size() > 0) {
+            // check if any VMs are within skip.counting.hours, if yes we have to consider the host.
+            for (VMInstanceVO stoppedVM : vmsByLastHostId) {
+                long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime()
+                        .getTime()) / 1000;
+                if (secondsSinceLastUpdate < capacityReleaseInterval) {
+                    vms.add(stoppedVM);
+                }
+            }
+        }
+
+        return vms;
+    }
+    private boolean isServiceOfferingUsingPlannerInPreferredMode(long serviceOfferingId) {
+        boolean preferred = false;
+        Map<String, String> details = serviceOfferingDetailsDao.findDetails(serviceOfferingId);
+        if (details != null && !details.isEmpty()) {
+            String preferredAttribute = details.get("ImplicitDedicationMode");
+            if (preferredAttribute != null && preferredAttribute.equals("Preferred")) {
+                preferred = true;
+            }
+        }
+        return preferred;
+    }
+
+    private boolean checkIfAllVmsCreatedInStrictMode(Long accountId, List<VMInstanceVO> allVmsOnHost) {
+        boolean createdByImplicitStrict = true;
+        if (allVmsOnHost.isEmpty())
+            return false;
+        for (VMInstanceVO vm : allVmsOnHost) {
+            if (!isImplicitPlannerUsedByOffering(vm.getServiceOfferingId()) || vm.getAccountId()!= accountId) {
+                s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by a planner other" +
+                        " than implicit, or running vms of other account");
+                createdByImplicitStrict = false;
+                break;
+            } else if (isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId()) || vm.getAccountId()!= accountId) {
+                s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by an implicit planner" +
+                        " in preferred mode, or running vms of other account");
+                createdByImplicitStrict = false;
+                break;
+            }
+        }
+        return createdByImplicitStrict;
+    }
+
+    private boolean isImplicitPlannerUsedByOffering(long offeringId) {
+        boolean implicitPlannerUsed = false;
+        ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(offeringId);
+        if (offering == null) {
+            s_logger.error("Couldn't retrieve the offering by the given id : " + offeringId);
+        } else {
+            String plannerName = offering.getDeploymentPlanner();
+            if (plannerName != null) {
+                if(plannerName.equals("ImplicitDedicationPlanner")) {
+                    implicitPlannerUsed = true;
+                }
+            }
+        }
+
+        return implicitPlannerUsed;
+    }
+
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = "migrating VM", async = true)
     public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinationHost,
@@ -4043,6 +4243,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
                     " migrate to this host");
         }
 
+        checkHostsDedication(vm, srcHostId, destinationHost.getId());
+
         VMInstanceVO migratedVm = _itMgr.migrateWithStorage(vm, srcHostId, destinationHost.getId(), volToPoolObjectMap);
         return migratedVm;
 }