locale - let it check interactive-sections again (#937)
* locale - let it check interactive-sections again * Turn Serial into a whole new screen When in serial, first offer the rich/basic choice (or SSH button), and only show the current welcome screen if we choose rich mode. Add a back button on Welcome if we are on serial. LP: #1919251
This commit is contained in:
parent
046949f087
commit
2719c57c1b
|
@ -93,6 +93,7 @@ class SubiquityClient(TuiApplication):
|
||||||
return SubiquityUI(self, self.help_menu)
|
return SubiquityUI(self, self.help_menu)
|
||||||
|
|
||||||
controllers = [
|
controllers = [
|
||||||
|
"Serial",
|
||||||
"Welcome",
|
"Welcome",
|
||||||
"Refresh",
|
"Refresh",
|
||||||
"Keyboard",
|
"Keyboard",
|
||||||
|
|
|
@ -22,11 +22,13 @@ from .network import NetworkController
|
||||||
from .progress import ProgressController
|
from .progress import ProgressController
|
||||||
from .proxy import ProxyController
|
from .proxy import ProxyController
|
||||||
from .refresh import RefreshController
|
from .refresh import RefreshController
|
||||||
|
from .serial import SerialController
|
||||||
from .snaplist import SnapListController
|
from .snaplist import SnapListController
|
||||||
from .ssh import SSHController
|
from .ssh import SSHController
|
||||||
from .welcome import WelcomeController
|
from .welcome import WelcomeController
|
||||||
from .zdev import ZdevController
|
from .zdev import ZdevController
|
||||||
|
|
||||||
|
# see SubiquityClient.controllers for another list
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'FilesystemController',
|
'FilesystemController',
|
||||||
'IdentityController',
|
'IdentityController',
|
||||||
|
@ -37,6 +39,7 @@ __all__ = [
|
||||||
'ProxyController',
|
'ProxyController',
|
||||||
'RefreshController',
|
'RefreshController',
|
||||||
'RepeatedController',
|
'RepeatedController',
|
||||||
|
'SerialController',
|
||||||
'SnapListController',
|
'SnapListController',
|
||||||
'SSHController',
|
'SSHController',
|
||||||
'WelcomeController',
|
'WelcomeController',
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Copyright 2021 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from subiquity.client.controller import SubiquityTuiController
|
||||||
|
from subiquity.ui.views.serial import SerialView
|
||||||
|
from subiquitycore.tuicontroller import Skip
|
||||||
|
|
||||||
|
log = logging.getLogger('subiquity.client.controllers.serial')
|
||||||
|
|
||||||
|
|
||||||
|
class SerialController(SubiquityTuiController):
|
||||||
|
async def make_ui(self):
|
||||||
|
if not self.app.opts.run_on_serial:
|
||||||
|
raise Skip()
|
||||||
|
ssh_info = await self.app.client.meta.ssh_info.GET()
|
||||||
|
return SerialView(self, ssh_info)
|
||||||
|
|
||||||
|
def done(self, rich):
|
||||||
|
log.debug("SerialController.done rich %s next_screen", rich)
|
||||||
|
self.app.set_rich(rich)
|
||||||
|
self.app.next_screen()
|
||||||
|
|
||||||
|
def cancel(self):
|
||||||
|
# Can't go back from here!
|
||||||
|
pass
|
|
@ -16,6 +16,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from subiquitycore import i18n
|
from subiquitycore import i18n
|
||||||
|
from subiquitycore.tuicontroller import Skip
|
||||||
from subiquity.client.controller import SubiquityTuiController
|
from subiquity.client.controller import SubiquityTuiController
|
||||||
from subiquity.ui.views.welcome import WelcomeView
|
from subiquity.ui.views.welcome import WelcomeView
|
||||||
|
|
||||||
|
@ -27,14 +28,12 @@ class WelcomeController(SubiquityTuiController):
|
||||||
endpoint_name = 'locale'
|
endpoint_name = 'locale'
|
||||||
|
|
||||||
async def make_ui(self):
|
async def make_ui(self):
|
||||||
|
if not self.app.rich_mode:
|
||||||
|
raise Skip()
|
||||||
language = await self.endpoint.GET()
|
language = await self.endpoint.GET()
|
||||||
i18n.switch_language(language)
|
i18n.switch_language(language)
|
||||||
serial = self.app.opts.run_on_serial
|
self.serial = self.app.opts.run_on_serial
|
||||||
if serial:
|
return WelcomeView(self, language, self.serial)
|
||||||
ssh_info = await self.app.client.meta.ssh_info.GET()
|
|
||||||
else:
|
|
||||||
ssh_info = None
|
|
||||||
return WelcomeView(self, language, serial, ssh_info)
|
|
||||||
|
|
||||||
def run_answers(self):
|
def run_answers(self):
|
||||||
if 'lang' in self.answers:
|
if 'lang' in self.answers:
|
||||||
|
@ -45,6 +44,8 @@ class WelcomeController(SubiquityTuiController):
|
||||||
i18n.switch_language(code)
|
i18n.switch_language(code)
|
||||||
self.app.next_screen(self.endpoint.POST(code))
|
self.app.next_screen(self.endpoint.POST(code))
|
||||||
|
|
||||||
def cancel(self):
|
def cancel(self, sender=None):
|
||||||
# Can't go back from here!
|
if not self.serial:
|
||||||
|
# Can't go back from here unless we're on serial!
|
||||||
pass
|
pass
|
||||||
|
self.app.prev_screen()
|
||||||
|
|
|
@ -31,9 +31,6 @@ class LocaleController(SubiquityController):
|
||||||
autoinstall_schema = {'type': 'string'}
|
autoinstall_schema = {'type': 'string'}
|
||||||
autoinstall_default = 'en_US.UTF-8'
|
autoinstall_default = 'en_US.UTF-8'
|
||||||
|
|
||||||
def interactive(self):
|
|
||||||
return self.app.interactive
|
|
||||||
|
|
||||||
def load_autoinstall_data(self, data):
|
def load_autoinstall_data(self, data):
|
||||||
os.environ["LANG"] = data
|
os.environ["LANG"] = data
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
# Copyright 2021 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Welcome
|
||||||
|
|
||||||
|
Welcome provides user with language selection
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from urwid import Text
|
||||||
|
|
||||||
|
from subiquitycore.ui.buttons import forward_btn, other_btn
|
||||||
|
from subiquitycore.ui.utils import rewrap, screen
|
||||||
|
from subiquitycore.view import BaseView
|
||||||
|
|
||||||
|
log = logging.getLogger("subiquity.views.serial")
|
||||||
|
|
||||||
|
|
||||||
|
SERIAL_TEXT = """
|
||||||
|
|
||||||
|
As the installer is running on a serial console, it has started in
|
||||||
|
basic mode, using only the ASCII character set and black and white
|
||||||
|
colours.
|
||||||
|
|
||||||
|
If you are connecting from a terminal emulator such as gnome-terminal
|
||||||
|
that supports unicode and rich colours you can switch to "rich mode"
|
||||||
|
which uses unicode, colours and supports many languages.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
SSH_TEXT = """
|
||||||
|
You can also connect to the installer over the network via SSH, which
|
||||||
|
will allow use of rich mode.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class SerialView(BaseView):
|
||||||
|
title = "Serial"
|
||||||
|
|
||||||
|
def __init__(self, controller, ssh_info):
|
||||||
|
self.controller = controller
|
||||||
|
self.ssh_info = ssh_info
|
||||||
|
super().__init__(self.make_serial())
|
||||||
|
|
||||||
|
def make_serial(self):
|
||||||
|
btns = [
|
||||||
|
forward_btn(
|
||||||
|
label="Continue in rich mode",
|
||||||
|
on_press=self.rich_mode),
|
||||||
|
forward_btn(
|
||||||
|
label="Continue in basic mode",
|
||||||
|
on_press=self.basic_mode),
|
||||||
|
]
|
||||||
|
widgets = [
|
||||||
|
Text(""),
|
||||||
|
Text(rewrap(SERIAL_TEXT)),
|
||||||
|
Text(""),
|
||||||
|
]
|
||||||
|
if self.ssh_info:
|
||||||
|
widgets.append(Text(rewrap(SSH_TEXT)))
|
||||||
|
widgets.append(Text(""))
|
||||||
|
btns.append(other_btn(
|
||||||
|
label="View SSH instructions",
|
||||||
|
on_press=self.ssh_help))
|
||||||
|
return screen(widgets, btns)
|
||||||
|
|
||||||
|
def rich_mode(self, sender):
|
||||||
|
self.controller.done(True)
|
||||||
|
|
||||||
|
def basic_mode(self, sender):
|
||||||
|
self.controller.done(False)
|
||||||
|
|
||||||
|
def ssh_help(self, sender):
|
||||||
|
menu = self.controller.app.help_menu
|
||||||
|
menu.ssh_info = self.ssh_info
|
||||||
|
menu.ssh_help()
|
|
@ -14,7 +14,7 @@ class WelcomeViewTests(unittest.TestCase):
|
||||||
controller = mock.create_autospec(spec=WelcomeController)
|
controller = mock.create_autospec(spec=WelcomeController)
|
||||||
with mock.patch("subiquity.ui.views.welcome.get_languages") as p:
|
with mock.patch("subiquity.ui.views.welcome.get_languages") as p:
|
||||||
p.return_value = languages
|
p.return_value = languages
|
||||||
return WelcomeView(controller, languages[0][0], False, None)
|
return WelcomeView(controller, languages[0][0], False)
|
||||||
|
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
# Clicking the button for a language calls "switch_language"
|
# Clicking the button for a language calls "switch_language"
|
||||||
|
|
|
@ -38,23 +38,6 @@ Select the language to use for the installer and to be configured in the
|
||||||
installed system.
|
installed system.
|
||||||
""")
|
""")
|
||||||
|
|
||||||
SERIAL_TEXT = """
|
|
||||||
|
|
||||||
As the installer is running on a serial console, it has started in
|
|
||||||
basic mode, using only the ASCII character set and black and white
|
|
||||||
colours.
|
|
||||||
|
|
||||||
If you are connecting from a terminal emulator such as gnome-terminal
|
|
||||||
that supports unicode and rich colours you can switch to "rich mode"
|
|
||||||
which uses unicode, colours and supports many languages.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
SSH_TEXT = """
|
|
||||||
You can also connect to the installer over the network via SSH, which
|
|
||||||
will allow use of rich mode.
|
|
||||||
"""
|
|
||||||
|
|
||||||
CLOUD_INIT_FAIL_TEXT = """
|
CLOUD_INIT_FAIL_TEXT = """
|
||||||
cloud-init failed to complete after 10 minutes of waiting. This
|
cloud-init failed to complete after 10 minutes of waiting. This
|
||||||
suggests a bug, which we would appreciate help understanding. If you
|
suggests a bug, which we would appreciate help understanding. If you
|
||||||
|
@ -81,15 +64,11 @@ def get_languages():
|
||||||
class WelcomeView(BaseView):
|
class WelcomeView(BaseView):
|
||||||
title = "Willkommen! Bienvenue! Welcome! Добро пожаловать! Welkom!"
|
title = "Willkommen! Bienvenue! Welcome! Добро пожаловать! Welkom!"
|
||||||
|
|
||||||
def __init__(self, controller, cur_lang, serial, ssh_info):
|
def __init__(self, controller, cur_lang, serial):
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.cur_lang = cur_lang
|
self.cur_lang = cur_lang
|
||||||
if serial and not controller.app.rich_mode:
|
self.serial = serial
|
||||||
s = self.make_serial_choices(ssh_info)
|
super().__init__(self.make_language_choices())
|
||||||
self.title = "Welcome!"
|
|
||||||
else:
|
|
||||||
s = self.make_language_choices()
|
|
||||||
super().__init__(s)
|
|
||||||
|
|
||||||
def make_language_choices(self):
|
def make_language_choices(self):
|
||||||
btns = []
|
btns = []
|
||||||
|
@ -109,51 +88,16 @@ class WelcomeView(BaseView):
|
||||||
user_arg=code))
|
user_arg=code))
|
||||||
|
|
||||||
lb = ListBox(btns)
|
lb = ListBox(btns)
|
||||||
|
back = None
|
||||||
|
if self.serial:
|
||||||
|
back = other_btn(_("Back"), on_press=self.controller.cancel)
|
||||||
if current_index is not None:
|
if current_index is not None:
|
||||||
lb.base_widget.focus_position = current_index
|
lb.base_widget.focus_position = current_index
|
||||||
return screen(
|
return screen(
|
||||||
lb, buttons=None, narrow_rows=True,
|
lb, focus_buttons=False, narrow_rows=True,
|
||||||
|
buttons=[back] if back else None,
|
||||||
excerpt=_("Use UP, DOWN and ENTER keys to select your language."))
|
excerpt=_("Use UP, DOWN and ENTER keys to select your language."))
|
||||||
|
|
||||||
def make_serial_choices(self, ssh_info):
|
|
||||||
btns = [
|
|
||||||
other_btn(
|
|
||||||
label="Switch to rich mode",
|
|
||||||
on_press=self.enable_rich),
|
|
||||||
forward_btn(
|
|
||||||
label="Continue in basic mode",
|
|
||||||
on_press=self.choose_language,
|
|
||||||
user_arg='C'),
|
|
||||||
]
|
|
||||||
widgets = [
|
|
||||||
Text(""),
|
|
||||||
Text(rewrap(SERIAL_TEXT)),
|
|
||||||
Text(""),
|
|
||||||
]
|
|
||||||
if ssh_info:
|
|
||||||
widgets.append(Text(rewrap(SSH_TEXT)))
|
|
||||||
widgets.append(Text(""))
|
|
||||||
btns.insert(1, other_btn(
|
|
||||||
label="View SSH instructions",
|
|
||||||
on_press=self.ssh_help,
|
|
||||||
user_arg=ssh_info))
|
|
||||||
widgets.extend([
|
|
||||||
button_pile(btns),
|
|
||||||
])
|
|
||||||
lb = ListBox(widgets)
|
|
||||||
return screen(lb, buttons=None)
|
|
||||||
|
|
||||||
def enable_rich(self, sender):
|
|
||||||
self.controller.app.toggle_rich()
|
|
||||||
self.title = self.__class__.title
|
|
||||||
self.controller.ui.set_header(self.title)
|
|
||||||
self._w = self.make_language_choices()
|
|
||||||
|
|
||||||
def ssh_help(self, sender, ssh_info):
|
|
||||||
menu = self.controller.app.help_menu
|
|
||||||
menu.ssh_info = ssh_info
|
|
||||||
menu.ssh_help()
|
|
||||||
|
|
||||||
def choose_language(self, sender, code):
|
def choose_language(self, sender, code):
|
||||||
log.debug('WelcomeView %s', code)
|
log.debug('WelcomeView %s', code)
|
||||||
self.controller.done(code)
|
self.controller.done(code)
|
||||||
|
|
|
@ -312,6 +312,11 @@ class TuiApplication(Application):
|
||||||
|
|
||||||
self.aio_loop.call_later(0.06, _run_script)
|
self.aio_loop.call_later(0.06, _run_script)
|
||||||
|
|
||||||
|
def set_rich(self, rich):
|
||||||
|
if rich == self.rich_mode:
|
||||||
|
return
|
||||||
|
self.toggle_rich()
|
||||||
|
|
||||||
def toggle_rich(self):
|
def toggle_rich(self):
|
||||||
if self.rich_mode:
|
if self.rich_mode:
|
||||||
urwid.util.set_encoding('ascii')
|
urwid.util.set_encoding('ascii')
|
||||||
|
|
Loading…
Reference in New Issue