Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/lib/disk/btrfs.py
diff options
context:
space:
mode:
Diffstat (limited to 'archinstall/lib/disk/btrfs.py')
-rw-r--r--archinstall/lib/disk/btrfs.py56
1 files changed, 48 insertions, 8 deletions
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)