From e5328f66c60e8f79af884159521b773cff0b26c1 Mon Sep 17 00:00:00 2001 From: Ali Mirjamali Date: Wed, 27 Aug 2025 19:46:20 +0330 Subject: [PATCH] Initialize asyncio event loop before using it Python 3.14 (in Fedora 43) throws RunetimeError of event loop is not initialized before using it. Resolves: https://github.com/QubesOS/qubes-issues/issues/10188 --- qubesadmin/tools/qvm_backup.py | 3 ++- qubesadmin/tools/qvm_shutdown.py | 3 ++- qubesadmin/tools/qvm_start_daemon.py | 6 ++++-- qubesadmin/tools/qvm_template_postprocess.py | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/qubesadmin/tools/qvm_backup.py b/qubesadmin/tools/qvm_backup.py index 6d4c1773c..29b5182f0 100644 --- a/qubesadmin/tools/qvm_backup.py +++ b/qubesadmin/tools/qvm_backup.py @@ -205,7 +205,8 @@ def main(args=None, app=None): with open(profile_path, 'w', encoding='utf-8') as f_profile: write_backup_profile(f_profile, args, passphrase) - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) if have_events: # pylint: disable=no-member events_dispatcher = qubesadmin.events.EventsDispatcher(args.app) diff --git a/qubesadmin/tools/qvm_shutdown.py b/qubesadmin/tools/qvm_shutdown.py index f1fb971d2..765b10391 100644 --- a/qubesadmin/tools/qvm_shutdown.py +++ b/qubesadmin/tools/qvm_shutdown.py @@ -75,7 +75,8 @@ def main(args=None, app=None): # pylint: disable=missing-docstring force = args.force or bool(args.all_domains) if have_events: - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) remaining_domains = args.domains for _ in range(len(args.domains)): this_round_domains = set(remaining_domains) diff --git a/qubesadmin/tools/qvm_start_daemon.py b/qubesadmin/tools/qvm_start_daemon.py index bc6304f96..7b0829d7c 100644 --- a/qubesadmin/tools/qvm_start_daemon.py +++ b/qubesadmin/tools/qvm_start_daemon.py @@ -1138,7 +1138,8 @@ def main(): print(os.getpid(), file=lock_f) lock_f.flush() lock_f.truncate() - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) # pylint: disable=no-member events = qubesadmin.events.EventsDispatcher(args.app) # pylint: enable=no-member @@ -1183,7 +1184,8 @@ def main(): except (FileNotFoundError, ValueError) as e: parser.error(f"Cannot open pidfile {pidfile_path}: {str(e)}") else: - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) tasks = [] for vm in args.domains: if vm.is_running(): diff --git a/qubesadmin/tools/qvm_template_postprocess.py b/qubesadmin/tools/qvm_template_postprocess.py index 613a1e8f7..52ada2365 100644 --- a/qubesadmin/tools/qvm_template_postprocess.py +++ b/qubesadmin/tools/qvm_template_postprocess.py @@ -454,7 +454,8 @@ def main(args=None, app=None): if not args.really: parser.error('Do not call this tool directly.') if args.action == 'post-install': - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) try: loop.run_until_complete(post_install(args)) loop.stop()