Я написал эту задачу ansible для запуска процесса на удаленном компьютере Vagrant. (Ну, на самом деле, сам файл 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 }}"
Работает со следующими переменными во включенном файле переменных:
---
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/run" после изменения каталога на "/home/myappname/bin". Если я делаю это вручную, все работает нормально, т. е. каталоги существуют, файлы читаются, скрипт работает и т. д., все отлично. Но если я запускаю скрипт, что-то, похоже, не так с генерацией кода выполнения 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, которые я использую с тем же набором переменных из некоторых соседних плейбуков, работают просто отлично. Также встроенные вещи, такие как group, user, file, apt, unarchive, copy. Обратите внимание, что некоторые из них также требуют, чтобы group/user вещи были правильными, поэтому я знаю, что это тоже нормально.
/edit: Я также знаю, что путь к скрипту запуска правильный, потому что если я переименую скрипт запуска и запущу плейбук, я получу еще одну ошибку («msg: [Errno 2] No such file or directory», как и ожидалось). Так что на самом деле он пытается запустить существующий скрипт запуска, но не может.
Но, похоже, ничего не работает. Что происходит, что не так с этим последним сгенерированным EXEC? Спасибо за ваше время.
решение1
Если вы пытаетесь запустить скрипт оболочки, проверьте:
Что в верхней части не пропущена строка-шебэнг, например:
#!/usr/bin/env bash
- Что пользователь ansible будет работать, так как имеет разрешения на выполнение для него (например, mode
0755
)
решение2
В общем случае «ошибка формата exec» в ansible может означать:
- программа, которую вы дали ansible для выполнения, в буквальном смысле не является исполняемым файлом.
- ansible обнаружил файл, помеченный как исполняемый, который на самом деле не является исполняемым, и попытался выполнить его.
Другими словами: это почти всегда означает, что разрешения неверны, но это может происходить в обоих направлениях (недостаточно привилегированные или избыточно привилегированные файлы могут вызывать ошибки exec по-разному).
Лично я обнаружил, что получаю такую ошибку, когда выполняю команды вроде «chmod 777 /etc/ansible/facts/..» в определенных каталогах и т. д.
решение3
"Ошибка формата Exec" означает, попросту говоря, что вы попытались выполнить файл, который ядро не распознает как допустимую программу – он в неподходящем формате. В этом случае это, похоже, относится к rm
целевому серверу.
Подключитесь напрямую к серверу по SSH и проверьте, что он rm
работает; используйте file $(which rm)
для проверки его формата (сравните с другими инструментами, такими как mkdir
). Сделайте то же самое /usr/bin/python
на всякий случай. Возможно, он был скопирован из системы с другой архитектурой, или из другой ОС, или просто заполнен мусором.
решение4
Проверьте, что
#!/usr/bin/env bash
находится в строке 1. В моем случае ansible выдал ошибку из-за того, что было в строке 2