Skip to content

Commit 307b583

Browse files
committed
VM caching on export/import
1 parent 887b1e7 commit 307b583

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
@@ -366,6 +366,13 @@ def create_vms(request, host):
366366
> ...
367367
368368
"""
369+
# Do we cache VMs?
370+
try:
371+
from data import CACHE_IMPORTED_VM
372+
except ImportError:
373+
CACHE_IMPORTED_VM = False
374+
assert CACHE_IMPORTED_VM in [True, False]
375+
369376
marker = request.node.get_closest_marker("vm_definitions")
370377
if marker is None:
371378
raise Exception("No vm_definitions marker specified.")
@@ -385,7 +392,7 @@ def create_vms(request, host):
385392
if "template" in vm_def:
386393
_create_vm(vm_def, host, vms, vdis, vbds)
387394
elif "image" in vm_def:
388-
_import_vm(vm_def, host, vms)
395+
_import_vm(vm_def, host, vms, use_cache=CACHE_IMPORTED_VM)
389396
yield vms
390397

391398
except Exception:
@@ -433,10 +440,19 @@ def _create_vm(marker, host, vms, vdis, vbds):
433440
logging.info("Setting param %s", param_def)
434441
vm.param_set(**param_def)
435442

436-
def _import_vm(marker, host, vms):
443+
def _import_vm(marker, host, vms, *, use_cache):
437444
vm_name = marker["name"]
438445
vm_image = marker["image"]
439-
vm = host.import_vm(vm_image)
446+
base_vm = host.import_vm(vm_image, sr_uuid=host.main_sr_uuid(), use_cache=use_cache)
447+
448+
if use_cache:
449+
# Clone the VM before running tests, so that the original VM remains untouched
450+
logging.info(">> Clone cached VM before running tests")
451+
vm = base_vm.clone()
452+
# Remove the description, which may contain a cache identifier
453+
vm.param_set('name-description', "")
454+
else:
455+
vm = base_vm
440456
vms.append(vm)
441457

442458
@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,9 +200,13 @@ 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 {strip_suffix(uri, '.xva')}]"
206+
203207
def cached_vm(self, uri, sr_uuid):
204208
assert sr_uuid, "A SR UUID is necessary to use import cache"
205-
cache_key = f"[Cache for {strip_suffix(uri, '.xva')}]"
209+
cache_key = self.vm_cache_key(uri)
206210
# Look for an existing cache VM
207211
vm_uuids = safe_split(self.xe('vm-list', {'name-description': cache_key}, minimal=True), ',')
208212

tests/install/test.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 TestNested:
1218
@pytest.mark.vm_definitions(
1319
dict(name="vm 1",
@@ -111,7 +117,8 @@ def test_install_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_821_uefi-vm1.xva"])
114-
host_vm.export("test_install_821_uefi-vm1.xva", "zstd")
120+
host_vm.export("test_install_821_uefi-vm1.xva", "zstd",
121+
use_cache=CACHE_IMPORTED_VM)
115122

116123
@pytest.mark.vm_definitions(
117124
dict(name="vm 1",
@@ -218,4 +225,5 @@ def test_firstboot_821_uefi(self, create_vms):
218225
# FIXME move to fixture
219226
# FIXME where to store?
220227
host_vm.host.ssh(["rm -f test_firstboot_821_uefi-vm1.xva"])
221-
host_vm.export("test_firstboot_821_uefi-vm1.xva", "zstd")
228+
host_vm.export("test_firstboot_821_uefi-vm1.xva", "zstd",
229+
use_cache=CACHE_IMPORTED_VM)

0 commit comments

Comments
 (0)