Skip to content

Commit b632add

Browse files
tests/storage/linstor: Added test_linstor_sr_expand_host to validate the expansion of Linstor SR by integrating a new host into the storage pool.
The test: - Ensures the new host has available disks and installs required Linstor packages. - Configures LVM and integrates it into Linstor SR pool. - Expands SR capacity and validates the increase. - Handles cleanup in case of failure, including removing the node, ejecting the host, and uninstalling Linstor packages. Signed-off-by: Rushikesh Jadhav <[email protected]>
1 parent 3c29683 commit b632add

File tree

1 file changed

+92
-1
lines changed

1 file changed

+92
-1
lines changed

tests/storage/linstor/test_linstor_sr.py

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import pytest
33
import time
44

5-
from .conftest import GROUP_NAME, LINSTOR_PACKAGE
5+
from .conftest import GROUP_NAME, LINSTOR_PACKAGE, LINSTOR_RELEASE_PACKAGE
66
from lib.commands import SSHCommandFailed
77
from lib.common import wait_for, vm_image
88
from tests.storage import vdi_is_open
@@ -139,6 +139,97 @@ def test_linstor_sr_expand_disk(self, linstor_sr, provisioning_type, storage_poo
139139
# Ensure VM is able to start and shutdown on expanded SR
140140
self.test_start_and_shutdown_VM(vm)
141141

142+
@pytest.mark.small_vm
143+
def test_linstor_sr_expand_host(self, linstor_sr, host, hostB1, provisioning_type,
144+
storage_pool_name, vm_on_linstor_sr):
145+
"""
146+
Join new host in the same pool, detect LINSTOR packages,
147+
detect free disks, create LVM, and integrate it into LINSTOR SR.
148+
"""
149+
sr = linstor_sr
150+
vm = vm_on_linstor_sr
151+
vm.start()
152+
sr_size = sr.pool.master.xe('sr-param-get', {'uuid': sr.uuid, 'param-name': 'physical-size'})
153+
resized = False
154+
# Ensure that its a single host pool and not multi host pool
155+
assert len(hostB1.pool.hosts) == 1, "This test requires second host to be a single host"
156+
# Ensure that the host has disks available to use, we do not care about disks symmetry across pool
157+
available_disks = hostB1.available_disks()
158+
# We need the disk to be "raw" (non LVM_member etc) to use
159+
available_disks = [disk for disk in available_disks if hostB1.raw_disk_is_available(disk)]
160+
assert len(available_disks) >= 1, "This test requires second host to have free disk(s)"
161+
if not hostB1.is_package_installed(LINSTOR_PACKAGE):
162+
logging.info("Installing %s on host %s", LINSTOR_PACKAGE, hostB1)
163+
hostB1.yum_install([LINSTOR_RELEASE_PACKAGE])
164+
hostB1.yum_install([LINSTOR_PACKAGE], enablerepo="xcp-ng-linstor-testing")
165+
# Needed because the linstor driver is not in the xapi sm-plugins list
166+
# before installing the LINSTOR packages.
167+
hostB1.ssh(["systemctl", "restart", "multipathd"])
168+
hostB1.restart_toolstack(verify=True)
169+
170+
devices = [f"/dev/{disk}" for disk in available_disks]
171+
172+
for disk in available_disks:
173+
logging.info("Found Disk %s", disk)
174+
device = "/dev/" + disk
175+
hostB1.ssh(['pvcreate', '-ff', '-y', device])
176+
177+
hostB1.ssh(['vgcreate', GROUP_NAME] + devices)
178+
179+
sr_group_name = "xcp-sr-" + storage_pool_name.replace("/", "_")
180+
hostname_hostB1 = hostB1.xe('host-param-get', {'uuid': hostB1.uuid,
181+
'param-name': 'name-label'})
182+
183+
controller_option = "--controllers="
184+
for member in host.pool.hosts:
185+
controller_option += f"{member.hostname_or_ip},"
186+
187+
hostB1_pool = hostB1.pool # Saving the hostB1 pool info before overwrite in join_pool.
188+
try:
189+
logging.info("Joining host %s to pool %s", hostB1, host)
190+
# This will cause hostB1 pool to overwrite itself as host.pool creating issues on next run.
191+
hostB1.join_pool(host.pool)
192+
logging.info("Current list of linstor nodes:")
193+
logging.info(host.ssh_with_result(["linstor", controller_option, "node", "list"]).stdout)
194+
logging.info("Creating linstor node")
195+
host.ssh(["linstor", controller_option, "node", "create", "--node-type", "combined",
196+
"--communication-type", "plain", hostname_hostB1, hostB1.hostname_or_ip]) # Linstor Node Create
197+
logging.info(hostB1.ssh_with_result(['systemctl', 'restart', 'linstor-satellite.service']).stdout)
198+
time.sleep(45) # Wait for node to come online
199+
logging.info("New list of linstor nodes:")
200+
logging.info(host.ssh_with_result(["linstor", controller_option, "node", "list"]).stdout)
201+
logging.info("Expanding with linstor node")
202+
203+
if provisioning_type == "thin":
204+
hostB1.ssh(['lvcreate', '-l', '+100%FREE', '-T', storage_pool_name])
205+
host.ssh_with_result(["linstor", controller_option, "storage-pool", "create", "lvmthin",
206+
hostname_hostB1, sr_group_name, storage_pool_name]).stdout # Expand linstor
207+
else:
208+
host.ssh_with_result(["linstor", controller_option, "storage-pool", "create", "lvm",
209+
hostname_hostB1, sr_group_name, storage_pool_name]).stdout # Expand linstor
210+
except Exception as e:
211+
logging.info("Exception: {}".format(e))
212+
host.ssh(["linstor", controller_option, "node", "delete", hostname_hostB1]) # Linstor Node Delete
213+
host.pool.eject_host(hostB1)
214+
hostB1.ssh(['vgremove', '-y', GROUP_NAME])
215+
hostB1.ssh(['pvremove', '-y'] + devices) # Device cleanup
216+
hostB1.yum_remove([LINSTOR_PACKAGE]) # Package cleanup
217+
218+
resized = True
219+
sr.scan()
220+
new_sr_size = sr.pool.master.xe('sr-param-get', {'uuid': sr.uuid, 'param-name': 'physical-size'})
221+
assert int(new_sr_size) > int(sr_size) and resized is True, \
222+
f"Expected SR size to increase but got old size: {sr_size}, new size: {new_sr_size}"
223+
logging.info("SR expansion completed from size %s to %s", sr_size, new_sr_size)
224+
vm.shutdown(verify=True)
225+
# Ensure VM is able to start and shutdown on expanded SR
226+
self.test_start_and_shutdown_VM(vm)
227+
228+
host.ssh_with_result(["linstor", controller_option, "node", "delete", hostname_hostB1]).stdout
229+
host.pool.eject_host(hostB1)
230+
hostB1.pool = hostB1_pool # Post eject, reset hostB1.pool for next run ("thick")
231+
hostB1.yum_remove([LINSTOR_PACKAGE]) # Package cleanup
232+
142233
# *** tests with reboots (longer tests).
143234

144235
@pytest.mark.reboot

0 commit comments

Comments
 (0)