summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Tantsur <dtantsur@protonmail.com>2021-11-16 11:37:52 +0100
committerDmitry Tantsur <dtantsur@protonmail.com>2021-11-16 11:37:52 +0100
commitc8708760bad1ce12ffb0421cb7d47872f63afdbb (patch)
treeabfe8963335d1bd16003fe262b44d3588506ae6f
parent3c25d0c3bdd9e1fcedf60b879f164f8363a64395 (diff)
downloadeventlet-c8708760bad1ce12ffb0421cb7d47872f63afdbb.tar.gz
Create a DNS resolver lazily rather than on import (fixes #736)
Creating a DNS resolver on import results in a failure in environments where DNS is not available (containers, service ramdisks, etc).
-rw-r--r--eventlet/support/greendns.py16
-rw-r--r--tests/greendns_test.py3
2 files changed, 18 insertions, 1 deletions
diff --git a/eventlet/support/greendns.py b/eventlet/support/greendns.py
index 76545c7..b2f77ab 100644
--- a/eventlet/support/greendns.py
+++ b/eventlet/support/greendns.py
@@ -322,7 +322,21 @@ class ResolverProxy(object):
"""
self._hosts = hosts_resolver
self._filename = filename
- self.clear()
+ # NOTE(dtantsur): we cannot create a resolver here since this code is
+ # executed on eventlet import. In an environment without DNS, creating
+ # a Resolver will fail making eventlet unusable at all. See
+ # https://github.com/eventlet/eventlet/issues/736 for details.
+ self._cached_resolver = None
+
+ @property
+ def _resolver(self):
+ if self._cached_resolver is None:
+ self.clear()
+ return self._cached_resolver
+
+ @_resolver.setter
+ def _resolver(self, value):
+ self._cached_resolver = value
def clear(self):
self._resolver = dns.resolver.Resolver(filename=self._filename)
diff --git a/tests/greendns_test.py b/tests/greendns_test.py
index 7419b35..feab2b6 100644
--- a/tests/greendns_test.py
+++ b/tests/greendns_test.py
@@ -297,8 +297,11 @@ class TestProxyResolver(tests.LimitedTestCase):
def test_clear(self):
rp = greendns.ResolverProxy()
+ assert rp._cached_resolver is None
resolver = rp._resolver
+ assert resolver is not None
rp.clear()
+ assert rp._resolver is not None
assert rp._resolver != resolver
def _make_mock_hostsresolver(self):