モジュールのデバッグ
詳細なデバッグ手順
Ansible モジュールは、モジュールファイルとラッパースクリプト内のさまざまな Python モジュールの boilerplate で構成される zip ファイルとしてまとめて置かれます。モジュールで実際に何が発生しているかを確認するには、ラッパーからファイルを抽出する必要があります。ラッパースクリプトは、これを可能にするヘルパーメソッドを提供します。
以下の手順では、ターゲットホストに localhost を使用していますが、同じ手順を使用してリモートホストに対してデバッグすることもできます。一時ファイルを使用せずにデバッグを行う簡単な方法は、「簡単なデバッグ」を参照してください。
コントロールホストで
ANSIBLE_KEEP_REMOTE_FILESを1に設定します。これにより、Ansible はモジュール実行後も削除せずにリモートモジュールファイルを維持します。-vvvオプションを使用すると、Ansible の詳細が表示されます。一時モジュールファイルのファイル名が表示されます。$ ANSIBLE_KEEP_REMOTE_FILES=1 ansible localhost -m ping -a 'data=debugging_session' -vvv <127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: badger <127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1461434734.35-235318071810595 `" && echo "` echo $HOME/.ansible/tmp/ansible-tmp-1461434734.35-235318071810595 `" )' <127.0.0.1> PUT /var/tmp/tmpjdbJ1w TO /home/badger/.ansible/tmp/ansible-tmp-1461434734.35-235318071810595/AnsiballZ_ping.py <127.0.0.1> EXEC /bin/sh -c 'LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/bin/python /home/badger/.ansible/tmp/ansible-tmp-1461434734.35-235318071810595/AnsiballZ_ping.py && sleep 0' localhost | SUCCESS => { "changed": false, "invocation": { "module_args": { "data": "debugging_session" }, "module_name": "ping" }, "ping": "debugging_session" }
前の手順から一時ディレクトリーに移動します。前のコマンドがリモートホストに対して実行した場合は、最初にそのホストに接続します。一時ディレクトリーに移動する前に、そのホストに接続します。
$ ssh remotehost # only if not debugging against localhost $ cd /home/badger/.ansible/tmp/ansible-tmp-1461434734.35-235318071810595
ラッパーの
explodeコマンドを実行して、文字列を使用可能な Python ファイルに変換します。$ python AnsiballZ_ping.py explode Module expanded into: /home/badger/.ansible/tmp/ansible-tmp-1461434734.35-235318071810595/debug_dir
ラッパーファイルを調べたい場合は、小さい Python スクリプトに、大きな base64 でエンコードされた文字列が記載されます。文字列には、実行するモジュールが含まれます。
一時ディレクトリーを確認すると、以下のような構造が表示されます。
├── AnsiballZ_ping.py └── debug_dir ├── ansible │ ├── __init__.py │ ├── module_utils │ │ ├── __init__.py │ │ ├── _text.py │ │ ├── basic.py │ │ ├── common │ │ ├── compat │ │ ├── distro │ │ ├── parsing │ │ ├── pycompat24.py │ │ └── six │ └── modules │ ├── __init__.py │ └── ping.py └── args
AnsiballZ_ping.pybase64 でエンコードされた文字列に保存されたモジュールコードを含む Python スクリプトで、モジュールを実行するためのさまざまなヘルパー関数が含まれます。ping.pyは、モジュール自体のコードです。このコードを変更して、モジュールまたはデバッグの目的を確認することができます。argsファイルには JSON 文字列が含まれています。この文字列は、モジュール引数および、Ansible がモジュールに渡すその他の変数を含むディクショナリーで、動作を変更します。このファイルを変更して、モジュールに渡されるパラメーターを変更します。ansibleディレクトリーには、modulesのモジュールコードと、モジュールに使用されるansible.module_utilsのコードが含まれています。Ansible には、モジュール内のansible.module_utilsインポートのファイルが含まれますが、他のモジュールからのファイルは含まれません。モジュールでansible.module_utils.urlが使用される場合は、Ansible にそれが含まれます。ただし、モジュールに requests が含まれる場合は、モジュールを実行する前に Python requests ライブラリー がシステムにインストールされていることを確認する必要があります。
作成したモジュールコードではなく、モジュールのこの boilerplate コードの一部に問題があると思われる場合は、このディレクトリーのファイルを変更できます。
展開されたツリーのコードまたは引数を編集したら、
executeサブコマンドを使用してこれを実行します。$ python AnsiballZ_ping.py execute {"invocation": {"module_args": {"data": "debugging_session"}}, "changed": false, "ping": "debugging_session"}
このサブコマンドは、
sys.pathの最初の項目としてdebug_dirに絶対パスを挿入し、argsファイルの引数を使用してスクリプトを呼び出します。問題を理解するまで、このモジュールの実行を継続できます。変更を実際のモジュールファイルにコピーし、実際のモジュールがansibleまたはansible-playbookで動作することをテストすることができます。
簡単なデバッグ
モジュール (ローカルまたはリモートのいずれか) でデバッガーを実行する最も簡単な方法は、epdb を使用します。任意のブレークポイントで、コントロールノードのモジュールコードに import epdb; epdb.serve() を追加します。デバッガーに接続するには、epdb.connect() を実行します。host および port を指定する方法は、epdb ドキュメント を参照してください。リモートノードに接続する場合は、コントロールノードとリモートノードとの間のファイアウォールが許可されているポートを使用するようにしてください。
この手法はリモートデバッガーと動作しますが、特定のリモートデバッグツールが機能する保証はありません。
q ライブラリーは、もう 1 つの便利なデバッグツールです。
print() ステートメントはモジュール内では機能しないため、特定のデータを確認する場合は例外を発生させます。モジュール内のどこかに raise Exception(some_value) を置き、通常どおり実行します。Ansible はこの例外を処理し、メッセージをコントロールノードに渡し、表示します。