index : archinstall32 | |
Archlinux32 installer | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | archinstall/lib/disk/btrfs.py | 56 |
diff --git a/archinstall/lib/disk/btrfs.py b/archinstall/lib/disk/btrfs.py index ad8d0a52..f2da957f 100644 --- a/archinstall/lib/disk/btrfs.py +++ b/archinstall/lib/disk/btrfs.py @@ -2,7 +2,9 @@ from __future__ import annotations import pathlib import glob import logging -from typing import Union, Dict, TYPE_CHECKING +import re +from typing import Union, Dict, TYPE_CHECKING, Any, Iterator +from dataclasses import dataclass # https://stackoverflow.com/a/39757388/929999 if TYPE_CHECKING: @@ -11,7 +13,49 @@ from .helpers import get_mount_info from ..exceptions import DiskError from ..general import SysCommand from ..output import log - +from ..exceptions import SysCallError + +@dataclass +class BtrfsSubvolume: + target :str + source :str + fstype :str + name :str + options :str + root :bool = False + +def get_subvolumes_from_findmnt(struct :Dict[str, Any], index=0) -> Iterator[BtrfsSubvolume]: + if '@' in struct['source']: + subvolume = re.findall(r'\[.*?\]', struct['source'])[0][1:-1] + struct['source'] = struct['source'].replace(f"[{subvolume}]", "") + yield BtrfsSubvolume( + target=struct['target'], + source=struct['source'], + fstype=struct['fstype'], + name=subvolume, + options=struct['options'], + root=index == 0 + ) + index += 1 + + for child in struct.get('children', []): + for item in get_subvolumes_from_findmnt(child, index=index): + yield item + index += 1 + +def get_subvolume_info(path :pathlib.Path) -> Dict[str, Any]: + try: + output = SysCommand(f"btrfs subvol show {path}").decode() + except SysCallError as error: + print('Error:', error) + + result = {} + for line in output.replace('\r\n', '\n').split('\n'): + if ':' in line: + key, val = line.replace('\t', '').split(':', 1) + result[key.strip().lower().replace(' ', '_')] = val.strip() + + return result def mount_subvolume(installation :Installer, subvolume_location :Union[pathlib.Path, str], force=False) -> bool: """ @@ -24,7 +68,7 @@ def mount_subvolume(installation :Installer, subvolume_location :Union[pathlib.P This function is DEPRECATED. you can get the same result creating a partition dict like any other partition, and using the standard mount procedure. Only change partition['device_instance'].path with the apropriate bind name: real_partition_path[/subvolume_name] """ - log("function btrfs.mount_subvolume DEPRECATED. See code for alternatives",fg="yellow",level=logging.WARNING) + log("[Deprecated] function btrfs.mount_subvolume is deprecated. See code for alternatives",fg="yellow",level=logging.WARNING) installation_mountpoint = installation.target if type(installation_mountpoint) == str: installation_mountpoint = pathlib.Path(installation_mountpoint) @@ -179,11 +223,7 @@ def manage_btrfs_subvolumes(installation :Installer, # As the rest will query there the path of the "partition" to be mounted, we feed it with the bind name needed to mount subvolumes # As we made a deepcopy we have a fresh instance of this object we can manipulate problemless fake_partition['device_instance'].path = f"{partition['device_instance'].path}[/{name}]" - # we reset this attribute, which holds where the partition is actually mounted. Remember, the physical partition is mounted at this moment and therefore has the value '/'. - # If i don't reset it, process will abort as "already mounted' . - # TODO It works for this purpose, but the fact that this bevahiour can happed, should make think twice - fake_partition['device_instance'].mountpoint = None - # + # Well, now that this "fake partition" is ready, we add it to the list of the ones which are to be mounted, # as "normal" ones mountpoints.append(fake_partition) |