From ceaf79d191eae3c2ba600d294c9fed474986a5bf Mon Sep 17 00:00:00 2001
From: Oliver Walsh <owalsh@redhat.com>
Date: Wed, 4 Sep 2019 14:34:04 +0100
Subject: [PATCH] Ensure nouveau is blacklisted in initramfs too

To ensure dracut does not load nouveau we need to explicitly disable it via
omit_drivers.
This change adds a method to drop in arbitary dracut conf files to an element
which are picked up by dracut-regenerate and included in the chroot where we
run dracut.

The disable-nouveau element just adds a conf file with
`omit_drivers += " nouveau"`
The default dracut conf files in /usr/lib include a similar file to omit the
nvidia kernel modules.

Change-Id: I6375e4843fd08d1410141fbbd8658042dcd5ad05
Closes-bug: 1842664
---
 .../dracut.conf.d/disable-nouveau.conf        |  1 +
 .../elements/dracut-regenerate/README.rst     |  4 ++++
 .../extra-data.d/50-dracut-conf               | 23 +++++++++++++++++++
 .../finalise.d/50-dracut-regenerate           | 15 ++++++++----
 4 files changed, 38 insertions(+), 5 deletions(-)
 create mode 100644 diskimage_builder/elements/disable-nouveau/dracut.conf.d/disable-nouveau.conf
 create mode 100755 diskimage_builder/elements/dracut-regenerate/extra-data.d/50-dracut-conf

diff --git a/diskimage_builder/elements/disable-nouveau/dracut.conf.d/disable-nouveau.conf b/diskimage_builder/elements/disable-nouveau/dracut.conf.d/disable-nouveau.conf
new file mode 100644
index 000000000..32c5e6d7c
--- /dev/null
+++ b/diskimage_builder/elements/disable-nouveau/dracut.conf.d/disable-nouveau.conf
@@ -0,0 +1 @@
+omit_drivers+=" nouveau "
diff --git a/diskimage_builder/elements/dracut-regenerate/README.rst b/diskimage_builder/elements/dracut-regenerate/README.rst
index 759d6b114..9649b4947 100644
--- a/diskimage_builder/elements/dracut-regenerate/README.rst
+++ b/diskimage_builder/elements/dracut-regenerate/README.rst
@@ -16,3 +16,7 @@ a yaml blob with the following format::
       - <package4>
 
 By default, this element will bring lvm and crypt modules.
+
+Also adds the ability to copy specific files into /etc/dracut.conf.d directory
+to allow any dracut settings to be configured. To achieve that the files to be
+copied need to be placed inside an specific dracut.d directory of the element.
diff --git a/diskimage_builder/elements/dracut-regenerate/extra-data.d/50-dracut-conf b/diskimage_builder/elements/dracut-regenerate/extra-data.d/50-dracut-conf
new file mode 100755
index 000000000..b02c0bed9
--- /dev/null
+++ b/diskimage_builder/elements/dracut-regenerate/extra-data.d/50-dracut-conf
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+if [ ${DIB_DEBUG_TRACE:-1} -gt 1 ]; then
+    set -x
+fi
+set -eu
+set -o pipefail
+
+if [ ! -d $TMP_MOUNT_PATH/etc/dracut.conf.d ]; then
+    sudo mkdir -p $TMP_MOUNT_PATH/etc/dracut.conf.d
+fi
+
+eval declare -A image_elements=($(get_image_element_array))
+
+for i in "${!image_elements[@]}"; do
+    element=$i
+    element_dir=${image_elements[$i]}
+
+    if [ -d "${element_dir}/dracut.conf.d/" ]; then
+        echo "Copying dracut config from ${element_dir}"
+        sudo cp ${element_dir}/dracut.conf.d/*.conf $TMP_MOUNT_PATH/etc/dracut.conf.d/
+    fi
+done
diff --git a/diskimage_builder/elements/dracut-regenerate/finalise.d/50-dracut-regenerate b/diskimage_builder/elements/dracut-regenerate/finalise.d/50-dracut-regenerate
index e30de8a72..7bf8d1725 100755
--- a/diskimage_builder/elements/dracut-regenerate/finalise.d/50-dracut-regenerate
+++ b/diskimage_builder/elements/dracut-regenerate/finalise.d/50-dracut-regenerate
@@ -14,6 +14,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import glob
 import logging
 import os
 import re
@@ -52,8 +53,10 @@ def main():
         # second, compose the list of modules to boot
         modules_to_boot.append(dracut_object.get('name', None))
 
-    # regenerate dracut with the list of installed modules
-    if len(modules_to_boot) > 0:
+    conf_overrides = glob.glob('/etc/dracut.conf.d/*.conf')
+
+    # regenerate dracut with the list of installed modules and conf overrides
+    if modules_to_boot or conf_overrides:
         cmdline = ["select-boot-kernel-initrd"]
         logging.debug("Calling: %s" % cmdline)
         subp = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
@@ -67,10 +70,12 @@ def main():
         kernel_search = re.match("vmlinuz-(.*)", kernel_set[0])
         kernel_version = "%s" % kernel_search.groups(1)
         ramdisk_path = "/boot/%s" % kernel_set[1].strip()
-        modules_to_boot = ' ' .join(modules_to_boot)
 
-        cmdline = ['dracut', '--force', '--add', modules_to_boot,
-                   '-f', ramdisk_path, kernel_version]
+        cmdline = ['dracut', '--force']
+        if modules_to_boot:
+            modules_to_boot = ' ' .join(modules_to_boot)
+            cmdline += ['--add', modules_to_boot]
+        cmdline += ['-f', ramdisk_path, kernel_version]
         logging.debug("Calling: %s" % cmdline)
         subp = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
         out, err = subp.communicate()