use asyncio.Event()s to indicate when config is done
stop using urwid signals to indicate to installprogress when a particular piece of config is done and instead call .set() on an Event that installprogress can wait on.
This commit is contained in:
parent
2e59d11ad3
commit
016b7a4d46
|
@ -312,7 +312,7 @@ class FilesystemController(BaseController):
|
||||||
def finish(self):
|
def finish(self):
|
||||||
log.debug("FilesystemController.finish next_screen")
|
log.debug("FilesystemController.finish next_screen")
|
||||||
# start curtin install in background
|
# start curtin install in background
|
||||||
self.signal.emit_signal('installprogress:filesystem-config-done')
|
self.app.base_model.configured("filesystem")
|
||||||
# switch to next screen
|
# switch to next screen
|
||||||
self.app.next_screen()
|
self.app.next_screen()
|
||||||
|
|
||||||
|
|
|
@ -50,5 +50,5 @@ class IdentityController(BaseController):
|
||||||
"IdentityController.done next_screen user_spec=%s",
|
"IdentityController.done next_screen user_spec=%s",
|
||||||
safe_spec)
|
safe_spec)
|
||||||
self.model.add_user(user_spec)
|
self.model.add_user(user_spec)
|
||||||
self.signal.emit_signal('installprogress:identity-config-done')
|
self.app.base_model.configured("identity")
|
||||||
self.app.next_screen()
|
self.app.next_screen()
|
||||||
|
|
|
@ -89,12 +89,6 @@ def install_step(label):
|
||||||
|
|
||||||
|
|
||||||
class InstallProgressController(BaseController):
|
class InstallProgressController(BaseController):
|
||||||
signals = [
|
|
||||||
('installprogress:filesystem-config-done', 'filesystem_config_done'),
|
|
||||||
('installprogress:identity-config-done', 'identity_config_done'),
|
|
||||||
('installprogress:ssh-config-done', 'ssh_config_done'),
|
|
||||||
('installprogress:snap-config-done', 'snap_config_done'),
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
super().__init__(app)
|
super().__init__(app)
|
||||||
|
@ -103,12 +97,6 @@ class InstallProgressController(BaseController):
|
||||||
self.install_state = InstallState.NOT_STARTED
|
self.install_state = InstallState.NOT_STARTED
|
||||||
self.journal_listener_handle = None
|
self.journal_listener_handle = None
|
||||||
|
|
||||||
self.filesystem_event = asyncio.Event()
|
|
||||||
self._postinstall_prerequisites = {
|
|
||||||
'ssh': asyncio.Event(),
|
|
||||||
'identity': asyncio.Event(),
|
|
||||||
'snap': asyncio.Event(),
|
|
||||||
}
|
|
||||||
self.reboot_clicked = asyncio.Event()
|
self.reboot_clicked = asyncio.Event()
|
||||||
if self.answers.get('reboot', False):
|
if self.answers.get('reboot', False):
|
||||||
self.reboot_clicked.set()
|
self.reboot_clicked.set()
|
||||||
|
@ -126,21 +114,6 @@ class InstallProgressController(BaseController):
|
||||||
def tpath(self, *path):
|
def tpath(self, *path):
|
||||||
return os.path.join(self.model.target, *path)
|
return os.path.join(self.model.target, *path)
|
||||||
|
|
||||||
def filesystem_config_done(self):
|
|
||||||
self.filesystem_event.set()
|
|
||||||
|
|
||||||
def _step_done(self, step):
|
|
||||||
self._postinstall_prerequisites[step].set()
|
|
||||||
|
|
||||||
def identity_config_done(self):
|
|
||||||
self._step_done('identity')
|
|
||||||
|
|
||||||
def ssh_config_done(self):
|
|
||||||
self._step_done('ssh')
|
|
||||||
|
|
||||||
def snap_config_done(self):
|
|
||||||
self._step_done('snap')
|
|
||||||
|
|
||||||
def curtin_error(self):
|
def curtin_error(self):
|
||||||
self.install_state = InstallState.ERROR
|
self.install_state = InstallState.ERROR
|
||||||
kw = {}
|
kw = {}
|
||||||
|
@ -274,12 +247,13 @@ class InstallProgressController(BaseController):
|
||||||
|
|
||||||
async def install(self):
|
async def install(self):
|
||||||
try:
|
try:
|
||||||
await self.filesystem_event.wait()
|
await asyncio.wait(
|
||||||
|
{e.wait() for e in self.model.install_events})
|
||||||
|
|
||||||
await self.curtin_install()
|
await self.curtin_install()
|
||||||
|
|
||||||
await asyncio.wait(
|
await asyncio.wait(
|
||||||
{e.wait() for e in self._postinstall_prerequisites.values()})
|
{e.wait() for e in self.model.postinstall_events})
|
||||||
|
|
||||||
await self.drain_curtin_events()
|
await self.drain_curtin_events()
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ class KeyboardController(BaseController):
|
||||||
async def apply_settings(self, setting):
|
async def apply_settings(self, setting):
|
||||||
await self.model.set_keyboard(setting)
|
await self.model.set_keyboard(setting)
|
||||||
log.debug("KeyboardController next_screen")
|
log.debug("KeyboardController next_screen")
|
||||||
|
self.app.base_model.configured("keyboard")
|
||||||
self.app.next_screen()
|
self.app.next_screen()
|
||||||
|
|
||||||
def done(self, setting):
|
def done(self, setting):
|
||||||
|
|
|
@ -105,4 +105,5 @@ class MirrorController(BaseController):
|
||||||
log.debug("MirrorController.done next_screen mirror=%s", mirror)
|
log.debug("MirrorController.done next_screen mirror=%s", mirror)
|
||||||
if mirror != self.model.mirror:
|
if mirror != self.model.mirror:
|
||||||
self.model.mirror = mirror
|
self.model.mirror = mirror
|
||||||
|
self.app.base_model.configured("mirror")
|
||||||
self.app.next_screen()
|
self.app.next_screen()
|
||||||
|
|
|
@ -17,4 +17,7 @@ from subiquitycore.controllers.network import NetworkController
|
||||||
|
|
||||||
|
|
||||||
class NetworkController(NetworkController):
|
class NetworkController(NetworkController):
|
||||||
pass
|
|
||||||
|
def done(self):
|
||||||
|
self.app.base_model.configured("network")
|
||||||
|
super().done()
|
||||||
|
|
|
@ -49,4 +49,5 @@ class ProxyController(BaseController):
|
||||||
self.model.proxy = proxy
|
self.model.proxy = proxy
|
||||||
os.environ['http_proxy'] = os.environ['https_proxy'] = proxy
|
os.environ['http_proxy'] = os.environ['https_proxy'] = proxy
|
||||||
self.signal.emit_signal('network-proxy-set')
|
self.signal.emit_signal('network-proxy-set')
|
||||||
|
self.app.base_model.configured("proxy")
|
||||||
self.app.next_screen()
|
self.app.next_screen()
|
||||||
|
|
|
@ -148,7 +148,7 @@ class SnapListController(BaseController):
|
||||||
"SnapListController.done next_screen snaps_to_install=%s",
|
"SnapListController.done next_screen snaps_to_install=%s",
|
||||||
snaps_to_install)
|
snaps_to_install)
|
||||||
self.model.set_installed_list(snaps_to_install)
|
self.model.set_installed_list(snaps_to_install)
|
||||||
self.signal.emit_signal("installprogress:snap-config-done")
|
self.app.base_model.configured("snaplist")
|
||||||
self.app.next_screen()
|
self.app.next_screen()
|
||||||
|
|
||||||
def cancel(self, sender=None):
|
def cancel(self, sender=None):
|
||||||
|
|
|
@ -116,5 +116,5 @@ class SSHController(BaseController):
|
||||||
self.model.authorized_keys = result.get('authorized_keys', [])
|
self.model.authorized_keys = result.get('authorized_keys', [])
|
||||||
self.model.pwauth = result.get('pwauth', True)
|
self.model.pwauth = result.get('pwauth', True)
|
||||||
self.model.ssh_import_id = result.get('ssh_import_id', None)
|
self.model.ssh_import_id = result.get('ssh_import_id', None)
|
||||||
self.signal.emit_signal('installprogress:ssh-config-done')
|
self.app.base_model.configured("ssh")
|
||||||
self.app.next_screen()
|
self.app.next_screen()
|
||||||
|
|
|
@ -48,6 +48,7 @@ class WelcomeController(BaseController):
|
||||||
log.debug("WelcomeController.done %s next_screen", code)
|
log.debug("WelcomeController.done %s next_screen", code)
|
||||||
self.signal.emit_signal('l10n:language-selected', code)
|
self.signal.emit_signal('l10n:language-selected', code)
|
||||||
self.model.switch_language(code)
|
self.model.switch_language(code)
|
||||||
|
self.app.base_model.configured("locale")
|
||||||
self.app.next_screen()
|
self.app.next_screen()
|
||||||
|
|
||||||
def cancel(self):
|
def cancel(self):
|
||||||
|
|
|
@ -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
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
@ -61,6 +62,25 @@ ff02::1 ip6-allnodes
|
||||||
ff02::2 ip6-allrouters
|
ff02::2 ip6-allrouters
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Models that contribute to the curtin config
|
||||||
|
INSTALL_MODEL_NAMES = [
|
||||||
|
"keyboard",
|
||||||
|
"network",
|
||||||
|
"proxy",
|
||||||
|
"mirror",
|
||||||
|
"filesystem",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Models that contribute to the cloud-init config
|
||||||
|
POSTINSTALL_MODEL_NAMES = [
|
||||||
|
"locale",
|
||||||
|
"identity",
|
||||||
|
"ssh",
|
||||||
|
"snaplist",
|
||||||
|
]
|
||||||
|
|
||||||
|
ALL_MODEL_NAMES = INSTALL_MODEL_NAMES + POSTINSTALL_MODEL_NAMES
|
||||||
|
|
||||||
|
|
||||||
class SubiquityModel:
|
class SubiquityModel:
|
||||||
"""The overall model for subiquity."""
|
"""The overall model for subiquity."""
|
||||||
|
@ -78,20 +98,23 @@ class SubiquityModel:
|
||||||
self.proxy = ProxyModel()
|
self.proxy = ProxyModel()
|
||||||
self.mirror = MirrorModel()
|
self.mirror = MirrorModel()
|
||||||
self.filesystem = FilesystemModel()
|
self.filesystem = FilesystemModel()
|
||||||
|
|
||||||
# Collect the models that produce data for the curtin config.
|
|
||||||
self._install_models = [
|
|
||||||
self.keyboard,
|
|
||||||
self.network,
|
|
||||||
self.proxy,
|
|
||||||
self.mirror,
|
|
||||||
self.filesystem,
|
|
||||||
]
|
|
||||||
|
|
||||||
self.identity = IdentityModel()
|
self.identity = IdentityModel()
|
||||||
self.ssh = SSHModel()
|
self.ssh = SSHModel()
|
||||||
self.snaplist = SnapListModel()
|
self.snaplist = SnapListModel()
|
||||||
|
|
||||||
|
self._events = {
|
||||||
|
name: asyncio.Event() for name in ALL_MODEL_NAMES
|
||||||
|
}
|
||||||
|
self.install_events = {
|
||||||
|
self._events[name] for name in INSTALL_MODEL_NAMES
|
||||||
|
}
|
||||||
|
self.postinstall_events = {
|
||||||
|
self._events[name] for name in POSTINSTALL_MODEL_NAMES
|
||||||
|
}
|
||||||
|
|
||||||
|
def configured(self, model_name):
|
||||||
|
self._events[model_name].set()
|
||||||
|
|
||||||
def get_target_groups(self):
|
def get_target_groups(self):
|
||||||
command = ['chroot', self.target, 'getent', 'group']
|
command = ['chroot', self.target, 'getent', 'group']
|
||||||
if self.root != '/':
|
if self.root != '/':
|
||||||
|
@ -248,7 +271,8 @@ class SubiquityModel:
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for model in self._install_models:
|
for model_name in INSTALL_MODEL_NAMES:
|
||||||
|
model = getattr(self, model_name)
|
||||||
log.debug("merging config from %s", model)
|
log.debug("merging config from %s", model)
|
||||||
merge_config(config, model.render())
|
merge_config(config, model.render())
|
||||||
|
|
||||||
|
|
|
@ -43,3 +43,4 @@ class TestSubiquityModel(unittest.TestCase):
|
||||||
model.config_path)
|
model.config_path)
|
||||||
self.assertEqual(new_setting, read_setting)
|
self.assertEqual(new_setting, read_setting)
|
||||||
loop.run_until_complete(t())
|
loop.run_until_complete(t())
|
||||||
|
loop.close()
|
||||||
|
|
|
@ -106,7 +106,7 @@ class TestSubiquityModel(unittest.TestCase):
|
||||||
def test_writes_machine_id_media_info(self):
|
def test_writes_machine_id_media_info(self):
|
||||||
model_no_proxy = SubiquityModel('test')
|
model_no_proxy = SubiquityModel('test')
|
||||||
model_proxy = SubiquityModel('test')
|
model_proxy = SubiquityModel('test')
|
||||||
model_proxy.proxy = 'http://something'
|
model_proxy.proxy.proxy = 'http://something'
|
||||||
for model in model_no_proxy, model_proxy:
|
for model in model_no_proxy, model_proxy:
|
||||||
config = model.render('ident')
|
config = model.render('ident')
|
||||||
self.assertConfigWritesFile(config, 'etc/machine-id')
|
self.assertConfigWritesFile(config, 'etc/machine-id')
|
||||||
|
|
Loading…
Reference in New Issue