ansible: reload /etc/resolv.conf for each task.
The OpenShift installer modifies /etc/resolv.conf then tests the new resolver configuration, however, there was no mechanism to reload resolv.conf in our reuseable interpreter. https://github.com/openshift/openshift-ansible/blob/release-3.9/roles/openshift_web_console/tasks/install.yml#L137 This inserts an explicit call to res_init() for every new style invocation, with an approximate cost of ~1usec on Linux since glibc verifies resolv.conf has changed before reloading it. There is little to be done for users of the thread-safe resolver APIs, their state is hidden from us. If bugs like that manifest, whack-a-mole style 'del sys.modules[thatmod]' patches may suffice.
This commit is contained in:
parent
c00e7ed367
commit
2ad0d0521d
|
@ -37,6 +37,7 @@ how to build arguments for it, preseed related data, etc.
|
|||
|
||||
from __future__ import absolute_import
|
||||
import cStringIO
|
||||
import ctypes
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
@ -57,6 +58,17 @@ except ImportError:
|
|||
import ansible.module_utils.basic
|
||||
ansible.module_utils.basic._ANSIBLE_ARGS = '{}'
|
||||
|
||||
# For tasks that modify /etc/resolv.conf, non-Debian derivative glibcs cache
|
||||
# resolv.conf at startup and never implicitly reload it. Cope with that via an
|
||||
# explicit call to res_init() on each task invocation. BSD-alikes export it
|
||||
# directly, Linux #defines it as "__res_init".
|
||||
libc = ctypes.CDLL(None)
|
||||
libc__res_init = None
|
||||
for symbol in 'res_init', '__res_init':
|
||||
try:
|
||||
libc__res_init = getattr(libc, symbol)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -397,6 +409,8 @@ class NewStyleRunner(ScriptRunner):
|
|||
# module, but this has never been a bug report. Instead act like an
|
||||
# interpreter that had its script piped on stdin.
|
||||
self._argv = TemporaryArgv([''])
|
||||
if libc__res_init:
|
||||
libc__res_init()
|
||||
|
||||
def revert(self):
|
||||
self._argv.revert()
|
||||
|
|
|
@ -13,3 +13,4 @@
|
|||
- import_playbook: remote_tmp/all.yml
|
||||
- import_playbook: runner/all.yml
|
||||
- import_playbook: ssh/all.yml
|
||||
- import_playbook: glibc_caches/all.yml
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
- import_playbook: resolv_conf.yml
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
# This cannot run against localhost, it damages /etc
|
||||
|
||||
- name: integration/glibc_caches/resolv_conf.yml
|
||||
gather_facts: true
|
||||
become: true
|
||||
hosts: test-targets
|
||||
vars:
|
||||
ansible_become_pass: has_sudo_pubkey_password
|
||||
tasks:
|
||||
|
||||
- debug: msg={{hostvars}}
|
||||
- mitogen_test_gethostbyname:
|
||||
name: www.google.com
|
||||
register: out
|
||||
when: ansible_virtualization_type == "docker"
|
||||
|
||||
- shell: cp /etc/resolv.conf /tmp/resolv.conf
|
||||
when: ansible_virtualization_type == "docker"
|
||||
|
||||
- shell: echo > /etc/resolv.conf
|
||||
when: ansible_virtualization_type == "docker"
|
||||
|
||||
- mitogen_test_gethostbyname:
|
||||
name: www.google.com
|
||||
register: out
|
||||
ignore_errors: true
|
||||
when: ansible_virtualization_type == "docker"
|
||||
|
||||
- shell: cat /tmp/resolv.conf > /etc/resolv.conf
|
||||
when: ansible_virtualization_type == "docker"
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- out.failed
|
||||
- '"Name or service not known" in out.msg or
|
||||
"Temporary failure in name resolution" in out.msg'
|
||||
when: ansible_virtualization_type == "docker"
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# I am a module that indirectly depends on glibc cached /etc/resolv.conf state.
|
||||
|
||||
import socket
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(argument_spec={'name': {'type': 'str'}})
|
||||
try:
|
||||
module.exit_json(addr=socket.gethostbyname(module.params['name']))
|
||||
except socket.error, e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue