You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2020/11/18 12:11:55 UTC

[cloudstack] branch master updated: Moved dedicated hosts to the end of the resultset when selecting an e… (#4428)

This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/master by this push:
     new acee15a  Moved dedicated hosts to the end of the resultset when selecting an e… (#4428)
acee15a is described below

commit acee15a530cc9f3dc8710de108b36e61a75c75c9
Author: Spaceman1984 <49...@users.noreply.github.com>
AuthorDate: Wed Nov 18 14:07:14 2020 +0200

    Moved dedicated hosts to the end of the resultset when selecting an e… (#4428)
---
 .../com/cloud/vm/VirtualMachineManagerImpl.java    |  9 ++--
 .../storage/endpoint/DefaultEndPointSelector.java  | 56 +++++++++++++++++++-
 .../com/cloud/dc/dao/DedicatedResourceDao.java     |  3 ++
 .../com/cloud/dc/dao/DedicatedResourceDaoImpl.java | 59 ++++++++++++++++++++++
 4 files changed, 123 insertions(+), 4 deletions(-)

diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
index 8e9ec45..f1ab9cd 100755
--- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -1672,10 +1672,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
                 }
 
                 guru.finalizeStop(profile, answer);
+
+                final UserVmVO userVm = _userVmDao.findById(vm.getId());
                 if (vm.getType() == VirtualMachine.Type.User) {
-                    final UserVmVO userVm = _userVmDao.findById(vm.getId());
-                    userVm.setPowerState(PowerState.PowerOff);
-                    _userVmDao.update(userVm.getId(), userVm);
+                    if (userVm != null){
+                        userVm.setPowerState(PowerState.PowerOff);
+                        _userVmDao.update(userVm.getId(), userVm);
+                    }
                 }
             } else {
                 s_logger.error("Invalid answer received in response to a StopCommand for " + vm.getInstanceName());
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
index 09b4b1a..6a903e4 100644
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
@@ -25,10 +25,16 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 
 import javax.inject.Inject;
 
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
@@ -64,6 +70,8 @@ public class DefaultEndPointSelector implements EndPointSelector {
     private static final Logger s_logger = Logger.getLogger(DefaultEndPointSelector.class);
     @Inject
     private HostDao hostDao;
+    @Inject
+    private DedicatedResourceDao dedicatedResourceDao;
     private final String findOneHostOnPrimaryStorage = "select t.id from "
                             + "(select h.id, cd.value "
                             + "from host h join storage_pool_host_ref s on h.id = s.host_id  "
@@ -115,6 +123,8 @@ public class DefaultEndPointSelector implements EndPointSelector {
         StringBuilder sbuilder = new StringBuilder();
         sbuilder.append(sqlBase);
 
+        List<Long> dedicatedHosts = new ArrayList<Long>();
+
         if (scope != null) {
             if (scope.getScopeType() == ScopeType.HOST) {
                 sbuilder.append(" and h.id = ");
@@ -122,15 +132,23 @@ public class DefaultEndPointSelector implements EndPointSelector {
             } else if (scope.getScopeType() == ScopeType.CLUSTER) {
                 sbuilder.append(" and h.cluster_id = ");
                 sbuilder.append(scope.getScopeId());
+                dedicatedHosts = dedicatedResourceDao.findHostsByCluster(scope.getScopeId());
             } else if (scope.getScopeType() == ScopeType.ZONE) {
                 sbuilder.append(" and h.data_center_id = ");
                 sbuilder.append(scope.getScopeId());
+                dedicatedHosts = dedicatedResourceDao.findHostsByZone(scope.getScopeId());
             }
+        } else {
+            dedicatedHosts = dedicatedResourceDao.listAllHosts();
         }
 
         // TODO: order by rand() is slow if there are lot of hosts
         sbuilder.append(") t where t.value<>'true' or t.value is null");    //Added for exclude cluster's subquery
-        sbuilder.append(" ORDER by rand() limit 1");
+        sbuilder.append(" ORDER by ");
+        if (dedicatedHosts.size() > 0) {
+            moveDedicatedHostsToLowerPriority(sbuilder, dedicatedHosts);
+        }
+        sbuilder.append(" rand() limit 1");
         String sql = sbuilder.toString();
         HostVO host = null;
         TransactionLegacy txn = TransactionLegacy.currentTxn();
@@ -154,6 +172,42 @@ public class DefaultEndPointSelector implements EndPointSelector {
         return RemoteHostEndPoint.getHypervisorHostEndPoint(host);
     }
 
+    private void moveDedicatedHostsToLowerPriority(StringBuilder sbuilder, List<Long> dedicatedHosts) {
+
+        // Check if we have a call context
+        final CallContext context = CallContext.current();
+        if (context != null) {
+            Account account = context.getCallingAccount();
+            if (account != null) {
+                // Remove hosts for this account. Only leave hosts dedicated to other accounts in the lower priority list.
+                Pair<List<DedicatedResourceVO>, Integer> hostIds = dedicatedResourceDao.searchDedicatedHosts(null, null, account.getId(), null, null);
+                List<DedicatedResourceVO> accountDedicatedHosts = hostIds.first();
+                for (DedicatedResourceVO accountDedicatedResource: accountDedicatedHosts){
+                    Iterator<Long> dedicatedHostsIterator = dedicatedHosts.iterator();
+                    while (dedicatedHostsIterator.hasNext()) {
+                        if (dedicatedHostsIterator.next() == accountDedicatedResource.getHostId()) {
+                            dedicatedHostsIterator.remove();
+                        }
+                    }
+                }
+            }
+        }
+
+        if (dedicatedHosts.size() > 0) {
+            Collections.shuffle(dedicatedHosts); // Randomize dedicated hosts as well.
+            sbuilder.append("field(t.id, ");
+            int hostIndex = 0;
+            for (Long hostId: dedicatedHosts) { // put dedicated hosts at the end of the result set
+                sbuilder.append("'" + hostId + "'");
+                hostIndex++;
+                if (hostIndex < dedicatedHosts.size()){
+                    sbuilder.append(",");
+                }
+            }
+            sbuilder.append(")," );
+        }
+    }
+
     protected EndPoint findEndPointForImageMove(DataStore srcStore, DataStore destStore) {
         // find any xenserver/kvm host in the scope
         Scope srcScope = srcStore.getScope();
diff --git a/server/src/main/java/com/cloud/dc/dao/DedicatedResourceDao.java b/server/src/main/java/com/cloud/dc/dao/DedicatedResourceDao.java
index 7c41439..3527ef7 100644
--- a/server/src/main/java/com/cloud/dc/dao/DedicatedResourceDao.java
+++ b/server/src/main/java/com/cloud/dc/dao/DedicatedResourceDao.java
@@ -55,4 +55,7 @@ public interface DedicatedResourceDao extends GenericDao<DedicatedResourceVO, Lo
 
     List<DedicatedResourceVO> listByAffinityGroupId(Long affinityGroupId);
 
+    List<Long> findHostsByCluster(Long clusterId);
+
+    List<Long> findHostsByZone(Long zoneId);
 }
\ No newline at end of file
diff --git a/server/src/main/java/com/cloud/dc/dao/DedicatedResourceDaoImpl.java b/server/src/main/java/com/cloud/dc/dao/DedicatedResourceDaoImpl.java
index c406755..c10ef2d 100644
--- a/server/src/main/java/com/cloud/dc/dao/DedicatedResourceDaoImpl.java
+++ b/server/src/main/java/com/cloud/dc/dao/DedicatedResourceDaoImpl.java
@@ -16,9 +16,14 @@
 // under the License.
 package com.cloud.dc.dao;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
 import com.cloud.utils.db.Filter;
 import org.springframework.stereotype.Component;
 
@@ -32,10 +37,17 @@ import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.db.SearchCriteria.Func;
 import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.JoinBuilder;
+
+import javax.inject.Inject;
 
 @Component
 @DB
 public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO, Long> implements DedicatedResourceDao {
+
+    @Inject
+    protected HostDao hostDao;
+
     protected final SearchBuilder<DedicatedResourceVO> ZoneSearch;
     protected final SearchBuilder<DedicatedResourceVO> PodSearch;
     protected final SearchBuilder<DedicatedResourceVO> ClusterSearch;
@@ -64,6 +76,8 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
     protected GenericSearchBuilder<DedicatedResourceVO, Long> ListPodsSearch;
     protected GenericSearchBuilder<DedicatedResourceVO, Long> ListClustersSearch;
     protected GenericSearchBuilder<DedicatedResourceVO, Long> ListHostsSearch;
+    protected SearchBuilder<DedicatedResourceVO> ListHostsByCluster;
+    protected SearchBuilder<DedicatedResourceVO> ListHostsByZone;
 
     protected DedicatedResourceDaoImpl() {
         PodSearch = createSearchBuilder();
@@ -369,4 +383,49 @@ public class DedicatedResourceDaoImpl extends GenericDaoBase<DedicatedResourceVO
         sc.setParameters("affinityGroupId", affinityGroupId);
         return listBy(sc);
     }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) {
+        ListHostsByCluster = createSearchBuilder();
+        SearchBuilder<HostVO> clusterHostsSB = hostDao.createSearchBuilder();
+        clusterHostsSB.and("cluster_id", clusterHostsSB.entity().getClusterId(), Op.EQ);
+        clusterHostsSB.and("type", clusterHostsSB.entity().getType(), Op.EQ);
+        ListHostsByCluster.join("clusterHostsSB", clusterHostsSB, clusterHostsSB.entity().getId(), ListHostsByCluster.entity().getHostId(), JoinBuilder.JoinType.INNER);
+        ListHostsByCluster.done();
+
+        ListHostsByZone = createSearchBuilder();
+        SearchBuilder<HostVO> zoneHostsSB = hostDao.createSearchBuilder();
+        zoneHostsSB = hostDao.createSearchBuilder();
+        zoneHostsSB.and("zone_id", zoneHostsSB.entity().getDataCenterId(), Op.EQ);
+        zoneHostsSB.and("type", zoneHostsSB.entity().getType(), Op.EQ);
+        ListHostsByZone.join("zoneHostsSB", zoneHostsSB, zoneHostsSB.entity().getId(), ListHostsByZone.entity().getHostId(), JoinBuilder.JoinType.INNER);
+        ListHostsByZone.done();
+        return true;
+    }
+
+    @Override
+    public List<Long> findHostsByCluster(Long clusterId) {
+        List<Long> hosts = new ArrayList<>();
+        SearchCriteria<DedicatedResourceVO> sc = ListHostsByCluster.create();
+        sc.setJoinParameters("clusterHostsSB", "type", Host.Type.Routing);
+        sc.setJoinParameters("clusterHostsSB","cluster_id", clusterId);
+        List<DedicatedResourceVO> results = customSearch(sc, null);
+        for (DedicatedResourceVO dedicatedResourceVO: results){
+            hosts.add(dedicatedResourceVO.getHostId());
+        }
+        return hosts;
+    }
+
+    @Override
+    public List<Long> findHostsByZone(Long zoneId) {
+        List<Long> hosts = new ArrayList<>();
+        SearchCriteria<DedicatedResourceVO> sc = ListHostsByZone.create();
+        sc.setJoinParameters("zoneHostsSB", "type", Host.Type.Routing);
+        sc.setJoinParameters("zoneHostsSB","zone_id", zoneId);
+        List<DedicatedResourceVO> results = customSearch(sc, null);
+        for (DedicatedResourceVO dedicatedResourceVO: results){
+            hosts.add(dedicatedResourceVO.getHostId());
+        }
+        return hosts;
+    }
 }