Fix encoding issues with file paths. (#50830)

* Fix encoding issues with file paths.

Discovered while testing with ANSIBLE_CONFIG env var set to a path
that contained unicode characters while LC_ALL=C.

* Fix unit tests.

* Fix another path encoding issue.
pull/50795/head
Matt Clay 6 years ago committed by GitHub
parent 15b1a31aa8
commit 465df0ef8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -186,7 +186,7 @@ def find_ini_config_file(warnings=None):
path_from_env = os.getenv("ANSIBLE_CONFIG", SENTINEL) path_from_env = os.getenv("ANSIBLE_CONFIG", SENTINEL)
if path_from_env is not SENTINEL: if path_from_env is not SENTINEL:
path_from_env = unfrackpath(path_from_env, follow=False) path_from_env = unfrackpath(path_from_env, follow=False)
if os.path.isdir(path_from_env): if os.path.isdir(to_bytes(path_from_env)):
path_from_env = os.path.join(path_from_env, "ansible.cfg") path_from_env = os.path.join(path_from_env, "ansible.cfg")
potential_paths.append(path_from_env) potential_paths.append(path_from_env)
@ -214,7 +214,7 @@ def find_ini_config_file(warnings=None):
potential_paths.append("/etc/ansible/ansible.cfg") potential_paths.append("/etc/ansible/ansible.cfg")
for path in potential_paths: for path in potential_paths:
if os.path.exists(path): if os.path.exists(to_bytes(path)):
break break
else: else:
path = None path = None
@ -254,7 +254,7 @@ class ConfigManager(object):
# consume configuration # consume configuration
if self._config_file: if self._config_file:
if os.path.exists(self._config_file): if os.path.exists(to_bytes(self._config_file)):
# initialize parser and read config # initialize parser and read config
self._parse_config_file() self._parse_config_file()
@ -288,7 +288,7 @@ class ConfigManager(object):
if cfile is not None: if cfile is not None:
if ftype == 'ini': if ftype == 'ini':
self._parsers[cfile] = configparser.ConfigParser() self._parsers[cfile] = configparser.ConfigParser()
with open(cfile, 'rb') as f: with open(to_bytes(cfile), 'rb') as f:
try: try:
cfg_text = to_text(f.read(), errors='surrogate_or_strict') cfg_text = to_text(f.read(), errors='surrogate_or_strict')
except UnicodeError as e: except UnicodeError as e:

@ -23,7 +23,7 @@ import os
from ansible import constants as C from ansible import constants as C
from ansible.errors import AnsibleParserError from ansible.errors import AnsibleParserError
from ansible.module_utils._text import to_text, to_native from ansible.module_utils._text import to_bytes, to_text, to_native
from ansible.playbook.play import Play from ansible.playbook.play import Play
from ansible.playbook.playbook_include import PlaybookInclude from ansible.playbook.playbook_include import PlaybookInclude
from ansible.plugins.loader import get_all_plugin_loaders from ansible.plugins.loader import get_all_plugin_loaders
@ -68,7 +68,7 @@ class Playbook:
for name, obj in get_all_plugin_loaders(): for name, obj in get_all_plugin_loaders():
if obj.subdir: if obj.subdir:
plugin_path = os.path.join(self._basedir, obj.subdir) plugin_path = os.path.join(self._basedir, obj.subdir)
if os.path.isdir(plugin_path): if os.path.isdir(to_bytes(plugin_path)):
obj.add_directory(plugin_path) obj.add_directory(plugin_path)
try: try:

@ -77,12 +77,12 @@ class VarsModule(BaseVarsPlugin):
try: try:
found_files = [] found_files = []
# load vars # load vars
opath = os.path.realpath(os.path.join(self._basedir, subdir)) b_opath = os.path.realpath(to_bytes(os.path.join(self._basedir, subdir)))
opath = to_text(b_opath)
key = '%s.%s' % (entity.name, opath) key = '%s.%s' % (entity.name, opath)
if cache and key in FOUND: if cache and key in FOUND:
found_files = FOUND[key] found_files = FOUND[key]
else: else:
b_opath = to_bytes(opath)
# no need to do much if path does not exist for basedir # no need to do much if path does not exist for basedir
if os.path.exists(b_opath): if os.path.exists(b_opath):
if os.path.isdir(b_opath): if os.path.isdir(b_opath):

@ -35,7 +35,7 @@ from ansible import constants as C
from ansible.errors import AnsibleError, AnsibleParserError, AnsibleUndefinedVariable, AnsibleFileNotFound, AnsibleAssertionError, AnsibleTemplateError from ansible.errors import AnsibleError, AnsibleParserError, AnsibleUndefinedVariable, AnsibleFileNotFound, AnsibleAssertionError, AnsibleTemplateError
from ansible.inventory.host import Host from ansible.inventory.host import Host
from ansible.inventory.helpers import sort_groups, get_group_vars from ansible.inventory.helpers import sort_groups, get_group_vars
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_bytes, to_native
from ansible.module_utils.common._collections_compat import Mapping, MutableMapping, Sequence from ansible.module_utils.common._collections_compat import Mapping, MutableMapping, Sequence
from ansible.module_utils.six import iteritems, text_type, string_types from ansible.module_utils.six import iteritems, text_type, string_types
from ansible.plugins.loader import lookup_loader, vars_loader from ansible.plugins.loader import lookup_loader, vars_loader
@ -240,7 +240,7 @@ class VariableManager:
for inventory_dir in self._inventory._sources: for inventory_dir in self._inventory._sources:
if ',' in inventory_dir and not os.path.exists(inventory_dir): # skip host lists if ',' in inventory_dir and not os.path.exists(inventory_dir): # skip host lists
continue continue
elif not os.path.isdir(inventory_dir): # always pass 'inventory directory' elif not os.path.isdir(to_bytes(inventory_dir)): # always pass 'inventory directory'
inventory_dir = os.path.dirname(inventory_dir) inventory_dir = os.path.dirname(inventory_dir)
for plugin in vars_loader.all(): for plugin in vars_loader.all():

@ -13,7 +13,7 @@ import stat
import pytest import pytest
from ansible.config.manager import find_ini_config_file from ansible.config.manager import find_ini_config_file
from ansible.module_utils._text import to_text
real_exists = os.path.exists real_exists = os.path.exists
real_isdir = os.path.isdir real_isdir = os.path.isdir
@ -48,7 +48,7 @@ def setup_env(request):
@pytest.fixture @pytest.fixture
def setup_existing_files(request, monkeypatch): def setup_existing_files(request, monkeypatch):
def _os_path_exists(path): def _os_path_exists(path):
if path in (request.param[0]): if to_text(path) in (request.param[0]):
return True return True
else: else:
return False return False
@ -56,7 +56,7 @@ def setup_existing_files(request, monkeypatch):
# Enable user and system dirs so that we know cwd takes precedence # Enable user and system dirs so that we know cwd takes precedence
monkeypatch.setattr("os.path.exists", _os_path_exists) monkeypatch.setattr("os.path.exists", _os_path_exists)
monkeypatch.setattr("os.getcwd", lambda: os.path.dirname(cfg_dir)) monkeypatch.setattr("os.getcwd", lambda: os.path.dirname(cfg_dir))
monkeypatch.setattr("os.path.isdir", lambda path: True if path == cfg_dir else real_isdir(path)) monkeypatch.setattr("os.path.isdir", lambda path: True if to_text(path) == cfg_dir else real_isdir(path))
class TestFindIniFile: class TestFindIniFile:

Loading…
Cancel
Save