refactor startup a little

the point of this is to have the event loop running while loading
autoinstall commands, which means we do not have to start and stop the
event loop inside load_autoinstall_config if there are early-commands to
run.
This commit is contained in:
Michael Hudson-Doyle 2020-09-16 13:03:21 +12:00
parent 88821f745c
commit 45009e3a12
3 changed files with 28 additions and 29 deletions

View File

@ -13,6 +13,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 logging
import os
import platform
@ -219,7 +220,7 @@ class Subiquity(TuiApplication):
tty = '/dev/' + work[len('console='):].split(',')[0]
return tty
def load_autoinstall_config(self):
async def load_autoinstall_config(self):
with open(self.opts.autoinstall) as fp:
self.autoinstall_config = yaml.safe_load(fp)
primary_tty = self.get_primary_tty()
@ -252,9 +253,7 @@ class Subiquity(TuiApplication):
while not os.path.exists(stamp_file):
time.sleep(1)
elif not os.path.exists(stamp_file):
self.aio_loop.run_until_complete(
self.controllers.Early.run())
self.new_event_loop()
await self.controllers.Early.run()
open(stamp_file, 'w').close()
with open(self.opts.autoinstall) as fp:
self.autoinstall_config = yaml.safe_load(fp)
@ -272,19 +271,18 @@ class Subiquity(TuiApplication):
# in next_screen below will be confusing.
os.system('stty sane')
def new_event_loop(self):
super().new_event_loop()
self.aio_loop.add_reader(self.journal_fd, self.journal_watcher)
async def start(self):
if self.opts.autoinstall is not None:
await self.load_autoinstall_config()
if not self.interactive() and not self.opts.dry_run:
open('/run/casper-no-prompt', 'w').close()
await super().start()
def extra_urwid_loop_args(self):
return dict(input_filter=self.input_filter.filter)
def run(self):
try:
if self.opts.autoinstall is not None:
self.load_autoinstall_config()
if not self.interactive() and not self.opts.dry_run:
open('/run/casper-no-prompt', 'w').close()
super().run()
except Exception:
print("generating crash report")
@ -299,8 +297,9 @@ class Subiquity(TuiApplication):
traceback.print_exc()
Error = getattr(self.controllers, "Error", None)
if Error is not None and Error.cmds:
self.new_event_loop()
self.aio_loop.run_until_complete(Error.run())
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
new_loop.run_until_complete(Error.run())
if self.interactive():
self._remove_last_screen()
raise

View File

@ -74,7 +74,8 @@ class Application:
self.updated = os.path.exists(self.state_path('updating'))
self.signal = Signal()
self.prober = prober
self.new_event_loop()
self.aio_loop = asyncio.get_event_loop()
self.aio_loop.set_exception_handler(self._exception_handler)
self.controllers = ControllerSet(
self.controllers_mod, self.controllers, init_args=(self,))
self.context = Context.new(self)
@ -87,12 +88,6 @@ class Application:
else:
loop.default_exception_handler(context)
def new_event_loop(self):
new_loop = asyncio.new_event_loop()
new_loop.set_exception_handler(self._exception_handler)
asyncio.set_event_loop(new_loop)
self.aio_loop = new_loop
def _connect_base_signals(self):
"""Connect signals used in the core controller."""
# Registers signals from each controller
@ -139,13 +134,16 @@ class Application:
with open(state_path) as fp:
controller.deserialize(json.load(fp))
async def start(self):
self.controllers.load_all()
self.load_serialized_state()
self._connect_base_signals()
self.start_controllers()
def run(self):
self.base_model = self.make_model()
try:
self.controllers.load_all()
self.load_serialized_state()
self._connect_base_signals()
self.start_controllers()
self.aio_loop.create_task(self.start())
self.aio_loop.run_forever()
finally:
self.aio_loop.run_until_complete(

View File

@ -251,6 +251,7 @@ class TuiApplication(Application):
extend_dec_special_charmap()
self.toggle_rich()
self.urwid_loop.start()
self.select_initial_screen(self.initial_controller_index())
def initial_controller_index(self):
if not self.updated:
@ -266,14 +267,15 @@ class TuiApplication(Application):
controller_index = i
return controller_index
async def start(self):
await super().start()
self.start_urwid()
def run(self):
if self.opts.scripts:
self.run_scripts(self.opts.scripts)
self.aio_loop.call_soon(self.start_urwid)
self.aio_loop.call_soon(
lambda: self.select_initial_screen(
self.initial_controller_index()))
try:
super().run()
finally:
self.urwid_loop.stop()
if self.urwid_loop is not None:
self.urwid_loop.stop()