From 7d22e299bdeaa78546b5085e493df6d79cd4dca4 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Fri, 9 Oct 2020 12:47:23 +1300 Subject: [PATCH 1/4] do not call setup_autoinstall as part of __init__ --- subiquity/controller.py | 4 +++- subiquity/core.py | 11 ++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/subiquity/controller.py b/subiquity/controller.py index 180dd47c..bfd09e0d 100644 --- a/subiquity/controller.py +++ b/subiquity/controller.py @@ -43,7 +43,6 @@ class SubiquityController(BaseController): super().__init__(app) self.autoinstall_applied = False self.context.set('controller', self) - self.setup_autoinstall() def interactive(self): return False @@ -109,6 +108,9 @@ class RepeatedController(RepeatedController): super().__init__(orig, index) self.autoinstall_applied = False + def setup_autoinstall(self): + pass + async def apply_autoinstall_config(self): await self.orig.apply_autoinstall_config(index=self.index) diff --git a/subiquity/core.py b/subiquity/core.py index 35b09531..f8237c58 100644 --- a/subiquity/core.py +++ b/subiquity/core.py @@ -257,12 +257,12 @@ class Subiquity(TuiApplication): print(_("press enter to start a shell")) input() os.system("cd / && bash") - self.controllers.load("Reporting") self.controllers.Reporting.start() - self.controllers.load("Error") with self.context.child("core_validation", level="INFO"): jsonschema.validate(self.autoinstall_config, self.base_schema) - self.controllers.load("Early") + self.controllers.Reporting.setup_autoinstall() + self.controllers.Early.setup_autoinstall() + self.controllers.Error.setup_autoinstall() if self.controllers.Early.cmds: stamp_file = self.state_path("early-commands") if our_tty != primary_tty: @@ -278,8 +278,8 @@ class Subiquity(TuiApplication): self.autoinstall_config = yaml.safe_load(fp) with self.context.child("core_validation", level="INFO"): jsonschema.validate(self.autoinstall_config, self.base_schema) - for controller in self.controllers.instances: - controller.setup_autoinstall() + for controller in self.controllers.instances: + controller.setup_autoinstall() if not self.interactive() and self.opts.run_on_serial: # Thanks to the fact that we are launched with agetty's # --skip-login option, on serial lines we can end up starting with @@ -327,6 +327,7 @@ class Subiquity(TuiApplication): break async def start(self): + self.controllers.load_all() await self.connect() if self.opts.autoinstall is not None: await self.load_autoinstall_config() From 2bf981ebb8cbf59c1d74eab407a96f8b8a6cbdd3 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Fri, 9 Oct 2020 10:55:58 +1300 Subject: [PATCH 2/4] move "last-screen" handling out of generic code --- subiquity/controller.py | 14 ++++++++++++++ subiquity/core.py | 30 ++++++++++++++++++++++++++++++ subiquitycore/core.py | 9 --------- subiquitycore/tui.py | 28 +--------------------------- 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/subiquity/controller.py b/subiquity/controller.py index bfd09e0d..701dcc77 100644 --- a/subiquity/controller.py +++ b/subiquity/controller.py @@ -13,7 +13,9 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import json import logging +import os import jsonschema @@ -79,9 +81,18 @@ class SubiquityController(BaseController): def configured(self): """Let the world know that this controller's model is now configured. """ + with open(self.app.state_path('states', self.name), 'w') as fp: + json.dump(self.serialize(), fp) if self.model_name is not None: self.app.base_model.configured(self.model_name) + def load_state(self): + state_path = self.app.state_path('states', self.name) + if not os.path.exists(state_path): + return + with open(state_path) as fp: + self.deserialize(json.load(fp)) + def deserialize(self, state): pass @@ -122,3 +133,6 @@ class RepeatedController(RepeatedController): def make_autoinstall(self): return {} + + def load_state(self): + pass diff --git a/subiquity/core.py b/subiquity/core.py index f8237c58..0b937822 100644 --- a/subiquity/core.py +++ b/subiquity/core.py @@ -326,8 +326,13 @@ class Subiquity(TuiApplication): print() break + def load_serialized_state(self): + for controller in self.controllers.instances: + controller.load_state() + async def start(self): self.controllers.load_all() + self.load_serialized_state() await self.connect() if self.opts.autoinstall is not None: await self.load_autoinstall_config() @@ -347,6 +352,15 @@ class Subiquity(TuiApplication): return super()._exception_handler(loop, context) + def _remove_last_screen(self): + last_screen = self.state_path('last-screen') + if os.path.exists(last_screen): + os.unlink(last_screen) + + def exit(self): + self._remove_last_screen() + super().exit() + def extra_urwid_loop_args(self): return dict(input_filter=self.input_filter.filter) @@ -411,6 +425,20 @@ class Subiquity(TuiApplication): if isinstance(self.ui.body, BaseView): self.ui.body.remove_overlay(overlay) + def initial_controller_index(self): + if not self.updated: + return 0 + state_path = self.state_path('last-screen') + if not os.path.exists(state_path): + return 0 + with open(state_path) as fp: + last_screen = fp.read().strip() + controller_index = 0 + for i, controller in enumerate(self.controllers.instances): + if controller.name == last_screen: + controller_index = i + return controller_index + def select_initial_screen(self, index): self.error_reporter.load_reports() for report in self.error_reporter.reports: @@ -454,6 +482,8 @@ class Subiquity(TuiApplication): view = await super().make_view_for_controller(new) if new.answers: self.aio_loop.call_soon(new.run_answers) + with open(self.state_path('last-screen'), 'w') as fp: + fp.write(new.name) return view else: if self.autoinstall_config and not new.autoinstall_applied: diff --git a/subiquitycore/core.py b/subiquitycore/core.py index f2f704ef..90b3aee4 100644 --- a/subiquitycore/core.py +++ b/subiquitycore/core.py @@ -122,17 +122,8 @@ class Application: controller.start() log.debug("controllers started") - def load_serialized_state(self): - for controller in self.controllers.instances: - state_path = self.state_path('states', controller.name) - if not os.path.exists(state_path): - continue - 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() diff --git a/subiquitycore/tui.py b/subiquitycore/tui.py index 94f77e41..b1bc158b 100644 --- a/subiquitycore/tui.py +++ b/subiquitycore/tui.py @@ -16,7 +16,6 @@ import asyncio import inspect import logging -import os import yaml import urwid @@ -80,15 +79,6 @@ class TuiApplication(Application): self.urwid_loop = None self.cur_screen = None - def _remove_last_screen(self): - last_screen = self.state_path('last-screen') - if os.path.exists(last_screen): - os.unlink(last_screen) - - def exit(self): - self._remove_last_screen() - super().exit() - def run_command_in_foreground(self, cmd, before_hook=None, after_hook=None, **kw): screen = self.urwid_loop.screen @@ -122,8 +112,6 @@ class TuiApplication(Application): raise else: self.cur_screen = new - with open(self.state_path('last-screen'), 'w') as fp: - fp.write(new.name) return view async def _wait_with_indication(self, awaitable, show, hide=None): @@ -190,7 +178,6 @@ class TuiApplication(Application): async def _move_screen(self, increment, coro): if coro is not None: await coro - self.save_state() old, self.cur_screen = self.cur_screen, None if old is not None: old.context.exit("completed") @@ -232,8 +219,6 @@ class TuiApplication(Application): for controller in self.controllers.instances[:controller_index]: controller.configured() self.controllers.index = controller_index - 1 - for controller in self.controllers.instances[:controller_index]: - controller.configured() self.next_screen() def run_scripts(self, scripts): @@ -343,18 +328,7 @@ class TuiApplication(Application): self.select_initial_screen(self.initial_controller_index()) def initial_controller_index(self): - if not self.updated: - return 0 - state_path = self.state_path('last-screen') - if not os.path.exists(state_path): - return 0 - with open(state_path) as fp: - last_screen = fp.read().strip() - controller_index = 0 - for i, controller in enumerate(self.controllers.instances): - if controller.name == last_screen: - controller_index = i - return controller_index + return 0 async def start(self, start_urwid=True): await super().start() From c03f6580fde4cc25895f6b0e1285377f6bda46c0 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Fri, 9 Oct 2020 11:04:25 +1300 Subject: [PATCH 3/4] move more code that should never have been so generic --- subiquity/core.py | 2 ++ subiquitycore/tui.py | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/subiquity/core.py b/subiquity/core.py index 0b937822..0f7f735c 100644 --- a/subiquity/core.py +++ b/subiquity/core.py @@ -445,6 +445,8 @@ class Subiquity(TuiApplication): if report.kind == ErrorReportKind.UI and not report.seen: self.show_error_report(report.ref()) break + for controller in self.controllers.instances[:index]: + controller.configured() super().select_initial_screen(index) async def move_screen(self, increment, coro): diff --git a/subiquitycore/tui.py b/subiquitycore/tui.py index b1bc158b..da90bfc0 100644 --- a/subiquitycore/tui.py +++ b/subiquitycore/tui.py @@ -216,8 +216,6 @@ class TuiApplication(Application): self.aio_loop.create_task(self.move_screen(-1, None)) def select_initial_screen(self, controller_index): - for controller in self.controllers.instances[:controller_index]: - controller.configured() self.controllers.index = controller_index - 1 self.next_screen() From 673ade7f2afce4f45c2ea0a5c258042e5b6d0676 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Fri, 9 Oct 2020 11:07:10 +1300 Subject: [PATCH 4/4] make core interface a little simpler --- subiquity/core.py | 8 +++++--- subiquitycore/tui.py | 8 ++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/subiquity/core.py b/subiquity/core.py index 0f7f735c..3b8796d7 100644 --- a/subiquity/core.py +++ b/subiquity/core.py @@ -340,7 +340,7 @@ class Subiquity(TuiApplication): open('/run/casper-no-prompt', 'w').close() await super().start(start_urwid=self.interactive()) if not self.interactive(): - self.select_initial_screen(0) + self.select_initial_screen() def _exception_handler(self, loop, context): exc = context.get('exception') @@ -439,15 +439,17 @@ class Subiquity(TuiApplication): controller_index = i return controller_index - def select_initial_screen(self, index): + def select_initial_screen(self): self.error_reporter.load_reports() for report in self.error_reporter.reports: if report.kind == ErrorReportKind.UI and not report.seen: self.show_error_report(report.ref()) break + index = self.initial_controller_index() for controller in self.controllers.instances[:index]: controller.configured() - super().select_initial_screen(index) + self.controllers.index = index - 1 + self.next_screen() async def move_screen(self, increment, coro): try: diff --git a/subiquitycore/tui.py b/subiquitycore/tui.py index da90bfc0..bca47eb4 100644 --- a/subiquitycore/tui.py +++ b/subiquitycore/tui.py @@ -215,8 +215,7 @@ class TuiApplication(Application): def prev_screen(self): self.aio_loop.create_task(self.move_screen(-1, None)) - def select_initial_screen(self, controller_index): - self.controllers.index = controller_index - 1 + def select_initial_screen(self): self.next_screen() def run_scripts(self, scripts): @@ -323,10 +322,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): - return 0 + self.select_initial_screen() async def start(self, start_urwid=True): await super().start()