Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/lib
diff options
context:
space:
mode:
authorAnton Hvornum <anton@hvornum.se>2021-02-11 14:11:21 +0100
committerAnton Hvornum <anton@hvornum.se>2021-02-11 14:11:21 +0100
commite2cd617d05d87bbe3fe8f1809faecd8c1ebd230e (patch)
treeb1ec5d90d9869bc4ee1e877e5b8be97333b40ec3 /archinstall/lib
parent03c46cce2b62b41c5b73f86dffb90eff6a1b8eb2 (diff)
Reworked the way partition formatting works. As well as added some flags to the partition if it's locked/unlocked for partitioning. By defaults partitions will now be in a locked state - prohibiting formatting unless set or overridden in the formatting call. This allows us to selectively format partitions individually later on. There's also a target_mountpoint that is the desired relative mount point inside a installation. This can be pre-pended with the installation base directory during mount. These changes also function as indicators for the installation (and guided installation) for which partitions to use and/or wipe. If an entire drive is selected for wiping, these changes will have no affect in the decision making as all partitions will be new and have formatable set to true.
Diffstat (limited to 'archinstall/lib')
-rw-r--r--archinstall/lib/disk.py63
-rw-r--r--archinstall/lib/exceptions.py2
-rw-r--r--archinstall/lib/luks.py7
3 files changed, 57 insertions, 15 deletions
diff --git a/archinstall/lib/disk.py b/archinstall/lib/disk.py
index 5cb95226..aa3632d8 100644
--- a/archinstall/lib/disk.py
+++ b/archinstall/lib/disk.py
@@ -125,35 +125,57 @@ class Partition():
self.path = path
self.part_id = part_id
self.mountpoint = mountpoint
+ self.target_mountpoint = mountpoint
self.filesystem = filesystem
self.size = size # TODO: Refresh?
self.encrypted = encrypted
+ self.allow_formatting = False # A fail-safe for unconfigured partitions, such as windows NTFS partitions.
if mountpoint:
self.mount(mountpoint)
mount_information = get_mount_info(self.path)
- actual_fstype = get_filesystem_type(self.path) # blkid -o value -s TYPE self.path
+ fstype = get_filesystem_type(self.path) # blkid -o value -s TYPE self.path
if self.mountpoint != mount_information.get('target', None) and mountpoint:
raise DiskError(f"{self} was given a mountpoint but the actual mountpoint differs: {mount_information.get('target', None)}")
- if mount_information.get('fstype', None) != self.filesystem and filesystem:
- raise DiskError(f"{self} was given a filesystem format, but a existing format was detected: {mount_information.get('fstype', None)}")
if (target := mount_information.get('target', None)):
self.mountpoint = target
- if (fstype := mount_information.get('fstype', None)):
+ if (fstype := mount_information.get('fstype', fstype)):
self.filesystem = fstype
+ def __lt__(self, left_comparitor):
+ if type(left_comparitor) == Partition:
+ left_comparitor = left_comparitor.path
+ else:
+ left_comparitor = str(left_comparitor)
+ return self.path < left_comparitor # Not quite sure the order here is correct. But /dev/nvme0n1p1 comes before /dev/nvme0n1p5 so seems correct.
+
def __repr__(self, *args, **kwargs):
+ mount_repr = ''
+ if self.mountpoint:
+ mount_repr = f", mounted={self.mountpoint}"
+ elif self.target_mountpoint:
+ 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}, mounted={self.mountpoint})'
+ return f'Partition(path={self.path}, real_device={self.real_device}, fs={self.filesystem}{mount_repr})'
else:
- return f'Partition(path={self.path}, fs={self.filesystem}, mounted={self.mountpoint})'
+ return f'Partition(path={self.path}, fs={self.filesystem}{mount_repr})'
- def format(self, filesystem, path=None, log_formating=True):
- if not path:
+ def format(self, filesystem, path=None, allow_formatting=None, log_formating=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.
+ """
+ if path is None:
path = self.path
+ if allow_formatting is None:
+ allow_formatting = self.allow_formatting
+
+ 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:
log(f'Formatting {path} -> {filesystem}', level=LOG_LEVELS.Info)
@@ -173,13 +195,18 @@ class Partition():
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
self.filesystem = 'ext4'
elif filesystem == 'xfs':
- if (handle:= sys_command(f'/usr/bin/mkfs.xfs -f {path}')).exit_code != 0:
+ if (handle := sys_command(f'/usr/bin/mkfs.xfs -f {path}')).exit_code != 0:
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
self.filesystem = 'xfs'
elif filesystem == 'f2fs':
- if (handle:= sys_command(f'/usr/bin/mkfs.f2fs -f {path}')).exit_code != 0:
+ if (handle := sys_command(f'/usr/bin/mkfs.f2fs -f {path}')).exit_code != 0:
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
self.filesystem = 'f2fs'
+ elif filesystem == 'crypto_LUKS':
+ from .luks import luks2
+ encrypted_partition = luks2(self, None, None)
+ encrypted_partition.format(path)
+ self.filesystem = 'crypto_LUKS'
else:
raise UnknownFilesystemFormat(f"Fileformat '{filesystem}' is not yet implemented.")
return True
@@ -218,10 +245,14 @@ class Partition():
return True
def filesystem_supported(self):
- # We perform a dummy format on /dev/null with the given filesystem-type
- # in order to determain if we support it or not.
+ """
+ The support for a filesystem (this partition) is tested by calling
+ partition.format() with a path set to '/dev/null' which returns two exceptions:
+ 1. SysCallError saying that /dev/null is not formattable - but the filesystem is supported
+ 2. UnknownFilesystemFormat that indicates that we don't support the given filesystem type
+ """
try:
- self.format(self.filesystem, '/dev/null', log_formating=False)
+ self.format(self.filesystem, '/dev/null', log_formating=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:
@@ -364,4 +395,8 @@ def get_mount_info(path):
if len(output['filesystems']) > 1:
raise DiskError(f"Path '{path}' contains multiple mountpoints: {output['filesystems']}")
- return output['filesystems'][0] \ No newline at end of file
+ return output['filesystems'][0]
+
+def get_filesystem_type(path):
+ output = b''.join(sys_command(f"blkid -o value -s TYPE {path}"))
+ return output.strip().decode('UTF-8') \ No newline at end of file
diff --git a/archinstall/lib/exceptions.py b/archinstall/lib/exceptions.py
index a7864a23..5186bfd4 100644
--- a/archinstall/lib/exceptions.py
+++ b/archinstall/lib/exceptions.py
@@ -11,4 +11,6 @@ class SysCallError(BaseException):
class ProfileNotFound(BaseException):
pass
class HardwareIncompatibilityError(BaseException):
+ pass
+class PermissionError(BaseException):
pass \ No newline at end of file
diff --git a/archinstall/lib/luks.py b/archinstall/lib/luks.py
index e1f14bab..d62c2d4b 100644
--- a/archinstall/lib/luks.py
+++ b/archinstall/lib/luks.py
@@ -12,6 +12,7 @@ class luks2():
self.mountpoint = mountpoint
self.args = args
self.kwargs = kwargs
+ self.filesystem = 'crypto_LUKS'
def __enter__(self):
key_file = self.encrypt(self.partition, self.password, *self.args, **self.kwargs)
@@ -57,4 +58,8 @@ class luks2():
def close(self, mountpoint):
sys_command(f'cryptsetup close /dev/mapper/{mountpoint}')
- return os.path.islink(f'/dev/mapper/{mountpoint}') is False \ No newline at end of file
+ return os.path.islink(f'/dev/mapper/{mountpoint}') is False
+
+ def format(self, path):
+ if (handle := sys_command(f"/usr/bin/cryptsetup -q -v luksErase {path}")).exit_code != 0:
+ raise DiskError(f'Could not format {path} with {self.filesystem} because: {b"".join(handle)}') \ No newline at end of file