Fixes to the controller text model (#17527)
* Fixes to the controller text model * Change command line args to text type * Make display replace undecodable bytes with replacement chars. This is only a problem on pyhton3 where surrogates can enter into the msg but sys.stdout doesn't know how to handle them. * Remove a deprecated playbook syntax in unicode.yml * Fix up run_cmd to change its parameters to byte string at appropriate times.
This commit is contained in:
parent
9868117d1f
commit
bf29961947
4 changed files with 27 additions and 9 deletions
13
bin/ansible
13
bin/ansible
|
@ -91,9 +91,16 @@ if __name__ == '__main__':
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
cli = mycli(sys.argv)
|
try:
|
||||||
cli.parse()
|
args = [to_text(a, errors='surrogate_or_strict') for a in sys.argv]
|
||||||
exit_code = cli.run()
|
except UnicodeError:
|
||||||
|
display.error('Command line args are not in utf-8, unable to continue. Ansible currently only understands utf-8')
|
||||||
|
display.display(u"The full traceback was:\n\n%s" % to_text(traceback.format_exc()))
|
||||||
|
exit_code = 6
|
||||||
|
else:
|
||||||
|
cli = mycli(args)
|
||||||
|
cli.parse()
|
||||||
|
exit_code = cli.run()
|
||||||
|
|
||||||
except AnsibleOptionsError as e:
|
except AnsibleOptionsError as e:
|
||||||
cli.parser.print_help()
|
cli.parser.print_help()
|
||||||
|
|
|
@ -24,15 +24,26 @@ import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
import select
|
import select
|
||||||
|
|
||||||
|
from ansible.compat.six import PY2
|
||||||
|
from ansible.module_utils._text import to_bytes
|
||||||
|
|
||||||
def run_cmd(cmd, live=False, readsize=10):
|
def run_cmd(cmd, live=False, readsize=10):
|
||||||
|
|
||||||
#readsize = 10
|
#readsize = 10
|
||||||
|
|
||||||
|
# On python2, shlex needs byte strings
|
||||||
|
if PY2:
|
||||||
|
cmd = to_bytes(cmd, errors='surrogate_or_strict')
|
||||||
cmdargs = shlex.split(cmd)
|
cmdargs = shlex.split(cmd)
|
||||||
|
|
||||||
|
# subprocess should be passed byte strings. (on python2.6 it must be
|
||||||
|
# passed byte strtings)
|
||||||
|
cmdargs = [to_bytes(a, errors='surrogate_or_strict') for a in cmdargs]
|
||||||
|
|
||||||
p = subprocess.Popen(cmdargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
p = subprocess.Popen(cmdargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
|
||||||
stdout = ''
|
stdout = b''
|
||||||
stderr = ''
|
stderr = b''
|
||||||
rpipes = [p.stdout, p.stderr]
|
rpipes = [p.stdout, p.stderr]
|
||||||
while True:
|
while True:
|
||||||
rfd, wfd, efd = select.select(rpipes, [], rpipes, 1)
|
rfd, wfd, efd = select.select(rpipes, [], rpipes, 1)
|
||||||
|
@ -42,14 +53,14 @@ def run_cmd(cmd, live=False, readsize=10):
|
||||||
if live:
|
if live:
|
||||||
sys.stdout.write(dat)
|
sys.stdout.write(dat)
|
||||||
stdout += dat
|
stdout += dat
|
||||||
if dat == '':
|
if dat == b'':
|
||||||
rpipes.remove(p.stdout)
|
rpipes.remove(p.stdout)
|
||||||
if p.stderr in rfd:
|
if p.stderr in rfd:
|
||||||
dat = os.read(p.stderr.fileno(), readsize)
|
dat = os.read(p.stderr.fileno(), readsize)
|
||||||
stderr += dat
|
stderr += dat
|
||||||
if live:
|
if live:
|
||||||
sys.stdout.write(dat)
|
sys.stdout.write(dat)
|
||||||
if dat == '':
|
if dat == b'':
|
||||||
rpipes.remove(p.stderr)
|
rpipes.remove(p.stderr)
|
||||||
# only break out if we've emptied the pipes, or there is nothing to
|
# only break out if we've emptied the pipes, or there is nothing to
|
||||||
# read from and the process has finished.
|
# read from and the process has finished.
|
||||||
|
|
|
@ -124,7 +124,7 @@ class Display:
|
||||||
# Convert back to text string on python3
|
# Convert back to text string on python3
|
||||||
# We first convert to a byte string so that we get rid of
|
# We first convert to a byte string so that we get rid of
|
||||||
# characters that are invalid in the user's locale
|
# characters that are invalid in the user's locale
|
||||||
msg2 = to_text(msg2, self._output_encoding(stderr=stderr))
|
msg2 = to_text(msg2, self._output_encoding(stderr=stderr), errors='replace')
|
||||||
|
|
||||||
if not stderr:
|
if not stderr:
|
||||||
fileobj = sys.stdout
|
fileobj = sys.stdout
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
groups: 'ĪīĬĭ'
|
groups: 'ĪīĬĭ'
|
||||||
ansible_ssh_host: 127.0.0.1
|
ansible_ssh_host: 127.0.0.1
|
||||||
ansible_connection: local
|
ansible_connection: local
|
||||||
with_items: hostnames
|
with_items: "{{ hostnames }}"
|
||||||
|
|
||||||
- name: 'A task with unicode extra vars'
|
- name: 'A task with unicode extra vars'
|
||||||
debug: var=extra_var
|
debug: var=extra_var
|
||||||
|
|
Loading…
Reference in a new issue