From 04e927e67f6f4dca0b7506d131ac5156904487e5 Mon Sep 17 00:00:00 2001 From: dalto Date: Sun, 21 Feb 2021 17:27:46 -0600 Subject: [PATCH] EndeavourOS customizations --- src/modules/bootloader/bootloader.conf | 16 +- src/modules/bootloader/bootloader.schema.yaml | 10 +- src/modules/bootloader/main.py | 176 +++++++++++------- 3 files changed, 126 insertions(+), 76 deletions(-) diff --git a/src/modules/bootloader/bootloader.conf b/src/modules/bootloader/bootloader.conf index f471c2ee0..a8a82c368 100644 --- a/src/modules/bootloader/bootloader.conf +++ b/src/modules/bootloader/bootloader.conf @@ -7,21 +7,21 @@ --- # Define which bootloader you want to use for EFI installations # Possible options are 'grub', 'sb-shim' and 'systemd-boot'. -efiBootLoader: "grub" +efiBootLoader: "systemd-boot" -# systemd-boot configuration files settings, set kernel and initramfs file names +# systemd-boot configuration files settings, set kernel search path, kernel name # and amount of time before default selection boots -kernel: "/vmlinuz-linux" -img: "/initramfs-linux.img" -fallback: "/initramfs-linux-fallback.img" +kernelSearchPath: "/usr/lib/modules" +kernelName: "vmlinuz" timeout: "10" -# Optionally set the menu entry name and kernel name to use in systemd-boot. +# additionalInitrdFiles is a comma seperated list of file names +additionalInitrdFiles: "/boot/amd-ucode,/boot/intel-ucode" + +# Optionally set the menu entry name to use in systemd-boot. # If not specified here, these settings will be taken from branding.desc. # # bootloaderEntryName: "Generic GNU/Linux" -# kernelLine: ", with Stable-Kernel" -# fallbackKernelLine: ", with Stable-Kernel (fallback initramfs)" # GRUB 2 binary names and boot directory # Some distributions (e.g. Fedora) use grub2-* (resp. /boot/grub2/) names. diff --git a/src/modules/bootloader/bootloader.schema.yaml b/src/modules/bootloader/bootloader.schema.yaml index 152d3ab72..4554cbf73 100644 --- a/src/modules/bootloader/bootloader.schema.yaml +++ b/src/modules/bootloader/bootloader.schema.yaml @@ -7,10 +7,10 @@ additionalProperties: false type: object properties: efiBootLoader: { type: string } - kernel: { type: string } - img: { type: string } - fallback: { type: string } + kernelSearchPath: { type: string } + kernelName: { type: string } timeout: { type: string } # Inserted verbatim + additionalInitrdFiles: { type: string } bootloaderEntryName: { type: string } kernelLine: { type: string } fallbackKernelLine: { type: string } @@ -27,8 +27,8 @@ properties: required: - efiBootLoader - - kernel - - img + - kernelSearchPath + - kernelName - grubInstall - grubMkconfig - grubCfg diff --git a/src/modules/bootloader/main.py b/src/modules/bootloader/main.py index 68cbddd0e..e42f33b3e 100644 --- a/src/modules/bootloader/main.py +++ b/src/modules/bootloader/main.py @@ -73,26 +73,7 @@ def get_bootloader_entry_name(): return branding["bootloaderEntryName"] -def get_kernel_line(kernel_type): - """ - Passes 'kernel_line' to other routine based on configuration file. - - :param kernel_type: - :return: - """ - if kernel_type == "fallback": - if "fallbackKernelLine" in libcalamares.job.configuration: - return libcalamares.job.configuration["fallbackKernelLine"] - else: - return " (fallback)" - else: - if "kernelLine" in libcalamares.job.configuration: - return libcalamares.job.configuration["kernelLine"] - else: - return "" - - -def create_systemd_boot_conf(install_path, efi_dir, uuid, entry, entry_name, kernel_type): +def create_systemd_boot_conf(install_path, efi_dir, uuid, entry, entry_name, kernel, kernel_type, kernel_version): """ Creates systemd-boot configuration files based on given parameters. @@ -101,9 +82,10 @@ def create_systemd_boot_conf(install_path, efi_dir, uuid, entry, entry_name, ker :param uuid: :param entry: :param entry_name: + :param kernel: :param kernel_type: + :param kernel_version: """ - kernel = libcalamares.job.configuration["kernel"] kernel_params = ["quiet"] partitions = libcalamares.globalstorage.value("partitions") @@ -151,43 +133,84 @@ def create_systemd_boot_conf(install_path, efi_dir, uuid, entry, entry_name, ker kernel_params.append("resume=/dev/mapper/{!s}".format( swap_outer_mappername)) - kernel_line = get_kernel_line(kernel_type) + kernel_line = entry_name + " " + kernel_version libcalamares.utils.debug("Configure: \"{!s}\"".format(kernel_line)) if kernel_type == "fallback": - img = libcalamares.job.configuration["fallback"] - entry_name = entry_name + "-fallback" + version_string = kernel_version + "-fallback" + initrd = "initrd-fallback" + mkinitcpio_option = "-S autodetect" else: - img = libcalamares.job.configuration["img"] + version_string = kernel_version + initrd = "initrd" + mkinitcpio_option = "" + + # get the machine-id + with open(os.path.join(install_path, "etc", "machine-id"), 'r') as machineid_file: + machine_id = machineid_file.read().rstrip('\n') + + # Copy kernel to a subdirectory of /efi partition + machine_dir = os.path.join(install_path + efi_dir, machine_id) + try: + os.mkdir(machine_dir) + except FileExistsError: # We can ignore errors caused by the directory existing already + pass + + files_dir = os.path.join(machine_dir, kernel_version) + try: + os.mkdir(files_dir) + except FileExistsError: # We can ignore errors caused by the directory existing already + pass + + kernel_path = os.path.join(install_path, kernel) + kernel_name = os.path.basename(kernel_path) + shutil.copyfile(kernel_path, os.path.join(files_dir, "linux")) + + # generate the initramfs - this is Arch specific and should be replaced for other distros + try: + subprocess.run(["chroot " + + install_path + + " mkinitcpio -k " + kernel_version + " -g " + os.path.join("/", os.path.relpath(files_dir, install_path), initrd)], + shell=True, + capture_output=True, + check=True) + except subprocess.CalledProcessError as cpe: + libcalamares.utils.debug("mkiniticpio failed") + libcalamares.utils.debug("STDOUT: " + cpe.stdout.decode()) + libcalamares.utils.debug("STDERR: " + cpe.stderr.decode()) + raise + + + # write the entry + lines = [ + '## Generated by Calamares\n', + '\n', + "title {!s}\n".format(entry), + "version {!s}\n".format(version_string), + "machine-id {!s}\n".format(machine_id), + "linux {!s}\n".format(os.path.join("/", machine_id, kernel_version, "linux")), + ] + + try: + additional_initrd_files = libcalamares.job.configuration["additionalInitrdFiles"] + for initrd_file in additional_initrd_files.split(','): + libcalamares.utils.debug("Attempting to handle initrd image " + initrd_file) + if os.path.isfile(os.path.join(install_path, initrd_file)): + libcalamares.utils.debug("Found image " + initrd_file) + shutil.copyfile(os.path.join(install_path, initrd_file), os.path.join(files_dir, os.path.basename(initrd_file))) + lines.append("initrd {!s}\n".format(os.path.join("/", machine_id, kernel_version, os.path.basename(initrd_file)))) + except KeyError: # If the configuration option isn't set, we can just move on + libcalamares.utils.debug("Failed to find key additionalInitrdFiles") + pass + + lines.append("initrd {!s}\n".format(os.path.join("/", machine_id, kernel_version, initrd))) + lines.append("options {!s} rw\n".format(" ".join(kernel_params))) conf_path = os.path.join(install_path + efi_dir, "loader", "entries", - entry_name + ".conf") - - # Copy kernel and initramfs to a subdirectory of /efi partition - files_dir = os.path.join(install_path + efi_dir, entry_name) - os.mkdir(files_dir) - - kernel_path = install_path + kernel - kernel_name = os.path.basename(kernel_path) - shutil.copyfile(kernel_path, os.path.join(files_dir, kernel_name)) - - img_path = install_path + img - img_name = os.path.basename(img_path) - shutil.copyfile(img_path, os.path.join(files_dir, img_name)) - - lines = [ - '## This is just an example config file.\n', - '## Please edit the paths and kernel parameters according\n', - '## to your system.\n', - '\n', - "title {!s}{!s}\n".format(entry, kernel_line), - "linux {!s}\n".format(os.path.join("/", entry_name, kernel_name)), - "initrd {!s}\n".format(os.path.join("/", entry_name, img_name)), - "options {!s} rw\n".format(" ".join(kernel_params)), - ] - + machine_id + "-" + version_string + ".conf") + with open(conf_path, 'w') as conf_file: for line in lines: conf_file.write(line) @@ -261,6 +284,8 @@ def install_systemd_boot(efi_directory): """ libcalamares.utils.debug("Bootloader: systemd-boot") install_path = libcalamares.globalstorage.value("rootMountPoint") + kernel_search_path = libcalamares.job.configuration["kernelSearchPath"] + source_kernel_name = libcalamares.job.configuration["kernelName"] install_efi_directory = install_path + efi_directory uuid = get_uuid() distribution = get_bootloader_entry_name() @@ -271,21 +296,46 @@ def install_systemd_boot(efi_directory): subprocess.call(["bootctl", "--path={!s}".format(install_efi_directory), "install"]) - create_systemd_boot_conf(install_path, - efi_directory, - uuid, - distribution, - distribution_translated, - "default") - if "fallback" in libcalamares.job.configuration: - create_systemd_boot_conf(install_path, - efi_directory, - uuid, - distribution, - distribution_translated, - "fallback") + + # find all the installed kernels and generate default and fallback entries for each + # This is Arch-specific and may need adjustment for other distros + for root, dirs, files in os.walk(os.path.join(install_path, kernel_search_path)): + for file in files: + if file == source_kernel_name: + rel_root = os.path.relpath(root, install_path) + create_systemd_boot_conf(install_path, + efi_directory, + uuid, + distribution, + distribution_translated, + os.path.join(rel_root, file), + "default", + os.path.basename(root)) + create_systemd_boot_conf(install_path, + efi_directory, + uuid, + distribution, + distribution_translated, + os.path.join(rel_root, file), + "fallback", + os.path.basename(root)) + create_loader(loader_path, distribution_translated) + # clean up redundant kernel and initrd + try: + os.remove(os.path.join(install_path, "boot/vmlinuz-linux")) + except FileNotFoundError: + pass + try: + os.remove(os.path.join(install_path, "boot/initramfs-linux.img")) + except FileNotFoundError: + pass + try: + os.remove(os.path.join(install_path, "boot/initramfs-linux-fallback.img")) + except FileNotFoundError: + pass + def get_grub_efi_parameters(): """