From 0fb3371484f1d0f629d0b0e33f6aafbff0e43ee9 Mon Sep 17 00:00:00 2001 From: Sam Morrison Date: Tue, 18 Feb 2020 10:17:50 +1100 Subject: [PATCH] Delay importing swiftclient until after monkey-patching Commit message below partly copied from nova: Eventlet monkey patching should be as early as possible We were seeing infinite recursion opening an ssl socket when running various combinations of python3, eventlet, and urllib3. It is not clear exactly what combination of versions are affected, but for background there is an example of this issue documented here: https://github.com/eventlet/eventlet/issues/371 The immediate cause in swift's case was that we were calling eventlet.monkey_patch() after importing swiftclient (which imported requests, which finally imported urllib3). We only use the imported function in one place, however; hold off on importing until we actually need it to ensure that monkey patching happens first. Note that we *don't* want to monkey-patch at import time, as we've previously had bugs related to import-time side-effects. Change-Id: I24f4bcc3d62dc37fd9559032bfd25f5b15f98745 Closes-bug: #1863680 Related-bug: #1380815 --- swift/cli/dispersion_report.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/swift/cli/dispersion_report.py b/swift/cli/dispersion_report.py index 61708a3b17..a452e58251 100644 --- a/swift/cli/dispersion_report.py +++ b/swift/cli/dispersion_report.py @@ -26,10 +26,6 @@ from eventlet import GreenPool, hubs, patcher, Timeout from eventlet.pools import Pool from swift.common import direct_client -try: - from swiftclient import get_auth -except ImportError: - from swift.common.internal_client import get_auth from swift.common.internal_client import SimpleClient from swift.common.ring import Ring from swift.common.exceptions import ClientException @@ -365,6 +361,11 @@ Usage: %%prog [options] [conf_file] def generate_report(conf, policy_name=None): + try: + # Delay importing so urllib3 will import monkey-patched modules + from swiftclient import get_auth + except ImportError: + from swift.common.internal_client import get_auth global json_output json_output = config_true_value(conf.get('dump_json', 'no')) if policy_name is None: