Ansible コマンドタスクが「Exec 形式エラー」に遭遇する

Ansible コマンドタスクが「Exec 形式エラー」に遭遇する

リモートのVagrant Boxでプロセスを実行するために、このAnsibleタスクを書きました。(実際、Ansibleファイル自体はもっと長いのですが、これは再現するためのものです。のみ起動スクリプトを実行します。

---
- hosts: myappname_server
  vars_files:
    - install_myappname_vars.yaml
  gather_facts: false
  sudo: true
  sudo_user: "{{ project_name }}"

  tasks:
  - name: Restart application
    command: "{{ project_target_dir_env }}/run"
    args:
      chdir: "{{ project_target_dir_env }}"

これは、含まれている vars ファイル内の次の変数で動作します。

---
project_name: myappname
project_source_dir_files: files/myappname
project_source_dir_env: "{{ project_source_dir_files }}/environment_files"
project_target_root: /home/myappname
project_target_dir_env: "{{ project_target_root }}/bin"

アイデアは、リモート ボックスのユーザー「myappname」(「myappname_server」で正しくエイリアス化されています。私が実行する他のプレイは問題なく動作します) を使用して、ディレクトリを「/home/myappname/bin」に変更した後、「/home/myappname/bin/run」を実行することです。これを手動で実行すると、すべて正常に動作します。つまり、ディレクトリが存在し、ファイルが読み取り可能で、スクリプトが動作するなど、すべて問題ありません。ただし、スクリプトを実行すると、Ansible 実行コードの生成に問題があるようです。これは私と私の構成の問題でしょうか (そう願っています)? Ansible ですか?

多くの情報を取得するために、-vvvv で実行しました。

monsterkill@monsterkill-ub-dt:~/playbooks$ ansible-playbook install_myappname_restart.yaml -vvvv

PLAY [myappname_server] ********************************************************** 

TASK: [Restart application] *************************************************** 
<vagrant1> ESTABLISH CONNECTION FOR USER: vagrant
<vagrant1> REMOTE_MODULE command chdir=/home/myappname/bin /home/myappname/bin/run
<vagrant1> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/home/monsterkill/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'Port=22', '-o', 'IdentityFile=/home/monsterkill/insecure_private_key', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', 'vagrant1', "/bin/sh -c 'mkdir -p /tmp/ansible-tmp-1422343063.07-259463565013754 && chmod a+rx /tmp/ansible-tmp-1422343063.07-259463565013754 && echo /tmp/ansible-tmp-1422343063.07-259463565013754'"]
<vagrant1> PUT /tmp/tmpBduhE7 TO /tmp/ansible-tmp-1422343063.07-259463565013754/command
<vagrant1> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/home/monsterkill/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'Port=22', '-o', 'IdentityFile=/home/monsterkill/insecure_private_key', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', 'vagrant1', "/bin/sh -c 'chmod a+r /tmp/ansible-tmp-1422343063.07-259463565013754/command'"]
<vagrant1> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/home/monsterkill/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'Port=22', '-o', 'IdentityFile=/home/monsterkill/insecure_private_key', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', 'vagrant1', u'/bin/sh -c \'sudo -k && sudo -H -S -p "[sudo via ansible, key=ucmsbsauynfzeeyxwdmgfduwovdneeqg] password: " -u myappname /bin/sh -c \'"\'"\'echo SUDO-SUCCESS-ucmsbsauynfzeeyxwdmgfduwovdneeqg; /usr/bin/python /tmp/ansible-tmp-1422343063.07-259463565013754/command\'"\'"\'\'']
<vagrant1> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/home/monsterkill/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'Port=22', '-o', 'IdentityFile=/home/monsterkill/insecure_private_key', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', 'vagrant1', "/bin/sh -c 'rm -rf /tmp/ansible-tmp-1422343063.07-259463565013754/ >/dev/null 2>&1'"]
failed: [vagrant1] => {"cmd": ["/home/myappname/bin/run"], "failed": true, "rc": 8}
msg: [Errno 8] Exec format error

FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/home/monsterkill/install_myappname_restart.yaml.retry

vagrant1                   : ok=0    changed=0    unreachable=0    failed=1   

私は次のようなことを試しました:

  • ディレクトリの後のスラッシュで遊ぶ
  • リモートマシン上の相対パスと絶対パスを使用する
  • タスクで sudo と sudo_user の有無にかかわらず作業する

隣接するプレイブックからの同じ一連の変数を使用して使用する他のすべての Ansible モジュールは、問題なく動作することがわかっています。また、グループ、ユーザー、ファイル、apt、アーカイブ解除、コピーなどの組み込みのものも。これらの多くでは、グループ/ユーザーのものが正しいことも必要であることに注意してください。そのため、これもすべて問題ないことがわかっています。

/edit: 実行スクリプトへのパスが正しいこともわかっています。実行スクリプトの名前を変更してプレイブックを実行すると、別のエラー (予想どおり、「msg: [Errno 2] そのようなファイルまたはディレクトリはありません」) が発生するためです。つまり、実際には既存の実行スクリプトを実行しようとしていますが、失敗しています。

しかし、何も機能していないようです。何が起こっているのでしょうか。生成された EXEC の最後の部分に何が問題なのでしょうか。お時間をいただきありがとうございました。

答え1

実行しようとしているのがシェル スクリプトである場合は、次の点を確認してください。

  • 次のように、先頭にシェバン行が欠落していないことを確認します。

    #!/usr/bin/env bash
    
  • ansible を実行するユーザーには実行権限があること (例: mode 0755)

答え2

一般的に、Ansible の「exec フォーマット エラー」は次のような意味になります。

  • Ansible に実行を指示したプログラムは、文字通り実行可能ファイルではありません。
  • ansible は、実際には実行可能ではない実行可能ファイルとしてマークされたファイルを検出し、それを実行しようとしました。

言い換えると、ほとんどの場合、権限が正しくないことを意味しますが、両方向に発生する可能性があります (権限が不足しているファイルや権限が過剰なファイルは、さまざまな方法で exec エラーを引き起こす可能性があります)。

個人的には、特定のディレクトリなどで「chmod 777 /etc/ansible/facts/..」などの操作を実行すると、このようなエラーが発生することがわかりました。

答え3

「実行形式エラー」とは、カーネルが有効なプログラムとして認識しない、つまり不適切な形式のファイルを実行しようとしたことを意味します。この場合、これはrmターゲット サーバーに当てはまるようです。

サーバーに直接 ssh して、 がrm機能することを確認します。 を使用してfile $(which rm)形式を確認します ( などの他のツールと比較しますmkdir)。念のため、 でも同じ操作を行います/usr/bin/python。おそらく、異なるアーキテクチャ システムまたは異なる OS からコピーされたか、完全にゴミで満たされている可能性があります。

答え4

1行目にあることを確認してください #!/usr/bin/env bash 。私の場合、2行目にある内容が原因でAnsibleはエラーを出しました。

関連情報