Skip to content

Commit 9ad049f

Browse files
committed
VM caching on export/import
1 parent dc30149 commit 9ad049f

File tree

4 files changed

+49
-14
lines changed

4 files changed

+49
-14
lines changed

conftest.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,13 @@ def create_vms(request, host):
373373
> ...
374374
375375
"""
376+
# Do we cache VMs?
377+
try:
378+
from data import CACHE_IMPORTED_VM
379+
except ImportError:
380+
CACHE_IMPORTED_VM = False
381+
assert CACHE_IMPORTED_VM in [True, False]
382+
376383
markers = request.node.get_closest_marker("vm_definitions")
377384
if markers is None:
378385
raise Exception("No vm_definitions marker specified.")
@@ -392,7 +399,7 @@ def create_vms(request, host):
392399
if "template" in marker:
393400
_create_vm(marker, host, vms, vdis, vbds)
394401
elif "image" in marker:
395-
_import_vm(marker, host, vms)
402+
_import_vm(marker, host, vms, use_cache=CACHE_IMPORTED_VM)
396403
yield vms
397404

398405
except Exception:
@@ -440,10 +447,19 @@ def _create_vm(marker, host, vms, vdis, vbds):
440447
logging.info("Setting param %s", param_def)
441448
vm.param_set(**param_def)
442449

443-
def _import_vm(marker, host, vms):
450+
def _import_vm(marker, host, vms, *, use_cache):
444451
vm_name = marker["name"]
445452
vm_image = marker["image"]
446-
vm = host.import_vm(vm_image)
453+
base_vm = host.import_vm(vm_image, sr_uuid=host.main_sr_uuid(), use_cache=use_cache)
454+
455+
if use_cache:
456+
# Clone the VM before running tests, so that the original VM remains untouched
457+
logging.info(">> Clone cached VM before running tests")
458+
vm = base_vm.clone()
459+
# Remove the description, which may contain a cache identifier
460+
vm.param_set('name-description', "")
461+
else:
462+
vm = base_vm
447463
vms.append(vm)
448464

449465
@pytest.fixture(scope="module")

lib/basevm.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,18 @@ def get_sr(self):
6767
assert sr.attached_to_host(self.host)
6868
return sr
6969

70-
def export(self, filepath, compress='none'):
71-
logging.info("Export VM %s to %s with compress=%s" % (self.uuid, filepath, compress))
72-
params = {
73-
'uuid': self.uuid,
74-
'compress': compress,
75-
'filename': filepath
76-
}
77-
self.host.xe('vm-export', params)
70+
def export(self, filepath, compress='none', use_cache=False):
71+
72+
if use_cache:
73+
logging.info("Export VM %s to cache for %r as a clone" % (self.uuid, filepath))
74+
clone = self.clone()
75+
logging.info(f"Marking VM {clone.uuid} as cached")
76+
clone.param_set('name-description', self.host.vm_cache_key(filepath))
77+
else:
78+
logging.info("Export VM %s to %s with compress=%s" % (self.uuid, filepath, compress))
79+
params = {
80+
'uuid': self.uuid,
81+
'compress': compress,
82+
'filename': filepath
83+
}
84+
self.host.xe('vm-export', params)

lib/host.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,14 @@ def xo_server_reconnect(self):
200200
# is not enough to guarantee that the host object exists yet.
201201
wait_for(lambda: xo_object_exists(self.uuid), "Wait for XO to know about HOST %s" % self.uuid)
202202

203+
@staticmethod
204+
def vm_cache_key(uri):
205+
return f"[Cache for {uri}]"
206+
203207
def import_vm(self, uri, sr_uuid=None, use_cache=False):
204208
if use_cache:
205209
assert sr_uuid, "A SR UUID is necessary to use import cache"
206-
cache_key = f"[Cache for {uri}]"
210+
cache_key = self.vm_cache_key(uri)
207211
# Look for an existing cache VM
208212
vm_uuids = safe_split(self.xe('vm-list', {'name-description': cache_key}, minimal=True), ',')
209213

tests/install/test_install.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
from lib.host import Host
99
from lib.pool import Pool
1010

11+
try:
12+
from data import CACHE_IMPORTED_VM
13+
except ImportError:
14+
CACHE_IMPORTED_VM = False
15+
assert CACHE_IMPORTED_VM in [True, False]
16+
1117
class TestInstallNested:
1218
@pytest.mark.vm_definitions(
1319
dict(name="vm 1",
@@ -111,7 +117,8 @@ def test_install_nested_821_uefi(self, iso_remaster, create_vms):
111117
# FIXME move to fixture
112118
# FIXME where to store?
113119
host_vm.host.ssh(["rm -f test_install_nested_821_uefi-vm1.xva"])
114-
host_vm.export("test_install_nested_821_uefi-vm1.xva", "zstd")
120+
host_vm.export("test_install_nested_821_uefi-vm1.xva", "zstd",
121+
use_cache=CACHE_IMPORTED_VM)
115122

116123
@pytest.mark.vm_definitions(
117124
dict(name="vm 1",
@@ -213,4 +220,5 @@ def test_firstboot_nested_821_uefi(self, create_vms):
213220
# FIXME move to fixture
214221
# FIXME where to store?
215222
host_vm.host.ssh(["rm -f test_firstboot_nested_821_uefi-vm1.xva"])
216-
host_vm.export("test_firstboot_nested_821_uefi-vm1.xva", "zstd")
223+
host_vm.export("test_firstboot_nested_821_uefi-vm1.xva", "zstd",
224+
use_cache=CACHE_IMPORTED_VM)

0 commit comments

Comments
 (0)