diff --git a/subiquity/controllers/filesystem.py b/subiquity/controllers/filesystem.py index b7a8e4d0..1f92ffe2 100644 --- a/subiquity/controllers/filesystem.py +++ b/subiquity/controllers/filesystem.py @@ -14,7 +14,8 @@ # along with this program. If not, see . from subiquity.views.filesystem import (FilesystemView, - DiskPartitionView) + DiskPartitionView, + AddPartitionView) from subiquity.models.filesystem import FilesystemModel from subiquity.curtin import curtin_write_storage_actions @@ -85,15 +86,34 @@ class FilesystemController: self.ui.set_header(title) self.ui.set_footer(footer) dp_view = DiskPartitionView(self.fs_model, - disk, - self.finish_disk_paritition_view) + disk) connect_signal(dp_view, 'fs:dp:done', self.finish_disk_paritition_view) + connect_signal(dp_view, 'fs:show-add-partition', + self.show_add_disk_partition_view) + self.ui.set_body(dp_view) return - def finish_disk_paritition_view(self, is_finish): - log.debug("Finish disk-p-v: {}".format(is_finish)) + def finish_disk_paritition_view(self, result): + log.debug("Finish disk-p-v: {}".format(result)) + return self.ui.exit() + + # ADD Partitioning actions + def show_add_disk_partition_view(self, disk): + adp_view = AddPartitionView(self.fs_model, + disk) + connect_signal(adp_view, + 'fs:add-partition:done', + self.finish_add_disk_paritition_view) + self.ui.set_body(adp_view) + return + + def finish_add_disk_partition_view(self, partition_spec): + if not partition_spec: + log.debug("New partition: {}".format(partition_spec)) + else: + log.debug("Empty partition spec, should go back one.") return self.ui.exit() diff --git a/subiquity/models/filesystem.py b/subiquity/models/filesystem.py index 6e5f10a6..14767d2d 100644 --- a/subiquity/models/filesystem.py +++ b/subiquity/models/filesystem.py @@ -47,6 +47,16 @@ class FilesystemModel(models.Model): 'Format or create swap on entire device (unusual, advanced)' ] + supported_filesystems = [ + 'ext4', + 'xfs', + 'btrfs', + 'swap', + 'bcache cache', + 'bcache store', + 'leave unformatted' + ] + def __init__(self): self.storage = {} self.info = {} diff --git a/subiquity/views/filesystem.py b/subiquity/views/filesystem.py index 493c8308..3959301b 100644 --- a/subiquity/views/filesystem.py +++ b/subiquity/views/filesystem.py @@ -15,7 +15,8 @@ import logging import math -from urwid import (WidgetWrap, ListBox, Pile, BoxAdapter, Text, Columns) +from urwid import (WidgetWrap, ListBox, Pile, BoxAdapter, + Text, Columns, LineBox, Edit, RadioButton) from subiquity.ui.lists import SimpleList from subiquity.ui.buttons import done_btn, reset_btn, cancel_btn from subiquity.ui.utils import Padding, Color @@ -34,14 +35,87 @@ def _humanize_size(size): return "%.3f %s" % (size / math.pow(1024, p), units[int(p)]) +class AddPartitionView(WidgetWrap): + signals = [ + 'fs:add-partition:done', + 'fs:add-partition:cancel' + ] + + def __init__(self, model, selected_disk): + self.partition_spec = {} + self.model = model + body = ListBox([ + Padding.center_79( + Text("Adding partition to {}".format(selected_disk))), + Padding.center_79(self._container()), + Padding.center_79(self._build_buttons()) + ]) + box = BoxAdapter(body, + len(body)) + super().__init__(LineBox(box)) + + def _build_buttons(self): + cancel = cancel_btn(on_press=self.cancel) + done = done_btn(on_press=self.done) + + buttons = [ + Color.button_secondary(cancel, focus_map='button_secondary focus'), + Color.button_secondary(done, focus_map='button_secondary focus') + ] + return Pile(buttons) + + def _partition_edit(self): + return Edit(caption="Partition number (1-4)", + edit_text="1") + + def _size_edit(self): + return Edit(caption="Size (max 2Tb)") + + def _format_edit(self): + group = [] + for fs in self.model.supported_filesystems: + RadioButton(group, fs) + return SimpleList(group) + + def _mount_point_edit(self): + return Edit(caption="Mount", edit_text="/") + + def _container(self): + total_items = [ + self._partition_edit(), + self._size_edit(), + self._format_edit(), + self._mount_point_edit() + ] + + return SimpleList(total_items) + + def cancel(self, button): + emit_signal(self, 'fs:add-partition:done', False) + + def done(self): + """ partition spec + + { 'partition_number': Int, + 'size': Int(M|G), + 'format' Str(ext4|btrfs.., + 'mount_point': Str + } + """ + if not self.partition_spec: + # TODO: Maybe popup warning? + return + emit_signal(self, 'fs:add-partition:done', self.partition_spec) + + class DiskPartitionView(WidgetWrap): signals = [ + 'fs:dp:show-add-partition', 'fs:dp:done', ] - def __init__(self, model, selected_disk, cb): + def __init__(self, model, selected_disk): self.model = model - self.cb = cb self.selected_disk = selected_disk self.body = [ Padding.center_79(self._build_model_inputs()), @@ -67,7 +141,7 @@ class DiskPartitionView(WidgetWrap): col_2 = [] disk = self.model.get_disk_info(self.selected_disk) - btn = done_btn(label="FREE SPACE", on_press=self.edit_paritition) + btn = done_btn(label="FREE SPACE", on_press=self.add_paritition) col_1.append(Color.button_primary(btn, focus_map='button_primary focus')) disk_sz = str(_humanize_size(disk.size)) @@ -88,8 +162,8 @@ class DiskPartitionView(WidgetWrap): focus_map='button_secondary focus')) return Pile(opts) - def edit_paritition(self, partition): - emit_signal(self, 'fs:dp:done', partition.label) + def add_partition(self, partition): + emit_signal(self, 'fs:dp:show-add-partition', True) def done(self, button): emit_signal(self, 'fs:dp:done', True)