Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archinstall/lib/disk.py63
-rw-r--r--archinstall/lib/exceptions.py2
-rw-r--r--archinstall/lib/luks.py7
-rw-r--r--examples/guided.py16
4 files changed, 67 insertions, 21 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
diff --git a/examples/guided.py b/examples/guided.py
index c5e1474e..5e8a64c1 100644
--- a/examples/guided.py
+++ b/examples/guided.py
@@ -105,18 +105,22 @@ else:
if archinstall.arguments['harddrive'].has_partitions():
archinstall.log(f" ! {archinstall.arguments['harddrive']} contains existing partitions", fg='red')
try:
+ partition_mountpoints = {}
for partition in archinstall.arguments['harddrive']:
if partition.filesystem_supported():
archinstall.log(f" {partition}")
+ partition_mountpoints[partition] = None
- if (option := input('Do you wish to keep existing disk setup or format entire drive? (k/f): ')).lower() in ('k', 'keep'):
- # If we want to keep the existing partitioning table
- # Make sure that it's the selected drive mounted under /mnt
- # That way, we can rely on genfstab and some manual post-installation steps.
- if archinstall.arguments['harddrive'].has_mount_point(archinstall.storage['MOUNT_POINT']) is False:
- raise archinstall.DiskError(f"The selected drive {archinstall.arguments['harddrive']} is not pre-mounted to {archinstall.storage['MOUNT_POINT']}. This is required when keeping a existing partitioning scheme.")
+ if (option := input('Do you wish to keep one/more existing partitions or format entire drive? (k/f): ')).lower() in ('k', 'keep'):
+ archinstall.arguments['harddrive'].keep_partitions = True
+ while True:
+ partition = archinstall.generic_select(partition_mountpoints.values(), "Select a partition to assign mount-point to")
+
+ archinstall.arguments['harddrive'].allocate_partitions(selections)
archinstall.log('Using existing partition table reported above.')
+ else:
+ archinstall.arguments['harddrive'].keep_partitions = False
except archinstall.UnknownFilesystemFormat as err:
archinstall.log(f"Current filesystem is not supported: {err}", fg='red')
input(f"Do you wish to erase all data? (y/n):")