Я пытаюсь проанализировать вывод пьес Ansible, которые запускаются как часть более крупного приложения Python3.7. Я запускаю эти пьесы с
Popen(command, shell=False, cwd=[directory], stdout=PIPE, stderr=STDOUT)
, где command
- это что-то вроде ['ansible-playbook', '-i', 'hosts.yml', 'playbook.yml']
. Канал переходит к файлу, где я использую регулярное выражение для просмотра результатов и вывода.
Мои регулярные выражения ломаются, потому что на машине, на которой я это развернул, возникает проблема с Unicode: для задач, где яперебирая список объектов и используя свойства текущего объекта в пьесе, я получаю распечатку, подобную этой:
changed: [0.0.0.0] => (item={uprocess: upython, unumber: u4})
Я ожидаю, что получаю на своем компьютере для разработки:
changed: [0.0.0.0] => (item={process: python, number: 4})
Это не проблема для игр, в которых я перебираю плоский список.
Я пробовал:
добавление ansible_python_interpreter: /usr/bin/python3
в качестве переменной "all" в файле хоста
всевозможных махинаций с tojson
, to_json
, safe
и т. Д. В Jinjaчасть петли. {{ obj_list | list }}}
- это оригинальный цикл, который отлично работает на одном компьютере, а не на другом;Я поместил эти фильтры как до, так и после list
, и результаты были либо одинаковыми, либо совершенно новой ошибкой, поскольку вывод не является допустимым списком.
установка Python3быть версией Python по умолчанию на рабочей машине. Prod-машина работает под управлением Ubuntu 18.04, а версия Python по умолчанию - 3.6.8. Сравните машину разработчика, которая работает под управлением Ubuntu 16.04.6 и где версия Python по умолчанию - 3.7.3. В любом случае проект работает в Python 3.7 virtualenv.
Поскольку префикс «u» остается, но не в кавычках, я склонен полагать, что это проблема подпроцесса. Однако при запуске тестового сценария, содержащего только
import subprocess, sys
subprocess.run(['python'])
, создается консоль Python3. Я не уверен, как использовать связанные решения , потому что я не запускаю сценарий Python. Почему появляется префикс Unicode и как мне его остановить? Я знаю, как обойти это с помощью регулярных выражений, но это может быть повторяющейся проблемой.
Этот пример охватывает каждый элемент того, что я делаю, и создает проблему на машине prod, а не на devmachine:
hosts.yml:
all:
hosts:
127.0.0.1:
objects:
- number: '1'
name: one
type: 1
- number: '2'
name: two
type: 2
vars:
ansible_python_interpreter: /usr/bin/python3
test.yml:
---
- hosts: all
tasks:
- name: print objects
ignore_errors: true
shell: echo {{ item.number }} && echo {{ item.name }} && echo {{ item.type }}
loop: "{{ objects | list }}"
register: output
- name: show output
debug:
msg: "{{ item.stdout_lines | length > 0 }}"
loop: "{{ output.results }}"
loop_control:
label: "{{ item.item }}"
test.py
from asynchronousfilereader import AsynchronousFileReader
from pathlib import Path
from subprocess import Popen, PIPE, STDOUT
bash = ['ansible-playbook', '-i', 'hosts.yml', 'test.yml']
# Required to connect to localhost for the purposes of the example
bash += ['--connection=local']
proc = Popen(bash, shell=False, cwd=Path.cwd(), stdout=PIPE, stderr=STDOUT)
stdout_reader = AsynchronousFileReader(proc.stdout, autostart=True)
with open('output.txt', 'a') as f:
while not stdout_reader.eof():
for line in stdout_reader.readlines():
line = str(repr(line.decode("utf-8"))).replace("\'", '').replace('\\n', '\n')
f.write(line)
stdout_reader.join()
proc.stdout.close()
Хороший вывод:
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [127.0.0.1]
TASK [print objects] ***********************************************************
"changed: [127.0.0.1] => (item={number: 1, name: one, type: 1})
""changed: [127.0.0.1] => (item={number: 2, name: two, type: 2})
"
TASK [show output] *************************************************************
"ok: [127.0.0.1] => (item={number: 1, name: one, type: 1}) => {
" "msg": true
}
"ok: [127.0.0.1] => (item={number: 2, name: two, type: 2}) => {
" "msg": true
}
PLAY RECAP *********************************************************************
127.0.0.1 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Неверный вывод:
PLAY [all] **********************************************************************
TASK [Gathering Facts] **********************************************************
ok: [127.0.0.1]
TASK [print objects] ************************************************************
"changed: [127.0.0.1] => (item={utype: 1, unumber: u1, uname: uone})
""changed: [127.0.0.1] => (item={utype: 2, unumber: u2, uname: utwo})
"
TASK [show output] **************************************************************
"ok: [127.0.0.1] => (item={utype: 1, unumber: u1, uname: uone}) => {
" "msg": true
}
"ok: [127.0.0.1] => (item={utype: 2, unumber: u2, uname: utwo}) => {
" "msg": true
}
PLAY RECAP **********************************************************************
127.0.0.1 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Обратите внимание также, что порядок аргументов в item
изменился.