diff options
author | Dmitry Tantsur <dtantsur@protonmail.com> | 2021-11-16 11:37:52 +0100 |
---|---|---|
committer | Dmitry Tantsur <dtantsur@protonmail.com> | 2021-11-16 11:37:52 +0100 |
commit | c8708760bad1ce12ffb0421cb7d47872f63afdbb (patch) | |
tree | abfe8963335d1bd16003fe262b44d3588506ae6f | |
parent | 3c25d0c3bdd9e1fcedf60b879f164f8363a64395 (diff) | |
download | eventlet-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.py | 16 | ||||
-rw-r--r-- | tests/greendns_test.py | 3 |
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): |