From 40e4046633d857929b8fd1bfa121b38937add81c Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 4 Oct 2022 01:37:57 +1100 Subject: Exclude archiso devices from selectable blockdevices (#1481) * Exclude liveusb from disk selection * Exclude arch iso from being an option * Update * Update * Update * Mypy Co-authored-by: Daniel Girtler --- archinstall/lib/disk/diskinfo.py | 40 +++++++++++++++++++++++++ archinstall/lib/disk/helpers.py | 27 +++++++++++++---- archinstall/lib/menu/global_menu.py | 2 +- archinstall/lib/user_interaction/system_conf.py | 7 +---- 4 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 archinstall/lib/disk/diskinfo.py (limited to 'archinstall/lib') diff --git a/archinstall/lib/disk/diskinfo.py b/archinstall/lib/disk/diskinfo.py new file mode 100644 index 00000000..b56ba282 --- /dev/null +++ b/archinstall/lib/disk/diskinfo.py @@ -0,0 +1,40 @@ +import dataclasses +import json +from dataclasses import dataclass, field +from typing import Optional, List + +from ..general import SysCommand +from ..exceptions import DiskError + +@dataclass +class LsblkInfo: + size: int = 0 + log_sec: int = 0 + pttype: Optional[str] = None + rota: bool = False + tran: Optional[str] = None + ptuuid: Optional[str] = None + partuuid: Optional[str] = None + uuid: Optional[str] = None + fstype: Optional[str] = None + type: Optional[str] = None + mountpoints: List[str] = field(default_factory=list) + + +def get_lsblk_info(dev_path: str) -> LsblkInfo: + fields = [f.name for f in dataclasses.fields(LsblkInfo)] + lsblk_fields = ','.join([f.upper().replace('_', '-') for f in fields]) + + output = SysCommand(f'lsblk --json -b -o+{lsblk_fields} {dev_path}').decode('UTF-8') + + if output: + block_devices = json.loads(output) + info = block_devices['blockdevices'][0] + lsblk_info = LsblkInfo() + + for f in fields: + setattr(lsblk_info, f, info[f.replace('_', '-')]) + + return lsblk_info + + raise DiskError(f'Failed to read disk "{dev_path}" with lsblk') diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index f19125f4..256f7abb 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -6,13 +6,12 @@ import pathlib import re import time import glob + from typing import Union, List, Iterator, Dict, Optional, Any, TYPE_CHECKING # https://stackoverflow.com/a/39757388/929999 +from .diskinfo import get_lsblk_info from ..models.subvolume import Subvolume -if TYPE_CHECKING: - from .partition import Partition - from .blockdevice import BlockDevice from .dmcryptdev import DMCryptDev from .mapperdev import MapperDev @@ -21,6 +20,10 @@ from ..general import SysCommand from ..output import log from ..storage import storage +if TYPE_CHECKING: + from .partition import Partition + + ROOT_DIR_PATTERN = re.compile('^.*?/devices') GIGA = 2 ** 30 @@ -204,11 +207,18 @@ def get_blockdevice_uevent(dev_name :str) -> Dict[str, Any]: } } + def all_disks() -> List[BlockDevice]: log(f"[Deprecated] archinstall.all_disks() is deprecated. Use archinstall.all_blockdevices() with the appropriate filters instead.", level=logging.WARNING, fg="yellow") return all_blockdevices(partitions=False, mappers=False) -def all_blockdevices(mappers=False, partitions=False, error=False) -> Dict[str, Any]: + +def all_blockdevices( + mappers: bool = False, + partitions: bool = False, + error: bool = False, + exclude_iso_dev: bool = True +) -> Dict[str, Any]: """ Returns BlockDevice() and Partition() objects for all available devices. """ @@ -227,6 +237,13 @@ def all_blockdevices(mappers=False, partitions=False, error=False) -> Dict[str, continue try: + if exclude_iso_dev: + # exclude all devices associated with the iso boot locations + iso_devs = ['/run/archiso/airootfs', '/run/archiso/bootmnt'] + lsblk_info = get_lsblk_info(device_path) + if any([dev in lsblk_info.mountpoints for dev in iso_devs]): + continue + information = blkid(f'blkid -p -o export {device_path}') except SysCallError as ex: if ex.exit_code in (512, 2): @@ -416,7 +433,7 @@ def get_partitions_in_use(mountpoint :str) -> Dict[str, Any]: # Since all_blockdevices() returns PosixPath objects, we need to convert # findmnt paths to pathlib.Path() first: mountpoint = pathlib.Path(mountpoint) - + if mountpoint in block_devices_mountpoints: if mountpoint not in mounts: mounts[mountpoint] = block_devices_mountpoints[mountpoint] diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index d1bec189..444ba7ee 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -341,7 +341,7 @@ class GlobalMenu(GeneralMenu): return ntp - def _select_harddrives(self, old_harddrives : list) -> List: + def _select_harddrives(self, old_harddrives: List[str] = []) -> List: harddrives = select_harddrives(old_harddrives) if harddrives is not None: diff --git a/archinstall/lib/user_interaction/system_conf.py b/archinstall/lib/user_interaction/system_conf.py index 0416e91f..8b574b2c 100644 --- a/archinstall/lib/user_interaction/system_conf.py +++ b/archinstall/lib/user_interaction/system_conf.py @@ -52,11 +52,6 @@ def select_harddrives(preset: List[str] = []) -> List[str]: hard_drives = all_blockdevices(partitions=False).values() options = {f'{option}': option for option in hard_drives} - if preset: - preset_disks = {f'{option}': option for option in preset} - else: - preset_disks = {} - title = str(_('Select one or more hard drives to use and configure\n')) title += str(_('Any modifications to the existing setting will reset the disk layout!')) @@ -65,7 +60,7 @@ def select_harddrives(preset: List[str] = []) -> List[str]: selected_harddrive = Menu( title, list(options.keys()), - preset_values=list(preset_disks.keys()), + preset_values=preset, multi=True, raise_error_on_interrupt=True, raise_error_warning_msg=warning -- cgit v1.2.3-70-g09d2