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:
parent
0b3879ac58
commit
6306de4bfe
|
|
@ -196,28 +196,34 @@ class Partition():
|
||||||
if b'UUID' not in o:
|
if b'UUID' not in o:
|
||||||
raise DiskError(f'Could not format {path} with {filesystem} because: {o}')
|
raise DiskError(f'Could not format {path} with {filesystem} because: {o}')
|
||||||
self.filesystem = 'btrfs'
|
self.filesystem = 'btrfs'
|
||||||
|
|
||||||
elif filesystem == 'vfat':
|
elif filesystem == 'vfat':
|
||||||
o = b''.join(sys_command(f'/usr/bin/mkfs.vfat -F32 {path}'))
|
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:
|
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}')
|
raise DiskError(f'Could not format {path} with {filesystem} because: {o}')
|
||||||
self.filesystem = 'vfat'
|
self.filesystem = 'vfat'
|
||||||
|
|
||||||
elif filesystem == 'ext4':
|
elif filesystem == 'ext4':
|
||||||
if (handle := sys_command(f'/usr/bin/mkfs.ext4 -F {path}')).exit_code != 0:
|
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)}')
|
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
|
||||||
self.filesystem = 'ext4'
|
self.filesystem = 'ext4'
|
||||||
|
|
||||||
elif filesystem == 'xfs':
|
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)}')
|
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
|
||||||
self.filesystem = 'xfs'
|
self.filesystem = 'xfs'
|
||||||
|
|
||||||
elif filesystem == 'f2fs':
|
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)}')
|
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
|
||||||
self.filesystem = 'f2fs'
|
self.filesystem = 'f2fs'
|
||||||
|
|
||||||
elif filesystem == 'crypto_LUKS':
|
elif filesystem == 'crypto_LUKS':
|
||||||
from .luks import luks2
|
from .luks import luks2
|
||||||
encrypted_partition = luks2(self, None, None)
|
encrypted_partition = luks2(self, None, None)
|
||||||
encrypted_partition.format(path)
|
encrypted_partition.format(path)
|
||||||
self.filesystem = 'crypto_LUKS'
|
self.filesystem = 'crypto_LUKS'
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise UnknownFilesystemFormat(f"Fileformat '{filesystem}' is not yet implemented.")
|
raise UnknownFilesystemFormat(f"Fileformat '{filesystem}' is not yet implemented.")
|
||||||
return True
|
return True
|
||||||
|
|
@ -327,7 +333,7 @@ class Filesystem():
|
||||||
if prep_mode == 'luks2':
|
if prep_mode == 'luks2':
|
||||||
self.add_partition('primary', start='513MiB', end='100%')
|
self.add_partition('primary', start='513MiB', end='100%')
|
||||||
else:
|
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):
|
def add_partition(self, type, start, end, format=None):
|
||||||
log(f'Adding partition to {self.blockdevice}', level=LOG_LEVELS.Info)
|
log(f'Adding partition to {self.blockdevice}', level=LOG_LEVELS.Info)
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,28 @@ from .output import log, LOG_LEVELS
|
||||||
from .storage import storage
|
from .storage import storage
|
||||||
|
|
||||||
class luks2():
|
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.password = password
|
||||||
self.partition = partition
|
self.partition = partition
|
||||||
self.mountpoint = mountpoint
|
self.mountpoint = mountpoint
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
self.key_file = key_file
|
||||||
self.filesystem = 'crypto_LUKS'
|
self.filesystem = 'crypto_LUKS'
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
key_file = self.encrypt(self.partition, self.password, *self.args, **self.kwargs)
|
if self.partition.allow_formatting:
|
||||||
return self.unlock(self.partition, self.mountpoint, key_file)
|
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):
|
def __exit__(self, *args, **kwargs):
|
||||||
# TODO: https://stackoverflow.com/questions/28157929/how-to-safely-handle-an-exception-inside-a-context-manager
|
# 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]
|
raise args[1]
|
||||||
return True
|
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.
|
# TODO: We should be able to integrate this into the main log some how.
|
||||||
# Perhaps post-mortem?
|
# Perhaps post-mortem?
|
||||||
log(f'Encrypting {partition} (This might take a while)', level=LOG_LEVELS.Info)
|
log(f'Encrypting {partition} (This might take a while)', level=LOG_LEVELS.Info)
|
||||||
|
|
||||||
if not key_file:
|
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')
|
if type(password) != bytes: password = bytes(password, 'UTF-8')
|
||||||
|
|
||||||
with open(key_file, 'wb') as fh:
|
with open(key_file, 'wb') as fh:
|
||||||
|
|
|
||||||
|
|
@ -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: ")
|
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)
|
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):
|
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
|
A generic select function that does not output anything
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ if archinstall.arguments['harddrive'].has_partitions():
|
||||||
|
|
||||||
archinstall.log('Using existing partition table reported above.')
|
archinstall.log('Using existing partition table reported above.')
|
||||||
elif option == 'format-all':
|
elif option == 'format-all':
|
||||||
|
archinstall.arguments['filesystem'] = archinstall.ask_for_main_filesystem_format()
|
||||||
archinstall.arguments['harddrive'].keep_partitions = False
|
archinstall.arguments['harddrive'].keep_partitions = False
|
||||||
|
|
||||||
# Get disk encryption password (or skip if blank)
|
# 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:
|
with archinstall.Filesystem(archinstall.arguments['harddrive'], archinstall.GPT) as fs:
|
||||||
if archinstall.arguments['harddrive'].keep_partitions is False:
|
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')
|
fs.use_entire_disk('luks2')
|
||||||
else:
|
else:
|
||||||
fs.use_entire_disk('ext4')
|
fs.use_entire_disk(archinstall.arguments.get('filesystem', 'ext4'))
|
||||||
else:
|
else:
|
||||||
for partition in archinstall.arguments['harddrive']:
|
for partition in archinstall.arguments['harddrive']:
|
||||||
if partition.allow_formatting:
|
if partition.allow_formatting:
|
||||||
partition.format()
|
partition.format()
|
||||||
|
|
||||||
exit(0)
|
if archinstall.arguments.get('!encryption-password', None):
|
||||||
if disk_password:
|
|
||||||
# First encrypt and unlock, then format the desired partition inside the encrypted part.
|
# 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
|
# 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.
|
# 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:
|
with archinstall.luks2(harddrive.partition[1], 'luksloop', archinstall.arguments.get('!encryption-password', None)) as unlocked_device:
|
||||||
unlocked_device.format('btrfs')
|
unlocked_device.format(archinstall.arguments.get('filesystem', 'btrfs'))
|
||||||
|
|
||||||
perform_installation(unlocked_device,
|
perform_installation(unlocked_device,
|
||||||
harddrive.partition[0],
|
harddrive.partition[0],
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue