it-swarm.com.de

Ansible schlägt fehl mit/bin/sh: 1:/usr/bin/python: nicht gefunden

Ich bin auf einen Fehler gestoßen, den ich noch nie gesehen habe. Hier ist der Befehl und der Fehler:

$ ansible-playbook create_api.yml

PLAY [straw] ******************************************************************

GATHERING FACTS ***************************************************************
failed: [104.55.47.224] => {"failed": true, "parsed": false}
/bin/sh: 1: /usr/bin/python: not found


TASK: [typical | install required system packages] *****************************
FATAL: no hosts matched or all hosts have already failed -- aborting


PLAY RECAP ********************************************************************
           to retry, use: --limit @/Users/john/create_api.retry

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

Hier ist die Datei create_api.yml:

---

- hosts: api
  remote_user: root
  roles:
    - api

Und hier ist die hosts-Datei:

[api]
104.55.47.224

Ich kann den Rollenabschnitt entfernen und er wird es nicht bis zur ersten AUFGABE schaffen, stattdessen wird er es nur in die Zeile /bin/sh: 1: /usr/bin/python: not found bringen. Was könnte hier los sein? 


HINWEIS: Falls jemand die IP-Adresse anpingt und keine Antwort erhält, sollten Sie wissen, dass ich die IP-Adresse seit dem Einfügen des Codes geändert habe.

EDIT python wurde lokal installiert. Das Problem war, dass es nicht auf dem Remote-Computer installiert war, auf dem Ubuntu 15.04 ausgeführt wurde

158
jdavis

Ich bin auf diesen Fehler gestoßen, der auf Ubuntu 15.10 -Server ausgeführt wird, da er mit Python 3.4.3 ausgeliefert wird und ansible Python 2 erfordert.

So sieht mein provision.yml jetzt aus:

- hosts: my_app
  Sudo: yes
  remote_user: root
  gather_facts: no
  pre_tasks:
    - name: 'install python2'
      raw: Sudo apt-get -y install python

  tasks:
    - name: 'ensure user {{ project_name }} exists'
      user: name={{ project_name }} state=present
  • Vergiss nicht die Option -y (sagt ja zu allen Fragen) mit apt-get (oder das Rohmodul bleibt stumm)

  • gather_facts: noline ist auch kritisch (da wir ohne Python keine Fakten sammeln können)

154
lakesare

Ansible 2.2 bietet eine technische Vorschau der Python 3-Unterstützung. Um dies zu nutzen (damit Sie Python 2 nicht auf Ubuntu 16.04 installieren müssen), setzen Sie die Option ansible_python_interpreter config auf /usr/bin/python3. Dies kann pro Host in Ihrer Inventardatei erfolgen:

[db]
123.123.123.123 ansible_python_interpreter=/usr/bin/python3
104
jamix

Lösung 1:

Wenn Sie Ansible >2.2.0 verwenden, können Sie die Konfigurationsoption ansible_python_interpreter auf /usr/bin/python3 setzen:

ansible my_ubuntu_Host -m ping -e 'ansible_python_interpreter=/usr/bin/python3'

oder in Ihrer Inventardatei:

[ubuntu_hosts]
<xxx.xxx.xxx.xxx>

[ubuntu_hosts:vars]
ansible_python_interpreter=/usr/bin/python3

Lösung 2:

Wenn Sie Ansible <2.2.0 verwenden, können Sie diese pre_tasks zu Ihrem Playbook hinzufügen:

gather_facts: False
pre_tasks:
  - name: Install python for Ansible
    raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
    register: output
    changed_when: output.stdout != ""
    tags: always
  - setup: # aka gather_facts
74
Arbab Nazar

Sie können das Modul raw verwenden, um Python auf den Remote-Hosts zu installieren:

- raw: Sudo apt-get install python-simplejson
31
udondan

Um die Antworten aller anderen zusammenzufassen, hier die kombinierten Einstellungen, die für mich funktioniert haben

 - hosts: all
   become: true
   gather_facts: false

   # Ansible requires python2, which is not installed by default on Ubuntu Xenial
   pre_tasks:
     - raw: Sudo apt-get -y install python-simplejson
     # action: setup will gather facts after python2 has been installed
     - action: setup
17
Bobby

Sie benötigen Python 2.7, um Ansible auszuführen. Unter Ubuntu 16.04 können Sie es mit diesem Befehl installieren:

Sudo apt-get install python-minimal

Danach konnte ich rennen 

ansible-playbook -i inventories/staging playbook.yml

Run ansible successfully

Bitte überprüfen Sie mehr unter Using ansible auf Ubuntu 16.04 .

13
phanvugiap

Ich persönlich habe 3 mögliche Lösungen für dieses Problem gefunden, die in verschiedenen Situationen gut funktionieren:

Option 1 - Stellen Sie ansible_python_interpreter: /usr/bin/python3 Für Hosts ein, auf denen standardmäßig python3 Installiert ist

Ich denke, dies ist die beste Methode, um das Problem zu lösen, wenn Sie die Möglichkeit haben, Ihre Hosts danach zu gruppieren, ob standardmäßig python3 Installiert ist oder nicht. Soweit mir bekannt ist, ist python3 Auf allen Ubuntu-Releases 16.04 und höher verfügbar.

  • Wenn alle Ihre Hosts definitiv python3 Haben, können Sie die Variable zu Ihrem group_vars/all.yml (Oder einem gleichwertigen Wert) hinzufügen:
# group_vars/all.yml

ansible_python_interpreter: /usr/bin/python3
  • Wenn einige Ihrer Hosts nicht über python3 Verfügen und Sie diese mithilfe des dynamischen Inventars mit Tags versehen können (z. B. AWS-Tagging für ec2.py), Können Sie die Variable auf bestimmte Hosts wie diesen anwenden :
# group_vars/tag_OS_ubuntu1804.yml

ansible_python_interpreter: /usr/bin/python3
  • Wenn Sie statisches Inventar verwenden und Hosts nach python3 Gruppieren können, können Sie Folgendes tun:
# inventory/hosts

[python2_hosts]
centos7_server

[python3_hosts]
u1804_server

[python3_hosts:vars]
ansible_python_interpreter=/usr/bin/python3

Ich mag diese Option am meisten, weil sie keine Änderungen auf dem Remote-Host und nur geringfügige Änderungen an Variablen erfordert, im Gegensatz zu den Optionen 2 und 3, die Ergänzungen zu jedem Playbook erfordern.

Option 2 - Installieren Sie Python 2 mit raw

Diese Option setzt voraus, dass jedes Playbook mit gather_facts: false, Das raw verwendet, um python zu installieren, oben mit einem Stück versehen wird:

- name: install python2 on all instances
  hosts: "*"
  gather_facts: false
  tasks:
    - name: run apt-get update and install python
      raw: "{{ item }}"
      loop:
        - Sudo apt-get update
        - Sudo apt-get -y install python
      become: true
      ignore_errors: true

ignore_errors: true Ist erforderlich, wenn Sie das Spiel auf Hosts ausführen möchten, auf denen apt-get Nicht installiert ist (z. B. auf RHEL-Basis). Andernfalls treten Fehler beim ersten Spiel auf.

Diese Lösung funktioniert, ist jedoch aus folgenden Gründen die niedrigste auf meiner Liste:

  1. Muss ganz oben in every playbook stehen (im Gegensatz zu Option 1)
  2. Angenommen, apt befindet sich im System und ignoriert Fehler (im Gegensatz zu Option 3)
  3. apt-get - Befehle sind langsam (im Gegensatz zu Option 3)

Option 3 - Symlink /usr/bin/python -> /usr/bin/python3 Mit raw

Ich habe diese von niemandem vorgeschlagene Lösung gesehen. Es ist nicht ideal, aber ich denke, es ist Option 2 in vielerlei Hinsicht überlegen. Mein Vorschlag ist, raw zu verwenden, um einen Shell-Befehl zum Verknüpfen von /usr/bin/python -> /usr/bin/python3 Auszuführen, wenn python3 Auf dem System vorhanden ist ndpython nicht:

- name: symlink /usr/bin/python -> /usr/bin/python3
  hosts: "*"
  gather_facts: false
  tasks:
    - name: symlink /usr/bin/python -> /usr/bin/python3
      raw: |
        if [ -f /usr/bin/python3 ] && [ ! -f /usr/bin/python ]; then
          ln --symbolic /usr/bin/python3 /usr/bin/python; 
        fi
      become: true

Diese Lösung ist ähnlich wie Option 2, da wir sie an die Spitze jedes Spielbuchs setzen müssen, aber ich denke, dass sie in einigen Punkten überlegen ist:

  • Erstellt den Symlink nur in dem speziellen Fall, dass python3 Vorhanden ist und python nicht - es wird Python 2 nicht überschrieben, wenn es bereits installiert ist
  • Geht nicht davon aus, dass apt installiert ist
  • Kann ohne spezielle Fehlerbehandlung auf allen Hosts ausgeführt werden
  • Ist super schnell im Vergleich zu allem mit apt-get

Wenn Sie brauchen Python 2 bei /usr/bin/python Installiert haben, ist diese Lösung ein No-Go und Option 2 ist besser.

Fazit

  • Ich schlage vor, Option 1 in allen Fällen zu verwenden, wenn Sie können.
  • Ich schlage vor, Option zu verwenden, wenn Ihr Inventar wirklich groß/komplex ist und Sie keine Möglichkeit haben, Hosts mit python3 Einfach zu gruppieren, was Option 1 viel schwieriger macht und fehleranfällig.
  • Ich empfehle nur Option 2 über Option, wenn Sie Python 2 bei /usr/bin/python Installiert haben müssen.

Quellen

12
percygrunwald

Was ich früher auf Ubuntu 15.10 an einem frischen Digital-Ocean-Tropfen gearbeitet habe:

# my-playbook.yml
- name: python2
  hosts: test
  gather_facts: no
  pre_tasks:
    - raw: Sudo apt-get -y install python-simplejson

$ ansible-playbook path/to/my-playbook.yml

Für Ubuntu 16.04 auf einer neuen OVH-SSD musste ich apt-get upgraden, bevor die python2-Pakete verfügbar waren.

11
deadghost

Ich habe herausgefunden, dass es tatsächlich möglich ist, mehrere Spiele in einem einzigen Spielbuch zu haben. Daher enthält mein Setup jetzt ein "Abhängigkeitsbereitstellung", das auf allen Hosts läuft, und andere Spiele für bestimmte Hosts. Also kein pre_tasks mehr.

Zum Beispiel:

- name: dependency provisioning
  hosts: all
  become: yes
  become_method: Sudo
  gather_facts: false
  tasks:
    - name: install python2
      raw: Sudo apt-get -y install python-simplejson

- name: production
  hosts: production_Host
  roles:
    - nginx
  tasks:
    - name: update apt cache
      apt: update_cache=yes cache_valid_time=3600
  # ....

- name: staging
  hosts: staging_Host
  roles:
    - nginx
  tasks:
    - name: update apt cache
      apt: update_cache=yes cache_valid_time=3600
  # ....
8
Koen.

Wie andere sagten, liegt dies an fehlendem Python2. Andere Antworten hier bieten eine Problemumgehung mit pre_tasks und gather_facts: no. Wenn Sie jedoch mit EC2 arbeiten und die Instanz mit ansible starten, können Sie die user_data-Option verwenden:

- ec2:
    key_name: mykey
    instance_type: t2.micro
    image: AMI-123456
    wait: yes
    group: webserver
    count: 3
    vpc_subnet_id: subnet-29e63245
    assign_public_ip: yes
    user_data: |
      #!/bin/bash
      apt-get update
      apt-get install -y python-simplejson
    register: ec2

Dann warten die Leute normalerweise darauf, dass ssh so verfügbar ist: 

  - name: "Wait for the instances to boot and start ssh"
    wait_for:
      Host: "{{item.public_ip}}"
      port: 22
      delay: 5
      timeout: 300
    with_items: "{{ ec2.tagged_instances }}"
    when: ec2|changed

Ich habe jedoch festgestellt, dass dies nicht immer lange genug ist, da CloudInit ziemlich spät im Bootvorgang ausgeführt wird, sodass der Python2 möglicherweise nicht direkt installiert wird, nachdem ssh verfügbar ist. Ich habe also eine Pause hinzugefügt, falls die Instanz gerade erstellt wurde:

  - name: "Wait for cloud init on first boot"
    pause: minutes=2
    when: ec2|changed

Dies erledigt die Aufgabe perfekt, und als Vorteil wird nicht bei jedem Durchlauf nach Python2 gesucht, und Sie müssen keine Problemumgehungen durchführen, um später Informationen zu sammeln.

Ich bin sicher, dass andere Cloud-Anbieter eine ähnliche CloudInit-Funktionalität bieten, passen Sie sich also an Ihren Anwendungsfall an. 

5
Miroslav

@Miroslav, danke, dass du mich in die richtige Richtung zeigst. Ich habe auch user_data im ec2_instance-Modul verwendet und es funktioniert wie ein Genuss. 

Das heißt.

- name: Creating single EC2 instance 
  ec2_instance:
    region: "{{ aws_region }}"
    key_name: "{{ aws_ec2_key_pair }}"
    name: "some-cool-name"
    instance_type: t1.micro
    image_id: AMI-d38a4ab1
    security_group: sg-123456
    vpc_subnet_id: sn-678901234
    network:
        assign_public_ip: no
    volumes:
      - device_name: /dev/sda1
        ebs:
          volume_type: gp2
          volume_size: 15
    user_data: |
      #!/bin/bash
      #
      apt update
      apt install -y python-simplejson              
    termination_protection: yes
    wait: yes     
1
Luuk

Ich konnte das gleiche Problem beheben, indem ich Python auf dem Zielrechner installierte, d. H. Dem Rechner, auf den wir SSH wollen. Ich hatte folgenden Befehl verwendet:

Sudo apt-get install python-minimal
1
anshul

Viele Antworten .. Danke fürs Posting, da ich auch von dieser Seite angefangen habe!

Ich grub ein bisschen und es war solide mit Ubuntu 14.04LTS, Ubuntu 15.04LTS schien den neuesten python gelöscht zu haben, und Ubuntu 16.04LTS schien aptitude fallen zu lassen.

Ich füge die folgende Aktion in meinen Bootstrap ein, bevor ich apt aufrufe:

- name: "FIX: Ubuntu 16.04 LTS doesn't come with certain modules, required by ansible"
  raw: apt-get install python-minimal aptitude -y
  become: true
  become_user: root
  become_method: Sudo

Wenn Sie become an anderer Stelle verwalten, können Sie es entfernen.

Quellen:

1
sonjz

Nach this Gist können Sie Python2 auf Ubuntu 16.04 wie folgt installieren:

enter code here
gather_facts: False
pre_tasks:
  - raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
  - setup: # aka gather_facts

tasks:
  # etc. etc.
1
wedesoft

Standardmäßig benötigt Ansible Python 2 , jedoch kann Ansible 2.2+ auch mit Python 3 funktionieren.

Installieren Sie entweder Python 2 mithilfe des Moduls raw , z.

ansible localhost --Sudo -m raw -a "yum install -y python2 python-simplejson"

oder setze ansible_python_interpreter variable in der Inventardatei wie:

[local]
localhost ansible_python_interpreter="env python3"

Für Docker können Sie folgende Zeile hinzufügen:

RUN printf '[local]\r\nlocalhost ansible_python_interpreter="env python3"\r\n' > /etc/ansible/hosts

oder führe es als:

ansible-playbook /ansible/provision.yml -e 'ansible_python_interpreter=/usr/bin/python3' -c local
1
kenorb

Für Benutzer, die Packer verwenden, ist die folgende Lösung möglicherweise hilfreich

nehmen wir an, Sie verwenden einen ansible provisioner of packer. Ihre Konfiguration könnte wie folgt aussehen

sie können Python zuerst mit Shell Provisioner installieren und dann die Option ansible_python_intepreter wie unten gezeigt konfigurieren

"provisioners": [
    {
      "type": "Shell",
      "inline": [
        "apk update && apk add --no-cache python python-dev ansible bash"
      ]
    },
    {
      "type": "ansible-local",
      "playbook_file": "playbooks/your-play-book.yml",
      "playbook_dir": "playbooks",
      "extra_arguments": [
        "-e",
        "'ansible_python_interpreter=/usr/bin/python3'",
        "-vvv"
      ]
    },
1
smakintel.com

Sie können Ubuntu 18.04 mitteilen, dass Sie Python3 als erste Priorität für /usr/bin/python verwenden möchten.

- hosts: all
  become: true
  pre_tasks:
    - raw: update-alternatives --install /usr/bin/python python /usr/bin/python3 1
0
Ryan

Ich hatte das gleiche Problem, bis mir klar wurde, dass Sie Python sowohl auf dem Remote-Host als auch auf Ihrem eigenen lokalen Computer installieren müssen. jetzt gehts!

0
GAV