index : archinstall32 | |
Archlinux32 installer | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | archinstall/lib/disk/mapperdev.py | 83 |
diff --git a/archinstall/lib/disk/mapperdev.py b/archinstall/lib/disk/mapperdev.py new file mode 100644 index 00000000..91ec6d25 --- /dev/null +++ b/archinstall/lib/disk/mapperdev.py @@ -0,0 +1,83 @@ +import glob +import pathlib +import logging +import json +from dataclasses import dataclass +from typing import Optional, List, Dict, Any, Iterator, TYPE_CHECKING + +from ..exceptions import SysCallError +from ..general import SysCommand +from ..output import log + +if TYPE_CHECKING: + from .btrfs import BtrfsSubvolume + +@dataclass +class MapperDev: + mappername :str + + @property + def name(self): + return self.mappername + + @property + def path(self): + return f"/dev/mapper/{self.mappername}" + + @property + def partition(self): + from .helpers import uevent, get_parent_of_partition + from .partition import Partition + from .blockdevice import BlockDevice + + for mapper in glob.glob('/dev/mapper/*'): + path_obj = pathlib.Path(mapper) + if path_obj.name == self.mappername and pathlib.Path(mapper).is_symlink(): + dm_device = (pathlib.Path("/dev/mapper/") / path_obj.readlink()).resolve() + + for slave in glob.glob(f"/sys/class/block/{dm_device.name}/slaves/*"): + partition_belonging_to_dmcrypt_device = pathlib.Path(slave).name + + try: + uevent_data = SysCommand(f"blkid -o export /dev/{partition_belonging_to_dmcrypt_device}").decode() + except SysCallError as error: + log(f"Could not get information on device /dev/{partition_belonging_to_dmcrypt_device}: {error}", level=logging.ERROR, fg="red") + + information = uevent(uevent_data) + block_device = BlockDevice(get_parent_of_partition('/dev/' / pathlib.Path(information['DEVNAME']))) + + return Partition(information['DEVNAME'], block_device) + + raise ValueError(f"Could not convert {self.mappername} to a real dm-crypt device") + + @property + def mountpoint(self) -> Optional[str]: + try: + data = json.loads(SysCommand(f"findmnt --json -R {self.path}").decode()) + for filesystem in data['filesystems']: + return filesystem.get('target') + + except SysCallError as error: + # Not mounted anywhere most likely + log(f"Could not locate mount information for {self.path}: {error}", level=logging.WARNING, fg="yellow") + pass + + return None + + @property + def mount_information(self) -> List[Dict[str, Any]]: + from .helpers import find_mountpoint + return list(find_mountpoint(self.path)) + + @property + def filesystem(self) -> Optional[str]: + from .helpers import get_filesystem_type + return get_filesystem_type(self.path) + + @property + def subvolumes(self) -> Iterator['BtrfsSubvolume']: + from .btrfs import get_subvolumes_from_findmnt + + for mountpoint in self.mount_information: + for result in get_subvolumes_from_findmnt(mountpoint): + yield result
\ No newline at end of file |