Blame SOURCES/sos-bz1709682-grub2-mkconfig-dont-remove-kernel-opts.patch

30a705
From 7097f737339f0cde6da923a4ce16a008d229cda7 Mon Sep 17 00:00:00 2001
30a705
From: Pavel Moravec <pmoravec@redhat.com>
30a705
Date: Mon, 16 Sep 2019 17:13:27 +0200
30a705
Subject: [PATCH 1/2] [plugins] extend SoSPredicate by command output inclusion
30a705
 test
30a705
30a705
Add a predicate type in form
30a705
30a705
cmd_outputs={'cmd': 'foo --help', 'output': 'bar'}
30a705
30a705
that checks whether output of given command contains given string.
30a705
30a705
Multiple commands/outputs can be provided in a list.
30a705
30a705
Related to: #1682
30a705
30a705
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
30a705
---
30a705
 sos/plugins/__init__.py | 57 +++++++++++++++++++++++++++++++++++------
30a705
 1 file changed, 49 insertions(+), 8 deletions(-)
30a705
30a705
diff --git a/sos/plugins/__init__.py b/sos/plugins/__init__.py
30a705
index a0b291bea..516a61109 100644
30a705
--- a/sos/plugins/__init__.py
30a705
+++ b/sos/plugins/__init__.py
30a705
@@ -115,6 +115,9 @@ class SoSPredicate(object):
30a705
     #: Services enablement list
30a705
     services = []
30a705
 
30a705
+    # Command output inclusion pairs {'cmd': 'foo --help', 'output': 'bar'}
30a705
+    cmd_outputs = []
30a705
+
30a705
     def __str(self, quote=False, prefix="", suffix=""):
30a705
         """Return a string representation of this SoSPredicate with
30a705
             optional prefix, suffix and value quoting.
30a705
@@ -128,14 +131,23 @@ class SoSPredicate(object):
30a705
 
30a705
         services = self.services
30a705
         services = [quotes % s for s in services] if quote else services
30a705
-        pstr += "services=[%s]" % (",".join(services))
30a705
+        pstr += "services=[%s], " % (",".join(services))
30a705
+
30a705
+        cmdoutputs = [
30a705
+            "{ %s: %s, %s: %s }" % (quotes % "cmd",
30a705
+                                    quotes % cmdoutput['cmd'],
30a705
+                                    quotes % "output",
30a705
+                                    quotes % cmdoutput['output'])
30a705
+            for cmdoutput in self.cmd_outputs
30a705
+        ]
30a705
+        pstr += "cmdoutputs=[%s]" % (",".join(cmdoutputs))
30a705
 
30a705
         return prefix + pstr + suffix
30a705
 
30a705
     def __str__(self):
30a705
         """Return a string representation of this SoSPredicate.
30a705
 
30a705
-            "dry_run=False, kmods=[], services=[]"
30a705
+            "dry_run=False, kmods=[], services=[], cmdoutputs=[]"
30a705
         """
30a705
         return self.__str()
30a705
 
30a705
@@ -143,7 +155,7 @@ class SoSPredicate(object):
30a705
         """Return a machine readable string representation of this
30a705
             SoSPredicate.
30a705
 
30a705
-            "SoSPredicate(dry_run=False, kmods=[], services=[])"
30a705
+            "SoSPredicate(dry_run=False, kmods=[], services=[], cmdoutputs=[])"
30a705
         """
30a705
         return self.__str(quote=True, prefix="SoSPredicate(", suffix=")")
30a705
 
30a705
@@ -170,15 +182,39 @@ class SoSPredicate(object):
30a705
         else:
30a705
             return all(_svcs)
30a705
 
30a705
+    def _eval_cmd_output(self, cmd_output):
30a705
+        '''Does 'cmd' output contain string 'output'?'''
30a705
+        if 'cmd' not in cmd_output or 'output' not in cmd_output:
30a705
+            return False
30a705
+        result = sos_get_command_output(cmd_output['cmd'])
30a705
+        if result['status'] != 0:
30a705
+            return False
30a705
+        for line in result['output'].splitlines():
30a705
+            if cmd_output['output'] in line:
30a705
+                return True
30a705
+        return False
30a705
+
30a705
+    def _eval_cmd_outputs(self):
30a705
+        if not self.cmd_outputs:
30a705
+            return True
30a705
+
30a705
+        _cmds = [self._eval_cmd_output(c) for c in self.cmd_outputs]
30a705
+
30a705
+        if self.required['commands'] == 'any':
30a705
+            return any(_cmds)
30a705
+        else:
30a705
+            return all(_cmds)
30a705
+
30a705
     def __nonzero__(self):
30a705
         """Predicate evaluation hook.
30a705
         """
30a705
 
30a705
         # Null predicate?
30a705
-        if not any([self.kmods, self.services, self.dry_run]):
30a705
+        if not any([self.kmods, self.services, self.cmd_outputs, self.dry_run]):
30a705
             return True
30a705
 
30a705
-        return ((self._eval_kmods() and self._eval_services()) and not
30a705
+        return ((self._eval_kmods() and self._eval_services() and
30a705
+                 self._eval_cmd_outputs()) and not
30a705
                 self.dry_run)
30a705
 
30a705
     def __bool__(self):
30a705
@@ -187,14 +223,17 @@ class SoSPredicate(object):
30a705
         return self.__nonzero__()
30a705
 
30a705
     def __init__(self, owner, dry_run=False, kmods=[], services=[],
30a705
-                 required={}):
30a705
+                 cmd_outputs=[], required={}):
30a705
         """Initialise a new SoSPredicate object.
30a705
         """
30a705
         self._owner = owner
30a705
         self.kmods = list(kmods)
30a705
         self.services = list(services)
30a705
+        if not isinstance(cmd_outputs, list):
30a705
+            cmd_outputs = [cmd_outputs]
30a705
+        self.cmd_outputs = cmd_outputs
30a705
         self.dry_run = dry_run | self._owner.commons['cmdlineopts'].dry_run
30a705
-        self.required = {'kmods': 'any', 'services': 'any'}
30a705
+        self.required = {'kmods': 'any', 'services': 'any', 'commands': 'any'}
30a705
         self.required.update({
30a705
             k: v for k, v in required.items() if
30a705
             required[k] != self.required[k]
30a705
30a705
From 47e434c50e63f80e4b620e74d81c636c8c8a8d97 Mon Sep 17 00:00:00 2001
30a705
From: Pavel Moravec <pmoravec@redhat.com>
30a705
Date: Mon, 16 Sep 2019 17:15:40 +0200
30a705
Subject: [PATCH 2/2] [grub2] call grub2-config with --no-grubenv-update when
30a705
 appropriate
30a705
30a705
On some newer grub2 versions, grub2-config removes extra args in
30a705
$kernel_opts until --no-grubenv-update option is used.
30a705
30a705
Test if the option is present in "grub2-config --help" and if so, use it.
30a705
30a705
Resolves: #1682
30a705
30a705
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
30a705
---
30a705
diff --git a/sos/plugins/grub2.py b/sos/plugins/grub2.py
30a705
index 9786de44d..0ca6fe096 100644
30a705
--- a/sos/plugins/grub2.py
30a705
+++ b/sos/plugins/grub2.py
30a705
@@ -6,7 +6,8 @@
30a705
 #
30a705
 # See the LICENSE file in the source distribution for further information.
30a705
 
30a705
-from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin
30a705
+from sos.plugins import (Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin,
30a705
+                         SoSPredicate)
30a705
 
30a705
 
30a705
 class Grub2(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin):
30a705
@@ -32,9 +33,16 @@ def setup(self):
30a705
         self.add_cmd_output("ls -lanR /boot")
30a705
         # call grub2-mkconfig with GRUB_DISABLE_OS_PROBER=true to prevent
30a705
         # possible unwanted loading of some kernel modules
30a705
+        # further, check if the command supports --no-grubenv-update option
30a705
+        # to prevent removing of extra args in $kernel_opts, and (only) if so,
30a705
+        # call the command with this argument
30a705
         env = {}
30a705
         env['GRUB_DISABLE_OS_PROBER'] = 'true'
30a705
-        self.add_cmd_output("grub2-mkconfig", env=env)
30a705
+        grub_cmd = 'grub2-mkconfig'
30a705
+        co = {'cmd': 'grub2-mkconfig --help', 'output': '--no-grubenv-update'}
30a705
+        if self.test_predicate(self, pred=SoSPredicate(self, cmd_outputs=co)):
30a705
+            grub_cmd += ' --no-grubenv-update'
30a705
+        self.add_cmd_output(grub_cmd, env=env)
30a705
 
30a705
     def postproc(self):
30a705
         # the trailing space is required; python treats '_' as whitespace