我编写了这个 ansible 任务来在远程 vagrant box 上运行一个进程。(实际上 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 文件中的这些 var 一起工作:
---
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
如果您尝试运行的是 shell 脚本,请检查:
它没有缺少顶部的一行,例如:
#!/usr/bin/env bash
- 用户 ansible 将以具有执行权限的身份运行(例如模式
0755
)
答案2
一般来说,ansible 中的 'exec format error' 可能意味着:
- 您让 ansible 执行的程序实际上并不是可执行文件。
- ansible 发现一个标记为可执行文件但实际上不可执行的文件,并尝试执行它。
换句话说:它几乎总是意味着权限不正确,但它可能在两个方向上发生(权限不足或权限过高的文件可能以不同的方式导致执行错误)。
就我个人而言,我发现当我在某些目录等上执行“chmod 777 /etc/ansible/facts/..”之类的操作时会出现这样的错误。
答案3
“执行格式错误”的意思是,您尝试执行一个内核无法识别为有效程序的文件——该文件的格式不合适。在这种情况下,这似乎适用于rm
目标服务器。
直接通过 SSH 进入服务器并验证其是否rm
正常工作;使用file $(which rm)
检查其格式(与其他工具进行比较,如mkdir
)。以防万一,请对 执行相同操作/usr/bin/python
。也许它是从不同的架构系统复制而来,或者从不同的操作系统复制而来,或者完全充满了垃圾。
答案4
检查
#!/usr/bin/env bash
位于第 1 行的内容。在我的例子中,ansible 报错,原因是第 2 行的内容