index : archinstall32 | |
Archlinux32 installer | gitolite user |
summaryrefslogtreecommitdiff |
author | Anton Hvornum <anton@hvornum.se> | 2021-02-11 14:11:21 +0100 |
---|---|---|
committer | Anton Hvornum <anton@hvornum.se> | 2021-02-11 14:11:21 +0100 |
commit | e2cd617d05d87bbe3fe8f1809faecd8c1ebd230e (patch) | |
tree | b1ec5d90d9869bc4ee1e877e5b8be97333b40ec3 | |
parent | 03c46cce2b62b41c5b73f86dffb90eff6a1b8eb2 (diff) |
-rw-r--r-- | archinstall/lib/disk.py | 63 | ||||
-rw-r--r-- | archinstall/lib/exceptions.py | 2 | ||||
-rw-r--r-- | archinstall/lib/luks.py | 7 | ||||
-rw-r--r-- | examples/guided.py | 16 |
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):") |