Skip to content

Commit 561c22c

Browse files
committed
Use admin utils wrapper for vm actions
1 parent ec2e23c commit 561c22c

2 files changed

Lines changed: 33 additions & 36 deletions

File tree

qui/updater/summary_page.py

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -296,55 +296,54 @@ def perform_restart(self):
296296

297297
# clear err and perform shutdown/start
298298
self.err = ""
299-
self.shutdown_domains(tmpls_to_shutdown)
300-
self.restart_vms(to_restart)
301-
self.shutdown_domains(to_shutdown)
299+
try:
300+
loop = asyncio.get_event_loop()
301+
except RuntimeError:
302+
# changes between GLib versions and python versions mean that the above
303+
# can fail on some dom0/gui domain configurations
304+
loop = asyncio.new_event_loop()
305+
loop.run_until_complete(self.shutdown_domains(tmpls_to_shutdown))
306+
loop.run_until_complete(self.restart_vms(to_restart))
307+
loop.run_until_complete(self.shutdown_domains(to_shutdown))
302308

303309
if self.status is RestartStatus.NONE:
304310
self.status = RestartStatus.OK
305311

306-
def shutdown_domains(self, to_shutdown):
312+
async def shutdown_domains(self, to_shutdown):
307313
"""
308314
Try to shut down vms and wait to finish.
309315
"""
310-
try:
311-
loop = asyncio.get_event_loop()
312-
except RuntimeError:
313-
# changes between GLib versions and python versions mean that the above
314-
# can fail on some dom0/gui domain configurations
315-
loop = asyncio.new_event_loop()
316-
tasks = [asyncio.to_thread(vm.shutdown, force=True, wait=True) for vm in to_shutdown]
317-
results = loop.run_until_complete(
318-
asyncio.gather(*tasks, return_exceptions=True)
316+
failed = await qubesadmin.utils.shutdown(
317+
domains=to_shutdown, force=True, wait=True, logger=self.log
319318
)
320-
done = []
321-
for vm, res in zip(to_shutdown, results):
322-
if not isinstance(res, BaseException):
323-
self.log.info("Shutdown %s", vm.name)
324-
done.append(vm)
325-
continue
326-
self.err += vm.name + " cannot shutdown: " + str(res) + "\n"
327-
self.log.error("Cannot shutdown %s because %s", vm.name, str(res))
328-
self.status = RestartStatus.ERROR_TMPL_DOWN
319+
unhandled, used, timedout = failed
320+
if not unhandled and not used and not timedout:
321+
return to_shutdown
322+
self.status = RestartStatus.ERROR_TMPL_DOWN
323+
all_failed = []
324+
if unhandled:
325+
for qube in unhandled:
326+
all_failed.append(qube)
327+
self.err += vm.name + " cannot shutdown: unknown reason\n"
328+
for qube in used:
329+
all_failed.append(qube)
330+
self.err += vm.name + " cannot shutdown: in use\n"
331+
for qube in timedout:
332+
all_failed.append(qube)
333+
self.err += vm.name + " cannot shutdown: timed out\n"
334+
done = [qube for qube in to_shutdown if qube not in all_failed]
329335
return done
330336

331-
def restart_vms(self, to_restart):
337+
async def restart_vms(self, to_restart):
332338
"""
333339
Try to restart vms.
334340
"""
335-
shutdowns = self.shutdown_domains(to_restart)
341+
shutdowns = await self.shutdown_domains(to_restart)
336342

343+
# TODO: ben: decide if this is better or worse than the above method
337344
# restart shutdown qubes
338-
try:
339-
loop = asyncio.get_event_loop()
340-
except RuntimeError:
341-
# changes between GLib versions and python versions mean that the above
342-
# can fail on some dom0/gui domain configurations
343-
loop = asyncio.new_event_loop()
344345
tasks = [asyncio.to_thread(vm.start) for vm in shutdowns]
345-
results = loop.run_until_complete(
346-
asyncio.gather(*tasks, return_exceptions=True)
347-
)
346+
results = await asyncio.gather(*tasks, return_exceptions=True)
348347
for vm, res in zip(shutdowns, results):
349348
if not isinstance(res, qubesadmin.exc.QubesVMError):
350349
self.log.info("Restart %s", vm.name)

qui/updater/tests/test_summary_page.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,7 @@ def set_deletable(self, deletable):
354354
mock_show_dialog.assert_has_calls(calls)
355355

356356

357-
@patch("qui.updater.summary_page.wait_for_domain_shutdown")
358357
def test_perform_restart(
359-
_mock_wait_for_domain_shutdown,
360358
test_qapp,
361359
real_builder,
362360
mock_next_button,
@@ -389,7 +387,7 @@ def test_perform_restart(
389387
"vault",
390388
)
391389
expected_shutdown_calls = [
392-
(tmpl, "admin.vm.Shutdown", "force", None) for tmpl in to_shutdown
390+
(tmpl, "admin.vm.Shutdown", "force+wait", None) for tmpl in to_shutdown
393391
]
394392
for call_ in expected_shutdown_calls:
395393
test_qapp.expected_calls[call_] = b"0\x00"

0 commit comments

Comments
 (0)