From ec5e1b24e2c4615654ea5aa75e419c6de4d88751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 22 Jul 2026 12:05:02 +0200 Subject: [PATCH] Skip RemoteVM when suspending the system Perform suspend-related actions only on LocalVMs. Fixes QubesOS/qubes-issues#11001 --- qubes/api/internal.py | 8 ++++++++ qubes/tests/api_internal.py | 18 +++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/qubes/api/internal.py b/qubes/api/internal.py index d828ce431..de34172f8 100644 --- a/qubes/api/internal.py +++ b/qubes/api/internal.py @@ -310,6 +310,8 @@ async def suspend_pre(self): for vm in self.app.domains: if isinstance(vm, qubes.vm.adminvm.AdminVM): continue + if not isinstance(vm, qubes.vm.LocalVM): + continue if not vm.is_running(): continue if vm.name in previously_paused: @@ -352,6 +354,8 @@ async def suspend_pre(self): for vm in self.app.domains: if isinstance(vm, qubes.vm.adminvm.AdminVM): continue + if not isinstance(vm, qubes.vm.LocalVM): + continue if vm.name in previously_paused: continue if vm.is_running(): @@ -395,6 +399,8 @@ async def suspend_post(self): for vm in self.app.domains: if isinstance(vm, qubes.vm.adminvm.AdminVM): continue + if not isinstance(vm, qubes.vm.LocalVM): + continue if vm.name in previously_paused: continue if vm.get_power_state() in ["Paused", "Suspended"]: @@ -407,6 +413,8 @@ async def suspend_post(self): for vm in self.app.domains: if isinstance(vm, qubes.vm.adminvm.AdminVM): continue + if not isinstance(vm, qubes.vm.LocalVM): + continue if not vm.is_running(): continue if vm.name in previously_paused: diff --git a/qubes/tests/api_internal.py b/qubes/tests/api_internal.py index 45f4cde4e..e3f1f876d 100644 --- a/qubes/tests/api_internal.py +++ b/qubes/tests/api_internal.py @@ -64,15 +64,19 @@ def tearDown(self): def create_mockvm(self, features=None): if features is None: features = {} - vm = mock.Mock() + vm = mock.Mock(spec=qubes.vm.LocalVM) + vm.configure_mock( + features=mock.Mock(), + run_service=mock.AsyncMock(), + suspend=mock.AsyncMock(), + resume=mock.AsyncMock(), + is_running=mock.Mock(), + get_power_state=mock.Mock(), + remove_preload_excess=mock.Mock(), + ) vm.features.check_with_template.side_effect = features.get vm.features.get.side_effect = features.get - vm.run_service.return_value.wait = mock_coro( - vm.run_service.return_value.wait - ) - vm.run_service = mock_coro(vm.run_service) - vm.suspend = mock_coro(vm.suspend) - vm.resume = mock_coro(vm.resume) + vm.run_service.return_value.wait = mock.AsyncMock() return vm def call_mgmt_func(self, method, arg=b"", payload=b""):