From 259dd744330faa0c0bde0d67b92cc53f9d34f41c Mon Sep 17 00:00:00 2001 From: Shyukri Shyukriev Date: Thu, 21 Nov 2019 15:04:02 +0100 Subject: [PATCH] ceph-volume: util: look for executable in $PATH Fixes: https://tracker.ceph.com/issues/36728 Fallback to predefined paths for backward compatibility. Alter test involved for partial match in warning Signed-off-by: Shyukri Shyukriev (cherry picked from commit a8577085dc52b0f214d9568c29a9605d1a826a45) --- .../ceph_volume/tests/util/test_system.py | 9 +++---- src/ceph-volume/ceph_volume/util/system.py | 27 +++++++++++++------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/ceph-volume/ceph_volume/tests/util/test_system.py b/src/ceph-volume/ceph_volume/tests/util/test_system.py index 4073cf381da6c..7499994900cae 100644 --- a/src/ceph-volume/ceph_volume/tests/util/test_system.py +++ b/src/ceph-volume/ceph_volume/tests/util/test_system.py @@ -206,8 +206,9 @@ class TestWhich(object): assert system.which('exedir') == 'exedir' def test_executable_exists_as_file(self, monkeypatch): - monkeypatch.setattr(system.os.path, 'isfile', lambda x: True) - monkeypatch.setattr(system.os.path, 'exists', lambda x: True) + monkeypatch.setattr(system.os, 'getenv', lambda x, y: '') + monkeypatch.setattr(system.os.path, 'isfile', lambda x: x != 'ceph') + monkeypatch.setattr(system.os.path, 'exists', lambda x: x != 'ceph') assert system.which('ceph') == '/usr/local/bin/ceph' def test_warnings_when_executable_isnt_matched(self, monkeypatch, capsys): @@ -215,9 +216,7 @@ class TestWhich(object): monkeypatch.setattr(system.os.path, 'exists', lambda x: False) system.which('exedir') cap = capsys.readouterr() - assert 'Absolute path not found for executable: exedir' in cap.err - assert 'Ensure $PATH environment variable contains common executable locations' in cap.err - + assert 'Executable exedir not in PATH' in cap.err @pytest.fixture def stub_which(monkeypatch): diff --git a/src/ceph-volume/ceph_volume/util/system.py b/src/ceph-volume/ceph_volume/util/system.py index 5aaca59af7557..27d62ea9c6210 100644 --- a/src/ceph-volume/ceph_volume/util/system.py +++ b/src/ceph-volume/ceph_volume/util/system.py @@ -39,7 +39,21 @@ def generate_uuid(): def which(executable): """find the location of an executable""" - locations = ( + def _get_path(executable, locations): + for location in locations: + executable_path = os.path.join(location, executable) + if os.path.exists(executable_path) and os.path.isfile(executable_path): + return executable_path + return None + + path = os.getenv('PATH', '') + path_locations = path.split(':') + exec_in_path = _get_path(executable, path_locations) + if exec_in_path: + return exec_in_path + mlogger.warning('Executable {} not in PATH: {}'.format(executable, path)) + + static_locations = ( '/usr/local/bin', '/bin', '/usr/bin', @@ -47,13 +61,10 @@ def which(executable): '/usr/sbin', '/sbin', ) - - for location in locations: - executable_path = os.path.join(location, executable) - if os.path.exists(executable_path) and os.path.isfile(executable_path): - return executable_path - mlogger.warning('Absolute path not found for executable: %s', executable) - mlogger.warning('Ensure $PATH environment variable contains common executable locations') + exec_in_static_locations = _get_path(executable, static_locations) + if exec_in_static_locations: + mlogger.warning('Found executable under {}, please ensure $PATH is set correctly!'.format(exec_in_static_locations)) + return exec_in_static_locations # fallback to just returning the argument as-is, to prevent a hard fail, # and hoping that the system might have the executable somewhere custom return executable -- 2.39.5