Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/lib/disk.py
diff options
context:
space:
mode:
Diffstat (limited to 'archinstall/lib/disk.py')
-rw-r--r--archinstall/lib/disk.py80
1 files changed, 57 insertions, 23 deletions
diff --git a/archinstall/lib/disk.py b/archinstall/lib/disk.py
index 4ea9f214..67c2bdcd 100644
--- a/archinstall/lib/disk.py
+++ b/archinstall/lib/disk.py
@@ -25,11 +25,12 @@ class BlockDevice():
self.path = path
self.info = info
+ self.keep_partitions = True
self.part_cache = OrderedDict()
- # TODO: Currently disk encryption is a BIT missleading.
+ # TODO: Currently disk encryption is a BIT misleading.
# It's actually partition-encryption, but for future-proofing this
# I'm placing the encryption password on a BlockDevice level.
- self.encryption_passwoed = None
+ self.encryption_password = None
def __repr__(self, *args, **kwargs):
return f"BlockDevice({self.device})"
@@ -126,6 +127,18 @@ class BlockDevice():
def partition_table_type(self):
return GPT
+ @property
+ def uuid(self):
+ log(f'BlockDevice().uuid is untested!', level=LOG_LEVELS.Warning, fg='yellow')
+ """
+ Returns the disk UUID as returned by lsblk.
+ This is more reliable than relying on /dev/disk/by-partuuid as
+ it doesn't seam to be able to detect md raid partitions.
+ """
+ lsblk = b''.join(sys_command(f'lsblk -J -o+UUID {self.path}'))
+ for partition in json.loads(lsblk.decode('UTF-8'))['blockdevices']:
+ return partition.get('uuid', None)
+
def has_partitions(self):
return len(self.partitions)
@@ -166,7 +179,7 @@ class Partition():
self.mountpoint = target
if not self.filesystem and autodetect_filesystem:
- if (fstype := mount_information.get('fstype', get_filesystem_type(self.real_device))):
+ if (fstype := mount_information.get('fstype', get_filesystem_type(path))):
self.filesystem = fstype
if self.filesystem == 'crypto_LUKS':
@@ -187,9 +200,9 @@ class Partition():
mount_repr = f", rel_mountpoint={self.target_mountpoint}"
if self._encrypted:
- return f'Partition(path={self.path}, real_device={self.real_device}, fs={self.filesystem}{mount_repr})'
+ return f'Partition(path={self.path}, size={self.size}, real_device={self.real_device}, fs={self.filesystem}{mount_repr})'
else:
- return f'Partition(path={self.path}, fs={self.filesystem}{mount_repr})'
+ return f'Partition(path={self.path}, size={self.size}, fs={self.filesystem}{mount_repr})'
@property
def uuid(self) -> str:
@@ -215,13 +228,14 @@ class Partition():
self._encrypted = value
@property
+ def parent(self):
+ return self.real_device
+
+ @property
def real_device(self):
- if not self._encrypted:
- return self.path
- else:
- for blockdevice in json.loads(b''.join(sys_command(['lsblk', '-J'])).decode('UTF-8'))['blockdevices']:
- if (parent := self.find_parent_of(blockdevice, os.path.basename(self.path))):
- return f"/dev/{parent}"
+ for blockdevice in json.loads(b''.join(sys_command('lsblk -J')).decode('UTF-8'))['blockdevices']:
+ if (parent := self.find_parent_of(blockdevice, os.path.basename(self.path))):
+ return f"/dev/{parent}"
# raise DiskError(f'Could not find appropriate parent for encrypted partition {self}')
return self.path
@@ -285,10 +299,10 @@ class Partition():
handle = luks2(self, None, None)
return handle.encrypt(self, *args, **kwargs)
- def format(self, filesystem=None, path=None, allow_formatting=None, log_formating=True):
+ def format(self, filesystem=None, path=None, allow_formatting=None, log_formatting=True):
"""
Format can be given an overriding path, for instance /dev/null to test
- the formating functionality and in essence the support for the given filesystem.
+ the formatting functionality and in essence the support for the given filesystem.
"""
if filesystem is None:
filesystem = self.filesystem
@@ -306,7 +320,7 @@ class Partition():
if not allow_formatting:
raise PermissionError(f"{self} is not formatable either because instance is locked ({self.allow_formatting}) or a blocking flag was given ({allow_formatting})")
- if log_formating:
+ if log_formatting:
log(f'Formatting {path} -> {filesystem}', level=LOG_LEVELS.Info)
if filesystem == 'btrfs':
@@ -366,14 +380,16 @@ class Partition():
if not fs:
if not self.filesystem: raise DiskError(f'Need to format (or define) the filesystem on {self} before mounting.')
fs = self.filesystem
- ## libc has some issues with loop devices, defaulting back to sys calls
- # ret = libc.mount(self.path.encode(), target.encode(), fs.encode(), 0, options.encode())
- # if ret < 0:
- # errno = ctypes.get_errno()
- # raise OSError(errno, f"Error mounting {self.path} ({fs}) on {target} with options '{options}': {os.strerror(errno)}")
- if sys_command(f'/usr/bin/mount {self.path} {target}').exit_code == 0:
- self.mountpoint = target
- return True
+
+ pathlib.Path(target).mkdir(parents=True, exist_ok=True)
+
+ try:
+ sys_command(f'/usr/bin/mount {self.path} {target}')
+ except SysCallError as err:
+ raise err
+
+ self.mountpoint = target
+ return True
def unmount(self):
try:
@@ -401,7 +417,7 @@ class Partition():
2. UnknownFilesystemFormat that indicates that we don't support the given filesystem type
"""
try:
- self.format(self.filesystem, '/dev/null', log_formating=False, allow_formatting=True)
+ self.format(self.filesystem, '/dev/null', log_formatting=False, allow_formatting=True)
except SysCallError:
pass # We supported it, but /dev/null is not formatable as expected so the mkfs call exited with an error code
except UnknownFilesystemFormat as err:
@@ -588,6 +604,24 @@ def get_mount_info(path):
return output['filesystems'][0]
+def get_partitions_in_use(mountpoint):
+ try:
+ output = b''.join(sys_command(f'/usr/bin/findmnt --json -R {mountpoint}'))
+ except SysCallError:
+ return {}
+
+ mounts = []
+
+ output = output.decode('UTF-8')
+ output = json.loads(output)
+ for target in output.get('filesystems', []):
+ mounts.append(Partition(target['source'], None, filesystem=target.get('fstype', None), mountpoint=target['target']))
+
+ for child in target.get('children', []):
+ mounts.append(Partition(child['source'], None, filesystem=child.get('fstype', None), mountpoint=child['target']))
+
+ return mounts
+
def get_filesystem_type(path):
try:
handle = sys_command(f"blkid -o value -s TYPE {path}")