From 3fc23e3b07da9c4036d24fb9aee77830e4319664 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Aug 2020 11:43:48 +0200 Subject: [PATCH 1/6] [grubcfg] Fix config schema --- src/modules/grubcfg/grubcfg.schema.yaml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/modules/grubcfg/grubcfg.schema.yaml b/src/modules/grubcfg/grubcfg.schema.yaml index 10aa34c2b..5121e2be7 100644 --- a/src/modules/grubcfg/grubcfg.schema.yaml +++ b/src/modules/grubcfg/grubcfg.schema.yaml @@ -4,12 +4,14 @@ $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 } + 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 ] From f85c70d4d2c731dc66bae4a0cc42e4946f2330b0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Aug 2020 11:55:16 +0200 Subject: [PATCH 2/6] [grubcfg] Introduce prefer_grub_d - new setting for using /etc/defaults/grub.d/ (SEE #1457), not implemented - add missing fields to schema for config file --- src/modules/grubcfg/grubcfg.conf | 5 +++++ src/modules/grubcfg/grubcfg.schema.yaml | 2 ++ 2 files changed, 7 insertions(+) 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 5121e2be7..f010ac694 100644 --- a/src/modules/grubcfg/grubcfg.schema.yaml +++ b/src/modules/grubcfg/grubcfg.schema.yaml @@ -5,6 +5,8 @@ additionalProperties: false type: object properties: 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 From aa50dfb8a12a349d7fdd4172f38ad2925e676e82 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Aug 2020 12:02:42 +0200 Subject: [PATCH 3/6] [grubcfg] refactor finding-the-grub-paths into a function --- src/modules/grubcfg/main.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/modules/grubcfg/main.py b/src/modules/grubcfg/main.py index 77a668960..bf1ec4b9f 100644 --- a/src/modules/grubcfg/main.py +++ b/src/modules/grubcfg/main.py @@ -37,6 +37,19 @@ def pretty_name(): return _("Configure GRUB.") +def get_grub_config_paths(root_mount_point): + """ + Figures out where to put the grub config files. Returns + a directory path and the full path of a file inside that + directory, as "the grub-directory" and "the config file". + + Returns a path into @p root_mount_point. + """ + default_dir = os.path.join(root_mount_point, "etc/default") + default_grub = os.path.join(default_dir, "grub") + + return (default_dir, default_grub) + def modify_grub_default(partitions, root_mount_point, distributor): """ Configures '/etc/default/grub' for hibernation and plymouth. @@ -54,8 +67,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_dir, default_grub = get_grub_config_paths(root_mount_point) distributor_replace = distributor.replace("'", "'\\''") dracut_bin = libcalamares.utils.target_env_call( ["sh", "-c", "which dracut"] From 064fff0c12067a370fbbcc64c6d1c0efb0ba4df0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Aug 2020 12:05:46 +0200 Subject: [PATCH 4/6] [grubcfg] Drop default_dir - the default_dir was only stored in modify_grub_default() to create the directory if needed; move that functionality to the get_grub_config_paths() function (and drop the "s", since it now returns just one). --- src/modules/grubcfg/main.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/modules/grubcfg/main.py b/src/modules/grubcfg/main.py index bf1ec4b9f..3c3f3d447 100644 --- a/src/modules/grubcfg/main.py +++ b/src/modules/grubcfg/main.py @@ -37,18 +37,21 @@ def pretty_name(): return _("Configure GRUB.") -def get_grub_config_paths(root_mount_point): +def get_grub_config_path(root_mount_point): """ Figures out where to put the grub config files. Returns - a directory path and the full path of a file inside that - directory, as "the grub-directory" and "the config file". + 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_grub = os.path.join(default_dir, "grub") - return (default_dir, default_grub) + if not os.path.exists(default_dir): + os.mkdir(default_dir) + + return default_grub def modify_grub_default(partitions, root_mount_point, distributor): """ @@ -67,7 +70,7 @@ def modify_grub_default(partitions, root_mount_point, distributor): is always updated to set this value. :return: """ - default_dir, default_grub = get_grub_config_paths(root_mount_point) + default_grub = get_grub_config_path(root_mount_point) distributor_replace = distributor.replace("'", "'\\''") dracut_bin = libcalamares.utils.target_env_call( ["sh", "-c", "which dracut"] @@ -154,9 +157,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 From 8bf95b68812ada29ba82bddf67a0f243ae97cd42 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Aug 2020 12:13:51 +0200 Subject: [PATCH 5/6] [grubcfg] Support prefer_grub_d settings --- src/modules/grubcfg/main.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/modules/grubcfg/main.py b/src/modules/grubcfg/main.py index 3c3f3d447..04b5eba9e 100644 --- a/src/modules/grubcfg/main.py +++ b/src/modules/grubcfg/main.py @@ -46,12 +46,19 @@ def get_grub_config_path(root_mount_point): Returns a path into @p root_mount_point. """ default_dir = os.path.join(root_mount_point, "etc/default") - default_grub = os.path.join(default_dir, "grub") + 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): os.mkdir(default_dir) - return default_grub + return os.path.join(default_dir, default_config_file) + def modify_grub_default(partitions, root_mount_point, distributor): """ From 473daecdbfe659cec0e307b341636a8a76c1d4da Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Aug 2020 13:42:47 +0200 Subject: [PATCH 6/6] [grubcfg] expand config-testing for the new features - create directories for new tests ahead of the tests themselves; this **can** still cause problems if a test is run standalone. - if creating the grub-dir at runtime is necessary, be informative if it fails. --- src/modules/grubcfg/main.py | 6 +++++- src/modules/grubcfg/tests/2.global | 2 +- src/modules/grubcfg/tests/3.global | 10 ++++++++++ src/modules/grubcfg/tests/3.job | 10 ++++++++++ src/modules/grubcfg/tests/4.global | 10 ++++++++++ src/modules/grubcfg/tests/4.job | 10 ++++++++++ src/modules/grubcfg/tests/CMakeTests.txt | 10 +++++++--- 7 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 src/modules/grubcfg/tests/3.global create mode 100644 src/modules/grubcfg/tests/3.job create mode 100644 src/modules/grubcfg/tests/4.global create mode 100644 src/modules/grubcfg/tests/4.job diff --git a/src/modules/grubcfg/main.py b/src/modules/grubcfg/main.py index 04b5eba9e..fad6d3677 100644 --- a/src/modules/grubcfg/main.py +++ b/src/modules/grubcfg/main.py @@ -55,7 +55,11 @@ def get_grub_config_path(root_mount_point): default_config_file = "00calamares" if not os.path.exists(default_dir): - os.mkdir(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) 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) +