From 54b1f820fb2d58be777246cfd166a563a0ccae71 Mon Sep 17 00:00:00 2001
From: James Cammarata <jimi@sngx.net>
Date: Thu, 1 May 2014 10:34:53 -0500
Subject: [PATCH] Modify the way we set the localization environment
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, we set the LANG (and LC_CTYPE) environment variables
directly in the module code and applied them with os.environ().
Instead, we are now pre-pending those variables to the environment
string used to execute the command which allows the user to
override the localization values by setting the environment values
directly (even on a per-task basis):

  - subversion: repo=file:///path/to/repos/svn_über dest=/tmp/svntest
    environment:
      LANG: "C"
      LC_CTYPE: "en_US.UTF-8"

So if a user wishes to default their LANG back to C, they can still
avoid unicode issues by doing the above.

Fixes #7060
---
 lib/ansible/module_common.py      |  4 ----
 lib/ansible/module_utils/basic.py |  3 ---
 lib/ansible/runner/__init__.py    | 22 ++++++++++++++--------
 3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/lib/ansible/module_common.py b/lib/ansible/module_common.py
index a6af86d6fcb..fa8be1a4a07 100644
--- a/lib/ansible/module_common.py
+++ b/lib/ansible/module_common.py
@@ -28,7 +28,6 @@ from ansible import constants as C
 
 REPLACER = "#<<INCLUDE_ANSIBLE_MODULE_COMMON>>"
 REPLACER_ARGS = "\"<<INCLUDE_ANSIBLE_MODULE_ARGS>>\""
-REPLACER_LANG = "\"<<INCLUDE_ANSIBLE_MODULE_LANG>>\""
 REPLACER_COMPLEX = "\"<<INCLUDE_ANSIBLE_MODULE_COMPLEX_ARGS>>\""
 
 class ModuleReplacer(object):
@@ -140,12 +139,10 @@ class ModuleReplacer(object):
                 encoded_args = repr(module_args.encode('utf-8'))
             except UnicodeDecodeError:
                 encoded_args = repr(module_args)
-            encoded_lang = repr(C.DEFAULT_MODULE_LANG)
             encoded_complex = repr(complex_args_json)
 
             # these strings should be part of the 'basic' snippet which is required to be included
             module_data = module_data.replace(REPLACER_ARGS, encoded_args)
-            module_data = module_data.replace(REPLACER_LANG, encoded_lang)
             module_data = module_data.replace(REPLACER_COMPLEX, encoded_complex)
 
             if module_style == 'new':
@@ -154,7 +151,6 @@ class ModuleReplacer(object):
                     facility = inject['ansible_syslog_facility']
                 module_data = module_data.replace('syslog.LOG_USER', "syslog.%s" % facility)
 
-
             lines = module_data.split("\n")
             shebang = None
             if lines[0].startswith("#!"):
diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py
index 60a4d0655fd..c0b00d38652 100644
--- a/lib/ansible/module_utils/basic.py
+++ b/lib/ansible/module_utils/basic.py
@@ -30,7 +30,6 @@
 # == BEGIN DYNAMICALLY INSERTED CODE ==
 
 MODULE_ARGS = "<<INCLUDE_ANSIBLE_MODULE_ARGS>>"
-MODULE_LANG = "<<INCLUDE_ANSIBLE_MODULE_LANG>>"
 MODULE_COMPLEX_ARGS = "<<INCLUDE_ANSIBLE_MODULE_COMPLEX_ARGS>>"
 
 BOOLEANS_TRUE = ['yes', 'on', '1', 'true', 1]
@@ -191,8 +190,6 @@ class AnsibleModule(object):
                 if k not in self.argument_spec:
                     self.argument_spec[k] = v
 
-        os.environ['LANG'] = MODULE_LANG
-        os.environ['LC_CTYPE'] = MODULE_LANG
         (self.params, self.args) = self._load_params()
 
         self._legal_inputs = ['CHECKMODE', 'NO_LOG']
diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py
index dbcb869ae2b..bb661a0c52a 100644
--- a/lib/ansible/runner/__init__.py
+++ b/lib/ansible/runner/__init__.py
@@ -287,15 +287,21 @@ class Runner(object):
     def _compute_environment_string(self, inject=None):
         ''' what environment variables to use when running the command? '''
 
-        if not self.environment:
-            return ""
-        enviro = template.template(self.basedir, self.environment, inject, convert_bare=True)
-        enviro = utils.safe_eval(enviro)
-        if type(enviro) != dict:
-            raise errors.AnsibleError("environment must be a dictionary, received %s" % enviro)
+        default_environment = collections.OrderedDict([
+            ('LANG', C.DEFAULT_MODULE_LANG),
+            ('LC_CTYPE', C.DEFAULT_MODULE_LANG),
+        ])
+
+        if self.environment:
+            enviro = template.template(self.basedir, self.environment, inject, convert_bare=True)
+            enviro = utils.safe_eval(enviro)
+            if type(enviro) != dict:
+                raise errors.AnsibleError("environment must be a dictionary, received %s" % enviro)
+            default_environment.update(enviro)
+
         result = ""
-        for (k,v) in enviro.iteritems():
-            result = "%s=%s %s" % (k, pipes.quote(unicode(v)), result)
+        for (k,v) in default_environment.iteritems():
+            result = "%s %s=%s" % (result, k, pipes.quote(unicode(v)))
         return result
 
     # *****************************************************