Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 43 additions & 15 deletions qubes/tests/integ/dispvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -802,17 +802,23 @@ async def _test_018_preload_global(self):
self.log_preload()
logger.info("end")

def test_019_preload_refresh(self):
"""Refresh preload on volume change."""
self.loop.run_until_complete(self._test_019_preload_refresh())
def test_019_preload_discard_outdated_volumes(self):
"""Discard preload if volumes are outdated compared to its templates."""
self.loop.run_until_complete(
self._test_019_preload_discard_outdated_volumes()
)

async def _test_019_preload_refresh(self):
async def _test_019_preload_discard_outdated_volumes(self):
logger.info("start")
self.log_preload()
preload_max = 1

self.disp_base.features["preload-dispvm-max"] = str(preload_max)
for qube in [self.disp_base, self.disp_base.template]:
logger.info(
"discard because of outdated volume originating from %s",
qube.name,
)
await self.wait_preload(preload_max)
old_preload = self.disp_base.get_feat_preload()
await qube.start()
Expand All @@ -832,25 +838,47 @@ async def _test_019_preload_refresh(self):
self.log_preload()
logger.info("end")

def test_020_preload_discard_outdated(self):
"""Discard preload if properties differ from the disposable template."""
self.loop.run_until_complete(self._test_020_preload_discard_outdated())
def test_020_preload_discard_outdated_volume_size(self):
"""Discard preload if private size differs with disposable template."""
self.loop.run_until_complete(
self._test_020_preload_discard_outdated_volume_size()
)

async def _test_020_preload_discard_outdated(self):
async def _test_020_preload_discard_outdated_volume_size(self):
logger.info("start")
self.log_preload()
preload_max = 1
self.disp_base.features["preload-dispvm-max"] = str(preload_max)
await self.wait_preload(preload_max)
preload_dispvm = self.disp_base.get_feat_preload()
old_size = self.disp_base.volume_config["private"]["size"]
size = int(old_size) + 512
self.disp_base.storage.resize("private", size)
self.app.save()
dispvm = await asyncio.wait_for(
qubes.vm.dispvm.DispVM.from_appvm(self.disp_base), 30
)
self.assertNotIn(dispvm.name, preload_dispvm)
logger.info("end")

def test_021_preload_discard_outdated_setting(self):
"""Discard preload if properties differ with the disposable template."""
self.loop.run_until_complete(
self._test_020_preload_discard_outdated_setting()
)

async def _test_021_preload_discard_outdated_setting(self):
logger.info("start")
self.log_preload()
preload_max = 1
self.disp_base.features["preload-dispvm-max"] = str(preload_max)
await self.wait_preload(preload_max)
preload_dispvm = self.disp_base.get_feat_preload()
self.disp_base.netvm = None
try:
dispvm = await asyncio.wait_for(
qubes.vm.dispvm.DispVM.from_appvm(self.disp_base), 30
)
self.assertNotIn(dispvm.name, preload_dispvm)
finally:
await dispvm.cleanup()
dispvm = await asyncio.wait_for(
qubes.vm.dispvm.DispVM.from_appvm(self.disp_base), 30
)
self.assertNotIn(dispvm.name, preload_dispvm)
logger.info("end")

@unittest.skipUnless(which("xdotool"), "xdotool not installed")
Expand Down
5 changes: 2 additions & 3 deletions qubes/vm/dispvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,8 @@ def is_preload_outdated(self) -> dict:
return differed

appvm = self.template
if (
self.volume_config["private"]["size"]
!= appvm.volume_config["private"]["size"]
if int(self.volume_config["private"]["size"]) != int(
appvm.volume_config["private"]["size"]
):
differed["volumes"] = ["private"]
return differed
Expand Down
14 changes: 6 additions & 8 deletions qubes/vm/mix/dvmtemplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -702,19 +702,17 @@ def request_preload(self) -> Optional["qubes.vm.dispvm.DispVM"]:
for item in preload_dispvm:
qube = self.app.domains[item]
if outdated_reason := qube.is_preload_outdated():
if "properties" in outdated_reason:
discard_reason = "property(ies): " + ", ".join(
map(str, outdated_reason["properties"])
)
else:
discard_reason = "volume(s)"
discard_reason = []
for k, v in outdated_reason.items():
discard_reason.append(k + ": " + ", ".join(map(str, v)))
discard_reason_str = "; ".join(discard_reason)
qube.log.warning(
"Discarding preloaded disposable as it has has outdated %s",
discard_reason,
discard_reason_str,
)
# Not refilling now to deliver a disposable faster.
self.remove_preload_from_list(
[qube.name], reason="of outdated " + discard_reason
[qube.name], reason="of outdated " + discard_reason_str
)
# Delay to not affect this run.
asyncio.ensure_future(
Expand Down