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;
+ }
}