diff --git a/changelogs/fragments/2731-mh-cmd-locale.yml b/changelogs/fragments/2731-mh-cmd-locale.yml new file mode 100644 index 0000000000..ea905cce4b --- /dev/null +++ b/changelogs/fragments/2731-mh-cmd-locale.yml @@ -0,0 +1,5 @@ +bugfixes: + - module_helper module utils - ``CmdMixin`` must also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731). + - xfconf - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/issues/2715). + - cpanm - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731). + - snap - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731). diff --git a/plugins/module_utils/mh/mixins/cmd.py b/plugins/module_utils/mh/mixins/cmd.py index 724708868e..0367b6173c 100644 --- a/plugins/module_utils/mh/mixins/cmd.py +++ b/plugins/module_utils/mh/mixins/cmd.py @@ -155,13 +155,16 @@ class CmdMixin(object): def run_command(self, extra_params=None, params=None, process_output=None, *args, **kwargs): self.vars.cmd_args = self._calculate_args(extra_params, params) options = dict(self.run_command_fixed_options) - env_update = dict(options.get('environ_update', {})) options['check_rc'] = options.get('check_rc', self.check_rc) + options.update(kwargs) + env_update = dict(options.get('environ_update', {})) if self.force_lang: - env_update.update({'LANGUAGE': self.force_lang}) + env_update.update({ + 'LANGUAGE': self.force_lang, + 'LC_ALL': self.force_lang, + }) self.update_output(force_lang=self.force_lang) options['environ_update'] = env_update - options.update(kwargs) rc, out, err = self.module.run_command(self.vars.cmd_args, *args, **options) self.update_output(rc=rc, stdout=out, stderr=err) if process_output is None: diff --git a/tests/unit/plugins/modules/packaging/language/test_cpanm.py b/tests/unit/plugins/modules/packaging/language/test_cpanm.py index fd52fc1cc9..10a2955019 100644 --- a/tests/unit/plugins/modules/packaging/language/test_cpanm.py +++ b/tests/unit/plugins/modules/packaging/language/test_cpanm.py @@ -38,7 +38,7 @@ TEST_CASES = [ ), ( ['/testbin/cpanm', 'Dancer'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err ), ], @@ -65,7 +65,7 @@ TEST_CASES = [ 'id': 'install_dancer', 'run_command.calls': [( ['/testbin/cpanm', 'Dancer'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -77,7 +77,7 @@ TEST_CASES = [ 'id': 'install_distribution_file_compatibility', 'run_command.calls': [( ['/testbin/cpanm', 'MIYAGAWA/Plack-0.99_05.tar.gz'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -89,7 +89,7 @@ TEST_CASES = [ 'id': 'install_distribution_file', 'run_command.calls': [( ['/testbin/cpanm', 'MIYAGAWA/Plack-0.99_05.tar.gz'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -101,7 +101,7 @@ TEST_CASES = [ 'id': 'install_into_locallib', 'run_command.calls': [( ['/testbin/cpanm', '--local-lib', '/srv/webapps/my_app/extlib', 'Dancer'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -113,7 +113,7 @@ TEST_CASES = [ 'id': 'install_from_local_directory', 'run_command.calls': [( ['/testbin/cpanm', '/srv/webapps/my_app/src/'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -125,7 +125,7 @@ TEST_CASES = [ 'id': 'install_into_locallib_no_unit_testing', 'run_command.calls': [( ['/testbin/cpanm', '--notest', '--local-lib', '/srv/webapps/my_app/extlib', 'Dancer'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -137,7 +137,7 @@ TEST_CASES = [ 'id': 'install_from_mirror', 'run_command.calls': [( ['/testbin/cpanm', '--mirror', 'http://cpan.cpantesters.org/', 'Dancer'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -158,7 +158,7 @@ TEST_CASES = [ 'id': 'install_minversion_implicit', 'run_command.calls': [( ['/testbin/cpanm', 'Dancer~1.0'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -170,7 +170,7 @@ TEST_CASES = [ 'id': 'install_minversion_explicit', 'run_command.calls': [( ['/testbin/cpanm', 'Dancer~1.5'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -182,7 +182,7 @@ TEST_CASES = [ 'id': 'install_specific_version', 'run_command.calls': [( ['/testbin/cpanm', 'Dancer@1.7'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -215,7 +215,7 @@ TEST_CASES = [ 'id': 'install_specific_version_from_git_url_explicit', 'run_command.calls': [( ['/testbin/cpanm', 'git://github.com/plack/Plack.git@1.7'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -228,7 +228,7 @@ TEST_CASES = [ 'id': 'install_specific_version_from_git_url_implicit', 'run_command.calls': [( ['/testbin/cpanm', 'git://github.com/plack/Plack.git@2.5'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, diff --git a/tests/unit/plugins/modules/system/test_xfconf.py b/tests/unit/plugins/modules/system/test_xfconf.py index dee387bd7d..d8c9a30a9a 100644 --- a/tests/unit/plugins/modules/system/test_xfconf.py +++ b/tests/unit/plugins/modules/system/test_xfconf.py @@ -49,7 +49,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '100\n', '',), ), @@ -69,7 +69,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/i_dont_exist'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (1, '', 'Property "/general/i_dont_exist" does not exist on channel "xfwm4".\n',), ), @@ -89,7 +89,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'Value is an array with 3 items:\n\nMain\nWork\nTmp\n', '',), ), @@ -109,7 +109,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/use_compositing'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'true', '',), ), @@ -129,7 +129,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/use_compositing'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'false', '',), ), @@ -155,7 +155,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '100\n', '',), ), @@ -164,7 +164,7 @@ TEST_CASES = [ ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity', '--create', '--type', 'int', '--set', '90'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '', '',), ), @@ -190,7 +190,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '90\n', '',), ), @@ -199,7 +199,7 @@ TEST_CASES = [ ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity', '--create', '--type', 'int', '--set', '90'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '', '',), ), @@ -225,7 +225,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'Value is an array with 3 items:\n\nMain\nWork\nTmp\n', '',), ), @@ -235,7 +235,7 @@ TEST_CASES = [ '--create', '--force-array', '--type', 'string', '--set', 'A', '--type', 'string', '--set', 'B', '--type', 'string', '--set', 'C'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '', '',), ), @@ -261,7 +261,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'Value is an array with 3 items:\n\nA\nB\nC\n', '',), ), @@ -271,7 +271,7 @@ TEST_CASES = [ '--create', '--force-array', '--type', 'string', '--set', 'A', '--type', 'string', '--set', 'B', '--type', 'string', '--set', 'C'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '', '',), ), @@ -295,7 +295,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'Value is an array with 3 items:\n\nA\nB\nC\n', '',), ), @@ -304,7 +304,7 @@ TEST_CASES = [ ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names', '--reset'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '', '',), ),