diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index aeb5c6ae..fc4e2594 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1331,6 +1331,7 @@ class Installer: efi_partition: PartitionModification | None, uki_enabled: bool = False, bootloader_removable: bool = False, + os_prober: bool = False, ) -> None: debug('Installing grub bootloader') @@ -1430,6 +1431,27 @@ class Installer: grub_default.write_text(config) + if os_prober: + self.pacman.strap('os-prober') + + # grub-mkconfig only runs os-prober when GRUB_DISABLE_OS_PROBER is + # explicitly set to false; the stock config ships the option commented out + grub_default = self.target / 'etc/default/grub' + config = grub_default.read_text() + + config, count = re.subn( + r'^#?GRUB_DISABLE_OS_PROBER=.*$', + 'GRUB_DISABLE_OS_PROBER=false', + config, + count=1, + flags=re.MULTILINE, + ) + + if count == 0: + config += '\nGRUB_DISABLE_OS_PROBER=false\n' + + grub_default.write_text(config) + try: self.arch_chroot( f'grub-mkconfig -o {boot_dir}/grub/grub.cfg', @@ -1833,7 +1855,12 @@ class Installer: error('Error generating initramfs (continuing anyway)') def add_bootloader( - self, bootloader: Bootloader, uki_enabled: bool = False, bootloader_removable: bool = False, plymouth: PlymouthTheme | None = None + self, + bootloader: Bootloader, + uki_enabled: bool = False, + bootloader_removable: bool = False, + plymouth: PlymouthTheme | None = None, + os_prober: bool = False, ) -> None: """ Adds a bootloader to the installation instance. @@ -1848,6 +1875,7 @@ class Installer: :param uki_enabled: Whether to use unified kernel images :param bootloader_removable: Whether to install to removable media location (UEFI only, for GRUB and Limine) :param plymouth: Optional Plymouth theme to install and configure + :param os_prober: Whether to enable os-prober so grub-mkconfig detects other operating systems (GRUB only) """ for plugin in plugins.values(): @@ -1883,6 +1911,11 @@ class Installer: warn(f'Bootloader {bootloader.value} lacks removable support; disabling.') bootloader_removable = False + # validate os-prober option + if os_prober and not bootloader.has_os_prober_support(): + warn(f'Bootloader {bootloader.value} does not support os-prober; disabling.') + os_prober = False + if plymouth is not None: self._install_plymouth(plymouth) @@ -1899,7 +1932,7 @@ class Installer: case Bootloader.Systemd: self._add_systemd_bootloader(boot_partition, root, efi_partition, uki_enabled) case Bootloader.Grub: - self._add_grub_bootloader(boot_partition, root, efi_partition, uki_enabled, bootloader_removable) + self._add_grub_bootloader(boot_partition, root, efi_partition, uki_enabled, bootloader_removable, os_prober) case Bootloader.Efistub: self._add_efistub_bootloader(boot_partition, root, uki_enabled) case Bootloader.Limine: diff --git a/archinstall/scripts/guided.py b/archinstall/scripts/guided.py index 627a3b75..9e5371c8 100644 --- a/archinstall/scripts/guided.py +++ b/archinstall/scripts/guided.py @@ -120,6 +120,7 @@ def perform_installation( config.bootloader_config.uki, config.bootloader_config.removable, config.bootloader_config.plymouth, + config.bootloader_config.os_prober, ) if config.network_config: