From 4245de0b978a4d28bb8c833c2f2f5a15a260bd22 Mon Sep 17 00:00:00 2001 From: Pavel Moravec Date: Mon, 12 Sep 2022 15:30:16 +0200 Subject: [PATCH] [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 --- requirements.txt | 1 - setup.py | 2 +- sos.spec | 2 +- sos/utilities.py | 50 +++++++++++++++++++++++++++++++++++------------- 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): -- 2.37.3