Skip to content

Commit d901663

Browse files
committed
CLOUDSTACK-4477: in order to select hypervisor host which can access storage pool, need to check storage_pool_host_ref
1 parent f501c7b commit d901663

4 files changed

Lines changed: 364 additions & 6 deletions

File tree

engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
import javax.inject.Inject;
2727
import javax.naming.ConfigurationException;
2828

29+
import com.cloud.host.Host;
30+
import com.cloud.host.Status;
31+
import com.cloud.utils.fsm.NoTransitionException;
32+
import com.cloud.utils.fsm.StateMachine2;
2933
import org.apache.log4j.Logger;
3034

3135
import com.cloud.agent.AgentManager;
@@ -65,6 +69,9 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa
6569
ClusterDao clusterDao;
6670
@Inject
6771
ClusterDetailsDao clusterDetailsDao;
72+
@Inject
73+
HostDao _hostDao;
74+
protected StateMachine2<Status, Event, Host> _statusStateMachine = Status.getStateMachine();
6875

6976
@Override
7077
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -249,8 +256,12 @@ public AgentAttache handleDirectConnectAgent(HostVO host, StartupCommand[] cmds,
249256

250257
@Override
251258
public boolean agentStatusTransitTo(HostVO host, Event e, long msId) {
252-
// TODO Auto-generated method stub
253-
return false;
259+
try {
260+
return _statusStateMachine.transitTo(host, e, host.getId(), _hostDao);
261+
} catch (NoTransitionException e1) {
262+
e1.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
263+
}
264+
return true;
254265
}
255266

256267
@Override
Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.cloudstack.storage.test;
20+
21+
import com.cloud.agent.AgentManager;
22+
import com.cloud.cluster.LockMasterListener;
23+
import com.cloud.dc.ClusterVO;
24+
import com.cloud.dc.DataCenter;
25+
import com.cloud.dc.DataCenterVO;
26+
import com.cloud.dc.HostPodVO;
27+
import com.cloud.dc.dao.ClusterDao;
28+
import com.cloud.dc.dao.DataCenterDao;
29+
import com.cloud.dc.dao.HostPodDao;
30+
import com.cloud.host.Host;
31+
import com.cloud.host.HostVO;
32+
import com.cloud.host.Status;
33+
import com.cloud.host.dao.HostDao;
34+
import com.cloud.hypervisor.Hypervisor;
35+
import com.cloud.org.Cluster;
36+
import com.cloud.org.Managed;
37+
import com.cloud.resource.ResourceState;
38+
import com.cloud.storage.DataStoreRole;
39+
import com.cloud.storage.ScopeType;
40+
import com.cloud.storage.Storage;
41+
import com.cloud.storage.StoragePoolHostVO;
42+
import com.cloud.storage.StoragePoolStatus;
43+
import com.cloud.storage.dao.SnapshotDao;
44+
import com.cloud.storage.dao.SnapshotPolicyDao;
45+
import com.cloud.storage.dao.StoragePoolHostDao;
46+
import com.cloud.storage.dao.VolumeDao;
47+
import com.cloud.user.Account;
48+
import com.cloud.user.AccountManager;
49+
import com.cloud.user.User;
50+
import com.cloud.utils.component.ComponentContext;
51+
import com.cloud.utils.db.Merovingian2;
52+
import junit.framework.Assert;
53+
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
54+
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
55+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
56+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
57+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
58+
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
59+
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
60+
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
61+
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
62+
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
63+
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
64+
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
65+
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
66+
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
67+
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
68+
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
69+
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
70+
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
71+
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
72+
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
73+
import org.junit.Before;
74+
import org.junit.Test;
75+
import org.junit.runner.RunWith;
76+
import org.mockito.Mockito;
77+
import org.springframework.test.context.ContextConfiguration;
78+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
79+
80+
import javax.inject.Inject;
81+
import java.net.URI;
82+
import java.util.HashSet;
83+
import java.util.List;
84+
import java.util.Set;
85+
import java.util.UUID;
86+
87+
import static org.mockito.Mockito.mock;
88+
import static org.mockito.Mockito.when;
89+
90+
@RunWith(SpringJUnit4ClassRunner.class)
91+
@ContextConfiguration(locations = { "classpath:/fakeDriverTestContext.xml" })
92+
public class EndpointSelectorTest {
93+
@Inject
94+
SnapshotService snapshotService;
95+
@Inject
96+
SnapshotDao snapshotDao;
97+
@Inject
98+
SnapshotDataFactory snapshotDataFactory;
99+
@Inject
100+
PrimaryDataStoreProvider primaryDataStoreProvider;
101+
@Inject
102+
SnapshotDataStoreDao snapshotDataStoreDao;
103+
@Inject
104+
VolumeDao volumeDao;
105+
@Inject
106+
VolumeService volumeService;
107+
@Inject
108+
VolumeDataFactory volumeDataFactory;
109+
@Inject
110+
DataCenterDao dcDao;
111+
Long dcId;
112+
@Inject
113+
HostPodDao podDao;
114+
Long podId;
115+
@Inject
116+
ClusterDao clusterDao;
117+
Long clusterId;
118+
@Inject
119+
ImageStoreDao imageStoreDao;
120+
ImageStoreVO imageStore;
121+
@Inject
122+
AccountManager accountManager;
123+
LockMasterListener lockMasterListener;
124+
VolumeInfo vol = null;
125+
FakePrimaryDataStoreDriver driver = new FakePrimaryDataStoreDriver();
126+
@Inject
127+
MockStorageMotionStrategy mockStorageMotionStrategy;
128+
Merovingian2 _lockMaster;
129+
@Inject
130+
DataStoreManager dataStoreManager;
131+
@Inject
132+
PrimaryDataStoreDao primaryDataStoreDao;
133+
@Inject
134+
SnapshotPolicyDao snapshotPolicyDao;
135+
@Inject
136+
HostDao hostDao;
137+
@Inject
138+
StoragePoolHostDao storagePoolHostDao;
139+
@Inject
140+
EndPointSelector endPointSelector;
141+
@Inject
142+
AgentManager agentMgr;
143+
@Before
144+
public void setUp() {
145+
// create data center
146+
147+
DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null,
148+
"10.0.0.1/24", null, null, DataCenter.NetworkType.Basic, null, null, true, true, null, null);
149+
dc = dcDao.persist(dc);
150+
dcId = dc.getId();
151+
// create pod
152+
153+
HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "10.223.0.1",
154+
"10.233.2.2/25", 8, "test");
155+
pod = podDao.persist(pod);
156+
podId = pod.getId();
157+
// create xen cluster
158+
ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
159+
cluster.setHypervisorType(Hypervisor.HypervisorType.XenServer.toString());
160+
cluster.setClusterType(Cluster.ClusterType.CloudManaged);
161+
cluster.setManagedState(Managed.ManagedState.Managed);
162+
cluster = clusterDao.persist(cluster);
163+
clusterId = cluster.getId();
164+
165+
imageStore = new ImageStoreVO();
166+
imageStore.setName(UUID.randomUUID().toString());
167+
imageStore.setDataCenterId(dcId);
168+
imageStore.setProviderName(DataStoreProvider.NFS_IMAGE);
169+
imageStore.setRole(DataStoreRole.Image);
170+
imageStore.setUrl(UUID.randomUUID().toString());
171+
imageStore.setUuid(UUID.randomUUID().toString());
172+
imageStore.setProtocol("nfs");
173+
imageStore = imageStoreDao.persist(imageStore);
174+
175+
when(primaryDataStoreProvider.configure(Mockito.anyMap())).thenReturn(true);
176+
Set<DataStoreProvider.DataStoreProviderType> types = new HashSet<DataStoreProvider.DataStoreProviderType>();
177+
types.add(DataStoreProvider.DataStoreProviderType.PRIMARY);
178+
179+
when(primaryDataStoreProvider.getTypes()).thenReturn(types);
180+
when(primaryDataStoreProvider.getName()).thenReturn(DataStoreProvider.DEFAULT_PRIMARY);
181+
when(primaryDataStoreProvider.getDataStoreDriver()).thenReturn(driver);
182+
User user = mock(User.class);
183+
when(user.getId()).thenReturn(1L);
184+
Account account = mock(Account.class);
185+
when(account.getId()).thenReturn(1L);
186+
when(accountManager.getSystemAccount()).thenReturn(account);
187+
when(accountManager.getSystemUser()).thenReturn(user);
188+
189+
if(Merovingian2.getLockMaster() == null) {
190+
_lockMaster = Merovingian2.createLockMaster(1234);
191+
} else {
192+
_lockMaster = Merovingian2.getLockMaster();
193+
}
194+
_lockMaster.cleanupThisServer();
195+
ComponentContext.initComponentsLifeCycle();
196+
}
197+
198+
public DataStore createPrimaryDataStore(ScopeType scope) {
199+
String uuid = UUID.randomUUID().toString();
200+
List<StoragePoolVO> pools = primaryDataStoreDao.findPoolByName(uuid);
201+
if (pools.size() > 0) {
202+
return dataStoreManager.getPrimaryDataStore(pools.get(0).getId());
203+
}
204+
205+
StoragePoolVO pool = new StoragePoolVO();
206+
if (scope != ScopeType.ZONE) {
207+
pool.setClusterId(clusterId);
208+
}
209+
pool.setDataCenterId(dcId);
210+
211+
pool.setHostAddress(uuid);
212+
pool.setPath(uuid);
213+
pool.setPort(0);
214+
pool.setName(uuid);
215+
pool.setUuid(uuid);
216+
pool.setStatus(StoragePoolStatus.Up);
217+
pool.setPoolType(Storage.StoragePoolType.NetworkFilesystem);
218+
pool.setPodId(podId);
219+
pool.setScope(scope);
220+
pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY);
221+
pool = primaryDataStoreDao.persist(pool);
222+
DataStore store = dataStoreManager.getPrimaryDataStore(pool.getId());
223+
return store;
224+
}
225+
226+
public HostVO createHost(Hypervisor.HypervisorType hypervisorType) {
227+
String uuid = UUID.randomUUID().toString();
228+
HostVO host = new HostVO(uuid);
229+
host.setName("devcloud xen host");
230+
host.setType(Host.Type.Routing);
231+
host.setPrivateIpAddress(uuid);
232+
host.setDataCenterId(dcId);
233+
host.setVersion("6.0.1");
234+
host.setAvailable(true);
235+
host.setSetup(true);
236+
host.setPodId(podId);
237+
host.setLastPinged(0);
238+
host.setResourceState(ResourceState.Enabled);
239+
host.setHypervisorType(hypervisorType);
240+
host.setClusterId(clusterId);
241+
242+
243+
host = hostDao.persist(host);
244+
agentMgr.agentStatusTransitTo(host, Status.Event.AgentConnected, 1L);
245+
host = hostDao.findById(host.getId());
246+
agentMgr.agentStatusTransitTo(host, Status.Event.Ready, 1L);
247+
return hostDao.findById(host.getId());
248+
}
249+
250+
public void addStorageToHost(DataStore store, HostVO host) {
251+
StoragePoolHostVO storagePoolHostVO = new StoragePoolHostVO(store.getId(), host.getId(), UUID.randomUUID().toString());
252+
storagePoolHostDao.persist(storagePoolHostVO);
253+
}
254+
255+
@Test
256+
public void testMixZonePrimaryStorages() {
257+
Long srcStoreId = null;
258+
Long destStoreId = imageStore.getId();
259+
DataStore store = createPrimaryDataStore(ScopeType.ZONE);
260+
srcStoreId = store.getId();
261+
HostVO host = createHost(Hypervisor.HypervisorType.VMware);
262+
addStorageToHost(store, host);
263+
264+
store = createPrimaryDataStore(ScopeType.ZONE);
265+
host = createHost(Hypervisor.HypervisorType.VMware);
266+
addStorageToHost(store, host);
267+
268+
Long xenStoreId = null;
269+
store = createPrimaryDataStore(ScopeType.CLUSTER);
270+
xenStoreId = store.getId();
271+
host = createHost(Hypervisor.HypervisorType.XenServer);
272+
addStorageToHost(store, host);
273+
274+
store = createPrimaryDataStore(ScopeType.CLUSTER);
275+
host = createHost(Hypervisor.HypervisorType.XenServer);
276+
addStorageToHost(store, host);
277+
278+
ZoneScope srcScope = new ZoneScope(dcId);
279+
280+
DataStore srcStore = mock(DataStore.class);
281+
DataStore destStore = mock(DataStore.class);
282+
283+
when(srcStore.getScope()).thenReturn(srcScope);
284+
when(srcStore.getRole()).thenReturn(DataStoreRole.Primary);
285+
when(srcStore.getId()).thenReturn(srcStoreId);
286+
when(destStore.getScope()).thenReturn(srcScope);
287+
when(destStore.getRole()).thenReturn(DataStoreRole.Image);
288+
when(destStore.getId()).thenReturn(destStoreId);
289+
290+
291+
292+
DataObject srcObj = mock(DataObject.class);
293+
DataObject destObj = mock(DataObject.class);
294+
when(srcObj.getDataStore()).thenReturn(srcStore);
295+
when(destObj.getDataStore()).thenReturn(destStore);
296+
EndPoint ep = endPointSelector.select(srcObj, destObj);
297+
298+
Assert.assertTrue(ep != null);
299+
Long hostId = ep.getId();
300+
HostVO newHost = hostDao.findById(hostId);
301+
Assert.assertTrue(newHost.getHypervisorType() == Hypervisor.HypervisorType.VMware);
302+
303+
when(srcStore.getRole()).thenReturn(DataStoreRole.Image);
304+
when(srcStore.getId()).thenReturn(destStoreId);
305+
when(destStore.getId()).thenReturn(srcStoreId);
306+
when(destStore.getRole()).thenReturn(DataStoreRole.Primary);
307+
ep = endPointSelector.select(srcObj, destObj);
308+
309+
Assert.assertTrue(ep != null);
310+
hostId = ep.getId();
311+
newHost = hostDao.findById(hostId);
312+
Assert.assertTrue(newHost.getHypervisorType() == Hypervisor.HypervisorType.VMware);
313+
314+
ClusterScope clusterScope = new ClusterScope(clusterId, podId, dcId);
315+
when(srcStore.getRole()).thenReturn(DataStoreRole.Primary);
316+
when(srcStore.getScope()).thenReturn(clusterScope);
317+
when(srcStore.getId()).thenReturn(xenStoreId);
318+
ep = endPointSelector.select(srcStore);
319+
Assert.assertTrue(ep != null);
320+
newHost = hostDao.findById(ep.getId());
321+
Assert.assertTrue(newHost.getHypervisorType() == Hypervisor.HypervisorType.XenServer);
322+
323+
324+
325+
}
326+
327+
}

engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakeDriverTestConfiguration.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@
2121
import com.cloud.storage.snapshot.SnapshotScheduler;
2222
import com.cloud.storage.snapshot.SnapshotSchedulerImpl;
2323
import com.cloud.user.DomainManager;
24+
import com.cloud.utils.component.ComponentContext;
2425
import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
2526
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
27+
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
2628
import org.apache.cloudstack.storage.datastore.provider.CloudStackPrimaryDataStoreProviderImpl;
2729
import org.apache.cloudstack.storage.datastore.type.DataStoreType;
30+
import org.apache.cloudstack.storage.endpoint.DefaultEndPointSelector;
2831
import org.mockito.Mockito;
2932
import org.springframework.context.annotation.Bean;
3033

@@ -55,4 +58,10 @@ public DomainManager DomainManager() {
5558
return Mockito.mock(DomainManager.class);
5659
}
5760

61+
@Override
62+
@Bean
63+
public EndPointSelector selector() {
64+
return ComponentContext.inject(DefaultEndPointSelector.class);
65+
}
66+
5867
}

0 commit comments

Comments
 (0)