general machinery for autoinstalls
This commit is contained in:
parent
671febc73f
commit
9c59fa59db
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue