diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java index 0613a11572f7..20e143e4fb98 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import java.util.List; public interface EndPointSelector { @@ -36,4 +37,6 @@ public interface EndPointSelector { EndPoint select(Scope scope, Long storeId); EndPoint select(DataStore store, String downloadUrl); + + EndPoint selectOneHypervisorHostByZone(long zoneId, HypervisorType hypervisorType); } diff --git a/engine/schema/src/com/cloud/host/dao/HostDao.java b/engine/schema/src/com/cloud/host/dao/HostDao.java index f98e8c19eebd..419b8930517e 100644 --- a/engine/schema/src/com/cloud/host/dao/HostDao.java +++ b/engine/schema/src/com/cloud/host/dao/HostDao.java @@ -24,6 +24,7 @@ import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.hypervisor.Hypervisor; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.info.RunningHostCountInfo; import com.cloud.resource.ResourceState; import com.cloud.utils.db.GenericDao; @@ -70,6 +71,10 @@ public interface HostDao extends GenericDao, StateDao findHypervisorHostInCluster(long clusterId); /** diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java index d08b40281e6e..a70d6e1612f8 100644 --- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java +++ b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java @@ -50,6 +50,7 @@ import com.cloud.host.Status; import com.cloud.host.Status.Event; import com.cloud.hypervisor.Hypervisor; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.info.RunningHostCountInfo; import com.cloud.org.Grouping; import com.cloud.org.Managed; @@ -85,7 +86,6 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao protected SearchBuilder IdStatusSearch; protected SearchBuilder TypeDcSearch; - protected SearchBuilder TypeDcStatusSearch; protected SearchBuilder TypeClusterStatusSearch; protected SearchBuilder MsStatusSearch; protected SearchBuilder DcPrivateIpAddressSearch; @@ -128,6 +128,7 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao protected GenericSearchBuilder ClustersForHostsNotOwnedByAnyMSSearch; protected GenericSearchBuilder AllClustersSearch; protected SearchBuilder HostsInClusterSearch; + protected SearchBuilder HostByHypervisor; protected Attribute _statusAttr; protected Attribute _resourceStateAttr; @@ -188,13 +189,6 @@ public void init() { SecondaryStorageVMSearch.and("status", SecondaryStorageVMSearch.entity().getStatus(), SearchCriteria.Op.EQ); SecondaryStorageVMSearch.done(); - TypeDcStatusSearch = createSearchBuilder(); - TypeDcStatusSearch.and("type", TypeDcStatusSearch.entity().getType(), SearchCriteria.Op.EQ); - TypeDcStatusSearch.and("dc", TypeDcStatusSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - TypeDcStatusSearch.and("status", TypeDcStatusSearch.entity().getStatus(), SearchCriteria.Op.EQ); - TypeDcStatusSearch.and("resourceState", TypeDcStatusSearch.entity().getResourceState(), SearchCriteria.Op.EQ); - TypeDcStatusSearch.done(); - TypeClusterStatusSearch = createSearchBuilder(); TypeClusterStatusSearch.and("type", TypeClusterStatusSearch.entity().getType(), SearchCriteria.Op.EQ); TypeClusterStatusSearch.and("cluster", TypeClusterStatusSearch.entity().getClusterId(), SearchCriteria.Op.EQ); @@ -410,6 +404,14 @@ public void init() { HostIdSearch.and("dataCenterId", HostIdSearch.entity().getDataCenterId(), Op.EQ); HostIdSearch.done(); + HostByHypervisor = createSearchBuilder(); + HostByHypervisor.and("hypervisorType", HostByHypervisor.entity().getHypervisorType(), Op.EQ); + HostByHypervisor.and("status", HostByHypervisor.entity().getStatus(), Op.EQ); + HostByHypervisor.and("zoneId", HostByHypervisor.entity().getDataCenterId(), Op.EQ); + HostByHypervisor.and("resourceState", HostByHypervisor.entity().getResourceState(), Op.EQ); + HostByHypervisor.and("type", HostByHypervisor.entity().getType(), Op.EQ); + HostByHypervisor.done(); + _statusAttr = _allAttributes.get("status"); _msIdAttr = _allAttributes.get("managementServerId"); _pingTimeAttr = _allAttributes.get("lastPinged"); @@ -695,6 +697,32 @@ public void markHostsAsDisconnected(long msId, long lastPing) { update(ub, sc, null); } + @Override + public HostVO findOneByZoneAndHypervisor(long zoneId, HypervisorType hypervisorType) { + return findOneByZoneAndHypervisorAndResourceState(zoneId, hypervisorType, ResourceState.Enabled); + } + + private HostVO findOneByZoneAndHypervisorAndResourceState(long zoneId, HypervisorType hypervisorType, ResourceState enabled) { + SearchCriteria sc = HostByHypervisor.create(); + sc.setParameters("hypervisorType", hypervisorType); + sc.setParameters("zoneId", zoneId); + sc.setParameters("status", Status.Up); + sc.setParameters("resourceState", enabled); + sc.setParameters("type", Type.Routing); + + Filter filter = new Filter(1); + List hostVOList = listBy(sc, filter); + if (hostVOList.isEmpty()) { + return null; + } + return hostVOList.get(0); + } + + @Override + public HostVO findOneDisabledByZoneAndHypervisor(long zoneId, HypervisorType hypervisorType) { + return findOneByZoneAndHypervisorAndResourceState(zoneId, hypervisorType, ResourceState.Disabled); + } + @Override public List listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index e414b6c4c357..625bb178a011 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -363,6 +363,18 @@ public EndPoint select(Scope scope, Long storeId) { return findEndPointInScope(scope, findOneHostOnPrimaryStorage, storeId); } + @Override + public EndPoint selectOneHypervisorHostByZone(long zoneId, Hypervisor.HypervisorType hypervisorType) { + Host host = hostDao.findOneByZoneAndHypervisor(zoneId, hypervisorType); + if (host == null) { + host = hostDao.findOneDisabledByZoneAndHypervisor(zoneId, hypervisorType); + } + if (host == null) { + throw new CloudRuntimeException("There is no host available in Up status in zone: " + zoneId + " for hypervisor: " + hypervisorType); + } + return RemoteHostEndPoint.getHypervisorHostEndPoint(host); + } + @Override public List selectAll(DataStore store) { List endPoints = new ArrayList(); diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java index 74f989bf0f27..1e766d2a0f1c 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java @@ -22,6 +22,8 @@ import javax.inject.Inject; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; @@ -75,6 +77,8 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru, private UserVmDao _userVmDao; @Inject GuestOsDetailsDao _guestOsDetailsDao; + @Inject + EndPointSelector endPointSelector; private static final ConfigKey MaxNumberOfVCPUSPerVM = new ConfigKey("Advanced", Integer.class, "xen.vm.vcpu.max", "16", "Maximum number of VCPUs that VM can get in XenServer.", true, ConfigKey.Scope.Cluster); @@ -183,19 +187,21 @@ public Pair getCommandHostDelegation(long hostId, Command cmd) { DataStoreTO destStore = destData.getDataStore(); if (srcStore instanceof NfsTO && destStore instanceof NfsTO) { HostVO host = hostDao.findById(hostId); + EndPoint ep = endPointSelector.selectOneHypervisorHostByZone(host.getDataCenterId(), HypervisorType.XenServer); + host = hostDao.findById(ep.getId()); hostDao.loadDetails(host); String hypervisorVersion = host.getHypervisorVersion(); String snapshotHotFixVersion = host.getDetail(XenserverConfigs.XS620HotFix); if (hypervisorVersion != null && !hypervisorVersion.equalsIgnoreCase("6.1.0")) { if (!(hypervisorVersion.equalsIgnoreCase("6.2.0") && !(snapshotHotFixVersion != null && snapshotHotFixVersion.equalsIgnoreCase(XenserverConfigs.XSHotFix62ESP1004)))) { - return new Pair(Boolean.TRUE, new Long(host.getId())); + return new Pair<>(Boolean.TRUE, ep.getId()); } } } } } - return new Pair(Boolean.FALSE, new Long(hostId)); + return new Pair<>(Boolean.FALSE, hostId); } @Override