loop: start running the event loop before doing anything else

This allows us to use asyncio.run() and to avoid many pitfalls.

Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This commit is contained in:
Olivier Gayot 2022-10-27 12:43:36 +02:00
parent 01567251f6
commit a62a0b6002
13 changed files with 41 additions and 31 deletions

View File

@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import argparse
import asyncio
import sys
import os
import logging
@ -68,7 +69,7 @@ def parse_options(argv):
LOGDIR = "/var/log/console-conf/"
def main():
async def main():
opts = parse_options(sys.argv[1:])
global LOGDIR
if opts.dry_run:
@ -87,7 +88,7 @@ def main():
else:
interface = ConsoleConf(opts)
interface.run()
await interface.run()
def restore_std_streams_from(from_file):
@ -104,4 +105,4 @@ def restore_std_streams_from(from_file):
if __name__ == '__main__':
sys.exit(main())
sys.exit(asyncio.run(main()))

View File

@ -1,5 +1,6 @@
import asyncio
import sys
if __name__ == '__main__':
from subiquity.cmd.tui import main
sys.exit(main())
sys.exit(asyncio.run(main()))

View File

@ -402,9 +402,9 @@ class SubiquityClient(TuiApplication):
def extra_urwid_loop_args(self):
return dict(input_filter=self.input_filter.filter)
def run(self):
async def run(self):
try:
super().run()
await super().run()
except Exception:
print("generating crash report")
try:

View File

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import asyncio
import copy
import json
import sys
@ -58,11 +59,11 @@ def make_app():
return app
def main():
async def main():
schema = make_schema(make_app())
jsonschema.validate({"version": 1}, schema)
print(json.dumps(schema, indent=4))
if __name__ == '__main__':
sys.exit(main())
sys.exit(asyncio.run(main()))

View File

@ -14,6 +14,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import argparse
import asyncio
import logging
import os
import pathlib
@ -111,7 +112,7 @@ def make_server_args_parser():
return parser
def main():
async def main():
print('starting server')
setup_environment()
# setup_environment sets $APPORT_DATA_DIR which must be set before
@ -161,8 +162,8 @@ def main():
server.note_file_for_apport(
"InstallerServerLogInfo", logfiles['info'])
server.run()
await server.run()
if __name__ == '__main__':
sys.exit(main())
sys.exit(asyncio.run(main()))

View File

@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import argparse
import asyncio
import logging
import os
import fcntl
@ -79,7 +80,7 @@ def make_client_args_parser():
AUTO_ANSWERS_FILE = "/subiquity_config/answers.yaml"
def main():
async def main():
setup_environment()
# setup_environment sets $APPORT_DATA_DIR which must be set before
# apport is imported, which is done by this import:
@ -147,8 +148,8 @@ def main():
subiquity_interface.note_file_for_apport(
"InstallerLogInfo", logfiles['info'])
subiquity_interface.run()
await subiquity_interface.run()
if __name__ == '__main__':
sys.exit(main())
sys.exit(asyncio.run(main()))

View File

@ -28,7 +28,7 @@ from subiquity.server.server import (
class TestAutoinstallLoad(SubiTestCase):
def setUp(self):
async def asyncSetUp(self):
self.tempdir = self.tmp_dir()
os.makedirs(self.tempdir + '/cdrom', exist_ok=True)
opts = Mock()

View File

@ -70,10 +70,11 @@ class Application:
os.environ.get('SUBIQUITY_REPLAY_TIMESCALE', "1"))
self.updated = os.path.exists(self.state_path('updating'))
self.hub = MessageHub()
self.aio_loop = asyncio.new_event_loop()
self.aio_loop = asyncio.get_running_loop()
self.aio_loop.set_exception_handler(self._exception_handler)
self.load_controllers(self.controllers)
self.context = Context.new(self)
self.exit_event = asyncio.Event()
def load_controllers(self, controllers):
""" Load the corresponding list of controllers
@ -86,7 +87,7 @@ class Application:
def _exception_handler(self, loop, context):
exc = context.get('exception')
if exc:
loop.stop()
self.exit_event.set()
self._exc = exc
else:
loop.default_exception_handler(context)
@ -114,7 +115,7 @@ class Application:
# EventLoop -------------------------------------------------------------------
def exit(self):
self.aio_loop.stop()
self.exit_event.set()
def start_controllers(self):
log.debug("starting controllers")
@ -126,10 +127,10 @@ class Application:
self.controllers.load_all()
self.start_controllers()
def run(self):
async def run(self):
self.base_model = self.make_model()
self.aio_loop.create_task(self.start())
self.aio_loop.run_forever()
await self.exit_event.wait()
if self._exc:
exc, self._exc = self._exc, None
raise exc

View File

@ -374,11 +374,11 @@ class TuiApplication(Application):
if start_urwid:
self.start_urwid()
def run(self):
async def run(self):
if self.opts.scripts:
self.run_scripts(self.opts.scripts)
try:
super().run()
await super().run()
finally:
if self.urwid_loop is not None:
self.urwid_loop.stop()

View File

@ -13,8 +13,9 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import asyncio
import sys
if __name__ == '__main__':
from system_setup.cmd.tui import main
sys.exit(main())
sys.exit(asyncio.run(main()))

View File

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import asyncio
import json
import sys
@ -37,11 +38,11 @@ def make_app():
return app
def main():
async def main():
schema = make_schema(make_app())
jsonschema.validate({"version": 1}, schema)
print(json.dumps(schema, indent=4))
if __name__ == '__main__':
sys.exit(main())
sys.exit(asyncio.run(main()))

View File

@ -14,6 +14,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import argparse
import asyncio
import logging
import os
import sys
@ -53,7 +54,7 @@ def make_server_args_parser():
return parser
def main():
async def main():
print('starting server')
setup_environment()
# setup_environment sets $APPORT_DATA_DIR which must be set before
@ -103,8 +104,8 @@ def main():
server.note_file_for_apport(
"InstallerServerLogInfo", logfiles['info'])
server.run()
await server.run()
if __name__ == '__main__':
sys.exit(main())
sys.exit(asyncio.run(main()))

View File

@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import argparse
import asyncio
import logging
import os
import fcntl
@ -65,7 +66,7 @@ def make_client_args_parser():
AUTO_ANSWERS_FILE = "/subiquity_config/answers.yaml"
def main():
async def main():
setup_environment()
# setup_environment sets $APPORT_DATA_DIR which must be set before
# apport is imported, which is done by this import:
@ -153,8 +154,8 @@ def main():
subiquity_interface.note_file_for_apport(
"InstallerLogInfo", logfiles['info'])
subiquity_interface.run()
await subiquity_interface.run()
if __name__ == '__main__':
sys.exit(main())
sys.exit(asyncio.run(main()))