Fix encryption + grub both in UEFI and BIOS systems.

We need to have two partitions in BIOS one for boot (grub)
and the other for root (/). The format of the boot partition
is ext2 (so it is added).

If disk is chosen to be encrypted, `then /etc/default/grub` is edited
as the followings: https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#Configuring_GRUB_2

Issue: https://github.com/archlinux/archinstall/issues/586

This work is done while working on CachyOS which is Arch based and
it is using customized archinstaller.

To test these changes you can try CachyOS installer which supports
encrypted disk with grub (https://wiki.cachyos.org/).

Hamad
This commit is contained in:
Hamad Al Marri 2021-07-07 18:38:55 +03:00
parent 3a40764194
commit 51eb05691a
3 changed files with 32 additions and 14 deletions

View File

@ -347,6 +347,11 @@ class Partition:
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
self.filesystem = 'ext4'
elif filesystem == 'ext2':
if (handle := SysCommand(f'/usr/bin/mkfs.ext2 -F {path}')).exit_code != 0:
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
self.filesystem = 'ext2'
elif filesystem == 'xfs':
if (handle := SysCommand(f'/usr/bin/mkfs.xfs -f {path}')).exit_code != 0:
raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}')
@ -518,12 +523,20 @@ class Filesystem:
self.blockdevice.partition[0].allow_formatting = True
self.blockdevice.partition[1].allow_formatting = True
else:
# we don't need a seprate boot partition it would be a waste of space
self.add_partition('primary', start='1MB', end='100%')
self.blockdevice.partition[0].filesystem = root_filesystem_type
log(f"Set the root partition {self.blockdevice.partition[0]} to use filesystem {root_filesystem_type}.", level=logging.DEBUG)
self.blockdevice.partition[0].target_mountpoint = '/'
self.add_partition('primary', start='1MiB', end='513MiB', partition_format='ext2')
self.set(0, 'boot on')
self.add_partition('primary', start='513MiB', end='100%')
self.blockdevice.partition[0].filesystem = 'ext2'
self.blockdevice.partition[1].filesystem = root_filesystem_type
log(f"Set the root partition {self.blockdevice.partition[1]} to use filesystem {root_filesystem_type}.", level=logging.DEBUG)
self.blockdevice.partition[0].target_mountpoint = '/boot'
self.blockdevice.partition[1].target_mountpoint = '/'
self.blockdevice.partition[0].allow_formatting = True
self.blockdevice.partition[1].allow_formatting = True
def add_partition(self, partition_type, start, end, partition_format=None):
log(f'Adding partition to {self.blockdevice}', level=logging.INFO)

View File

@ -409,7 +409,7 @@ class Installer:
return True
def add_bootloader(self, bootloader='systemd-bootctl'):
def add_bootloader(self, _device, bootloader='systemd-bootctl'):
for plugin in plugins.values():
if hasattr(plugin, 'on_add_bootloader'):
# Allow plugins to override the boot-loader handling.
@ -500,7 +500,16 @@ class Installer:
self.helper_flags['bootloader'] = bootloader
elif bootloader == "grub-install":
self.pacstrap('grub')
self.pacstrap('grub') # no need?
if real_device := self.detect_encryption(root_partition):
_file = "/etc/default/grub"
root_uuid = SysCommand(f"blkid -s UUID -o value {real_device.path}").decode().rstrip()
add_to_CMDLINE_LINUX = f"sed -i 's/GRUB_CMDLINE_LINUX=\"\"/GRUB_CMDLINE_LINUX=\"cryptdevice=UUID={root_uuid}:cryptlvm\"/'"
enable_CRYPTODISK = "sed -i 's/#GRUB_ENABLE_CRYPTODISK=y/GRUB_ENABLE_CRYPTODISK=y/'"
SysCommand(f"/usr/bin/arch-chroot {self.target} {add_to_CMDLINE_LINUX} {_file}")
SysCommand(f"/usr/bin/arch-chroot {self.target} {enable_CRYPTODISK} {_file}")
if has_uefi():
self.pacstrap('efibootmgr')
@ -509,10 +518,7 @@ class Installer:
self.helper_flags['bootloader'] = True
return True
else:
root_device = subprocess.check_output(f'basename "$(readlink -f /sys/class/block/{root_partition.path.replace("/dev/", "")}/..)"', shell=True).decode().strip()
if root_device == "block":
root_device = f"{root_partition.path}"
o = b''.join(SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --target=i386-pc /dev/{root_device}'))
o = b''.join(SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --target=i386-pc --recheck {_device.path}'))
SysCommand('/usr/bin/arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg')
self.helper_flags['bootloader'] = True
else:

View File

@ -322,8 +322,7 @@ def perform_installation_steps():
else:
fs.find_partition('/').mount(archinstall.storage.get('MOUNT_POINT', '/mnt'))
if has_uefi():
fs.find_partition('/boot').mount(archinstall.storage.get('MOUNT_POINT', '/mnt') + '/boot')
fs.find_partition('/boot').mount(archinstall.storage.get('MOUNT_POINT', '/mnt') + '/boot')
perform_installation(archinstall.storage.get('MOUNT_POINT', '/mnt'))
@ -352,7 +351,7 @@ def perform_installation(mountpoint):
installation.set_mirrors(archinstall.arguments['mirror-region']) # Set the mirrors in the installation medium
if archinstall.arguments["bootloader"] == "grub-install" and has_uefi():
installation.add_additional_packages("grub")
installation.add_bootloader(archinstall.arguments["bootloader"])
installation.add_bootloader(archinstall.arguments["harddrive"], archinstall.arguments["bootloader"])
# If user selected to copy the current ISO network configuration
# Perform a copy of the config