Skip to content

Commit bbc9204

Browse files
[CLOUDSTACK-10226] CloudStack is not importing Local storage properly (#2401)
* [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. * Cleanups and formatting
1 parent b08f9e0 commit bbc9204

File tree

15 files changed

+558
-379
lines changed

15 files changed

+558
-379
lines changed

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

Lines changed: 133 additions & 142 deletions
Large diffs are not rendered by default.

plugins/hypervisors/xenserver/src/main/java/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/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ private void mountNfs(Connection conn, String remoteDir, String localDir) {
7575
}
7676
String result = hypervisorResource.callHostPluginAsync(conn, "cloud-plugin-storage", "mountNfsSecondaryStorage", 100 * 1000, "localDir", localDir, "remoteDir", remoteDir);
7777
if (StringUtils.isBlank(result)) {
78-
final String errMsg = "Could not mount secondary storage " + remoteDir + " on host " + localDir;
78+
String errMsg = "Could not mount secondary storage " + remoteDir + " on host " + localDir;
7979
s_logger.warn(errMsg);
8080
throw new CloudRuntimeException(errMsg);
8181
}

plugins/hypervisors/xenserver/src/main/java/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/src/test/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBaseTest.java

Lines changed: 201 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,42 @@
1616
package com.cloud.hypervisor.xenserver.resource;
1717

1818
import java.io.File;
19+
import java.util.ArrayList;
1920
import java.util.HashMap;
21+
import java.util.HashSet;
2022
import java.util.List;
23+
import java.util.Map;
24+
import java.util.Set;
2125

2226
import org.apache.xmlrpc.XmlRpcException;
2327
import org.junit.Assert;
2428
import org.junit.Before;
2529
import org.junit.Test;
2630
import org.junit.runner.RunWith;
31+
import org.mockito.BDDMockito;
32+
import org.mockito.InOrder;
2733
import org.mockito.Mock;
2834
import org.mockito.Mockito;
2935
import org.mockito.Spy;
3036
import org.powermock.api.mockito.PowerMockito;
3137
import org.powermock.core.classloader.annotations.PrepareForTest;
3238
import org.powermock.modules.junit4.PowerMockRunner;
3339

40+
import com.cloud.agent.api.StartupStorageCommand;
41+
import com.cloud.agent.api.StoragePoolInfo;
42+
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase.SRType;
43+
import com.cloud.storage.Storage.StoragePoolType;
44+
import com.cloud.storage.Storage.StorageResourceType;
3445
import com.cloud.utils.script.Script;
3546
import com.xensource.xenapi.Connection;
3647
import com.xensource.xenapi.Host;
3748
import com.xensource.xenapi.Host.Record;
49+
import com.xensource.xenapi.PBD;
50+
import com.xensource.xenapi.SR;
3851
import com.xensource.xenapi.Types.XenAPIException;
3952

4053
@RunWith(PowerMockRunner.class)
41-
@PrepareForTest({Host.class, Script.class})
54+
@PrepareForTest({Host.class, Script.class, SR.class})
4255
public class CitrixResourceBaseTest {
4356

4457
@Spy
@@ -168,4 +181,191 @@ public void actualIsoTemplateTestXenServer71() throws XenAPIException, XmlRpcExc
168181

169182
Assert.assertEquals("guest-tools.iso", returnedIsoTemplateName);
170183
}
184+
185+
@Test
186+
public void getAllLocalSrForTypeTest() throws Exception {
187+
String mockHostUuid = "hostUuid";
188+
citrixResourceBase._host.setUuid(mockHostUuid);
189+
190+
Connection connectionMock = Mockito.mock(Connection.class);
191+
192+
SR srExtShared = Mockito.mock(SR.class);
193+
SR srExtNonShared = Mockito.mock(SR.class);
194+
195+
List<SR> expectedListOfSrs = new ArrayList<>();
196+
expectedListOfSrs.add(srExtNonShared);
197+
198+
Set<PBD> pbds = new HashSet<>();
199+
PBD pbdMock = Mockito.mock(PBD.class);
200+
Host hostMock = Mockito.mock(Host.class);
201+
Mockito.when(hostMock.getUuid(connectionMock)).thenReturn(mockHostUuid);
202+
Mockito.when(hostMock.toWireString()).thenReturn(mockHostUuid);
203+
204+
Mockito.when(pbdMock.getHost(connectionMock)).thenReturn(hostMock);
205+
pbds.add(pbdMock);
206+
207+
SR.Record srExtSharedRecord = Mockito.mock(SR.Record.class);
208+
srExtSharedRecord.type = "EXT";
209+
srExtSharedRecord.shared = true;
210+
srExtSharedRecord.PBDs = pbds;
211+
212+
SR.Record srExtNonSharedRecord = Mockito.mock(SR.Record.class);
213+
srExtNonSharedRecord.type = "EXT";
214+
srExtNonSharedRecord.shared = false;
215+
srExtNonSharedRecord.PBDs = pbds;
216+
217+
Map<SR, SR.Record> mapOfSrsRecords = new HashMap<>();
218+
mapOfSrsRecords.put(srExtShared, srExtSharedRecord);
219+
mapOfSrsRecords.put(srExtNonShared, srExtNonSharedRecord);
220+
221+
PowerMockito.mockStatic(SR.class);
222+
BDDMockito.given(SR.getAllRecords(connectionMock)).willReturn(mapOfSrsRecords);
223+
224+
List<SR> allLocalSrForType = citrixResourceBase.getAllLocalSrForType(connectionMock, SRType.EXT);
225+
226+
Assert.assertEquals(expectedListOfSrs.size(), allLocalSrForType.size());
227+
Assert.assertEquals(expectedListOfSrs.get(0), allLocalSrForType.get(0));
228+
}
229+
230+
@Test
231+
public void getAllLocalSrForTypeNoSrsFoundTest() throws XenAPIException, XmlRpcException {
232+
Connection connectionMock = Mockito.mock(Connection.class);
233+
List<SR> allLocalSrForType = citrixResourceBase.getAllLocalSrForType(connectionMock, SRType.EXT);
234+
Assert.assertTrue(allLocalSrForType.isEmpty());
235+
}
236+
237+
@Test
238+
public void getAllLocalSrsTest() throws XenAPIException, XmlRpcException {
239+
Connection connectionMock = Mockito.mock(Connection.class);
240+
SR sr1 = Mockito.mock(SR.class);
241+
List<SR> srsExt = new ArrayList<>();
242+
srsExt.add(sr1);
243+
244+
SR sr2 = Mockito.mock(SR.class);
245+
List<SR> srsLvm = new ArrayList<>();
246+
srsLvm.add(sr2);
247+
248+
Mockito.doReturn(srsExt).when(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.EXT);
249+
Mockito.doReturn(srsLvm).when(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.LVM);
250+
251+
List<SR> allLocalSrs = citrixResourceBase.getAllLocalSrs(connectionMock);
252+
253+
Assert.assertEquals(srsExt.size() + srsLvm.size(), allLocalSrs.size());
254+
Assert.assertEquals(srsExt.get(0), allLocalSrs.get(1));
255+
Assert.assertEquals(srsLvm.get(0), allLocalSrs.get(0));
256+
257+
InOrder inOrder = Mockito.inOrder(citrixResourceBase);
258+
inOrder.verify(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.LVM);
259+
inOrder.verify(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.EXT);
260+
}
261+
262+
@Test
263+
public void createStoragePoolInfoTest() throws XenAPIException, XmlRpcException {
264+
Connection connectionMock = Mockito.mock(Connection.class);
265+
Host hostMock = Mockito.mock(Host.class);
266+
SR srMock = Mockito.mock(SR.class);
267+
268+
String hostAddress = "hostAddress";
269+
Mockito.when(hostMock.getAddress(connectionMock)).thenReturn(hostAddress);
270+
271+
String hostUuid = "hostUuid";
272+
citrixResourceBase._host.setUuid(hostUuid);
273+
274+
PowerMockito.mockStatic(Host.class);
275+
PowerMockito.when(Host.getByUuid(connectionMock, hostUuid)).thenReturn(hostMock);
276+
277+
String srType = "ext";
278+
String srUuid = "srUuid";
279+
long srPhysicalSize = 100l;
280+
long physicalUtilization = 10l;
281+
282+
Mockito.when(srMock.getPhysicalSize(connectionMock)).thenReturn(srPhysicalSize);
283+
Mockito.when(srMock.getUuid(connectionMock)).thenReturn(srUuid);
284+
Mockito.when(srMock.getPhysicalUtilisation(connectionMock)).thenReturn(physicalUtilization);
285+
Mockito.when(srMock.getType(connectionMock)).thenReturn(srType);
286+
287+
StoragePoolInfo storagePoolInfo = citrixResourceBase.createStoragePoolInfo(connectionMock, srMock);
288+
289+
Assert.assertEquals(srUuid, storagePoolInfo.getUuid());
290+
Assert.assertEquals(hostAddress, storagePoolInfo.getHost());
291+
Assert.assertEquals(srType.toUpperCase(), storagePoolInfo.getHostPath());
292+
Assert.assertEquals(srType.toUpperCase(), storagePoolInfo.getLocalPath());
293+
Assert.assertEquals(StoragePoolType.EXT, storagePoolInfo.getPoolType());
294+
Assert.assertEquals(srPhysicalSize, storagePoolInfo.getCapacityBytes());
295+
Assert.assertEquals(srPhysicalSize - physicalUtilization, storagePoolInfo.getAvailableBytes());
296+
}
297+
298+
@Test
299+
public void configureStorageNameAndDescriptionTest() throws XenAPIException, XmlRpcException {
300+
String nameFormat = "Cloud Stack Local (%s) Storage Pool for %s";
301+
302+
String hostUuid = "hostUuid";
303+
citrixResourceBase._host.setUuid(hostUuid);
304+
305+
Connection connectionMock = Mockito.mock(Connection.class);
306+
SR srMock = Mockito.mock(SR.class);
307+
308+
String srUuid = "srUuid";
309+
String srType = "ext";
310+
String expectedNameDescription = String.format(nameFormat, srType, hostUuid);
311+
312+
Mockito.when(srMock.getUuid(connectionMock)).thenReturn(srUuid);
313+
Mockito.when(srMock.getType(connectionMock)).thenReturn(srType);
314+
315+
Mockito.doNothing().when(srMock).setNameLabel(connectionMock, srUuid);
316+
Mockito.doNothing().when(srMock).setNameDescription(connectionMock, expectedNameDescription);
317+
318+
citrixResourceBase.configureStorageNameAndDescription(connectionMock, srMock);
319+
320+
Mockito.verify(srMock).setNameLabel(connectionMock, srUuid);
321+
Mockito.verify(srMock).setNameDescription(connectionMock, expectedNameDescription);
322+
}
323+
324+
@Test
325+
public void createStartUpStorageCommandTest() throws XenAPIException, XmlRpcException {
326+
String hostUuid = "hostUUid";
327+
citrixResourceBase._host.setUuid(hostUuid);
328+
citrixResourceBase._dcId = 1;
329+
330+
Connection connectionMock = Mockito.mock(Connection.class);
331+
SR srMock = Mockito.mock(SR.class);
332+
333+
StoragePoolInfo storagePoolInfoMock = Mockito.mock(StoragePoolInfo.class);
334+
335+
Mockito.doNothing().when(citrixResourceBase).configureStorageNameAndDescription(connectionMock, srMock);
336+
Mockito.doReturn(storagePoolInfoMock).when(citrixResourceBase).createStoragePoolInfo(connectionMock, srMock);
337+
338+
StartupStorageCommand startUpStorageCommand = citrixResourceBase.createStartUpStorageCommand(connectionMock, srMock);
339+
340+
Assert.assertEquals(hostUuid, startUpStorageCommand.getGuid());
341+
Assert.assertEquals(storagePoolInfoMock, startUpStorageCommand.getPoolInfo());
342+
Assert.assertEquals(citrixResourceBase._dcId + "", startUpStorageCommand.getDataCenter());
343+
Assert.assertEquals(StorageResourceType.STORAGE_POOL, startUpStorageCommand.getResourceType());
344+
}
345+
346+
@Test
347+
public void initializeLocalSrTest() throws XenAPIException, XmlRpcException {
348+
Connection connectionMock = Mockito.mock(Connection.class);
349+
350+
List<SR> srsMocks = new ArrayList<>();
351+
SR srMock1 = Mockito.mock(SR.class);
352+
SR srMock2 = Mockito.mock(SR.class);
353+
354+
Mockito.when(srMock1.getPhysicalSize(connectionMock)).thenReturn(0l);
355+
Mockito.when(srMock2.getPhysicalSize(connectionMock)).thenReturn(100l);
356+
srsMocks.add(srMock1);
357+
srsMocks.add(srMock2);
358+
359+
Mockito.doReturn(srsMocks).when(citrixResourceBase).getAllLocalSrs(connectionMock);
360+
361+
StartupStorageCommand startupStorageCommandMock = Mockito.mock(StartupStorageCommand.class);
362+
Mockito.doReturn(startupStorageCommandMock).when(citrixResourceBase).createStartUpStorageCommand(Mockito.eq(connectionMock), Mockito.any(SR.class));
363+
364+
List<StartupStorageCommand> startUpCommandsForLocalStorage = citrixResourceBase.initializeLocalSrs(connectionMock);
365+
366+
Mockito.verify(citrixResourceBase, Mockito.times(0)).createStartUpStorageCommand(connectionMock, srMock1);
367+
Mockito.verify(citrixResourceBase, Mockito.times(1)).createStartUpStorageCommand(connectionMock, srMock2);
368+
369+
Assert.assertEquals(1, startUpCommandsForLocalStorage.size());
370+
}
171371
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.junit.Assert;
2020
import org.junit.Before;
2121
import org.junit.Test;
22+
import org.mockito.Mockito;
2223

2324
import com.cloud.utils.exception.CloudRuntimeException;
2425
import com.xensource.xenapi.Types.XenAPIException;
@@ -28,7 +29,7 @@ public class XcpOssResourceTest extends CitrixResourceBaseTest {
2829
@Before
2930
@Override
3031
public void beforeTest() throws XenAPIException, XmlRpcException {
31-
super.citrixResourceBase = new XcpOssResource();
32+
super.citrixResourceBase = Mockito.spy(new XcpOssResource());
3233
super.beforeTest();
3334
}
3435

@@ -41,12 +42,12 @@ public void testPatchFilePath() {
4142
}
4243

4344
@Test(expected = CloudRuntimeException.class)
44-
public void testGetFiles(){
45+
public void testGetFiles() {
4546
testGetPathFilesExeption();
4647
}
4748

4849
@Test
49-
public void testGetFilesListReturned(){
50+
public void testGetFilesListReturned() {
5051
testGetPathFilesListReturned();
5152
}
5253
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.junit.Assert;
2020
import org.junit.Before;
2121
import org.junit.Test;
22+
import org.mockito.Mockito;
2223

2324
import com.cloud.utils.exception.CloudRuntimeException;
2425
import com.xensource.xenapi.Types.XenAPIException;
@@ -28,7 +29,7 @@ public class XcpServerResourceTest extends CitrixResourceBaseTest {
2829
@Before
2930
@Override
3031
public void beforeTest() throws XenAPIException, XmlRpcException {
31-
super.citrixResourceBase = new XcpServerResource();
32+
super.citrixResourceBase = Mockito.spy(new XcpServerResource());
3233
super.beforeTest();
3334
}
3435

@@ -41,12 +42,12 @@ public void testPatchFilePath() {
4142
}
4243

4344
@Test(expected = CloudRuntimeException.class)
44-
public void testGetFilesExeption(){
45+
public void testGetFilesExeption() {
4546
testGetPathFilesExeption();
4647
}
4748

4849
@Test
49-
public void testGetFilesListReturned(){
50+
public void testGetFilesListReturned() {
5051
testGetPathFilesListReturned();
5152
}
5253
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.junit.Assert;
2020
import org.junit.Before;
2121
import org.junit.Test;
22+
import org.mockito.Mockito;
2223

2324
import com.cloud.utils.exception.CloudRuntimeException;
2425
import com.xensource.xenapi.Types.XenAPIException;
@@ -28,7 +29,7 @@ public class XenServer56FP1ResourceTest extends CitrixResourceBaseTest {
2829
@Before
2930
@Override
3031
public void beforeTest() throws XenAPIException, XmlRpcException {
31-
super.citrixResourceBase = new XenServer56FP1Resource();
32+
super.citrixResourceBase = Mockito.spy(new XenServer56FP1Resource());
3233
super.beforeTest();
3334
}
3435

@@ -41,12 +42,12 @@ public void testPatchFilePath() {
4142
}
4243

4344
@Test(expected = CloudRuntimeException.class)
44-
public void testGetFiles(){
45+
public void testGetFiles() {
4546
testGetPathFilesExeption();
4647
}
4748

4849
@Test
49-
public void testGetFilesListReturned(){
50+
public void testGetFilesListReturned() {
5051
testGetPathFilesListReturned();
5152
}
5253
}

0 commit comments

Comments
 (0)