Отладка ANSIBLE трассировки для возможной ошибки в модуле стека Python Cloud

1

Рассмотрим следующую проблему для Ansible задачи для загрузки ssh-ключа:

  File "/home/foo/.ansible/tmp/ansible-tmp-1539175437.69-201636907966313/AnsiballZ_cs_sshkeypair.py", line 113, in <module>
    _ansiballz_main()
  File "/home/foo/.ansible/tmp/ansible-tmp-1539175437.69-201636907966313/AnsiballZ_cs_sshkeypair.py", line 105, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/home/foo/.ansible/tmp/ansible-tmp-1539175437.69-201636907966313/AnsiballZ_cs_sshkeypair.py", line 48, in invoke_module
    imp.load_module('__main__', mod, module, MOD_DESC)
  File "/tmp/ansible_cs_sshkeypair_payload_Jb1ZG5/__main__.py", line 267, in <module>
  File "/tmp/ansible_cs_sshkeypair_payload_Jb1ZG5/__main__.py", line 258, in main
  File "/tmp/ansible_cs_sshkeypair_payload_Jb1ZG5/__main__.py", line 133, in register_ssh_key
  File "/tmp/ansible_cs_sshkeypair_payload_Jb1ZG5/__main__.py", line 211, in get_ssh_key
  File "/tmp/ansible_cs_sshkeypair_payload_Jb1ZG5/__main__.py", line 227, in _get_ssh_fingerprint
  File "/usr/local/lib/python2.7/dist-packages/sshpubkeys/keys.py", line 157, in hash_md5
    fp_plain = hashlib.md5(self._decoded_key).hexdigest()
TypeError: md5() argument 1 must be string or buffer, not None

fatal: [localhost]: FAILED! => {
    "changed": false, 
    "module_stderr": "Traceback (most recent call last):\n  File \"/home/foo/.ansible/tmp/ansible-tmp-1539175437.69-201636907966313/AnsiballZ_cs_sshkeypair.py\", line 113, in <module>\n    _ansiballz_main()\n  File \"/home/foo/.ansible/tmp/ansible-tmp-1539175437.69-201636907966313/AnsiballZ_cs_sshkeypair.py\", line 105, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/foo/.ansible/tmp/ansible-tmp-1539175437.69-201636907966313/AnsiballZ_cs_sshkeypair.py\", line 48, in invoke_module\n    imp.load_module('__main__', mod, module, MOD_DESC)\n  File \"/tmp/ansible_cs_sshkeypair_payload_Jb1ZG5/__main__.py\", line 267, in <module>\n  File \"/tmp/ansible_cs_sshkeypair_payload_Jb1ZG5/__main__.py\", line 258, in main\n  File \"/tmp/ansible_cs_sshkeypair_payload_Jb1ZG5/__main__.py\", line 133, in register_ssh_key\n  File \"/tmp/ansible_cs_sshkeypair_payload_Jb1ZG5/__main__.py\", line 211, in get_ssh_key\n  File \"/tmp/ansible_cs_sshkeypair_payload_Jb1ZG5/__main__.py\", line 227, in _get_ssh_fingerprint\n  File \"/usr/local/lib/python2.7/dist-packages/sshpubkeys/keys.py\", line 157, in hash_md5\n    fp_plain = hashlib.md5(self._decoded_key).hexdigest()\nTypeError: md5() argument 1 must be string or buffer, not None\n", 
    "module_stdout": "", 
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", 
    "rc": 1
}

В то время как ключ ssh присутствует, это кажется некоторой ошибкой, поскольку аргументы md5() могут быть потеряны.

Невозможно идентифицировать его именно в этой форме как известную проблему.

Эта проблема возникает как для Python 2.x, так и для 3.x. (Dockerfiles для Ubuntu 16.04/18.04 LTS ниже).

Ubuntu 16.04 LTS, Python 2

FROM ubuntu:16.04

ENV WORKDIR /work
WORKDIR $WORKDIR
COPY . $WORKDIR/example/


RUN mv example/.ssh/ ~/ && ls -alh ~/.ssh/ && \
    apt-get -y update && apt-get -y install software-properties-common && apt-add-repository ppa:ansible/ansible && \
    apt-get -y update && \
    apt-get -y install python-pip && pip install ansible cs sshpubkeys && \
    echo "List installed Python packages:" && pip list && python --version && ansible --version

Ubuntu 18.04 LTS, Python 3

FROM ubuntu:18.04

ENV WORKDIR /work
WORKDIR $WORKDIR
COPY . $WORKDIR/example/


RUN mv example/.ssh/ ~/ && ls -alh ~/.ssh/ && \
    apt-get -y update && apt-get -y install software-properties-common && apt-add-repository ppa:ansible/ansible && \
    apt-get -y update && \
    apt-get -y install python3-pip && pip3 install ansible cs sshpubkeys && \
    echo "List installed Python packages:" && pip3 list && python3 --version && ansible --version

Кажется, что система удаляет временные сгенерированные скрипты Python. Есть ли возможность сохранить их для отладки?

Боковое примечание: example/.ssh/ содержит свежий SSH-пиблический ключ, не известный целевой системе.

Предположение: в то время как окончательный динамический файл называется AnsiballZ_cs_sshkeypair.py, он исходит из модуля Python cs (Apache Cloud Stack bindings)?

Теги:
python-3.x
python-2.7
ansible
apache-cloudstack

1 ответ

1
Лучший ответ

Временные скрипты по умолчанию будут удалены, поскольку они в основном являются только копиями файла модуля (завернутого в Ansiballz), переданного с узла Ansible. В этом случае я предполагаю, что удаленный хост такой же, как и Ansible-хост, но это не имеет значения, так как концепция такая же. Схема именования модулей, обернутых ansiballz, в основном похожа на предполагаемую.

Но вы действительно можете перезаписать автоматическое удаление, ANSIBLE_KEEP_REMOTE_FILES=1 к вашему вызову в виде ANSIBLE_KEEP_REMOTE_FILES=1 следующим образом:

ANSIBLE_KEEP_REMOTE_FILES=1 ansible-playbook <playbookname>.yml -vvv

Таким образом, ansiballz *.py сохраняется, но сам модуль передается как некоторая строка base64. Я не думаю, что это поможет.

Для дальнейшей отладки я бы рекомендовал вам клонировать репозиторий Ansible из github, а затем делать (желательно в дополнительном помещении)

source /path/to/dev/Ansible/hacking/env-setup

для настройки среды dev. Затем вы можете вызвать модуль непосредственно с помощью Python Interpreter и использовать такие инструменты, как pdb. Я бы рекомендовал вам подготовить json файл в следующем формате.

{"ANSIBLE_MODULE_ARGS": { "key1": "value1", "key2"... }}

Затем вы можете вызвать модуль следующим образом:

python <module-name-plus-path> <json-file-plus-path>

Я надеюсь, что это помогает!

EDIT: Я забыл одно. Ознакомьтесь с документацией Ansible dev. Это очень поможет вам, если вы действительно захотите углубиться в дело.

  • 0
    спасибо @ кб-0! это очень полезный отзыв. Этот уровень понимания Ansible невозможно реализовать в текущем проекте ... Как ни странно, файл /root/.ansible/tmp/ansible-tmp-1540197991.746526-125643635688315/AnsiballZ_cs_instance.py генерируется каждый раз, когда я запускаю команду «повторить» шаг. Есть ли возможность отключить временные метки временных файлов, чтобы я мог вставлять точки останова?
  • 1
    К сожалению, Ansiballz-wrapper перехватывает трассировки стека pdb и всегда завершается ошибкой с помощью bdbquit (), который указывает, что оболочка закрывает оболочку отладки, а затем возвращает module.fail_json (). Пару раз он падал мне на ноги, когда я забывал следы в своем коде при разработке пользовательских модулей. Единственный способ использовать что-то вроде pdb (насколько я знаю) - вызвать модуль через собственный Python.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню