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