general machinery for autoinstalls

This commit is contained in:
Michael Hudson-Doyle 2019-12-20 14:09:21 +13:00
parent 671febc73f
commit 9c59fa59db
4 changed files with 71 additions and 2 deletions

View File

@ -26,8 +26,35 @@ log = logging.getLogger("subiquity.controller")
class SubiquityController(BaseController): class SubiquityController(BaseController):
def deserialize(self, state): autoinstall_key = None
self.configured() autoinstall_default = None
def __init__(self, app):
super().__init__(app)
self.autoinstall_applied = False
if app.autoinstall_config:
self.load_autoinstall_data(
app.autoinstall_config.get(
self.autoinstall_key,
self.autoinstall_default))
def load_autoinstall_data(self, data):
"""Load autoinstall data.
This is called if there is an autoinstall happening. This
controller may not have any data, and this controller may still
be interactive.
"""
pass
async def apply_autoinstall_config(self):
"""Apply autoinstall configuration.
This is only called for a non-interactive controller. It should
block until the configuration has been applied. (self.configured()
is called after this is done).
"""
pass
def interactive(self): def interactive(self):
if not self.app.autoinstall_config: if not self.app.autoinstall_config:
@ -44,6 +71,9 @@ class SubiquityController(BaseController):
if self.model_name is not None: if self.model_name is not None:
self.app.base_model.configured(self.model_name) self.app.base_model.configured(self.model_name)
def deserialize(self, state):
self.configured()
class NoUIController(SubiquityController): class NoUIController(SubiquityController):
@ -59,5 +89,15 @@ class NoUIController(SubiquityController):
class RepeatedController(RepeatedController): class RepeatedController(RepeatedController):
def __init__(self, orig, index):
super().__init__(orig, index)
self.autoinstall_applied = False
async def apply_autoinstall_config(self):
await self.orig.apply_autoinstall_config(self.index)
def configured(self):
self.orig.configured()
def interactive(self): def interactive(self):
return self.orig.interactive() return self.orig.interactive()

View File

@ -65,6 +65,9 @@ class RefreshController(SubiquityController):
self.check_for_update, propagate_errors=False) self.check_for_update, propagate_errors=False)
self.check_task.start_sync() self.check_task.start_sync()
async def apply_autoinstall_config(self, index=1):
pass
@property @property
def check_state(self): def check_state(self):
task = self.check_task.task task = self.check_task.task

View File

@ -37,6 +37,7 @@ class Thing:
class MiniApplication: class MiniApplication:
ui = signal = loop = None ui = signal = loop = None
project = "mini" project = "mini"
autoinstall_config = {}
answers = {} answers = {}
opts = Thing() opts = Thing()
opts.dry_run = True opts.dry_run = True

View File

@ -13,6 +13,7 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import asyncio
import logging import logging
import os import os
import platform import platform
@ -26,6 +27,7 @@ from subiquitycore.async_helpers import (
run_in_thread, run_in_thread,
schedule_task, schedule_task,
) )
from subiquitycore.controller import Skip
from subiquitycore.core import Application from subiquitycore.core import Application
from subiquitycore.utils import run_command from subiquitycore.utils import run_command
@ -165,6 +167,29 @@ class Subiquity(Application):
self.show_error_report(report) self.show_error_report(report)
return return
def select_screen(self, new):
if new.interactive():
super().select_screen(new)
return
elif self.autoinstall_config and not new.autoinstall_applied:
schedule_task(self._apply(new))
else:
raise Skip
async def _apply(self, controller):
with controller.context.child("apply_autoinstall_config"):
try:
await controller.apply_autoinstall_config()
except BaseException:
logging.exception(
"%s.apply_autoinstall_config failed", controller.name)
# Obviously need to something better here.
await asyncio.sleep(1800)
raise
controller.autoinstall_applied = True
controller.configured()
self.next_screen()
def _network_change(self): def _network_change(self):
self.signal.emit_signal('snapd-network-change') self.signal.emit_signal('snapd-network-change')