Blame SOURCES/sos-bz2129038-relax-magic-dep.patch

15b4e2
From 4245de0b978a4d28bb8c833c2f2f5a15a260bd22 Mon Sep 17 00:00:00 2001
15b4e2
From: Pavel Moravec <pmoravec@redhat.com>
15b4e2
Date: Mon, 12 Sep 2022 15:30:16 +0200
15b4e2
Subject: [PATCH] [utilities] Relax from hard dependency of python3-magic
15b4e2
15b4e2
For compatibility reasons on some distros, sos should not have a hard
15b4e2
dependency on 'magic' python library. It should attempt to use it for
15b4e2
detection of binary file content, but should fall back to previous "read
15b4e2
the very first byte" method otherwise.
15b4e2
15b4e2
Resolves: #3025
15b4e2
Relates: #3021
15b4e2
15b4e2
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
15b4e2
---
15b4e2
 requirements.txt |  1 -
15b4e2
 setup.py         |  2 +-
15b4e2
 sos.spec         |  2 +-
15b4e2
 sos/utilities.py | 50 +++++++++++++++++++++++++++++++++++-------------
15b4e2
 4 files changed, 39 insertions(+), 16 deletions(-)
15b4e2
15b4e2
diff --git a/requirements.txt b/requirements.txt
15b4e2
index c6ba1162..39f42161 100644
15b4e2
--- a/requirements.txt
15b4e2
+++ b/requirements.txt
15b4e2
@@ -2,5 +2,4 @@ pycodestyle>=2.4.0
15b4e2
 coverage>=4.0.3
15b4e2
 Sphinx>=1.3.5
15b4e2
 pexpect>=4.0.0
15b4e2
-python_magic>=0.4.20
15b4e2
 pyyaml
15b4e2
diff --git a/setup.py b/setup.py
15b4e2
index 2a70802d..f2f9ecbe 100644
15b4e2
--- a/setup.py
15b4e2
+++ b/setup.py
15b4e2
@@ -107,7 +107,7 @@ setup(
15b4e2
     ],
15b4e2
     cmdclass=cmdclass,
15b4e2
     command_options=command_options,
15b4e2
-    requires=['pexpect', 'python_magic', 'pyyaml']
15b4e2
+    requires=['pexpect', 'pyyaml']
15b4e2
     )
15b4e2
 
15b4e2
 
15b4e2
diff --git a/sos.spec b/sos.spec
15b4e2
index 748b9fd5..08499816 100644
15b4e2
--- a/sos.spec
15b4e2
+++ b/sos.spec
15b4e2
@@ -16,7 +16,7 @@ Requires: python3-rpm
15b4e2
 Requires: tar
15b4e2
 Requires: xz
15b4e2
 Requires: python3-pexpect
15b4e2
-Requires: python3-magic
15b4e2
+Recommends: python3-magic
15b4e2
 Recommends: python3-pyyaml
15b4e2
 Obsoletes: sos-collector <= 1.9
15b4e2
 
15b4e2
diff --git a/sos/utilities.py b/sos/utilities.py
15b4e2
index 2046c8fd..21c815d9 100644
15b4e2
--- a/sos/utilities.py
15b4e2
+++ b/sos/utilities.py
15b4e2
@@ -19,11 +19,26 @@ import tempfile
15b4e2
 import threading
15b4e2
 import time
15b4e2
 import io
15b4e2
-import magic
15b4e2
-
15b4e2
 from contextlib import closing
15b4e2
 from collections import deque
15b4e2
 
15b4e2
+# try loading magic>=0.4.20 which implements detect_from_filename method
15b4e2
+magic_mod = False
15b4e2
+try:
15b4e2
+    import magic
15b4e2
+    magic.detect_from_filename(__file__)
15b4e2
+    magic_mod = True
15b4e2
+except (ImportError, AttributeError):
15b4e2
+    log = logging.getLogger('sos')
15b4e2
+    from textwrap import fill
15b4e2
+    msg = ("""\
15b4e2
+WARNING: Failed to load 'magic' module version >= 0.4.20 which sos aims to \
15b4e2
+use for detecting binary files. A less effective method will be used. It is \
15b4e2
+recommended to install proper python3-magic package with the module.
15b4e2
+""")
15b4e2
+    log.warn('\n' + fill(msg, 72, replace_whitespace=False) + '\n')
15b4e2
+
15b4e2
+
15b4e2
 TIMEOUT_DEFAULT = 300
15b4e2
 
15b4e2
 
15b4e2
@@ -75,17 +90,26 @@ def file_is_binary(fname):
15b4e2
     :returns:   True if binary, else False
15b4e2
     :rtype:     ``bool``
15b4e2
     """
15b4e2
-    try:
15b4e2
-        _ftup = magic.detect_from_filename(fname)
15b4e2
-        _mimes = ['text/', 'inode/']
15b4e2
-        return (
15b4e2
-            _ftup.encoding == 'binary' and not
15b4e2
-            any(_ftup.mime_type.startswith(_mt) for _mt in _mimes)
15b4e2
-        )
15b4e2
-    except Exception:
15b4e2
-        # if for some reason this check fails, don't blindly remove all files
15b4e2
-        # but instead rely on other checks done by the component
15b4e2
-        return False
15b4e2
+    if magic_mod:
15b4e2
+        try:
15b4e2
+            _ftup = magic.detect_from_filename(fname)
15b4e2
+            _mimes = ['text/', 'inode/']
15b4e2
+            return (
15b4e2
+                _ftup.encoding == 'binary' and not
15b4e2
+                any(_ftup.mime_type.startswith(_mt) for _mt in _mimes)
15b4e2
+            )
15b4e2
+        except Exception:
15b4e2
+            pass
15b4e2
+    # if for some reason the above check fails or magic>=0.4.20 is not present,
15b4e2
+    # fail over to checking the very first byte of the file content
15b4e2
+    with open(fname, 'tr') as tfile:
15b4e2
+        try:
15b4e2
+            # when opened as above (tr), reading binary content will raise
15b4e2
+            # an exception
15b4e2
+            tfile.read(1)
15b4e2
+            return False
15b4e2
+        except UnicodeDecodeError:
15b4e2
+            return True
15b4e2
 
15b4e2
 
15b4e2
 def find(file_pattern, top_dir, max_depth=None, path_pattern=None):
15b4e2
-- 
15b4e2
2.37.3
15b4e2