Skip to content

Commit 6f1a4bf

Browse files
[CLOUDSTACK-10226] CloudStack is not importing Local storage properly
CloudStack is importing as Local storage any XenServer SR that is of type LVM or EXT. This causes a problem when one wants to use both Direct attach storage and local storage. Moreover, CloudStack was not importing all of the local storage that a host has available when local storage is enabled. It was only importing the First SR it sees. To fix the first problem we started ignoring SRs that have the flag shared=true when discovering local storages. SRs configured to be shared are used as direct attached storage, and therefore should not be imported again as local ones. To fix the second problem, we started loading all Local storage and importing them accordingly to ACS.
1 parent fa7c1e2 commit 6f1a4bf

File tree

16 files changed

+695
-452
lines changed

16 files changed

+695
-452
lines changed

plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java

Lines changed: 378 additions & 410 deletions
Large diffs are not rendered by default.

plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ public Boolean checkHeartbeat(final String hostuuid) {
125125
@Override
126126
public StartupCommand[] initialize() {
127127
pingXAPI();
128-
final StartupCommand[] cmds = super.initialize();
129-
return cmds;
128+
return super.initialize();
130129
}
131130
}

plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsHost.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ public class XsHost {
4343
private Integer cpuSockets;
4444
private int cpus;
4545
private String productVersion;
46-
private String localSRuuid;
4746

4847
public String getSystemvmisouuid() {
4948
return systemvmisouuid;
@@ -197,14 +196,6 @@ public void setProductVersion(final String productVersion) {
197196
this.productVersion = productVersion;
198197
}
199198

200-
public String getLocalSRuuid() {
201-
return localSRuuid;
202-
}
203-
204-
public void setLocalSRuuid(final String localSRuuid) {
205-
this.localSRuuid = localSRuuid;
206-
}
207-
208199
@Override
209200
public String toString() {
210201
return new StringBuilder("XS[").append(uuid).append("-").append(ip).append("]").toString();

plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixResourceBaseTest.java

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,41 @@
1616
package com.cloud.hypervisor.xenserver.resource;
1717

1818
import java.io.File;
19+
import java.util.ArrayList;
20+
import java.util.HashMap;
21+
import java.util.HashSet;
1922
import java.util.List;
23+
import java.util.Map;
24+
import java.util.Set;
2025

26+
import org.apache.xmlrpc.XmlRpcException;
2127
import org.junit.Assert;
2228
import org.junit.Test;
29+
import org.junit.runner.RunWith;
30+
import org.mockito.BDDMockito;
31+
import org.mockito.InOrder;
2332
import org.mockito.Mockito;
33+
import org.mockito.Spy;
2434
import org.powermock.api.mockito.PowerMockito;
35+
import org.powermock.core.classloader.annotations.PrepareForTest;
36+
import org.powermock.modules.junit4.PowerMockRunner;
2537

38+
import com.cloud.agent.api.StartupStorageCommand;
39+
import com.cloud.agent.api.StoragePoolInfo;
40+
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase.SRType;
41+
import com.cloud.storage.Storage.StoragePoolType;
42+
import com.cloud.storage.Storage.StorageResourceType;
2643
import com.cloud.utils.script.Script;
44+
import com.xensource.xenapi.Connection;
45+
import com.xensource.xenapi.Host;
46+
import com.xensource.xenapi.PBD;
47+
import com.xensource.xenapi.SR;
48+
import com.xensource.xenapi.Types.XenAPIException;
2749

50+
@RunWith(PowerMockRunner.class)
2851
public class CitrixResourceBaseTest {
2952

53+
@Spy
3054
protected CitrixResourceBase citrixResourceBase = new CitrixResourceBase() {
3155
@Override
3256
protected String getPatchFilePath() {
@@ -92,4 +116,193 @@ public void testGetGuestOsTypeOther() {
92116
String guestOsType = citrixResourceBase.getGuestOsType(platformEmulator);
93117
Assert.assertEquals(platformEmulator, guestOsType);
94118
}
119+
120+
@Test
121+
@PrepareForTest(SR.class)
122+
public void getAllLocalSrForTypeTest() throws Exception {
123+
String mockHostUuid = "hostUuid";
124+
citrixResourceBase._host.setUuid(mockHostUuid);
125+
126+
Connection connectionMock = Mockito.mock(Connection.class);
127+
128+
SR srExtShared = Mockito.mock(SR.class);
129+
SR srExtNonShared = Mockito.mock(SR.class);
130+
131+
List<SR> expectedListOfSrs = new ArrayList<>();
132+
expectedListOfSrs.add(srExtNonShared);
133+
134+
Set<PBD> pbds = new HashSet<>();
135+
PBD pbdMock = Mockito.mock(PBD.class);
136+
Host hostMock = Mockito.mock(Host.class);
137+
Mockito.when(hostMock.getUuid(connectionMock)).thenReturn(mockHostUuid);
138+
Mockito.when(hostMock.toWireString()).thenReturn(mockHostUuid);
139+
140+
Mockito.when(pbdMock.getHost(connectionMock)).thenReturn(hostMock);
141+
pbds.add(pbdMock);
142+
143+
SR.Record srExtSharedRecord = Mockito.mock(SR.Record.class);
144+
srExtSharedRecord.type = "EXT";
145+
srExtSharedRecord.shared = true;
146+
srExtSharedRecord.PBDs = pbds;
147+
148+
SR.Record srExtNonSharedRecord = Mockito.mock(SR.Record.class);
149+
srExtNonSharedRecord.type = "EXT";
150+
srExtNonSharedRecord.shared = false;
151+
srExtNonSharedRecord.PBDs = pbds;
152+
153+
Map<SR, SR.Record> mapOfSrsRecords = new HashMap<>();
154+
mapOfSrsRecords.put(srExtShared, srExtSharedRecord);
155+
mapOfSrsRecords.put(srExtNonShared, srExtNonSharedRecord);
156+
157+
PowerMockito.mockStatic(SR.class);
158+
BDDMockito.given(SR.getAllRecords(connectionMock)).willReturn(mapOfSrsRecords);
159+
160+
List<SR> allLocalSrForType = citrixResourceBase.getAllLocalSrForType(connectionMock, SRType.EXT);
161+
162+
Assert.assertEquals(expectedListOfSrs.size(), allLocalSrForType.size());
163+
Assert.assertEquals(expectedListOfSrs.get(0), allLocalSrForType.get(0));
164+
}
165+
166+
@Test
167+
public void getAllLocalSrForTypeNoSrsFoundTest() throws XenAPIException, XmlRpcException {
168+
Connection connectionMock = Mockito.mock(Connection.class);
169+
List<SR> allLocalSrForType = citrixResourceBase.getAllLocalSrForType(connectionMock, SRType.EXT);
170+
Assert.assertTrue(allLocalSrForType.isEmpty());
171+
}
172+
173+
@Test
174+
public void getAllLocalSrsTest() throws XenAPIException, XmlRpcException {
175+
Connection connectionMock = Mockito.mock(Connection.class);
176+
SR sr1 = Mockito.mock(SR.class);
177+
List<SR> srsExt = new ArrayList<>();
178+
srsExt.add(sr1);
179+
180+
SR sr2 = Mockito.mock(SR.class);
181+
List<SR> srsLvm = new ArrayList<>();
182+
srsLvm.add(sr2);
183+
184+
Mockito.doReturn(srsExt).when(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.EXT);
185+
Mockito.doReturn(srsLvm).when(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.LVM);
186+
187+
List<SR> allLocalSrs = citrixResourceBase.getAllLocalSrs(connectionMock);
188+
189+
Assert.assertEquals(srsExt.size() + srsLvm.size(), allLocalSrs.size());
190+
Assert.assertEquals(srsExt.get(0), allLocalSrs.get(1));
191+
Assert.assertEquals(srsLvm.get(0), allLocalSrs.get(0));
192+
193+
InOrder inOrder = Mockito.inOrder(citrixResourceBase);
194+
inOrder.verify(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.LVM);
195+
inOrder.verify(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.EXT);
196+
}
197+
198+
@Test
199+
@PrepareForTest(Host.class)
200+
public void createStoragePoolInfoTest() throws XenAPIException, XmlRpcException {
201+
Connection connectionMock = Mockito.mock(Connection.class);
202+
Host hostMock = Mockito.mock(Host.class);
203+
SR srMock = Mockito.mock(SR.class);
204+
205+
String hostAddress = "hostAddress";
206+
Mockito.when(hostMock.getAddress(connectionMock)).thenReturn(hostAddress);
207+
208+
String hostUuid = "hostUuid";
209+
citrixResourceBase._host.setUuid(hostUuid);
210+
211+
PowerMockito.mockStatic(Host.class);
212+
PowerMockito.when(Host.getByUuid(connectionMock, hostUuid)).thenReturn(hostMock);
213+
214+
String srType = "ext";
215+
String srUuid = "srUuid";
216+
long srPhysicalSize = 100l;
217+
long physicalUtilization = 10l;
218+
219+
Mockito.when(srMock.getPhysicalSize(connectionMock)).thenReturn(srPhysicalSize);
220+
Mockito.when(srMock.getUuid(connectionMock)).thenReturn(srUuid);
221+
Mockito.when(srMock.getPhysicalUtilisation(connectionMock)).thenReturn(physicalUtilization);
222+
Mockito.when(srMock.getType(connectionMock)).thenReturn(srType);
223+
224+
StoragePoolInfo storagePoolInfo = citrixResourceBase.createStoragePoolInfo(connectionMock, srMock);
225+
226+
Assert.assertEquals(srUuid, storagePoolInfo.getUuid());
227+
Assert.assertEquals(hostAddress, storagePoolInfo.getHost());
228+
Assert.assertEquals(srType.toUpperCase(), storagePoolInfo.getHostPath());
229+
Assert.assertEquals(srType.toUpperCase(), storagePoolInfo.getLocalPath());
230+
Assert.assertEquals(StoragePoolType.EXT, storagePoolInfo.getPoolType());
231+
Assert.assertEquals(srPhysicalSize, storagePoolInfo.getCapacityBytes());
232+
Assert.assertEquals(srPhysicalSize - physicalUtilization, storagePoolInfo.getAvailableBytes());
233+
}
234+
235+
@Test
236+
public void configureStorageNameAndDescriptionTest() throws XenAPIException, XmlRpcException {
237+
String nameFormat = "Cloud Stack Local (%s) Storage Pool for %s";
238+
239+
String hostUuid = "hostUuid";
240+
citrixResourceBase._host.setUuid(hostUuid);
241+
242+
Connection connectionMock = Mockito.mock(Connection.class);
243+
SR srMock = Mockito.mock(SR.class);
244+
245+
String srUuid = "srUuid";
246+
String srType = "ext";
247+
String expectedNameDescription = String.format(nameFormat, srType, hostUuid);
248+
249+
Mockito.when(srMock.getUuid(connectionMock)).thenReturn(srUuid);
250+
Mockito.when(srMock.getType(connectionMock)).thenReturn(srType);
251+
252+
Mockito.doNothing().when(srMock).setNameLabel(connectionMock, srUuid);
253+
Mockito.doNothing().when(srMock).setNameDescription(connectionMock, expectedNameDescription);
254+
255+
citrixResourceBase.configureStorageNameAndDescription(connectionMock, srMock);
256+
257+
Mockito.verify(srMock).setNameLabel(connectionMock, srUuid);
258+
Mockito.verify(srMock).setNameDescription(connectionMock, expectedNameDescription);
259+
}
260+
261+
@Test
262+
public void createStartUpStorageCommandTest() throws XenAPIException, XmlRpcException {
263+
String hostUuid = "hostUUid";
264+
citrixResourceBase._host.setUuid(hostUuid);
265+
citrixResourceBase._dcId = 1;
266+
267+
Connection connectionMock = Mockito.mock(Connection.class);
268+
SR srMock = Mockito.mock(SR.class);
269+
270+
StoragePoolInfo storagePoolInfoMock = Mockito.mock(StoragePoolInfo.class);
271+
272+
Mockito.doNothing().when(citrixResourceBase).configureStorageNameAndDescription(connectionMock, srMock);
273+
Mockito.doReturn(storagePoolInfoMock).when(citrixResourceBase).createStoragePoolInfo(connectionMock, srMock);
274+
275+
StartupStorageCommand startUpStorageCommand = citrixResourceBase.createStartUpStorageCommand(connectionMock, srMock);
276+
277+
Assert.assertEquals(hostUuid, startUpStorageCommand.getGuid());
278+
Assert.assertEquals(storagePoolInfoMock, startUpStorageCommand.getPoolInfo());
279+
Assert.assertEquals(citrixResourceBase._dcId + "", startUpStorageCommand.getDataCenter());
280+
Assert.assertEquals(StorageResourceType.STORAGE_POOL, startUpStorageCommand.getResourceType());
281+
}
282+
283+
@Test
284+
public void initializeLocalSrTest() throws XenAPIException, XmlRpcException {
285+
Connection connectionMock = Mockito.mock(Connection.class);
286+
287+
List<SR> srsMocks = new ArrayList<>();
288+
SR srMock1 = Mockito.mock(SR.class);
289+
SR srMock2 = Mockito.mock(SR.class);
290+
291+
Mockito.when(srMock1.getPhysicalSize(connectionMock)).thenReturn(0l);
292+
Mockito.when(srMock2.getPhysicalSize(connectionMock)).thenReturn(100l);
293+
srsMocks.add(srMock1);
294+
srsMocks.add(srMock2);
295+
296+
Mockito.doReturn(srsMocks).when(citrixResourceBase).getAllLocalSrs(connectionMock);
297+
298+
StartupStorageCommand startupStorageCommandMock = Mockito.mock(StartupStorageCommand.class);
299+
Mockito.doReturn(startupStorageCommandMock).when(citrixResourceBase).createStartUpStorageCommand(Mockito.eq(connectionMock), Mockito.any(SR.class));
300+
301+
List<StartupStorageCommand> startUpCommandsForLocalStorage = citrixResourceBase.initializeLocalSrs(connectionMock);
302+
303+
Mockito.verify(citrixResourceBase, Mockito.times(0)).createStartUpStorageCommand(connectionMock, srMock1);
304+
Mockito.verify(citrixResourceBase, Mockito.times(1)).createStartUpStorageCommand(connectionMock, srMock2);
305+
306+
Assert.assertEquals(1, startUpCommandsForLocalStorage.size());
307+
}
95308
}

plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XcpOssResourceTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,18 @@
1919
import org.junit.Before;
2020
import org.junit.Test;
2121
import org.junit.runner.RunWith;
22+
import org.mockito.Mockito;
2223
import org.powermock.core.classloader.annotations.PrepareForTest;
2324
import org.powermock.modules.junit4.PowerMockRunner;
2425

2526
import com.cloud.utils.exception.CloudRuntimeException;
2627
import com.cloud.utils.script.Script;
2728
@RunWith(PowerMockRunner.class)
28-
public class XcpOssResourceTest extends CitrixResourceBaseTest{
29+
public class XcpOssResourceTest extends CitrixResourceBaseTest {
2930

3031
@Before
3132
public void beforeTest() {
32-
super.citrixResourceBase = new XcpOssResource();
33+
super.citrixResourceBase = Mockito.spy(new XcpOssResource());
3334
}
3435

3536
@Test

plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XcpServerResourceTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,19 @@
1919
import org.junit.Before;
2020
import org.junit.Test;
2121
import org.junit.runner.RunWith;
22+
import org.mockito.Mockito;
2223
import org.powermock.core.classloader.annotations.PrepareForTest;
2324
import org.powermock.modules.junit4.PowerMockRunner;
2425

2526
import com.cloud.utils.exception.CloudRuntimeException;
2627
import com.cloud.utils.script.Script;
2728

2829
@RunWith(PowerMockRunner.class)
29-
public class XcpServerResourceTest extends CitrixResourceBaseTest{
30+
public class XcpServerResourceTest extends CitrixResourceBaseTest {
3031

3132
@Before
3233
public void beforeTest() {
33-
super.citrixResourceBase = new XcpServerResource();
34+
super.citrixResourceBase = Mockito.spy(new XcpServerResource());
3435
}
3536

3637
@Test

plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56FP1ResourceTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,19 @@
1919
import org.junit.Before;
2020
import org.junit.Test;
2121
import org.junit.runner.RunWith;
22+
import org.mockito.Mockito;
2223
import org.powermock.core.classloader.annotations.PrepareForTest;
2324
import org.powermock.modules.junit4.PowerMockRunner;
2425

2526
import com.cloud.utils.exception.CloudRuntimeException;
2627
import com.cloud.utils.script.Script;
2728

2829
@RunWith(PowerMockRunner.class)
29-
public class XenServer56FP1ResourceTest extends CitrixResourceBaseTest{
30+
public class XenServer56FP1ResourceTest extends CitrixResourceBaseTest {
3031

3132
@Before
3233
public void beforeTest() {
33-
super.citrixResourceBase = new XenServer56FP1Resource();
34+
super.citrixResourceBase = Mockito.spy(new XenServer56FP1Resource());
3435
}
3536

3637
@Test

plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56ResourceTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.junit.Before;
2020
import org.junit.Test;
2121
import org.junit.runner.RunWith;
22+
import org.mockito.Mockito;
2223
import org.powermock.core.classloader.annotations.PrepareForTest;
2324
import org.powermock.modules.junit4.PowerMockRunner;
2425

@@ -29,7 +30,7 @@ public class XenServer56ResourceTest extends CitrixResourceBaseTest {
2930

3031
@Before
3132
public void beforeTest() {
32-
super.citrixResourceBase = new XenServer56Resource();
33+
super.citrixResourceBase = Mockito.spy(new XenServer56Resource());
3334
}
3435

3536
@Test

plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56SP2ResourceTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.junit.Before;
2020
import org.junit.Test;
2121
import org.junit.runner.RunWith;
22+
import org.mockito.Mockito;
2223
import org.powermock.core.classloader.annotations.PrepareForTest;
2324
import org.powermock.modules.junit4.PowerMockRunner;
2425

@@ -29,7 +30,7 @@ public class XenServer56SP2ResourceTest extends CitrixResourceBaseTest{
2930

3031
@Before
3132
public void beforeTest() {
32-
super.citrixResourceBase = new XenServer56SP2Resource();
33+
super.citrixResourceBase = Mockito.spy(new XenServer56SP2Resource());
3334
}
3435

3536
@Test

plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer600ResourceTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.junit.Before;
2020
import org.junit.Test;
2121
import org.junit.runner.RunWith;
22+
import org.mockito.Mockito;
2223
import org.powermock.core.classloader.annotations.PrepareForTest;
2324
import org.powermock.modules.junit4.PowerMockRunner;
2425

@@ -29,7 +30,7 @@ public class XenServer600ResourceTest extends CitrixResourceBaseTest{
2930

3031
@Before
3132
public void beforeTest() {
32-
super.citrixResourceBase = new XenServer600Resource();
33+
super.citrixResourceBase = Mockito.spy(new XenServer600Resource());
3334
}
3435

3536

0 commit comments

Comments
 (0)