Ansible-Befehlsaufgabe führt zu „Exec-Formatfehler“

Ansible-Befehlsaufgabe führt zu „Exec-Formatfehler“

Ich habe diese Ansible-Aufgabe geschrieben, um einen Prozess auf einer Remote-Vagrant-Box auszuführen. (Tatsächlich ist die Ansible-Datei selbst viel länger, aber dies ist ein Reproduzierer, dernurführt das Startskript aus.)

---
- 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 }}"

Es funktioniert mit diesen Variablen in der enthaltenen Variablendatei:

---
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"

Die Idee ist, den Benutzer „myappname“ auf der Remote-Box zu verwenden (korrekt mit „myappname_server“ als Alias ​​versehen, andere Spiele, die ich dagegen ausführe, funktionieren genauso gut), um „/home/myappname/bin/run“ auszuführen, nachdem das Verzeichnis in „/home/myappname/bin“ geändert wurde. Wenn ich das manuell mache, funktioniert alles einwandfrei, d. h. die Verzeichnisse existieren, die Dateien sind lesbar, das Skript funktioniert usw., alles großartig. Aber wenn ich das Skript ausführe, scheint etwas mit der Generierung des Ansible-Ausführungscodes nicht zu stimmen. Liegt es an mir und meiner Konfiguration (hoffentlich)? Ist es Ansible?

Ich habe es mit -vvvv ausgeführt, um viele Informationen zu erhalten:

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   

Ich habe Dinge ausprobiert wie:

  • Herumspielen mit Schrägstrichen nach dem Verzeichnis
  • Verwendung mit relativen und absoluten Pfaden auf dem Remotecomputer
  • Arbeiten mit und ohne sudo und sudo_user in meinen Aufgaben

Ich weiß, dass alle anderen Ansible-Module, die ich mit derselben Gruppe von Variablen aus einigen benachbarten Playbooks verwende, einwandfrei funktionieren. Auch integrierte Dinge wie Gruppe, Benutzer, Datei, apt, Archivierung aufheben, Kopieren. Beachten Sie, dass einige davon auch erfordern, dass die Gruppen-/Benutzer-Sachen korrekt sind, also weiß ich, dass das auch alles in Ordnung ist.

/edit: Ich weiß auch, dass der Pfad zum Run-Skript korrekt ist, denn wenn ich das Run-Skript umbenenne und das Playbook ausführe, erhalte ich einen weiteren Fehler („msg: [Errno 2] Keine solche Datei oder kein solches Verzeichnis“, wie erwartet). Es versucht also tatsächlich, das vorhandene Run-Skript auszuführen, aber es schlägt fehl.

Aber nichts scheint zu funktionieren. Was ist los, was ist falsch an dem letzten Teil des generierten EXEC-Materials? Vielen Dank für Ihre Zeit.

Antwort1

Wenn Sie versuchen, ein Shell-Skript auszuführen, überprüfen Sie:

  • Dass am Anfang keine Shebang-Zeile fehlt, wie:

    #!/usr/bin/env bash
    
  • Der Benutzer, unter dem Ansible ausgeführt wird, hat Ausführungsberechtigungen dafür (z. B. mode 0755).

Antwort2

Im Allgemeinen kann „Exec-Formatfehler“ in Ansible Folgendes bedeuten:

  • Ein Programm, das Sie Ansible zur Ausführung gegeben haben, ist buchstäblich keine ausführbare Datei.
  • Ansible hat eine als ausführbare Datei markierte Datei gefunden, die nicht wirklich ausführbar ist, und versucht, sie auszuführen.

Mit anderen Worten: Es bedeutet fast immer, dass die Berechtigungen falsch sind, es kann jedoch in beide Richtungen passieren (Dateien mit unter- oder überprivilegierten Berechtigungen können auf unterschiedliche Weise Exec-Fehler verursachen).

Ich persönlich habe festgestellt, dass ich einen solchen Fehler erhalte, wenn ich Dinge wie „chmod 777 /etc/ansible/facts/..“ in bestimmten Verzeichnissen usw. mache.

Antwort3

rm„Exec-Formatfehler“ bedeutet einfach, dass Sie versucht haben, eine Datei auszuführen, die der Kernel nicht als gültiges Programm erkennt – sie hat ein ungeeignetes Format. In diesem Fall scheint das auf den Zielserver zuzutreffen .

Verbinden Sie sich per SSH direkt mit dem Server und prüfen Sie, ob es rmfunktioniert. Verwenden Sie , file $(which rm)um das Format zu überprüfen (vergleichen Sie es mit anderen Tools wie mkdir). Machen Sie dasselbe mit /usr/bin/pythonnur für den Fall. Vielleicht wurde es von einem System mit anderer Architektur oder einem anderen Betriebssystem kopiert oder einfach mit Müll gefüllt.

Antwort4

Überprüfen Sie, ob #!/usr/bin/env bash sich in Zeile 1 befindet. In meinem Fall hat Ansible einen Fehler ausgegeben, weil in Zeile 2 etwas stand

verwandte Informationen