From 2d371571783cde70554e3e4e272beab2546ffff9 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Mon, 2 May 2022 21:02:21 +1000 Subject: Fix 1091 and other minor fixes (#1103) * Fix 1091 * Update * flake8 * Only display btrfs options if there is a filesystem * Fix 1118 Co-authored-by: Daniel Girtler --- archinstall/lib/menu/list_manager.py | 35 ++++++++++------ archinstall/lib/user_interaction/disk_conf.py | 12 +++--- .../lib/user_interaction/manage_users_conf.py | 4 +- .../lib/user_interaction/partitioning_conf.py | 48 ++++++++++++++-------- .../lib/user_interaction/subvolume_config.py | 16 ++++---- 5 files changed, 71 insertions(+), 44 deletions(-) diff --git a/archinstall/lib/menu/list_manager.py b/archinstall/lib/menu/list_manager.py index 4e6dffbe..377d30f2 100644 --- a/archinstall/lib/menu/list_manager.py +++ b/archinstall/lib/menu/list_manager.py @@ -89,7 +89,7 @@ from .text_input import TextInput from .menu import Menu from os import system from copy import copy -from typing import Union, Any, List, TYPE_CHECKING +from typing import Union, Any, TYPE_CHECKING, Dict if TYPE_CHECKING: _: Any @@ -149,18 +149,26 @@ class ListManager: # default values for the null case self.target = None self.action = self._null_action + if len(self._data) == 0 and self._null_action: self.exec_action(self._data) def run(self): while True: - self._data_formatted = self.reformat(self._data) - options = self._data_formatted + [self.separator] + # this will return a dictionary with the key as the menu entry to be displayed + # and the value is the original value from the self._data container + data_formatted = self.reformat(self._data) + options = list(data_formatted.keys()) + options.append(self.separator) + if self._default_action: options += self._default_action + options += self.bottom_list + system('clear') - target = Menu(self._prompt, + target = Menu( + self._prompt, options, sort=False, clear_screen=False, @@ -171,19 +179,20 @@ class ListManager: if not target or target in self.bottom_list: self.action = target break - if target and target == self.separator: - continue + if target and target in self._default_action: self.action = target - target = None self.target = None self.exec_action(self._data) continue + if isinstance(self._data,dict): - key = list(self._data.keys())[self._data_formatted.index(target)] - self.target = {key: self._data[key]} + data_key = data_formatted[target] + key = self._data[data_key] + self.target = {data_key: key} else: - self.target = self._data[self._data_formatted.index(target)] + self.target = self._data[data_formatted[target]] + # Possible enhacement. If run_actions returns false a message line indicating the failure self.run_actions(target) @@ -211,15 +220,15 @@ class ListManager: The following methods are expected to be overwritten by the user if the needs of the list are beyond the simple case """ - def reformat(self, data: Any) -> List[Any]: + def reformat(self, data: Any) -> Dict[str, Any]: """ method to get the data in a format suitable to be shown It is executed once for run loop and processes the whole self._data structure """ if isinstance(data,dict): - return list(map(lambda x:f"{x} : {data[x]}",data)) + return {f'{k}: {v}': k for k, v in data.items()} else: - return list(map(lambda x:str(x),data)) + return {str(k): k for k in data} def action_list(self): """ diff --git a/archinstall/lib/user_interaction/disk_conf.py b/archinstall/lib/user_interaction/disk_conf.py index 9238a766..a51f10b8 100644 --- a/archinstall/lib/user_interaction/disk_conf.py +++ b/archinstall/lib/user_interaction/disk_conf.py @@ -41,13 +41,13 @@ def select_disk_layout(block_devices: list, advanced_options=False) -> Dict[str, custome_mode = str(_('Select what to do with each individual drive (followed by partition usage)')) modes = [wipe_mode, custome_mode] - print(modes) - mode = Menu(_('Select what you wish to do with the selected block devices'), modes, skip=False).run() + mode = Menu(_('Select what you wish to do with the selected block devices'), modes).run() - if mode == wipe_mode: - return get_default_partition_layout(block_devices, advanced_options) - else: - return select_individual_blockdevice_usage(block_devices) + if mode: + if mode == wipe_mode: + return get_default_partition_layout(block_devices, advanced_options) + else: + return select_individual_blockdevice_usage(block_devices) def select_disk(dict_o_disks: Dict[str, BlockDevice]) -> BlockDevice: diff --git a/archinstall/lib/user_interaction/manage_users_conf.py b/archinstall/lib/user_interaction/manage_users_conf.py index a6ff3111..d69ccce9 100644 --- a/archinstall/lib/user_interaction/manage_users_conf.py +++ b/archinstall/lib/user_interaction/manage_users_conf.py @@ -36,7 +36,7 @@ class UserList(ListManager): ] super().__init__(prompt, lusers, self.actions, self.actions[0]) - def reformat(self, data: Any) -> List[Any]: + def reformat(self, data: List) -> Dict: def format_element(elem :str): # secret gives away the length of the password if data[elem].get('!password'): @@ -49,7 +49,7 @@ class UserList(ListManager): super_user = ' ' return f"{elem:16}: password {pwd:16} {super_user}" - return list(map(lambda x: format_element(x), data)) + return {format_element(e): e for e in data} def action_list(self): if self.target: diff --git a/archinstall/lib/user_interaction/partitioning_conf.py b/archinstall/lib/user_interaction/partitioning_conf.py index db52d447..2182c6b3 100644 --- a/archinstall/lib/user_interaction/partitioning_conf.py +++ b/archinstall/lib/user_interaction/partitioning_conf.py @@ -65,21 +65,26 @@ def _current_partition_layout(partitions: List[Partition], with_idx: bool = Fals return f'\n\n{title}:\n\n{current_layout}' -def select_partition(title :str, partitions :List[Partition], multiple :bool = False, filter :Callable = None) -> Union[int, List[int], None]: +def _get_partitions(partitions :List[Partition], filter_ :Callable = None) -> List[str]: """ filter allows to filter out the indexes once they are set. Should return True if element is to be included """ partition_indexes = [] for i in range(len(partitions)): - if filter: - if filter(partitions[i]): + if filter_: + if filter_(partitions[i]): partition_indexes.append(str(i)) else: partition_indexes.append(str(i)) + + return partition_indexes + + +def select_partition(title :str, partitions :List[Partition], multiple :bool = False, filter_ :Callable = None) -> Union[int, List[int], None]: + partition_indexes = _get_partitions(partitions, filter_) + if len(partition_indexes) == 0: return None - # old code without filter - # partition_indexes = list(map(str, range(len(partitions)))) partition = Menu(title, partition_indexes, multi=multiple).run() @@ -133,7 +138,7 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, while True: modes = [new_partition, suggest_partition_layout] - if len(block_device_struct['partitions']): + if len(block_device_struct['partitions']) > 0: modes += [ delete_partition, delete_all_partitions, @@ -143,9 +148,16 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, mark_bootable, mark_compressed, set_filesystem_partition, - set_btrfs_subvolumes, ] + indexes = _get_partitions( + block_device_struct["partitions"], + filter_=lambda x: True if x.get('filesystem', {}).get('format') == 'btrfs' else False + ) + + if len(indexes) > 0: + modes += [set_btrfs_subvolumes] + title = _('Select what to do with\n{}').format(block_device) # show current partition layout: @@ -165,7 +177,10 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, # # https://www.gnu.org/software/parted/manual/html_node/mklabel.html # name = input("Enter a desired name for the partition: ").strip() - fstype = Menu(_('Enter a desired filesystem type for the partition'), fs_types(), skip=False).run() + fstype = Menu(_('Enter a desired filesystem type for the partition'), fs_types()).run() + + if not fstype: + continue prompt = _('Enter the start sector (percentage or block number, default: {}): ').format( block_device.first_free_sector) @@ -273,14 +288,13 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, if not block_device_struct["partitions"][partition].get('filesystem', None): block_device_struct["partitions"][partition]['filesystem'] = {} - fstype = Menu(_('Enter a desired filesystem type for the partition'), fs_types(), - skip=False).run() + fstype = Menu(_('Enter a desired filesystem type for the partition'), fs_types()).run() - block_device_struct["partitions"][partition]['filesystem']['format'] = fstype + if fstype: + block_device_struct["partitions"][partition]['filesystem']['format'] = fstype # Negate the current wipe marking - block_device_struct["partitions"][partition][ - 'wipe'] = not block_device_struct["partitions"][partition].get('wipe', False) + block_device_struct["partitions"][partition]['wipe'] = not block_device_struct["partitions"][partition].get('wipe', False) elif task == mark_encrypted: title = _('{}\n\nSelect which partition to mark as encrypted').format(current_layout) @@ -308,16 +322,18 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str, block_device_struct["partitions"][partition]['filesystem'] = {} fstype_title = _('Enter a desired filesystem type for the partition: ') - fstype = Menu(fstype_title, fs_types(), skip=False).run() + fstype = Menu(fstype_title, fs_types()).run() - block_device_struct["partitions"][partition]['filesystem']['format'] = fstype + if fstype: + block_device_struct["partitions"][partition]['filesystem']['format'] = fstype elif task == set_btrfs_subvolumes: from .subvolume_config import SubvolumeList # TODO get preexisting partitions title = _('{}\n\nSelect which partition to set subvolumes on').format(current_layout) - partition = select_partition(title, block_device_struct["partitions"],filter=lambda x:True if x.get('filesystem',{}).get('format') == 'btrfs' else False) + partition = select_partition(title, block_device_struct["partitions"],filter_=lambda x:True if x.get('filesystem',{}).get('format') == 'btrfs' else False) + if partition is not None: if not block_device_struct["partitions"][partition].get('btrfs', {}): block_device_struct["partitions"][partition]['btrfs'] = {} diff --git a/archinstall/lib/user_interaction/subvolume_config.py b/archinstall/lib/user_interaction/subvolume_config.py index 0515876b..adbb7430 100644 --- a/archinstall/lib/user_interaction/subvolume_config.py +++ b/archinstall/lib/user_interaction/subvolume_config.py @@ -1,9 +1,10 @@ -from typing import List, Any, Dict +from typing import Any, Dict from ..menu.list_manager import ListManager from ..menu.selection_menu import Selector, GeneralMenu from ..menu.text_input import TextInput from ..menu import Menu + """ UI classes """ @@ -14,7 +15,7 @@ class SubvolumeList(ListManager): self.ObjectDefaultAction = str(_('Add')) super().__init__(prompt,list,None,self.ObjectNullAction,self.ObjectDefaultAction) - def reformat(self, data: Any) -> List[Any]: + def reformat(self, data: Dict) -> Dict: def presentation(key :str, value :Dict): text = _(" Subvolume :{:16}").format(key) if isinstance(value,str): @@ -28,14 +29,15 @@ class SubvolumeList(ListManager): text += _(" with option {}").format(', '.join(value['options'])) return text - return sorted(list(map(lambda x:presentation(x,data[x]),data))) + formatted = {presentation(k, v): k for k, v in data.items()} + return {k: v for k, v in sorted(formatted.items(), key=lambda e: e[0])} def action_list(self): return super().action_list() - def exec_action(self, data: Any): + def exec_action(self, data: Dict): if self.target: - origkey,origval = list(self.target.items())[0] + origkey, origval = list(self.target.items())[0] else: origkey = None @@ -46,8 +48,8 @@ class SubvolumeList(ListManager): self.target = {} print(_('\n Fill the desired values for a new subvolume \n')) with SubvolumeMenu(self.target,self.action) as add_menu: - for data in ['name','mountpoint','options']: - add_menu.exec_option(data) + for elem in ['name','mountpoint','options']: + add_menu.exec_option(elem) else: SubvolumeMenu(self.target,self.action).run() -- cgit v1.2.3-70-g09d2