Reworked the guided partitioning logic to better match new expectations of flexability. Still some work to be done and features to be implemented, but the structure is taking place

This commit is contained in:
Anton Hvornum 2021-03-08 16:52:06 +01:00
parent 0b3879ac58
commit 6306de4bfe
4 changed files with 51 additions and 13 deletions

View File

@ -196,28 +196,34 @@ class Partition():
if b'UUID' not in o:
raise DiskError(f'Could not format {path} with {filesystem} because: {o}')
self.filesystem = 'btrfs'
elif filesystem == 'vfat':
o = b''.join(sys_command(f'/usr/bin/mkfs.vfat -F32 {path}'))
if (b'mkfs.fat' not in o and b'mkfs.vfat' not in o) or b'command not found' in o:
raise DiskError(f'Could not format {path} with {filesystem} because: {o}')
self.filesystem = 'vfat'
elif filesystem == 'ext4':
if (handle := sys_command(f'/usr/bin/mkfs.ext4 -F {path}')).exit_code != 0:
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:
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:
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
@ -327,7 +333,7 @@ class Filesystem():
if prep_mode == 'luks2':
self.add_partition('primary', start='513MiB', end='100%')
else:
self.add_partition('primary', start='513MiB', end='100%', format='ext4')
self.add_partition('primary', start='513MiB', end='100%', format=prep_mode)
def add_partition(self, type, start, end, format=None):
log(f'Adding partition to {self.blockdevice}', level=LOG_LEVELS.Info)

View File

@ -6,17 +6,28 @@ from .output import log, LOG_LEVELS
from .storage import storage
class luks2():
def __init__(self, partition, mountpoint, password, *args, **kwargs):
def __init__(self, partition, mountpoint, password, key_file=None, *args, **kwargs):
self.password = password
self.partition = partition
self.mountpoint = mountpoint
self.args = args
self.kwargs = kwargs
self.key_file = key_file
self.filesystem = 'crypto_LUKS'
def __enter__(self):
key_file = self.encrypt(self.partition, self.password, *self.args, **self.kwargs)
return self.unlock(self.partition, self.mountpoint, key_file)
if self.partition.allow_formatting:
self.key_file = self.encrypt(self.partition, *self.args, **self.kwargs)
else:
if not self.key_file:
self.key_file = f"/tmp/{os.path.basename(self.partition.path)}.disk_pw" # TODO: Make disk-pw-file randomly unique?
if type(self.password) != bytes: self.password = bytes(self.password, 'UTF-8')
with open(self.key_file, 'wb') as fh:
fh.write(self.password)
return self.unlock(self.partition, self.mountpoint, self.key_file)
def __exit__(self, *args, **kwargs):
# TODO: https://stackoverflow.com/questions/28157929/how-to-safely-handle-an-exception-inside-a-context-manager
@ -24,13 +35,20 @@ class luks2():
raise args[1]
return True
def encrypt(self, partition, password, key_size=512, hash_type='sha512', iter_time=10000, key_file=None):
def encrypt(self, partition, password=None, key_size=512, hash_type='sha512', iter_time=10000, key_file=None):
# TODO: We should be able to integrate this into the main log some how.
# Perhaps post-mortem?
log(f'Encrypting {partition} (This might take a while)', level=LOG_LEVELS.Info)
if not key_file:
key_file = f"/tmp/{os.path.basename(self.partition.path)}.disk_pw" # TODO: Make disk-pw-file randomly unique?
if self.key_file:
key_file = self.key_file
else:
key_file = f"/tmp/{os.path.basename(self.partition.path)}.disk_pw" # TODO: Make disk-pw-file randomly unique?
if not password:
password = self.password
if type(password) != bytes: password = bytes(password, 'UTF-8')
with open(key_file, 'wb') as fh:

View File

@ -97,6 +97,18 @@ def ask_for_disk_layout():
value = generic_select(options.values(), "Found partitions on the selected drive, (select by number) what you want to do: ")
return next((key for key, val in options.items() if val == value), None)
def ask_for_main_filesystem_format():
options = {
'btrfs' : 'btrfs',
'ext4' : 'ext4',
'xfs' : 'xfs',
'f2fs' : 'f2fs',
'vfat' : 'vfat'
}
value = generic_select(options.values(), "Select your main partitions filesystem by number or free-text: ")
return next((key for key, val in options.items() if val == value), None)
def generic_select(options, input_text="Select one of the above by index or absolute value: ", sort=True):
"""
A generic select function that does not output anything

View File

@ -165,6 +165,7 @@ if archinstall.arguments['harddrive'].has_partitions():
archinstall.log('Using existing partition table reported above.')
elif option == 'format-all':
archinstall.arguments['filesystem'] = archinstall.ask_for_main_filesystem_format()
archinstall.arguments['harddrive'].keep_partitions = False
# Get disk encryption password (or skip if blank)
@ -272,22 +273,23 @@ signal.signal(signal.SIGINT, original_sigint_handler)
"""
with archinstall.Filesystem(archinstall.arguments['harddrive'], archinstall.GPT) as fs:
if archinstall.arguments['harddrive'].keep_partitions is False:
if disk_password:
if archinstall.arguments.get('!encryption-password', None):
# Set a temporary partition format to indicate that the partitions is encrypted.
# Later on, we'll mount it and put an actual filesystem inside this encrypted container.
fs.use_entire_disk('luks2')
else:
fs.use_entire_disk('ext4')
fs.use_entire_disk(archinstall.arguments.get('filesystem', 'ext4'))
else:
for partition in archinstall.arguments['harddrive']:
if partition.allow_formatting:
partition.format()
exit(0)
if disk_password:
if archinstall.arguments.get('!encryption-password', None):
# First encrypt and unlock, then format the desired partition inside the encrypted part.
# archinstall.luks2() encrypts the partition when entering the with context manager, and
# unlocks the drive so that it can be used as a normal block-device within archinstall.
with archinstall.luks2(harddrive.partition[1], 'luksloop', disk_password) as unlocked_device:
unlocked_device.format('btrfs')
with archinstall.luks2(harddrive.partition[1], 'luksloop', archinstall.arguments.get('!encryption-password', None)) as unlocked_device:
unlocked_device.format(archinstall.arguments.get('filesystem', 'btrfs'))
perform_installation(unlocked_device,
harddrive.partition[0],