From 299e42bc28372f0a11a9935b8383ea4ebd86b5a0 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Tue, 19 Jan 2016 05:25:21 -0800 Subject: [PATCH] Make all parts of messages and pathnames into unicode so that we don't get UnicodeError tracebacks. Note that the fix for display normalizing to unicode is correct but the fix for pathnames is probably not. Changing pathnames to unicode type means that we will handle utf8 pathnames fine but pathnames can be any sequence of bytes that do not contain null. We do not handle sequences of bytes that are not valid utf8 here. To do that we need to revamp the handling of basedir and paths to transform to bytes instead of unicode. Didn't want to do that in 2.0.x as it will potentially introduce other bugs as we find all the places that we combine basedir with other path elements. Since no one has raised that as an issue thus far so it's not something we need to handle yet. But it's something to keep in mind for the future. To test utf8 handling, create a utf8 directory and run a playbook from within there. To test non-utf8 handling (currently doesn't work as stated above), create a directory with non-utf8 chars an run a playbook from there. In bash, create that directory like this: mkdir $'\377' Fixes #13937 --- lib/ansible/cli/__init__.py | 6 +++--- lib/ansible/inventory/__init__.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py index 77aa6a5549..12ba8f8900 100644 --- a/lib/ansible/cli/__init__.py +++ b/lib/ansible/cli/__init__.py @@ -32,7 +32,7 @@ import subprocess from ansible import __version__ from ansible import constants as C from ansible.errors import AnsibleError, AnsibleOptionsError -from ansible.utils.unicode import to_bytes +from ansible.utils.unicode import to_bytes, to_unicode try: from __main__ import display @@ -105,9 +105,9 @@ class CLI(object): if self.options.verbosity > 0: if C.CONFIG_FILE: - display.display("Using %s as config file" % C.CONFIG_FILE) + display.display(u"Using %s as config file" % to_unicode(C.CONFIG_FILE)) else: - display.display("No config file found; using defaults") + display.display(u"No config file found; using defaults") @staticmethod def ask_vault_passwords(ask_new_vault_pass=False, rekey=False): diff --git a/lib/ansible/inventory/__init__.py b/lib/ansible/inventory/__init__.py index 5885d28014..0184794fc0 100644 --- a/lib/ansible/inventory/__init__.py +++ b/lib/ansible/inventory/__init__.py @@ -735,11 +735,11 @@ class Inventory(object): if group and host is None: # load vars in dir/group_vars/name_of_group - base_path = os.path.realpath(os.path.join(basedir, "group_vars/%s" % group.name)) + base_path = os.path.realpath(os.path.join(to_unicode(basedir), "group_vars/%s" % group.name)) results = combine_vars(results, self._variable_manager.add_group_vars_file(base_path, self._loader)) elif host and group is None: # same for hostvars in dir/host_vars/name_of_host - base_path = os.path.realpath(os.path.join(basedir, "host_vars/%s" % host.name)) + base_path = os.path.realpath(os.path.join(to_unicode(basedir), "host_vars/%s" % host.name)) results = combine_vars(results, self._variable_manager.add_host_vars_file(base_path, self._loader)) # all done, results is a dictionary of variables for this particular host.