From 3098d108b28e276a00d17b3a536c641ae96f6257 Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Fri, 3 Mar 2017 15:38:47 -0500 Subject: [PATCH 01/13] Support special paths for environment check binaries in snaps. --- subiquitycore/utils.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/subiquitycore/utils.py b/subiquitycore/utils.py index 8a5f3c07..f31b655b 100644 --- a/subiquitycore/utils.py +++ b/subiquitycore/utils.py @@ -68,10 +68,18 @@ def environment_check(check): for ftype, items in checks[check_type].items(): for i in items: if not os.path.exists(i): - log.error('FAIL: {} is not found on the' - ' filesystem'.format(i)) - env_ok = False - continue + if 'SNAP' in os.environ: + log.warn("Adjusting path for snaps: {}".format(os.environ.get('SNAP'))) + i = os.environ.get('SNAP') + i + if not os.path.exists(i): + env_ok = False + else: + env_ok = False + + if not env_ok: + log.error('FAIL: {} is not found on the' + ' filesystem'.format(i)) + continue if check_map[ftype](i) is False: log.error('FAIL: {} is NOT of type: {}'.format(i, ftype)) env_ok = False From 462f4053acf4d494f0dfa07dbc32e3e325c0ae62 Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Mon, 13 Mar 2017 14:59:50 -0400 Subject: [PATCH 02/13] Add snapcraft.yaml --- snapcraft.yaml | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 snapcraft.yaml diff --git a/snapcraft.yaml b/snapcraft.yaml new file mode 100644 index 00000000..4529d2d9 --- /dev/null +++ b/snapcraft.yaml @@ -0,0 +1,40 @@ +name: subiquity +version: "0.0.30" +summary: Ubuntu installer +description: The Ubuntu server installer +confinement: classic + +apps: + subiquity: + command: usr/bin/subiquity + console-conf: + command: usr/bin/console-conf + probert: + command: bin/probert + +parts: + subiquity: + plugin: python + build-packages: [python-setuptools] + stage-packages: [curtin] + python-packages: + - urwid + - pyyaml + - pyudev + source: https://github.com/CanonicalLtd/subiquity.git + source-branch: cyphermox/snap + source-type: git + wrappers: + plugin: dump + source: https://github.com/CanonicalLtd/subiquity.git + source-type: git + organize: + 'bin/console-conf-tui': usr/bin/console-conf + 'bin/subiquity-tui': usr/bin/subiquity + snap: + - usr/bin + probert: + plugin: python + build-packages: [python-setuptools, libnl-3-dev, libnl-genl-3-dev, libnl-route-3-dev] + source: https://github.com/CanonicalLtd/probert.git + source-type: git From 6268d92f6a5664c06a8fc172baaf1e58bac355d6 Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Wed, 15 Mar 2017 10:39:35 -0400 Subject: [PATCH 03/13] Add postinst tasks to subiquity for cleanup. --- snapcraft.yaml | 2 +- subiquity/curtin.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/snapcraft.yaml b/snapcraft.yaml index 4529d2d9..b9f89181 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,5 +1,5 @@ name: subiquity -version: "0.0.30" +version: "0.0.31" summary: Ubuntu installer description: The Ubuntu server installer confinement: classic diff --git a/subiquity/curtin.py b/subiquity/curtin.py index fc701020..a810fb5c 100644 --- a/subiquity/curtin.py +++ b/subiquity/curtin.py @@ -71,6 +71,11 @@ network: # Reworked for flake8, but it does make it harder to read. POST_INSTALL_LIST = [ ("late_commands:"), + (" 05_clear_subiquity: curtin in-target -- " + "snap remove subiquity || true"), + (" 06_remove_subiquity_service: curtin in-target -- " + "rm -f /lib/systemd/system/subiquity*.service " + " /lib/systemd/system/multi-user.target.wants/subiquity* || true"), (" 10_mkdir_seed: curtin in-target -- " "mkdir -p /var/lib/cloud/seed/nocloud-net"), (" 11_postinst_metadata: [curtin, in-target, --, sh, '-c'," From 24168b9099eaab3c6d5302c88e2ae47351f0c264 Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Tue, 21 Mar 2017 18:09:46 -0400 Subject: [PATCH 04/13] Add /rofs as an install path; this is where the original read-only FS is using casper. --- subiquity/curtin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subiquity/curtin.py b/subiquity/curtin.py index a810fb5c..b2e62dbf 100644 --- a/subiquity/curtin.py +++ b/subiquity/curtin.py @@ -25,7 +25,7 @@ log = logging.getLogger("subiquity.curtin") TMPDIR = '/tmp' CURTIN_SEARCH_PATH = ['/usr/local/curtin/bin', '/usr/bin'] -CURTIN_INSTALL_PATH = ['/media/root-ro', '/'] +CURTIN_INSTALL_PATH = ['/media/root-ro', '/rofs', '/'] CURTIN_INSTALL_LOG = '/tmp/subiquity-curtin-install.log' CURTIN_POSTINSTALL_LOG = '/tmp/subiquity-curtin-postinstall.log' CONF_PREFIX = os.path.join(TMPDIR, 'subiquity-config-') From 38ed2028ae20a18dcc13124e506479d4eeddeeb1 Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Wed, 22 Mar 2017 13:40:46 -0400 Subject: [PATCH 05/13] Update snapcraft.yaml for added attrs python dependency. --- snapcraft.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/snapcraft.yaml b/snapcraft.yaml index b9f89181..4c7b4943 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,5 +1,5 @@ name: subiquity -version: "0.0.31" +version: "0.0.32" summary: Ubuntu installer description: The Ubuntu server installer confinement: classic @@ -21,6 +21,7 @@ parts: - urwid - pyyaml - pyudev + - attrs source: https://github.com/CanonicalLtd/subiquity.git source-branch: cyphermox/snap source-type: git From 295ae2882c8d1a92f2ebb1e5fd6fcba6128c5579 Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Tue, 28 Mar 2017 16:22:44 -0400 Subject: [PATCH 06/13] Bump version for snap. --- snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snapcraft.yaml b/snapcraft.yaml index 4c7b4943..26eb5158 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,5 +1,5 @@ name: subiquity -version: "0.0.32" +version: "0.0.35" summary: Ubuntu installer description: The Ubuntu server installer confinement: classic From 45146834f8bb8f83139ea01801be8fcf0441b64c Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Tue, 28 Mar 2017 16:48:41 -0400 Subject: [PATCH 07/13] Remove extra cleanup; enable ds-identify for cloud-init. --- subiquity/curtin.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/subiquity/curtin.py b/subiquity/curtin.py index a58b3ed2..47ae1392 100644 --- a/subiquity/curtin.py +++ b/subiquity/curtin.py @@ -71,11 +71,6 @@ network: # Reworked for flake8, but it does make it harder to read. POST_INSTALL_LIST = [ ("late_commands:"), - (" 05_clear_subiquity: curtin in-target -- " - "snap remove subiquity || true"), - (" 06_remove_subiquity_service: curtin in-target -- " - "rm -f /lib/systemd/system/subiquity*.service " - " /lib/systemd/system/multi-user.target.wants/subiquity* || true"), (" 10_mkdir_seed: curtin in-target -- " "mkdir -p /var/lib/cloud/seed/nocloud-net"), (" 11_postinst_metadata: [curtin, in-target, --, sh, '-c'," @@ -84,6 +79,9 @@ POST_INSTALL_LIST = [ (" 12_postinst_userdata: [curtin, in-target, --, sh, '-c'," "\"/bin/echo -e '#cloud-config\\n\\n{hostinfo}\\nusers:\\n{users}' > " "/var/lib/cloud/seed/nocloud-net/user-data\"]"), + (" 13_postinst_enable_cloud-init: [curtin, in-target, --, sh, '-c'," + '"/bin/echo -e policy: enabled ' + '> /etc/cloud/ds-identify.cfg"]'), ] POST_INSTALL = '\n' + "\n".join(POST_INSTALL_LIST) + '\n' From 32632497566d68b22609626503e1eda5875a5f83 Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Tue, 28 Mar 2017 17:33:17 -0400 Subject: [PATCH 08/13] Quote ssh_import_id; as otherwise curtin can fail to parse the resulting yaml (because it contains a colon). --- subiquity/curtin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subiquity/curtin.py b/subiquity/curtin.py index 47ae1392..bc94f5e9 100644 --- a/subiquity/curtin.py +++ b/subiquity/curtin.py @@ -94,7 +94,7 @@ def curtin_userinfo_to_config(userinfo): ' groups: admin\\n' + \ ' lock-passwd: false\\n' if 'ssh_import_id' in userinfo: - user_template += ' ssh-import-id: [{ssh_import_id}]\\n' + user_template += ' ssh-import-id: [ "{ssh_import_id}" ]\\n' return user_template.format(**userinfo) From 618c4e6e72603fe42da8eb0e35941c8488b9f3e2 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Wed, 5 Apr 2017 14:26:28 +1200 Subject: [PATCH 09/13] do not crash in final console-conf screen if no host keys are read (mostly dry-run mode) --- console_conf/controllers/identity.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/console_conf/controllers/identity.py b/console_conf/controllers/identity.py index 81e66f9f..9fed7a86 100644 --- a/console_conf/controllers/identity.py +++ b/console_conf/controllers/identity.py @@ -89,6 +89,8 @@ The {keytype} host key fingerprints is: def host_key_info(): fingerprints = host_key_fingerprints() + if len(fingerprints) == 0: + return [] if len(fingerprints) == 1: [(keytype, fingerprint)] = fingerprints return single_host_key_tmpl.format(keytype=keytype, fingerprint=fingerprint) From 395b30451e3b76939c6e8c17748eb748da99f2d3 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Tue, 4 Apr 2017 16:20:56 +1200 Subject: [PATCH 10/13] stop being clever in handling of escape in network screens --- console_conf/ui/views/identity.py | 2 +- subiquitycore/controllers/network.py | 20 ++----------------- subiquitycore/ui/views/network.py | 2 +- .../ui/views/network_bond_interfaces.py | 4 ++-- .../ui/views/network_configure_interface.py | 7 +++++-- .../network_configure_manual_interface.py | 9 ++++----- .../views/network_configure_wlan_interface.py | 9 ++++----- .../ui/views/network_default_route.py | 6 +++--- subiquitycore/view.py | 5 ++++- 9 files changed, 26 insertions(+), 38 deletions(-) diff --git a/console_conf/ui/views/identity.py b/console_conf/ui/views/identity.py index 3b3eacac..c8afb924 100644 --- a/console_conf/ui/views/identity.py +++ b/console_conf/ui/views/identity.py @@ -100,7 +100,7 @@ class IdentityView(BaseView): ] return Pile(buttons) - def cancel(self, button): + def cancel(self, button=None): self.controller.cancel() def done(self, button): diff --git a/subiquitycore/controllers/network.py b/subiquitycore/controllers/network.py index f3e1af67..a7feea1d 100644 --- a/subiquitycore/controllers/network.py +++ b/subiquitycore/controllers/network.py @@ -36,7 +36,7 @@ from subiquitycore.ui.views import (NetworkView, NetworkConfigureWLANView) from subiquitycore.ui.views.network import ApplyingConfigWidget from subiquitycore.ui.dummy import DummyView -from subiquitycore.controller import BaseController, view +from subiquitycore.controller import BaseController from subiquitycore.utils import run_command_start, run_command_summarize log = logging.getLogger("subiquitycore.controller.network") @@ -341,17 +341,9 @@ class NetworkController(BaseController): self.observer.wlan_listener.trigger_scan(dev.ifindex) def cancel(self): - if len(self.view_stack) <= 1: - self.signal.emit_signal('prev-screen') - else: - self.prev_view() + self.signal.emit_signal('prev-screen') def default(self): - self.view_stack = [] - self.start() - - @view - def start(self): title = "Network connections" excerpt = ("Configure at least one interface this server can use to talk to " "other machines, and which preferably provides sufficient access for " @@ -428,45 +420,37 @@ class NetworkController(BaseController): self.signal.emit_signal('network-config-written', self.netplan_path) self.signal.emit_signal('next-screen') - @view def set_default_v4_route(self): self.ui.set_header("Default route") self.ui.set_body(NetworkSetDefaultRouteView(self.model, socket.AF_INET, self)) - @view def set_default_v6_route(self): self.ui.set_header("Default route") self.ui.set_body(NetworkSetDefaultRouteView(self.model, socket.AF_INET6, self)) - @view def bond_interfaces(self): self.ui.set_header("Bond interfaces") self.ui.set_body(NetworkBondInterfacesView(self.model, self)) - @view def network_configure_interface(self, iface): self.ui.set_header("Network interface {}".format(iface)) self.ui.set_body(NetworkConfigureInterfaceView(self.model, self, iface)) - @view def network_configure_ipv4_interface(self, iface): self.ui.set_header("Network interface {} manual IPv4 " "configuration".format(iface)) self.ui.set_body(NetworkConfigureIPv4InterfaceView(self.model, self, iface)) - @view def network_configure_wlan_interface(self, iface): self.ui.set_header("Network interface {} WIFI " "configuration".format(iface)) self.ui.set_body(NetworkConfigureWLANView(self.model, self, iface)) - @view def network_configure_ipv6_interface(self, iface): self.ui.set_header("Network interface {} manual IPv6 " "configuration".format(iface)) self.ui.set_body(NetworkConfigureIPv6InterfaceView(self.model, self, iface)) - @view def install_network_driver(self): self.ui.set_body(DummyView(self)) diff --git a/subiquitycore/ui/views/network.py b/subiquitycore/ui/views/network.py index 9e3c6381..13204395 100644 --- a/subiquitycore/ui/views/network.py +++ b/subiquitycore/ui/views/network.py @@ -260,5 +260,5 @@ class NetworkView(BaseView): def done(self, result): self.controller.network_finish(self.model.render()) - def cancel(self, button): + def cancel(self, button=None): self.controller.cancel() diff --git a/subiquitycore/ui/views/network_bond_interfaces.py b/subiquitycore/ui/views/network_bond_interfaces.py index 983911c5..8b8185ed 100644 --- a/subiquitycore/ui/views/network_bond_interfaces.py +++ b/subiquitycore/ui/views/network_bond_interfaces.py @@ -127,8 +127,8 @@ class NetworkBondInterfacesView(BaseView): return log.debug('bond: successful bond creation') - self.controller.prev_view() + self.controller.default() def cancel(self, button): log.debug('bond: button_cancel') - self.controller.prev_view() + self.controller.default() diff --git a/subiquitycore/ui/views/network_configure_interface.py b/subiquitycore/ui/views/network_configure_interface.py index 90d9925d..73e05ea9 100644 --- a/subiquitycore/ui/views/network_configure_interface.py +++ b/subiquitycore/ui/views/network_configure_interface.py @@ -115,7 +115,7 @@ class NetworkConfigureInterfaceView(BaseView): self.dev = self.model.get_netdev_by_name(self.dev.name) except KeyError: # The interface is gone - self.controller.prev_view() + self.controller.default() return if self.dev.type == 'wlan': self.wifi_info.contents = [ (obj, ('pack', None)) for obj in _build_wifi_info(self.dev) ] @@ -155,5 +155,8 @@ class NetworkConfigureInterfaceView(BaseView): def show_ipv6_configuration(self, btn): self.controller.network_configure_ipv6_interface(self.dev.name) + def cancel(self): + self.controller.default() + def done(self, result): - self.controller.prev_view() + self.controller.default() diff --git a/subiquitycore/ui/views/network_configure_manual_interface.py b/subiquitycore/ui/views/network_configure_manual_interface.py index 71ded823..e9dc59dc 100644 --- a/subiquitycore/ui/views/network_configure_manual_interface.py +++ b/subiquitycore/ui/views/network_configure_manual_interface.py @@ -146,8 +146,7 @@ class BaseNetworkConfigureManualView(BaseView): self.dev = self.model.get_netdev_by_name(self.dev.name) except KeyError: # The interface is gone - self.controller.prev_view() - self.controller.prev_view() + self.controller.default() return def _build_set_as_default_gw_button(self): @@ -193,11 +192,11 @@ class BaseNetworkConfigureManualView(BaseView): self.dev.add_network(self.ip_version, result) # return - self.controller.prev_view() + self.controller.network_configure_interface(self.dev.name) - def cancel(self, sender): + def cancel(self, sender=None): self.model.default_gateway = None - self.controller.prev_view() + self.controller.network_configure_interface(self.dev.name) class NetworkConfigureIPv4InterfaceView(BaseNetworkConfigureManualView): ip_version = 4 diff --git a/subiquitycore/ui/views/network_configure_wlan_interface.py b/subiquitycore/ui/views/network_configure_wlan_interface.py index 0fe1a9fa..2eb4207f 100644 --- a/subiquitycore/ui/views/network_configure_wlan_interface.py +++ b/subiquitycore/ui/views/network_configure_wlan_interface.py @@ -138,8 +138,7 @@ class NetworkConfigureWLANView(BaseView): self.dev = self.model.get_netdev_by_name(self.dev.name) except KeyError: # The interface is gone - self.controller.prev_view() - self.controller.prev_view() + self.controller.default() return self.inputs.contents = [ (obj, ('pack', None)) for obj in self._build_iface_inputs() ] @@ -156,7 +155,7 @@ class NetworkConfigureWLANView(BaseView): else: psk = None self.dev.set_ssid_psk(ssid, psk) - self.controller.prev_view() + self.controller.network_configure_interface(self.dev.name) - def cancel(self, sender): - self.controller.prev_view() + def cancel(self, sender=None): + self.controller.network_configure_interface(self.dev.name) diff --git a/subiquitycore/ui/views/network_default_route.py b/subiquitycore/ui/views/network_default_route.py index 5626c957..16f39878 100644 --- a/subiquitycore/ui/views/network_default_route.py +++ b/subiquitycore/ui/views/network_default_route.py @@ -139,7 +139,7 @@ class NetworkSetDefaultRouteView(BaseView): except ValueError: # FIXME: raise UX error message pass - self.controller.prev_view() + self.controller.default() - def cancel(self, button): - self.controller.prev_view() + def cancel(self, button=None): + self.controller.default() diff --git a/subiquitycore/view.py b/subiquitycore/view.py index cfe4e646..6a894c71 100644 --- a/subiquitycore/view.py +++ b/subiquitycore/view.py @@ -38,12 +38,15 @@ class BaseView(WidgetWrap): self._w = self.orig_w self.orig_w = None + def cancel(self): + pass + def keypress(self, size, key): if key in ['ctrl x']: self.controller.signal.emit_signal('control-x-quit') return None key = super().keypress(size, key) if key == 'esc': - self.controller.cancel() + self.cancel() return None return key From 387f2c7b763d17f40f9cd092f7906d208e22d69f Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Wed, 5 Apr 2017 15:12:22 +1200 Subject: [PATCH 11/13] stop trying to be clever handling escape in filesystem views --- subiquity/controllers/filesystem.py | 20 ++++++------------- subiquity/ui/views/filesystem/add_format.py | 9 +++++---- .../ui/views/filesystem/add_partition.py | 8 +++----- subiquity/ui/views/filesystem/disk_info.py | 2 +- .../ui/views/filesystem/disk_partition.py | 6 +++--- subiquity/ui/views/filesystem/filesystem.py | 2 +- subiquity/ui/views/installpath.py | 2 +- 7 files changed, 20 insertions(+), 29 deletions(-) diff --git a/subiquity/controllers/filesystem.py b/subiquity/controllers/filesystem.py index d4532a40..bd8adb86 100644 --- a/subiquity/controllers/filesystem.py +++ b/subiquity/controllers/filesystem.py @@ -16,7 +16,7 @@ import logging import os -from subiquitycore.controller import BaseController, view +from subiquitycore.controller import BaseController from subiquitycore.ui.dummy import DummyView from subiquitycore.ui.error import ErrorView @@ -46,7 +46,6 @@ class FilesystemController(BaseController): self.raid_model = RaidModel() self.model.probe() # probe before we complete - @view def default(self, reset=False): # FIXME: Is this the best way to zero out this list for a reset? if reset: @@ -107,7 +106,6 @@ class FilesystemController(BaseController): self.signal.emit_signal('next-screen') # Filesystem/Disk partition ----------------------------------------------- - @view def partition_disk(self, disk): log.debug("In disk partition view, using {} as the disk.".format(disk.path)) title = ("Partition, format, and mount {}".format(disk.path)) @@ -119,7 +117,6 @@ class FilesystemController(BaseController): self.ui.set_body(dp_view) - @view def add_disk_partition(self, disk): log.debug("Adding partition to {}".format(disk)) footer = ("Select whole disk, or partition, to format and mount.") @@ -160,9 +157,9 @@ class FilesystemController(BaseController): self.model.add_mount(fs, spec['mountpoint']) log.info("Successfully added partition") - self.prev_view() + self.partition_disk(disk) - def add_format_handler(self, volume, spec): + def add_format_handler(self, volume, spec, back): log.debug('add_format_handler') if spec['fstype'] is not None: fs = self.model.add_filesystem(volume, spec['fstype']) @@ -172,7 +169,7 @@ class FilesystemController(BaseController): if fs is None: raise Exception("{} is not formatted".format(volume.path)) self.model.add_mount(fs, spec['mountpoint']) - self.prev_view() + back() def connect_iscsi_disk(self, *args, **kwargs): # title = ("Disk and filesystem setup") @@ -193,7 +190,6 @@ class FilesystemController(BaseController): # self.signal)) self.ui.set_body(DummyView(self.signal)) - @view def create_volume_group(self, *args, **kwargs): title = ("Create Logical Volume Group (\"LVM2\") disk") footer = ("ENTER on a disk will show detailed " @@ -204,7 +200,6 @@ class FilesystemController(BaseController): self.ui.set_footer(footer) self.ui.set_body(LVMVolumeGroupView(self.model, self.signal)) - @view def create_raid(self, *args, **kwargs): title = ("Create software RAID (\"MD\") disk") footer = ("ENTER on a disk will show detailed " @@ -218,7 +213,6 @@ class FilesystemController(BaseController): self.ui.set_body(RaidView(self.model, self.signal)) - @view def create_bcache(self, *args, **kwargs): title = ("Create hierarchical storage (\"bcache\") disk") footer = ("ENTER on a disk will show detailed " @@ -236,17 +230,15 @@ class FilesystemController(BaseController): self.model.add_raid_device(result) self.signal.prev_signal() - @view def format_entire(self, disk): log.debug("format_entire {}".format(disk)) header = ("Format and/or mount {}".format(disk.path)) footer = ("Format or mount whole disk.") self.ui.set_header(header) self.ui.set_footer(footer) - afv_view = AddFormatView(self.model, self, disk) + afv_view = AddFormatView(self.model, self, disk, lambda : self.partition_disk(disk)) self.ui.set_body(afv_view) - @view def format_mount_partition(self, partition): log.debug("format_entire {}".format(partition)) if partition.fs() is not None: @@ -257,7 +249,7 @@ class FilesystemController(BaseController): footer = ("Format and mount partition.") self.ui.set_header(header) self.ui.set_footer(footer) - afv_view = AddFormatView(self.model, self, partition) + afv_view = AddFormatView(self.model, self, partition, self.default) self.ui.set_body(afv_view) def show_disk_information_next(self, disk): diff --git a/subiquity/ui/views/filesystem/add_format.py b/subiquity/ui/views/filesystem/add_format.py index bb159905..99972b27 100644 --- a/subiquity/ui/views/filesystem/add_format.py +++ b/subiquity/ui/views/filesystem/add_format.py @@ -46,10 +46,11 @@ class AddFormatForm(Form): class AddFormatView(BaseView): - def __init__(self, model, controller, volume): + def __init__(self, model, controller, volume, back): self.model = model self.controller = controller self.volume = volume + self.back = back self.form = AddFormatForm(model) if self.volume.fs() is not None: @@ -71,8 +72,8 @@ class AddFormatView(BaseView): format_box = Padding.center_50(ListBox(body)) super().__init__(format_box) - def cancel(self, button): - self.controller.prev_view() + def cancel(self, button=None): + self.back() def done(self, result): """ format spec @@ -97,4 +98,4 @@ class AddFormatView(BaseView): result['fstype'] = None log.debug("Add Format Result: {}".format(result)) - self.controller.add_format_handler(self.volume, result) + self.controller.add_format_handler(self.volume, result, self.back) diff --git a/subiquity/ui/views/filesystem/add_partition.py b/subiquity/ui/views/filesystem/add_partition.py index 26d188c8..a9476661 100644 --- a/subiquity/ui/views/filesystem/add_partition.py +++ b/subiquity/ui/views/filesystem/add_partition.py @@ -20,11 +20,9 @@ configuration. """ import logging -import os -import re from urwid import connect_signal, Text -from subiquitycore.ui.container import Columns, ListBox +from subiquitycore.ui.container import ListBox from subiquitycore.ui.form import ( Form, FormField, @@ -114,8 +112,8 @@ class AddPartitionView(BaseView): partition_box = Padding.center_50(ListBox(body)) super().__init__(partition_box) - def cancel(self, button): - self.controller.prev_view() + def cancel(self, button=None): + self.controller.partition_disk(self.disk) def done(self, result): diff --git a/subiquity/ui/views/filesystem/disk_info.py b/subiquity/ui/views/filesystem/disk_info.py index 82e78cfd..56411a9b 100644 --- a/subiquity/ui/views/filesystem/disk_info.py +++ b/subiquity/ui/views/filesystem/disk_info.py @@ -63,5 +63,5 @@ class DiskInfoView(BaseView): ''' Return to FilesystemView ''' self.controller.partition_disk(self.disk) - def cancel(self, button): + def cancel(self, button=None): self.controller.partition_disk(self.disk) diff --git a/subiquity/ui/views/filesystem/disk_partition.py b/subiquity/ui/views/filesystem/disk_partition.py index 7a24ac57..85b04d1d 100644 --- a/subiquity/ui/views/filesystem/disk_partition.py +++ b/subiquity/ui/views/filesystem/disk_partition.py @@ -150,7 +150,7 @@ class DiskPartitionView(BaseView): def done(self, result): ''' Return to FilesystemView ''' - self.controller.prev_view() + self.controller.default() - def cancel(self, button): - self.controller.prev_view() + def cancel(self, button=None): + self.controller.default() diff --git a/subiquity/ui/views/filesystem/filesystem.py b/subiquity/ui/views/filesystem/filesystem.py index 0f4d499d..255b30c6 100644 --- a/subiquity/ui/views/filesystem/filesystem.py +++ b/subiquity/ui/views/filesystem/filesystem.py @@ -203,7 +203,7 @@ class FilesystemView(BaseView): user_data=sig))) return Pile(opts) - def cancel(self, button): + def cancel(self, button=None): self.controller.cancel() def reset(self, button): diff --git a/subiquity/ui/views/installpath.py b/subiquity/ui/views/installpath.py index f9c356e2..1aa3af84 100644 --- a/subiquity/ui/views/installpath.py +++ b/subiquity/ui/views/installpath.py @@ -63,5 +63,5 @@ class InstallpathView(BaseView): def confirm(self, result, sig): self.signal.emit_signal(sig) - def cancel(self, button): + def cancel(self, button=None): self.signal.emit_signal('prev-screen') From b3241d6b154d0a5f22d9ec0667847f071f32f099 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Wed, 5 Apr 2017 15:16:30 +1200 Subject: [PATCH 12/13] remove general clever escape handling --- subiquity/controllers/filesystem.py | 1 - subiquity/ui/views/identity.py | 6 +----- subiquitycore/controller.py | 14 -------------- 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/subiquity/controllers/filesystem.py b/subiquity/controllers/filesystem.py index bd8adb86..9b58eb14 100644 --- a/subiquity/controllers/filesystem.py +++ b/subiquity/controllers/filesystem.py @@ -61,7 +61,6 @@ class FilesystemController(BaseController): def reset(self): log.info("Resetting Filesystem model") self.model.reset() - self.view_stack = [] self.default() def cancel(self): diff --git a/subiquity/ui/views/identity.py b/subiquity/ui/views/identity.py index 59a4e648..73ddb439 100644 --- a/subiquity/ui/views/identity.py +++ b/subiquity/ui/views/identity.py @@ -102,14 +102,13 @@ class IdentityView(BaseView): self.form = IdentityForm() connect_signal(self.form, 'submit', self.done) - connect_signal(self.form, 'cancel', self.cancel) self.ssh_import_confirmed = True body = [ Padding.center_90(self.form.as_rows(self)), Padding.line_break(""), - Padding.fixed_10(self.form.buttons), + Padding.fixed_10(self.form.buttons[0]), ] super().__init__(ListBox(body)) @@ -136,6 +135,3 @@ class IdentityView(BaseView): log.debug("User input: {}".format(result)) self.controller.create_user(result) - - def cancel(self, button): - self.controller.cancel() diff --git a/subiquitycore/controller.py b/subiquitycore/controller.py index 743eb449..8faf97c6 100644 --- a/subiquitycore/controller.py +++ b/subiquitycore/controller.py @@ -20,14 +20,6 @@ import os log = logging.getLogger("subiquitycore.controller") -def view(func): - n = func.__name__ - def f(self, *args, **kw): - m = getattr(self, n) - self.view_stack.append((m, args, kw)) - return func(self, *args, **kw) - return f - class BaseController(ABC): """Base class for controllers.""" @@ -42,7 +34,6 @@ class BaseController(ABC): self.prober = common['prober'] self.controllers = common['controllers'] self.pool = common['pool'] - self.view_stack = [] def register_signals(self): """Defines signals associated with controller from model.""" @@ -51,11 +42,6 @@ class BaseController(ABC): signals.append((sig, getattr(self, cb))) self.signal.connect_signals(signals) - def prev_view(self): - self.view_stack.pop() - meth, args, kw = self.view_stack.pop() - meth(*args, **kw) - def run_in_bg(self, func, callback): """Run func() in a thread and call callback on UI thread. From 9afd3cbc5a7ab5c60d011ea5dc4320c832bf1d43 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Wed, 5 Apr 2017 15:19:01 +1200 Subject: [PATCH 13/13] have escape always remove an overlay view --- subiquitycore/ui/interactive.py | 5 ----- .../ui/views/network_configure_wlan_interface.py | 7 ------- subiquitycore/view.py | 13 +++++++++++-- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/subiquitycore/ui/interactive.py b/subiquitycore/ui/interactive.py index 049281c4..7144507d 100644 --- a/subiquitycore/ui/interactive.py +++ b/subiquitycore/ui/interactive.py @@ -243,11 +243,6 @@ class _HelpDisplay(WidgetWrap): self._closer = closer button = Color.button(PlainButton(label="Close", on_press=lambda btn:self._closer())) super().__init__(LineBox(Pile([Text(help_text), Padding.fixed_10(button)]), title="Help")) - def keypress(self, size, key): - if key == 'esc': - self._closer() - else: - return super().keypress(size, key) class Help(WidgetWrap): diff --git a/subiquitycore/ui/views/network_configure_wlan_interface.py b/subiquitycore/ui/views/network_configure_wlan_interface.py index 2eb4207f..e0cdf3fc 100644 --- a/subiquitycore/ui/views/network_configure_wlan_interface.py +++ b/subiquitycore/ui/views/network_configure_wlan_interface.py @@ -82,13 +82,6 @@ class NetworkConfigureWLANView(BaseView): self.orig_w = None super().__init__(ListBox(self.body)) - def keypress(self, size, key): - if key == 'esc': - if self.orig_w is not None: - self.remove_overlay() - return - return super().keypress(size, key) - def show_ssid_list(self, sender): self.show_overlay(NetworkList(self, self.dev.actual_ssids)) diff --git a/subiquitycore/view.py b/subiquitycore/view.py index 6a894c71..7563da52 100644 --- a/subiquitycore/view.py +++ b/subiquitycore/view.py @@ -22,6 +22,11 @@ from urwid import Overlay, WidgetWrap class BaseView(WidgetWrap): + + def __init__(self, w): + self.orig_w = None + super().__init__(w) + def show_overlay(self, overlay_widget, **kw): self.orig_w = self._w args = dict( @@ -47,6 +52,10 @@ class BaseView(WidgetWrap): return None key = super().keypress(size, key) if key == 'esc': - self.cancel() - return None + if self.orig_w is not None: + self.remove_overlay() + return None + else: + self.cancel() + return None return key