diff --git a/src/modules/grubcfg/grubcfg.conf b/src/modules/grubcfg/grubcfg.conf index ba31d6070..374561787 100644 --- a/src/modules/grubcfg/grubcfg.conf +++ b/src/modules/grubcfg/grubcfg.conf @@ -17,6 +17,11 @@ # already existed. If set to false, edits the existing file instead. overwrite: false +# If set to true, prefer to write files in /etc/default/grub.d/ +# rather than the single file /etc/default/grub. If this is set, +# Calamares will write /etc/default/grub.d/00Calamares instead. +prefer_grub_d: false + # If set to true, an **existing** setting for GRUB_DISTRIBUTOR is # kept, not updated to the *bootloaderEntryName* from the branding file. # Use this if the GRUB_DISTRIBUTOR setting in the file is "smart" in diff --git a/src/modules/grubcfg/grubcfg.schema.yaml b/src/modules/grubcfg/grubcfg.schema.yaml index 10aa34c2b..f010ac694 100644 --- a/src/modules/grubcfg/grubcfg.schema.yaml +++ b/src/modules/grubcfg/grubcfg.schema.yaml @@ -4,12 +4,16 @@ $id: https://calamares.io/schemas/grubcfg additionalProperties: false type: object properties: - "overwrite": { type: boolean, default: false } - "defaults": - type: map - mapping: - "GRUB_TIMEOUT": { type: int, required: true } - "GRUB_DEFAULT": { type: string, required: true } - "GRUB_DISABLE_SUBMENU": { type: boolean, default: true } - "GRUB_TERMINAL_OUTPUT": { type: string, required: true } - "GRUB_DISABLE_RECOVERY": { type: boolean, default: true } + overwrite: { type: boolean, default: false } + keepDistributor: { type: boolean, default: false } + prefer_grub_d: { type: boolean, default: false } + defaults: + type: object + additionalProperties: true # Other fields are acceptable + properties: + GRUB_TIMEOUT: { type: integer } + GRUB_DEFAULT: { type: string } + GRUB_DISABLE_SUBMENU: { type: boolean, default: true } + GRUB_TERMINAL_OUTPUT: { type: string } + GRUB_DISABLE_RECOVERY: { type: boolean, default: true } + required: [ GRUB_TIMEOUT, GRUB_DEFAULT, GRUB_TERMINAL_OUTPUT ] diff --git a/src/modules/grubcfg/main.py b/src/modules/grubcfg/main.py index 77a668960..fad6d3677 100644 --- a/src/modules/grubcfg/main.py +++ b/src/modules/grubcfg/main.py @@ -37,6 +37,33 @@ def pretty_name(): return _("Configure GRUB.") +def get_grub_config_path(root_mount_point): + """ + Figures out where to put the grub config files. Returns + a the full path of a file inside that + directory, as "the config file". + + Returns a path into @p root_mount_point. + """ + default_dir = os.path.join(root_mount_point, "etc/default") + default_config_file = "grub" + + if "prefer_grub_d" in libcalamares.job.configuration and libcalamares.job.configuration["prefer_grub_d"]: + possible_dir = os.path.join(root_mount_point, "etc/default/grub.d") + if os.path.exists(possible_dir) and os.path.isdir(possible_dir): + default_dir = possible_dir + default_config_file = "00calamares" + + if not os.path.exists(default_dir): + try: + os.mkdir(default_dir) + except: + libcalamares.utils.debug("Failed to create '%r'" % default_dir) + raise + + return os.path.join(default_dir, default_config_file) + + def modify_grub_default(partitions, root_mount_point, distributor): """ Configures '/etc/default/grub' for hibernation and plymouth. @@ -54,8 +81,7 @@ def modify_grub_default(partitions, root_mount_point, distributor): is always updated to set this value. :return: """ - default_dir = os.path.join(root_mount_point, "etc/default") - default_grub = os.path.join(default_dir, "grub") + default_grub = get_grub_config_path(root_mount_point) distributor_replace = distributor.replace("'", "'\\''") dracut_bin = libcalamares.utils.target_env_call( ["sh", "-c", "which dracut"] @@ -142,9 +168,6 @@ def modify_grub_default(partitions, root_mount_point, distributor): distributor_line = "GRUB_DISTRIBUTOR='{!s}'".format(distributor_replace) - if not os.path.exists(default_dir): - os.mkdir(default_dir) - have_kernel_cmd = False have_distributor_line = False diff --git a/src/modules/grubcfg/tests/2.global b/src/modules/grubcfg/tests/2.global index 83e79db28..88f789630 100644 --- a/src/modules/grubcfg/tests/2.global +++ b/src/modules/grubcfg/tests/2.global @@ -2,7 +2,7 @@ bogus: true firmwareType: bios bootLoader: grub -rootMountPoint: /tmp/calamares +rootMountPoint: /tmp/calamares/grubcfg-test-2 branding: bootloaderEntryName: generic diff --git a/src/modules/grubcfg/tests/3.global b/src/modules/grubcfg/tests/3.global new file mode 100644 index 000000000..45468d4df --- /dev/null +++ b/src/modules/grubcfg/tests/3.global @@ -0,0 +1,10 @@ +--- +bogus: true +firmwareType: bios +bootLoader: grub +rootMountPoint: /tmp/calamares/grubcfg-test-3 + +branding: + bootloaderEntryName: generic +partitions: [] + diff --git a/src/modules/grubcfg/tests/3.job b/src/modules/grubcfg/tests/3.job new file mode 100644 index 000000000..7182deeb2 --- /dev/null +++ b/src/modules/grubcfg/tests/3.job @@ -0,0 +1,10 @@ +--- +overwrite: true +prefer_grub_d: true # But it doesn't exist +keepDistributor: false +defaults: + GRUB_TIMEOUT: 5 + GRUB_DEFAULT: "saved" + GRUB_DISABLE_SUBMENU: true + GRUB_TERMINAL_OUTPUT: "console" + GRUB_DISABLE_RECOVERY: true diff --git a/src/modules/grubcfg/tests/4.global b/src/modules/grubcfg/tests/4.global new file mode 100644 index 000000000..fe24ba6ca --- /dev/null +++ b/src/modules/grubcfg/tests/4.global @@ -0,0 +1,10 @@ +--- +bogus: true +firmwareType: bios +bootLoader: grub +rootMountPoint: /tmp/calamares/grubcfg-test-4 + +branding: + bootloaderEntryName: generic +partitions: [] + diff --git a/src/modules/grubcfg/tests/4.job b/src/modules/grubcfg/tests/4.job new file mode 100644 index 000000000..f8f30f21b --- /dev/null +++ b/src/modules/grubcfg/tests/4.job @@ -0,0 +1,10 @@ +--- +overwrite: true +prefer_grub_d: true +keepDistributor: false +defaults: + GRUB_TIMEOUT: 5 + GRUB_DEFAULT: "saved" + GRUB_DISABLE_SUBMENU: true + GRUB_TERMINAL_OUTPUT: "console" + GRUB_DISABLE_RECOVERY: true diff --git a/src/modules/grubcfg/tests/CMakeTests.txt b/src/modules/grubcfg/tests/CMakeTests.txt index 299fccf07..78a0f85ac 100644 --- a/src/modules/grubcfg/tests/CMakeTests.txt +++ b/src/modules/grubcfg/tests/CMakeTests.txt @@ -2,11 +2,15 @@ # - 2.global specifies /tmp/calamares as the rootMountPath, # so we end up editing files there. Create the directory # beforehand, so the test doesn't blow up. -set(_grub_root /tmp/calamares/etc/default) -set(_grub_file ${_grub_root}/bogus) add_test( NAME make-grubcfg-dirs - COMMAND ${CMAKE_COMMAND} -E make_directory ${_grub_root} + COMMAND ${CMAKE_COMMAND} -E make_directory + /tmp/calamares/grubcfg-test-2/etc/default + /tmp/calamares/grubcfg-test-3/etc/default + /tmp/calamares/grubcfg-test-4/etc/default/grub.d ) set_tests_properties(load-grubcfg-2 PROPERTIES DEPENDS make-grubcfg-dirs) +set_tests_properties(load-grubcfg-3 PROPERTIES DEPENDS make-grubcfg-dirs) +set_tests_properties(load-grubcfg-4 PROPERTIES DEPENDS make-grubcfg-dirs) +