From e7326c7ebd585f1709b2b3140637b08ac9f3d3af Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 27 Mar 2024 14:35:40 +0100 Subject: [PATCH 01/13] lib/vdi: add shapshot and clone operations Signed-off-by: Yann Dirson --- lib/vdi.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/vdi.py b/lib/vdi.py index e9f82b18..b2781cfd 100644 --- a/lib/vdi.py +++ b/lib/vdi.py @@ -1,14 +1,27 @@ import logging class VDI: - def __init__(self, sr, uuid): + def __init__(self, sr, uuid, snapshot_of=None): self.uuid = uuid + self.snapshot_of = snapshot_of # TODO: use a different approach when migration is possible self.sr = sr + def snapshot(self): + logging.info(f"Create snapshot of {self}") + return VDI(self.sr, + self.sr.pool.master.xe('vdi-snapshot', {'uuid': self.uuid}), + snapshot_of=self) + + def clone(self): + logging.info(f"Create clone of {self}") + return VDI(self.sr, + self.sr.pool.master.xe('vdi-clone', {'uuid': self.uuid})) + def destroy(self): logging.info("Destroy %s", self) self.sr.pool.master.xe('vdi-destroy', {'uuid': self.uuid}) def __str__(self): - return f"VDI {self.uuid} on SR {self.sr.uuid}" + return (f"VDI {self.uuid} on SR {self.sr.uuid}" + f"{f' (snapshot of {self.snapshot_of})' if self.snapshot_of else ''}") From 25aafa17b4e31624f671b18879a2c62de690e8f4 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 27 Mar 2024 14:35:47 +0100 Subject: [PATCH 02/13] zfs-vol: add simple tests for cloning a VDI (xfail) and a VDI snapshot Signed-off-by: Yann Dirson --- tests/storage/zfsvol/test_zfsvol_sr.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index cc449e9c..c7796aab 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -29,8 +29,20 @@ def test_create_and_destroy_sr(self, host, sr_disk_wiped): sr.destroy(verify=True) @pytest.mark.usefixtures("zfsvol_sr") -class TestZfsvolVm: +class TestZfsvolSrBasics: + @pytest.mark.xfail # needs support for cloning non-snapshots + def test_vdi_clone(self, vdi_on_zfsvol_sr): + clone = vdi_on_zfsvol_sr.clone() + clone.destroy() + + def test_vdi_snap_clone(self, vdi_on_zfsvol_sr): + snap = vdi_on_zfsvol_sr.snapshot() + clone = snap.clone() + clone.destroy() + snap.destroy() +@pytest.mark.usefixtures("zfsvol_sr") +class TestZfsvolVm: @pytest.mark.xfail @pytest.mark.quicktest def test_quicktest(self, zfsvol_sr): From 31a72ab7535713b184eecef49ead38056c865d8c Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Tue, 19 Mar 2024 18:35:27 +0100 Subject: [PATCH 03/13] zfs-vol: create tests for VDI destroy as we want it for the public proto Signed-off-by: Yann Dirson --- tests/storage/zfsvol/test_zfsvol_sr.py | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index c7796aab..ac2a181a 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -83,3 +83,34 @@ def test_reboot(self, vm_on_zfsvol_sr, host, zfsvol_sr): vm.shutdown(verify=True) # *** End of tests with reboots + +@pytest.mark.usefixtures("zfsvol_sr") +class TestZfsngSrSingleVdiDestroy: + "Destruction tests of a single VDI involved in various topologies" + @pytest.mark.xfail # needs support for destroying non-snapshots blocked by snaps + def test_vdi_destroy_with_snap_but_no_clones(self, zfsvol_sr): + vdi = zfsvol_sr.create_vdi('ZFS-local-VDI-test') + snap = vdi.snapshot() + vdi.destroy() + + @pytest.mark.xfail # needs support for destroying non-snapshots blocked by snaps + def test_vdi_destroy_with_several_snaps_but_no_clones(self, zfsvol_sr): + vdi = zfsvol_sr.create_vdi('ZFS-local-VDI-test') + snaps = [] + for i in range(3): + snaps.append(vdi.snapshot()) + vdi.destroy() + + def test_vdi_destroy_with_snap_and_clone(self, zfsvol_sr): + vdi = zfsvol_sr.create_vdi('ZFS-local-VDI-test') + snap = vdi.snapshot() + clone = snap.clone() + vdi.destroy() + + def test_vdi_destroy_with_snap_and_several_clones(self, zfsvol_sr): + vdi = zfsvol_sr.create_vdi('ZFS-local-VDI-test') + snap = vdi.snapshot() + clones = [] + for i in range(3): + clones.append(snap.clone()) + vdi.destroy() From c69a32862dfbd982d7f959647eca629b34a1ad79 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Fri, 22 Mar 2024 16:45:59 +0100 Subject: [PATCH 04/13] WIP zfs-vol: add basics setup for testing snapshot/clone chains * this only tests clones of snapshots, as cloning without explicit snap is not supported yet FIXME: * vdi_and_snaps_chain is nothing specific to ZFS, should be moved to somewhere generic --- tests/storage/zfsvol/test_zfsvol_sr.py | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index ac2a181a..a9f26bc4 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -114,3 +114,37 @@ def test_vdi_destroy_with_snap_and_several_clones(self, zfsvol_sr): for i in range(3): clones.append(snap.clone()) vdi.destroy() + +# FIXME below should be independent from SR type and label + +def create_vdi_and_snaps_chain(sr, vdi_label): + "Create a chain of alternating VDI snapshots and clones on first host." + vdis = [sr.create_vdi(vdi_label)] + for i in range(2): + vdis.append(vdis[-1].snapshot()) + vdis.append(vdis[-1].clone()) + return vdis + +def teardown_vdi_chain(sr, vdis, order): + "Destroy a list of VDIs in order specified by a sequence of VDIs indices." + for i in order: + vdi = vdis[i] + logging.debug("zfs state: %r", sr.main_host().ssh( + "zfs list -Hp -t all -o name,origin".split())) + try: + vdi.destroy() + except Exception: + logging.error("failed to destroy %s", vdi) + raise + +@pytest.mark.usefixtures("zfsvol_sr") +class TestZfsvolSrVdiChainSnapDestroy: + "VDI chain destruction tests with alternating snap/clone" + def test_vdi_and_snaps_teardown(self, zfsvol_sr): + "Destroy snapshot chain in reverse order of creation" + vdis = create_vdi_and_snaps_chain(zfsvol_sr, 'ZFS-local-VDI-test') + assert len(vdis) == 5 + for (i, is_snap) in enumerate([False, True, False, True, False]): + assert (vdis[i].snapshot_of is not None) == is_snap, \ + f"vdis[{i}] should {'' if is_snap else 'not '}be a snapshot" + teardown_vdi_chain(zfsvol_sr, vdis, (4, 3, 2, 1, 0)) From 2fa842a90964d559952851c98f3cc41d6becbc18 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 27 Mar 2024 14:31:32 +0100 Subject: [PATCH 05/13] zfs-vol: test destroying each VDI in the chain independently from the others Signed-off-by: Yann Dirson --- tests/storage/zfsvol/test_zfsvol_sr.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index a9f26bc4..1b6c8d7f 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -148,3 +148,15 @@ def test_vdi_and_snaps_teardown(self, zfsvol_sr): assert (vdis[i].snapshot_of is not None) == is_snap, \ f"vdis[{i}] should {'' if is_snap else 'not '}be a snapshot" teardown_vdi_chain(zfsvol_sr, vdis, (4, 3, 2, 1, 0)) + + @pytest.mark.xfail # needs support for destroying non-snapshots blocked by snaps + def test_vdi_and_snaps_destroy_first_vdi(self, zfsvol_sr): + "Destroy first-created VDI, then the rest in reverse order of creation" + vdis = create_vdi_and_snaps_chain(zfsvol_sr, 'ZFS-local-VDI-test') + teardown_vdi_chain(zfsvol_sr, vdis, (0, 4, 3, 2, 1)) + + @pytest.mark.xfail # needs support for destroying non-snapshots blocked by snaps + def test_vdi_and_snaps_destroy_intermediate_vdi(self, zfsvol_sr): + "Destroy second-created VDI, then the rest in reverse order of creation" + vdis = create_vdi_and_snaps_chain(zfsvol_sr, 'ZFS-local-VDI-test') + teardown_vdi_chain(zfsvol_sr, vdis, (2, 4, 3, 1, 0)) From 6c216c3312c723a2f987800fa7b07523727cece5 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 27 Mar 2024 14:37:39 +0100 Subject: [PATCH 06/13] zfs-vol: test destroying the chain in all remaining orders supported by proto Signed-off-by: Yann Dirson --- tests/storage/zfsvol/test_zfsvol_sr.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index 1b6c8d7f..e1ada892 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -160,3 +160,21 @@ def test_vdi_and_snaps_destroy_intermediate_vdi(self, zfsvol_sr): "Destroy second-created VDI, then the rest in reverse order of creation" vdis = create_vdi_and_snaps_chain(zfsvol_sr, 'ZFS-local-VDI-test') teardown_vdi_chain(zfsvol_sr, vdis, (2, 4, 3, 1, 0)) + + # orderings expected to work on first proto + + def test_vdi_and_snaps_destroy_01432(self, zfsvol_sr): + vdis = create_vdi_and_snaps_chain(zfsvol_sr, 'ZFS-local-VDI-test') + teardown_vdi_chain(zfsvol_sr, vdis, (0, 1, 4, 3, 2)) + + def test_vdi_and_snaps_destroy_01234(self, zfsvol_sr): + vdis = create_vdi_and_snaps_chain(zfsvol_sr, 'ZFS-local-VDI-test') + teardown_vdi_chain(zfsvol_sr, vdis, (0, 1, 2, 3, 4)) + + def test_vdi_and_snaps_destroy_23410(self, zfsvol_sr): + vdis = create_vdi_and_snaps_chain(zfsvol_sr, 'ZFS-local-VDI-test') + teardown_vdi_chain(zfsvol_sr, vdis, (2, 3, 4, 1, 0)) + + def test_vdi_and_snaps_destroy_23014(self, zfsvol_sr): + vdis = create_vdi_and_snaps_chain(zfsvol_sr, 'ZFS-local-VDI-test') + teardown_vdi_chain(zfsvol_sr, vdis, (2, 3, 0, 1, 4)) From 1fb6d07b1f8117a51143aeb4d6b4362f7b43b8f7 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 27 Mar 2024 14:54:47 +0100 Subject: [PATCH 07/13] WIP zfs-vol: add a test for destroying base of a snap with 2 clones No failure should happen, but this can be used to check in the logs that we only perform the single required "zfs promote" and not one per clone. FIXME: automate this check --- tests/storage/zfsvol/test_zfsvol_sr.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index e1ada892..bfab77ce 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -178,3 +178,12 @@ def test_vdi_and_snaps_destroy_23410(self, zfsvol_sr): def test_vdi_and_snaps_destroy_23014(self, zfsvol_sr): vdis = create_vdi_and_snaps_chain(zfsvol_sr, 'ZFS-local-VDI-test') teardown_vdi_chain(zfsvol_sr, vdis, (2, 3, 0, 1, 4)) + + # other topologies + + def test_destroy_vdi_with_snap_with_multiple_clones(self, zfsvol_sr): + base_vdi = zfsvol_sr.create_vdi('ZFS-local-VDI-test') + snap = base_vdi.snapshot() + clones = [snap.clone(), snap.clone()] + + base_vdi.destroy() From 46077e94695440d959aa0e1a55a46356c04fbbea Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Fri, 22 Mar 2024 17:09:25 +0100 Subject: [PATCH 08/13] zfs-vol: test chain of VDI clones and their destuction (xfail) Cloning a VDI without a snapshot is not implemented yet. Signed-off-by: Yann Dirson --- tests/storage/zfsvol/test_zfsvol_sr.py | 29 ++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index bfab77ce..af433d72 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -187,3 +187,32 @@ def test_destroy_vdi_with_snap_with_multiple_clones(self, zfsvol_sr): clones = [snap.clone(), snap.clone()] base_vdi.destroy() + +@pytest.mark.xfail +@pytest.mark.usefixtures("zfsvol_sr") +class TestZfsvolSrVdiChainDestroy: + "VDI chain destruction tests with just clones and no snaps" + def test_destroy_210(self, zfsvol_sr): + vdis = create_vdi_chain(zfsvol_sr, 'ZFS-local-VDI-test') + assert len(vdis) == 3 + teardown_vdi_chain(zfsvol_sr, vdis, (2, 1, 0)) + + def test_destroy_201(self, zfsvol_sr): + vdis = create_vdi_chain(zfsvol_sr, 'ZFS-local-VDI-test') + teardown_vdi_chain(zfsvol_sr, vdis, (2, 0, 1)) + + def test_destroy_012(self, zfsvol_sr): + vdis = create_vdi_chain(zfsvol_sr, 'ZFS-local-VDI-test') + teardown_vdi_chain(zfsvol_sr, vdis, (0, 1, 2)) + + def test_destroy_021(self, zfsvol_sr): + vdis = create_vdi_chain(zfsvol_sr, 'ZFS-local-VDI-test') + teardown_vdi_chain(zfsvol_sr, vdis, (0, 2, 1)) + + def test_destroy_102(self, zfsvol_sr): + vdis = create_vdi_chain(zfsvol_sr, 'ZFS-local-VDI-test') + teardown_vdi_chain(zfsvol_sr, vdis, (1, 0, 2)) + + def test_destroy_120(self, zfsvol_sr): + vdis = create_vdi_chain(zfsvol_sr, 'ZFS-local-VDI-test') + teardown_vdi_chain(zfsvol_sr, vdis, (1, 2, 0)) From 4c7c21ed0edb978ef2839afa87b76088669537a6 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 27 Mar 2024 15:12:05 +0100 Subject: [PATCH 09/13] zfs-vol: now implements "extra clones to unlock promotion" ... with side effect that some extra clones will now prevent destruction of some snapshots Signed-off-by: Yann Dirson --- tests/storage/zfsvol/test_zfsvol_sr.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index af433d72..332e5bd4 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -87,13 +87,11 @@ def test_reboot(self, vm_on_zfsvol_sr, host, zfsvol_sr): @pytest.mark.usefixtures("zfsvol_sr") class TestZfsngSrSingleVdiDestroy: "Destruction tests of a single VDI involved in various topologies" - @pytest.mark.xfail # needs support for destroying non-snapshots blocked by snaps def test_vdi_destroy_with_snap_but_no_clones(self, zfsvol_sr): vdi = zfsvol_sr.create_vdi('ZFS-local-VDI-test') snap = vdi.snapshot() vdi.destroy() - @pytest.mark.xfail # needs support for destroying non-snapshots blocked by snaps def test_vdi_destroy_with_several_snaps_but_no_clones(self, zfsvol_sr): vdi = zfsvol_sr.create_vdi('ZFS-local-VDI-test') snaps = [] @@ -149,13 +147,12 @@ def test_vdi_and_snaps_teardown(self, zfsvol_sr): f"vdis[{i}] should {'' if is_snap else 'not '}be a snapshot" teardown_vdi_chain(zfsvol_sr, vdis, (4, 3, 2, 1, 0)) - @pytest.mark.xfail # needs support for destroying non-snapshots blocked by snaps def test_vdi_and_snaps_destroy_first_vdi(self, zfsvol_sr): "Destroy first-created VDI, then the rest in reverse order of creation" vdis = create_vdi_and_snaps_chain(zfsvol_sr, 'ZFS-local-VDI-test') teardown_vdi_chain(zfsvol_sr, vdis, (0, 4, 3, 2, 1)) - @pytest.mark.xfail # needs support for destroying non-snapshots blocked by snaps + @pytest.mark.xfail # needs GC of unused extra non-snapshots def test_vdi_and_snaps_destroy_intermediate_vdi(self, zfsvol_sr): "Destroy second-created VDI, then the rest in reverse order of creation" vdis = create_vdi_and_snaps_chain(zfsvol_sr, 'ZFS-local-VDI-test') From 2415229ccabce481acf71124e6962ce00b1227c8 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Tue, 19 Mar 2024 14:09:32 +0100 Subject: [PATCH 10/13] zfs-vol: vm-snapshot testing Signed-off-by: Yann Dirson --- tests/storage/zfsvol/test_zfsvol_sr.py | 68 ++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index 332e5bd4..46eaf1db 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -68,6 +68,74 @@ def test_snapshot(self, vm_on_zfsvol_sr): finally: vm.shutdown(verify=True) + @pytest.mark.small_vm + @pytest.mark.big_vm + def test_snapshots_revert(self, vm_on_zfsvol_sr): + vm = vm_on_zfsvol_sr + vm.start() + vm.wait_for_os_booted() + vm.wait_for_vm_running_and_ssh_up() + + snap1, snap2, snap3 = None, None, None + snap1 = vm.snapshot() + vm.ssh_touch_file(f"/{snap1.uuid}") + snap2 = vm.snapshot() + vm.ssh_touch_file(f"/{snap2.uuid}") + snap3 = vm.snapshot() + + # we are in "snap3" state, check all 6 "from A to B" + # combinations + snap1.revert() + vm.start() + vm.wait_for_vm_running_and_ssh_up() + logging.info("Check files state") + vm.ssh([f"test ! -f /{snap1.uuid}"]) + vm.ssh([f"test ! -f /{snap2.uuid}"]) + snap2.revert() + vm.start() + vm.wait_for_vm_running_and_ssh_up() + logging.info("Check files state") + vm.ssh([f"test -f /{snap1.uuid}"]) + vm.ssh([f"test ! -f /{snap2.uuid}"]) + snap3.revert() + vm.start() + vm.wait_for_vm_running_and_ssh_up() + logging.info("Check files state") + vm.ssh([f"test -f /{snap1.uuid}"]) + vm.ssh([f"test -f /{snap2.uuid}"]) + snap2.revert() + vm.start() + vm.wait_for_vm_running_and_ssh_up() + logging.info("Check files state") + vm.ssh([f"test -f /{snap1.uuid}"]) + vm.ssh([f"test ! -f /{snap2.uuid}"]) + snap1.revert() + vm.start() + vm.wait_for_vm_running_and_ssh_up() + logging.info("Check files state") + vm.ssh([f"test ! -f /{snap1.uuid}"]) + vm.ssh([f"test ! -f /{snap2.uuid}"]) + snap3.revert() + vm.start() + vm.wait_for_vm_running_and_ssh_up() + logging.info("Check files state") + vm.ssh([f"test -f /{snap1.uuid}"]) + vm.ssh([f"test -f /{snap2.uuid}"]) + +# FIXME: we don't support snapshot destruction yet +# snap1.destroy(verify=True) +# snap2.destroy(verify=True) +# snap3.destroy(verify=True) + + def get_messages(self, name): + args = { + 'obj-uuid': self.uuid, + 'name': name, + 'params': 'uuid', + } + + lines = self.host.xe('message-list', args).splitlines() + # *** tests with reboots (longer tests). @pytest.mark.reboot From dd75e387a28d544d7291648b9bd89617fd4ad88c Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 27 Mar 2024 15:36:18 +0100 Subject: [PATCH 11/13] zfs-vol: test chain of VDI clones and their destuction (xfail) Cloning a VDI without a snapshot is just not implemented yet. Signed-off-by: Yann Dirson --- tests/storage/zfsvol/test_zfsvol_sr.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index 46eaf1db..083e38b0 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -191,6 +191,13 @@ def create_vdi_and_snaps_chain(sr, vdi_label): vdis.append(vdis[-1].clone()) return vdis +def create_vdi_chain(sr, vdi_label): + "Create a chain of alternating VDI snapshots and clones on first host." + vdis = [sr.create_vdi(vdi_label)] + for i in range(2): + vdis.append(vdis[-1].clone()) + return vdis + def teardown_vdi_chain(sr, vdis, order): "Destroy a list of VDIs in order specified by a sequence of VDIs indices." for i in order: From cd35610e0fb02dd9b05f097cdc0a03c572e3ddec Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Fri, 29 Mar 2024 15:56:20 +0100 Subject: [PATCH 12/13] zfs-vol: add a test for VDI resize Signed-off-by: Yann Dirson --- lib/vdi.py | 4 ++++ tests/storage/zfsvol/test_zfsvol_sr.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/vdi.py b/lib/vdi.py index b2781cfd..562eb7bd 100644 --- a/lib/vdi.py +++ b/lib/vdi.py @@ -7,6 +7,10 @@ def __init__(self, sr, uuid, snapshot_of=None): # TODO: use a different approach when migration is possible self.sr = sr + def resize(self, size): + return self.sr.pool.master.xe('vdi-resize', {'uuid': self.uuid, + 'disk-size': str(size)}) + def snapshot(self): logging.info(f"Create snapshot of {self}") return VDI(self.sr, diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index 083e38b0..93ea5888 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -30,6 +30,20 @@ def test_create_and_destroy_sr(self, host, sr_disk_wiped): @pytest.mark.usefixtures("zfsvol_sr") class TestZfsvolSrBasics: + def test_vdi_resize(self, vdi_on_zfsvol_sr): + logging.info("Resize up") + vdi_on_zfsvol_sr.resize(1024 * 1024) + logging.info("Attempt to resize down") + try: + vdi_on_zfsvol_sr.resize(64 * 1024) + except Exception as e: + if "shrinking not allowed" in str(e): + # properly refused + pass + else: + logging.error("unexpected error on downsize attempt: %s", e) + raise + @pytest.mark.xfail # needs support for cloning non-snapshots def test_vdi_clone(self, vdi_on_zfsvol_sr): clone = vdi_on_zfsvol_sr.clone() From b1bc1f8c8da3132bef15bb348c79f4a039e7ee4d Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Thu, 25 Apr 2024 14:48:23 +0200 Subject: [PATCH 13/13] WIP test_create_and_destroy_sr: make sure SR is destroyed if VM.create fails TODO: all other SR --- tests/storage/zfsvol/test_zfsvol_sr.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/storage/zfsvol/test_zfsvol_sr.py b/tests/storage/zfsvol/test_zfsvol_sr.py index 93ea5888..d74aa538 100755 --- a/tests/storage/zfsvol/test_zfsvol_sr.py +++ b/tests/storage/zfsvol/test_zfsvol_sr.py @@ -20,13 +20,18 @@ class TestZfsvolSRCreateDestroy: """ def test_create_and_destroy_sr(self, host, sr_disk_wiped): - # Create and destroy tested in the same test to leave the host as unchanged as possible - sr = host.sr_create('zfs-vol', "ZFS-local-SR-test", {'device': '/dev/' + sr_disk_wiped}, verify=True) - # import a VM in order to detect vm import issues here rather than in the vm_on_xfs_fixture used in - # the next tests, because errors in fixtures break teardown - vm = host.import_vm(vm_image('mini-linux-x86_64-bios'), sr_uuid=sr.uuid) - vm.destroy(verify=True) - sr.destroy(verify=True) + # Create and destroy tested in the same test to leave the host + # as unchanged as possible + sr = host.sr_create('zfs-vol', "ZFS-local-SR-test", + {'device': '/dev/' + sr_disk_wiped}, verify=True) + try: + # import a VM in order to detect vm import issues here + # rather than in the vm_on_xfs_fixture used in the next + # tests, because errors in fixtures break teardown + vm = host.import_vm(vm_image('mini-linux-x86_64-bios'), sr_uuid=sr.uuid) + vm.destroy(verify=True) + finally: + sr.destroy(verify=True) @pytest.mark.usefixtures("zfsvol_sr") class TestZfsvolSrBasics: