UnicodeEncodeError

Hi all,

Trying to run a playbook here, but getting a Unicode error. Here’s what I’m doing:

The plays:

main.yml:

  • name: Check if new upstart job is needed
    template:
    src=syslog-ng-upstart.conf.j2
    dest=/etc/init/syslog-ng.conf
    owner=root
    group=root
    mode=0644
    backup=yes
    register: upstart

  • name: Update upstart configuration
    include: upstart.yml
    when: upstart.changed​​

Also, I tried changing “module_lang” to “en_US.UTF-8” in /etc/ansible/ansible.cfg, but it made no difference. I don’t have a ansible.cfg in the playbook directory or .ansible.cfg in the home directory.

Ansible version is 1.7.2.

Thanks!

There have been sporadic UnicodeErrors that crop up from time to time.
I've been trying squash them as they come up. 1.7.2 is pretty old so
it won't have a lot of those fixes. Are you able to test (at least
the failing task) on a newer version of ansible? That would tell you
if the problem has been fixed already in a newer version.

If it's still failing with the newer version, narrowing down the
problem would be helpful. Is it occurring with the first task or the
second? (I'm guessing the first). What is the output from
ansible-playbook -vvvv ? What LC* and LANG settings do you have on the
remote box?

-Toshio

Hey Toshio! Thanks for your reply.

Since these are production machines, I can only use 1.7.2 at the moment. However, I installed the newest ppa version (1.9.2) on a VM cluster to test.
The error stills pops up. The error happens when it tries running the first task from the second playbook. However, commenting that task out just makes the error pop up in the next task. So I believe it’s already carrying it from the first playbook, after completing the “Check if new upstart job is needed” task.

The LC and LANG settings are “en_US.UTF-8” in the remote box.

-vvvv doesn’t give me much new info. Here’s the compressed output when the error occurs:

ok: [anakin] => {“changed”: false, “gid”: 0, “group”: “root”, “mode”: “0644”, “owner”: “root”, “path”: “/etc/init/syslog-ng.conf”, “size”: 615, “state”: “file”, “uid”: 0}

TASK: [syslog-client | debug var=upstart] *******************************
ESTABLISH CONNECTION FOR USER: ******
ok: [anakin] => {
“var”: {
“upstart_times”: {
“changed”: false,
“gid”: 0,
“group”: “root”,
“invocation”: {
“module_args”: “src=syslog-ng-upstart.conf.j2 dest=/etc/init/syslog-ng.conf owner=root group=root mode=0644 backup=yes”,
“module_name”: “template”
},
“mode”: “0644”,
“owner”: “root”,
“path”: “/etc/init/syslog-ng.conf”,
“size”: 615,
“state”: “file”,
“uid”: 0
}
}
}

TASK: [syslog-client | Stop the syslog-ng service before upgrading to upstart] ***
Traceback (most recent call last):
File “/usr/bin/ansible-playbook”, line 324, in
sys.exit(main(sys.argv[1:]))
File “/usr/bin/ansible-playbook”, line 264, in main
pb.run()
File “/usr/lib/pymodules/python2.7/ansible/playbook/init.py”, line 348, in run
if not self._run_play(play):
File “/usr/lib/pymodules/python2.7/ansible/playbook/init.py”, line 789, in _run_play
if not self._run_task(play, task, False):
File “/usr/lib/pymodules/python2.7/ansible/playbook/init.py”, line 497, in _run_task
results = self._run_task_internal(task, include_failed=include_failed)
File “/usr/lib/pymodules/python2.7/ansible/playbook/init.py”, line 439, in _run_task_internal
results = runner.run()
File “/usr/lib/pymodules/python2.7/ansible/runner/init.py”, line 1493, in run
results = [ self._executor(h, None) for h in hosts ]
File “/usr/lib/pymodules/python2.7/ansible/runner/init.py”, line 590, in _executor
msg = str(ae)
UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 40-41: ordinal not in range(128)

Not a lot to go on... I do see that the two errors are happening in
different places. That might be bad news for you as may mean that any
fix for 1.9.3 might not be the fix needed for 1.7.2. But let's see
what we can find:

TASK: [syslog-client | Stop the syslog-ng service before upgrading to
upstart] ***
Traceback (most recent call last):
  File "/usr/bin/ansible-playbook", line 324, in <module>
    sys.exit(main(sys.argv[1:]))
  File "/usr/bin/ansible-playbook", line 264, in main
    pb.run()
  File "/usr/lib/pymodules/python2.7/ansible/playbook/__init__.py", line
348, in run
    if not self._run_play(play):
  File "/usr/lib/pymodules/python2.7/ansible/playbook/__init__.py", line
789, in _run_play
    if not self._run_task(play, task, False):
  File "/usr/lib/pymodules/python2.7/ansible/playbook/__init__.py", line
497, in _run_task
    results = self._run_task_internal(task, include_failed=include_failed)
  File "/usr/lib/pymodules/python2.7/ansible/playbook/__init__.py", line
439, in _run_task_internal
    results = runner.run()
  File "/usr/lib/pymodules/python2.7/ansible/runner/__init__.py", line 1493,
in run
    results = [ self._executor(h, None) for h in hosts ]
  File "/usr/lib/pymodules/python2.7/ansible/runner/__init__.py", line 590,
in _executor
    msg = str(ae)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 40-41:
ordinal not in range(128)

This is an error when trying to format this exception into a string
for display. We can probably just substitute that line like this:

- msg = str(ae)
+ from ansible.utils.unicode import to_bytes
+ msg = to_bytes(ae)

That should solve this traceback but the fact we're getting an
exception there means that something else has gone wrong... It could
be something that you're expected to be able to handle by changing
configuration in your network though, so doing this so that you can
see what the actual error is should be helpful.

If we're lucky, once you see what the underlying error is here, you
can correct something else on your network and then 1.7.2 will run for
you as well.

I'll add a patch to the stable-1.9 tree to do this as well. Not sure
if it will make 1.9.3 or not, though.

https://github.com/ansible/ansible/commit/f80494e434d36c1845c9fb830b6bd26ebcf35a89

>> fatal: [******] => Traceback (most recent call last):
>> File "/usr/lib/python2.7/dist-packages/ansible/runner/__init__.py",
>> line
>> 561, in _executor
>> exec_rc = self._executor_internal(host, new_stdin)
>> File "/usr/lib/python2.7/dist-packages/ansible/runner/__init__.py",
>> line
>> 666, in _executor_internal
>> return self._executor_internal_inner(host, self.module_name,
>> self.module_args, inject, port, complex_args=complex_args)
>> File "/usr/lib/python2.7/dist-packages/ansible/runner/__init__.py",
>> line
>> 756, in _executor_internal_inner
>> if not utils.check_conditional(cond, self.basedir, inject,
>> fail_on_undefined=self.error_on_undefined_vars):
>> File "/usr/lib/python2.7/dist-packages/ansible/utils/__init__.py",
>> line
>> 255, in check_conditional
>>
>> UnicodeEncodeError: 'ascii' codec can't encode characters in position
>> 15-16: ordinal not in range(128)

1.7.2 is old and I'm not sure of some of the ramifications of making
changes in the code (in newer versions of ansible we've been moving
towards making sure that internally we handle everything as unicode
strings and only using bytes when sending things externally. In 1.7.2
we weren't doing that so most things were likely byte strings. jinja2
takes and returns unicode type, however, so that's likely why we have
a problem converting from what jinja2 is returning to us here.) but we
may be able to fix this with the following code change:

- original = str(conditional).replace("jinja2_compare ","")
+ tmp_conditional = to_bytes(conditional,
errors='strict').replace("jinja2_compare ","")
+ original = tmp_conditional.replace("jinja2_compare ","")

Not sure if that will just bring us another error, further down the
line, though.

-Toshio

Thanks again for your reply Toshio. I apologize for not getting back to you sooner, was off of work for a week and a half. While I was gone, one of my fellow sysadmins updated ansible to 1.9.3, so I am now able to test the failing playbook in production. Once I get up to speed with everything and have a chance to check, I’ll post back here if I’m still having issues. Let’s hope 1.9.3 fixed the problem :slight_smile:

Gene