You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ed...@apache.org on 2013/08/24 01:56:31 UTC
git commit: updated refs/heads/4.2-forward to d901663
Updated Branches:
refs/heads/4.2-forward f501c7bbe -> d90166357
CLOUDSTACK-4477: in order to select hypervisor host which can access storage pool, need to check storage_pool_host_ref
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/d9016635
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/d9016635
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/d9016635
Branch: refs/heads/4.2-forward
Commit: d901663578f81dbb4bcc0ea8eeba2597dacfdc24
Parents: f501c7b
Author: Edison Su <su...@gmail.com>
Authored: Fri Aug 23 16:55:42 2013 -0700
Committer: Edison Su <su...@gmail.com>
Committed: Fri Aug 23 16:56:01 2013 -0700
----------------------------------------------------------------------
.../test/DirectAgentManagerSimpleImpl.java | 15 +-
.../storage/test/EndpointSelectorTest.java | 327 +++++++++++++++++++
.../test/FakeDriverTestConfiguration.java | 9 +
.../endpoint/DefaultEndPointSelector.java | 19 +-
4 files changed, 364 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d9016635/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
index ac50e9b..763a49e 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
@@ -26,6 +26,10 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.host.Host;
+import com.cloud.host.Status;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@@ -65,6 +69,9 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa
ClusterDao clusterDao;
@Inject
ClusterDetailsDao clusterDetailsDao;
+ @Inject
+ HostDao _hostDao;
+ protected StateMachine2<Status, Event, Host> _statusStateMachine = Status.getStateMachine();
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -249,8 +256,12 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa
@Override
public boolean agentStatusTransitTo(HostVO host, Event e, long msId) {
- // TODO Auto-generated method stub
- return false;
+ try {
+ return _statusStateMachine.transitTo(host, e, host.getId(), _hostDao);
+ } catch (NoTransitionException e1) {
+ e1.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ return true;
}
@Override
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d9016635/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/EndpointSelectorTest.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/EndpointSelectorTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/EndpointSelectorTest.java
new file mode 100644
index 0000000..15233bf
--- /dev/null
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/EndpointSelectorTest.java
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.test;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.cluster.LockMasterListener;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.org.Cluster;
+import com.cloud.org.Managed;
+import com.cloud.resource.ResourceState;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage;
+import com.cloud.storage.StoragePoolHostVO;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.SnapshotPolicyDao;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.db.Merovingian2;
+import junit.framework.Assert;
+import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
+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.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
+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.PrimaryDataStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.inject.Inject;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = { "classpath:/fakeDriverTestContext.xml" })
+public class EndpointSelectorTest {
+ @Inject
+ SnapshotService snapshotService;
+ @Inject
+ SnapshotDao snapshotDao;
+ @Inject
+ SnapshotDataFactory snapshotDataFactory;
+ @Inject
+ PrimaryDataStoreProvider primaryDataStoreProvider;
+ @Inject
+ SnapshotDataStoreDao snapshotDataStoreDao;
+ @Inject
+ VolumeDao volumeDao;
+ @Inject
+ VolumeService volumeService;
+ @Inject
+ VolumeDataFactory volumeDataFactory;
+ @Inject
+ DataCenterDao dcDao;
+ Long dcId;
+ @Inject
+ HostPodDao podDao;
+ Long podId;
+ @Inject
+ ClusterDao clusterDao;
+ Long clusterId;
+ @Inject
+ ImageStoreDao imageStoreDao;
+ ImageStoreVO imageStore;
+ @Inject
+ AccountManager accountManager;
+ LockMasterListener lockMasterListener;
+ VolumeInfo vol = null;
+ FakePrimaryDataStoreDriver driver = new FakePrimaryDataStoreDriver();
+ @Inject
+ MockStorageMotionStrategy mockStorageMotionStrategy;
+ Merovingian2 _lockMaster;
+ @Inject
+ DataStoreManager dataStoreManager;
+ @Inject
+ PrimaryDataStoreDao primaryDataStoreDao;
+ @Inject
+ SnapshotPolicyDao snapshotPolicyDao;
+ @Inject
+ HostDao hostDao;
+ @Inject
+ StoragePoolHostDao storagePoolHostDao;
+ @Inject
+ EndPointSelector endPointSelector;
+ @Inject
+ AgentManager agentMgr;
+ @Before
+ public void setUp() {
+ // create data center
+
+ DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null,
+ "10.0.0.1/24", null, null, DataCenter.NetworkType.Basic, null, null, true, true, null, null);
+ dc = dcDao.persist(dc);
+ dcId = dc.getId();
+ // create pod
+
+ HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "10.223.0.1",
+ "10.233.2.2/25", 8, "test");
+ pod = podDao.persist(pod);
+ podId = pod.getId();
+ // create xen cluster
+ ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
+ cluster.setHypervisorType(Hypervisor.HypervisorType.XenServer.toString());
+ cluster.setClusterType(Cluster.ClusterType.CloudManaged);
+ cluster.setManagedState(Managed.ManagedState.Managed);
+ cluster = clusterDao.persist(cluster);
+ clusterId = cluster.getId();
+
+ imageStore = new ImageStoreVO();
+ imageStore.setName(UUID.randomUUID().toString());
+ imageStore.setDataCenterId(dcId);
+ imageStore.setProviderName(DataStoreProvider.NFS_IMAGE);
+ imageStore.setRole(DataStoreRole.Image);
+ imageStore.setUrl(UUID.randomUUID().toString());
+ imageStore.setUuid(UUID.randomUUID().toString());
+ imageStore.setProtocol("nfs");
+ imageStore = imageStoreDao.persist(imageStore);
+
+ when(primaryDataStoreProvider.configure(Mockito.anyMap())).thenReturn(true);
+ Set<DataStoreProvider.DataStoreProviderType> types = new HashSet<DataStoreProvider.DataStoreProviderType>();
+ types.add(DataStoreProvider.DataStoreProviderType.PRIMARY);
+
+ when(primaryDataStoreProvider.getTypes()).thenReturn(types);
+ when(primaryDataStoreProvider.getName()).thenReturn(DataStoreProvider.DEFAULT_PRIMARY);
+ when(primaryDataStoreProvider.getDataStoreDriver()).thenReturn(driver);
+ User user = mock(User.class);
+ when(user.getId()).thenReturn(1L);
+ Account account = mock(Account.class);
+ when(account.getId()).thenReturn(1L);
+ when(accountManager.getSystemAccount()).thenReturn(account);
+ when(accountManager.getSystemUser()).thenReturn(user);
+
+ if(Merovingian2.getLockMaster() == null) {
+ _lockMaster = Merovingian2.createLockMaster(1234);
+ } else {
+ _lockMaster = Merovingian2.getLockMaster();
+ }
+ _lockMaster.cleanupThisServer();
+ ComponentContext.initComponentsLifeCycle();
+ }
+
+ public DataStore createPrimaryDataStore(ScopeType scope) {
+ String uuid = UUID.randomUUID().toString();
+ List<StoragePoolVO> pools = primaryDataStoreDao.findPoolByName(uuid);
+ if (pools.size() > 0) {
+ return dataStoreManager.getPrimaryDataStore(pools.get(0).getId());
+ }
+
+ StoragePoolVO pool = new StoragePoolVO();
+ if (scope != ScopeType.ZONE) {
+ pool.setClusterId(clusterId);
+ }
+ pool.setDataCenterId(dcId);
+
+ pool.setHostAddress(uuid);
+ pool.setPath(uuid);
+ pool.setPort(0);
+ pool.setName(uuid);
+ pool.setUuid(uuid);
+ pool.setStatus(StoragePoolStatus.Up);
+ pool.setPoolType(Storage.StoragePoolType.NetworkFilesystem);
+ pool.setPodId(podId);
+ pool.setScope(scope);
+ pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY);
+ pool = primaryDataStoreDao.persist(pool);
+ DataStore store = dataStoreManager.getPrimaryDataStore(pool.getId());
+ return store;
+ }
+
+ public HostVO createHost(Hypervisor.HypervisorType hypervisorType) {
+ String uuid = UUID.randomUUID().toString();
+ HostVO host = new HostVO(uuid);
+ host.setName("devcloud xen host");
+ host.setType(Host.Type.Routing);
+ host.setPrivateIpAddress(uuid);
+ host.setDataCenterId(dcId);
+ host.setVersion("6.0.1");
+ host.setAvailable(true);
+ host.setSetup(true);
+ host.setPodId(podId);
+ host.setLastPinged(0);
+ host.setResourceState(ResourceState.Enabled);
+ host.setHypervisorType(hypervisorType);
+ host.setClusterId(clusterId);
+
+
+ host = hostDao.persist(host);
+ agentMgr.agentStatusTransitTo(host, Status.Event.AgentConnected, 1L);
+ host = hostDao.findById(host.getId());
+ agentMgr.agentStatusTransitTo(host, Status.Event.Ready, 1L);
+ return hostDao.findById(host.getId());
+ }
+
+ public void addStorageToHost(DataStore store, HostVO host) {
+ StoragePoolHostVO storagePoolHostVO = new StoragePoolHostVO(store.getId(), host.getId(), UUID.randomUUID().toString());
+ storagePoolHostDao.persist(storagePoolHostVO);
+ }
+
+ @Test
+ public void testMixZonePrimaryStorages() {
+ Long srcStoreId = null;
+ Long destStoreId = imageStore.getId();
+ DataStore store = createPrimaryDataStore(ScopeType.ZONE);
+ srcStoreId = store.getId();
+ HostVO host = createHost(Hypervisor.HypervisorType.VMware);
+ addStorageToHost(store, host);
+
+ store = createPrimaryDataStore(ScopeType.ZONE);
+ host = createHost(Hypervisor.HypervisorType.VMware);
+ addStorageToHost(store, host);
+
+ Long xenStoreId = null;
+ store = createPrimaryDataStore(ScopeType.CLUSTER);
+ xenStoreId = store.getId();
+ host = createHost(Hypervisor.HypervisorType.XenServer);
+ addStorageToHost(store, host);
+
+ store = createPrimaryDataStore(ScopeType.CLUSTER);
+ host = createHost(Hypervisor.HypervisorType.XenServer);
+ addStorageToHost(store, host);
+
+ ZoneScope srcScope = new ZoneScope(dcId);
+
+ DataStore srcStore = mock(DataStore.class);
+ DataStore destStore = mock(DataStore.class);
+
+ when(srcStore.getScope()).thenReturn(srcScope);
+ when(srcStore.getRole()).thenReturn(DataStoreRole.Primary);
+ when(srcStore.getId()).thenReturn(srcStoreId);
+ when(destStore.getScope()).thenReturn(srcScope);
+ when(destStore.getRole()).thenReturn(DataStoreRole.Image);
+ when(destStore.getId()).thenReturn(destStoreId);
+
+
+
+ DataObject srcObj = mock(DataObject.class);
+ DataObject destObj = mock(DataObject.class);
+ when(srcObj.getDataStore()).thenReturn(srcStore);
+ when(destObj.getDataStore()).thenReturn(destStore);
+ EndPoint ep = endPointSelector.select(srcObj, destObj);
+
+ Assert.assertTrue(ep != null);
+ Long hostId = ep.getId();
+ HostVO newHost = hostDao.findById(hostId);
+ Assert.assertTrue(newHost.getHypervisorType() == Hypervisor.HypervisorType.VMware);
+
+ when(srcStore.getRole()).thenReturn(DataStoreRole.Image);
+ when(srcStore.getId()).thenReturn(destStoreId);
+ when(destStore.getId()).thenReturn(srcStoreId);
+ when(destStore.getRole()).thenReturn(DataStoreRole.Primary);
+ ep = endPointSelector.select(srcObj, destObj);
+
+ Assert.assertTrue(ep != null);
+ hostId = ep.getId();
+ newHost = hostDao.findById(hostId);
+ Assert.assertTrue(newHost.getHypervisorType() == Hypervisor.HypervisorType.VMware);
+
+ ClusterScope clusterScope = new ClusterScope(clusterId, podId, dcId);
+ when(srcStore.getRole()).thenReturn(DataStoreRole.Primary);
+ when(srcStore.getScope()).thenReturn(clusterScope);
+ when(srcStore.getId()).thenReturn(xenStoreId);
+ ep = endPointSelector.select(srcStore);
+ Assert.assertTrue(ep != null);
+ newHost = hostDao.findById(ep.getId());
+ Assert.assertTrue(newHost.getHypervisorType() == Hypervisor.HypervisorType.XenServer);
+
+
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d9016635/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakeDriverTestConfiguration.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakeDriverTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakeDriverTestConfiguration.java
index 3cf0cb6..75eda90 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakeDriverTestConfiguration.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakeDriverTestConfiguration.java
@@ -21,10 +21,13 @@ package org.apache.cloudstack.storage.test;
import com.cloud.storage.snapshot.SnapshotScheduler;
import com.cloud.storage.snapshot.SnapshotSchedulerImpl;
import com.cloud.user.DomainManager;
+import com.cloud.utils.component.ComponentContext;
import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
import org.apache.cloudstack.storage.datastore.provider.CloudStackPrimaryDataStoreProviderImpl;
import org.apache.cloudstack.storage.datastore.type.DataStoreType;
+import org.apache.cloudstack.storage.endpoint.DefaultEndPointSelector;
import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
@@ -55,4 +58,10 @@ public class FakeDriverTestConfiguration extends ChildTestConfiguration{
return Mockito.mock(DomainManager.class);
}
+ @Override
+ @Bean
+ public EndPointSelector selector() {
+ return ComponentContext.inject(DefaultEndPointSelector.class);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d9016635/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
----------------------------------------------------------------------
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 0cd8ad3..a1d7315 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
@@ -55,7 +55,8 @@ public class DefaultEndPointSelector implements EndPointSelector {
private static final Logger s_logger = Logger.getLogger(DefaultEndPointSelector.class);
@Inject
HostDao hostDao;
- private String findOneHostOnPrimaryStorage = "select id from host where status = 'Up' and type = 'Routing' and resource_state = 'Enabled'";
+ private String findOneHostOnPrimaryStorage = "select h.id from host h, storage_pool_host_ref s where h.status = 'Up' and h.type = 'Routing' and h.resource_state = 'Enabled' and" +
+ " h.id = s.host_id and s.pool_id = ? ";
protected boolean moveBetweenPrimaryImage(DataStore srcStore, DataStore destStore) {
DataStoreRole srcRole = srcStore.getRole();
@@ -90,7 +91,7 @@ public class DefaultEndPointSelector implements EndPointSelector {
}
@DB
- protected EndPoint findEndPointInScope(Scope scope, String sqlBase) {
+ protected EndPoint findEndPointInScope(Scope scope, String sqlBase, Long poolId) {
StringBuilder sbuilder = new StringBuilder();
sbuilder.append(sqlBase);
@@ -114,6 +115,7 @@ public class DefaultEndPointSelector implements EndPointSelector {
try {
pstmt = txn.prepareStatement(sql);
+ pstmt.setLong(1, poolId);
rs = pstmt.executeQuery();
while (rs.next()) {
long id = rs.getLong(1);
@@ -146,17 +148,26 @@ public class DefaultEndPointSelector implements EndPointSelector {
Scope srcScope = srcStore.getScope();
Scope destScope = destStore.getScope();
Scope selectedScope = null;
+ Long poolId = null;
+
// assumption, at least one of scope should be zone, find the least
// scope
if (srcScope.getScopeType() != ScopeType.ZONE) {
selectedScope = srcScope;
+ poolId = srcStore.getId();
} else if (destScope.getScopeType() != ScopeType.ZONE) {
selectedScope = destScope;
+ poolId = destStore.getId();
} else {
// if both are zone scope
selectedScope = srcScope;
+ if (srcStore.getRole() == DataStoreRole.Primary) {
+ poolId = srcStore.getId();
+ } else if (destStore.getRole() == DataStoreRole.Primary) {
+ poolId = destStore.getId();
+ }
}
- return findEndPointInScope(selectedScope, findOneHostOnPrimaryStorage);
+ return findEndPointInScope(selectedScope, findOneHostOnPrimaryStorage, poolId);
}
@Override
@@ -184,7 +195,7 @@ public class DefaultEndPointSelector implements EndPointSelector {
}
protected EndPoint findEndpointForPrimaryStorage(DataStore store) {
- return findEndPointInScope(store.getScope(), findOneHostOnPrimaryStorage);
+ return findEndPointInScope(store.getScope(), findOneHostOnPrimaryStorage, store.getId());
}
protected EndPoint findEndpointForImageStorage(DataStore store) {