From 99218fbeb46cc0cb9bfced7281cb0ec75538884f Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Fri, 20 Dec 2019 14:27:41 +1300 Subject: [PATCH] support early and late commands --- examples/autoinstall.yaml | 4 +++ subiquity/controllers/__init__.py | 3 +++ subiquity/controllers/cmdlist.py | 43 +++++++++++++++++++++++++++++++ subiquity/core.py | 41 ++++++++++++++++++----------- subiquitycore/core.py | 7 ++++- 5 files changed, 82 insertions(+), 16 deletions(-) create mode 100644 subiquity/controllers/cmdlist.py diff --git a/examples/autoinstall.yaml b/examples/autoinstall.yaml index c8cded4a..eca15727 100644 --- a/examples/autoinstall.yaml +++ b/examples/autoinstall.yaml @@ -3,6 +3,10 @@ early-commands: - echo a - sleep 1 - echo a +late-commands: + - echo a + - sleep 1 + - echo a keyboard: layout: gb identity: diff --git a/subiquity/controllers/__init__.py b/subiquity/controllers/__init__.py index 50481180..dd6a16fa 100644 --- a/subiquity/controllers/__init__.py +++ b/subiquity/controllers/__init__.py @@ -13,6 +13,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from .cmdlist import EarlyController, LateController from .error import ErrorController from .filesystem import FilesystemController from .identity import IdentityController @@ -29,11 +30,13 @@ from .ssh import SSHController from .welcome import WelcomeController from .zdev import ZdevController __all__ = [ + 'EarlyController', 'ErrorController', 'FilesystemController', 'IdentityController', 'InstallProgressController', 'KeyboardController', + 'LateController', 'ProxyController', 'MirrorController', 'NetworkController', diff --git a/subiquity/controllers/cmdlist.py b/subiquity/controllers/cmdlist.py new file mode 100644 index 00000000..9fb09510 --- /dev/null +++ b/subiquity/controllers/cmdlist.py @@ -0,0 +1,43 @@ +# Copyright 2019 Canonical, Ltd. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import asyncio + +from subiquity.controller import NoUIController + + +class CmdListController(NoUIController): + + autoinstall_default = [] + cmds = () + + def load_autoinstall_data(self, data): + self.cmds = data + + async def run(self): + for i, cmd in enumerate(self.cmds): + with self.context.child("command_{}".format(i), cmd): + proc = await asyncio.create_subprocess_shell(cmd) + await proc.communicate() + + +class EarlyController(CmdListController): + + autoinstall_key = 'early-commands' + + +class LateController(CmdListController): + + autoinstall_key = 'late-commands' diff --git a/subiquity/core.py b/subiquity/core.py index d849ce8a..57d4bf71 100644 --- a/subiquity/core.py +++ b/subiquity/core.py @@ -79,21 +79,23 @@ class Subiquity(Application): return SubiquityUI(self) controllers = [ - "Welcome", - "Refresh", - "Keyboard", - "Zdev", - "Network", - "Proxy", - "Mirror", - "Refresh", - "Filesystem", - "Identity", - "SSH", - "SnapList", - "InstallProgress", - "Error", # does not have a UI - "Reporting", # does not have a UI + "Early", + "Reporting", + "Error", + "Welcome", + "Refresh", + "Keyboard", + "Zdev", + "Network", + "Proxy", + "Mirror", + "Refresh", + "Filesystem", + "Identity", + "SSH", + "SnapList", + "InstallProgress", + "Late", ] def __init__(self, opts, block_log_dir): @@ -148,8 +150,17 @@ class Subiquity(Application): self.opts.autoinstall, self.merged_autoinstall_path) with open(self.merged_autoinstall_path) as fp: self.autoinstall_config = yaml.safe_load(fp) + self.controllers.load("Early") + self.controllers.load("Reporting") + self.controllers.Reporting.start() + self.aio_loop.run_until_complete(self.controllers.Early.run()) + self.new_event_loop() + with open(self.merged_autoinstall_path) as fp: + self.autoinstall_config = yaml.safe_load(fp) try: super().run() + self.new_event_loop() + self.aio_loop.run_until_complete(self.controllers.Late.run()) except Exception: print("generating crash report") report = self.make_apport_report( diff --git a/subiquitycore/core.py b/subiquitycore/core.py index 310d03f8..6f0a6611 100644 --- a/subiquitycore/core.py +++ b/subiquitycore/core.py @@ -363,11 +363,16 @@ class Application: self.updated = os.path.exists(os.path.join(self.state_dir, 'updating')) self.signal = Signal() self.prober = prober - self.aio_loop = asyncio.get_event_loop() + self.new_event_loop() self.urwid_loop = None self.controllers = ControllerSet(self, self.controllers) self.context = Context.new(self) + def new_event_loop(self): + new_loop = asyncio.new_event_loop() + asyncio.set_event_loop(new_loop) + self.aio_loop = new_loop + def run_command_in_foreground(self, cmd, before_hook=None, after_hook=None, **kw): screen = self.urwid_loop.screen