Kemungkinan gagal dengan / bin / sh: 1: / usr / bin / python: tidak ditemukan

187

Saya mengalami kesalahan yang belum pernah saya lihat sebelumnya. Inilah perintah dan kesalahannya:

$ 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

Ini file create_api.yml:

---

- hosts: api
  remote_user: root
  roles:
    - api

Dan inilah file hosts:

[api]
104.55.47.224

Saya dapat menghapus bagian peran dan itu tidak akan sampai ke TUGAS pertama, itu malah akan membuatnya hanya ke baris /bin/sh: 1: /usr/bin/python: not found. Apa yang mungkin terjadi di sini?


CATATAN: Jika ada orang yang melakukan ping alamat IP dan gagal mendapatkan respons, Anda harus tahu saya telah mengubah alamat IP sejak menempelkan kode.

EDIT python diinstal secara lokal, masalahnya adalah itu tidak diinstal pada mesin jarak jauh, yang menjalankan Ubuntu 15.04

jdavis
sumber

Jawaban:

171

Saya menemukan kesalahan ini menjalankan ansible di Ubuntu 15.10 server, karena ia dikirim dengan Python 3.4.3 dan ansible membutuhkan Python 2 .

Beginilah provision.ymlpenampilan saya sekarang:

- 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
  • Jangan lupa opsi -y (mengatakan ya untuk semua pertanyaan) dengan apt-get (atau modul mentah akan macet diam-diam)

  • gather_facts: no baris juga penting (karena kita tidak bisa mengumpulkan fakta tanpa python)

danau
sumber
12
Jadi peran selanjutnya tidak bisa menggunakan fakta ... adakah cara untuk mengumpulkan fakta lagi? aha, stackoverflow.com/questions/31054453/…
stephen
16
Perhatikan bahwa baris 'collect_facts: no' juga penting.
rcreswick
6
@ surfer190 temukan! Saya juga menemukan bahwa menambahkan action: setupsebagai pre_task terakhir juga bekerja dengan sangat baik :)
mrooney
1
@ surfer190 lihat jawaban saya di sini jika Anda menggunakan EC2 dengan memungkinkan, Anda dapat menggunakan CloudInit untuk menginstal python2 sehingga Anda dapat menggunakan mengumpulkan fakta seperti biasa.
Miroslav
1
Jika ada yang bertanya-tanya, tidak perlu menjalankan rawtugas untuk menginstal Python 2 di pre_tasks; biasa juga tasksberfungsi dengan baik. Tetapi memasukkannya pre_tasks, dengan tugas lain untuk memanggil setupmodul Ansible juga, akan memastikan fakta tersedia untuk setiap peran yang ditugaskan ke tuan rumah.
Kenny Evitt
125

An 2.2 dilengkapi fitur pratinjau teknologi dukungan Python 3. Untuk memanfaatkan ini (jadi Anda tidak perlu menginstal Python 2 di Ubuntu 16.04), cukup atur ansible_python_interpreteropsi konfigurasi ke /usr/bin/python3. Ini dapat dilakukan berdasarkan per-host dalam file inventaris Anda:

[db]
123.123.123.123 ansible_python_interpreter=/usr/bin/python3
jamix
sumber
Saya mencoba menambahkan / usr / bin / python ke variabel ini, tetapi tidak berhasil. Menambahkan python3 sebagai gantinya berhasil dan masalah ini diperbaiki
Deep LF
98

Solusi 1:

Jika Anda menggunakan Ansible >2.2.0, Anda dapat mengatur ansible_python_interpreteropsi konfigurasi ke /usr/bin/python3:

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

atau dalam file inventaris Anda:

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

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

Solusi 2:

Jika Anda menggunakan Ansible <2.2.0maka Anda dapat menambahkan ini pre_taskske buku pedoman Anda:

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

UPDATE Dengan ansible 2.8.x, Anda tidak perlu khawatir tentang hal itu, itu bekerja di luar kotak untuk python> 3,5 untuk kedua controller dan mesin target (s)

Arbab Nazar
sumber
Jika Anda menjalankan buku pedoman menggunakan tag, pastikan Anda menambahkan tag: selalu ke tugas pengaturan - jika tidak, maka tidak akan mengumpulkan fakta saat Anda menggunakan tag.
Ionut Bajescu
16
Saya punya ansible 2.3.0.0dan itu tidak berhasil di luar kotak. Kesalahan yang sama seperti yang diposting oleh OP.
The Coder
Dalam hal ini tidak jelas secara eksplisit, Anda harus menambahkan ini ke file inventaris host, bukan ke vars yang disertakan, yaitu, itu duduk di file inventaris yang sama dengan alamat / nama host.
Shawn Mehan
32

Anda dapat menggunakan modul mentah untuk menginstal Python di host jarak jauh:

- raw: sudo apt-get install python-simplejson
Udondan
sumber
11
Untuk memastikan ini dipanggil sebelum tugas dalam peran Anda, dan sebelum ada dependensi dalam file meta Anda, tambahkan seperti ini ke buku pedoman Anda: pre_tasks: - raw: sudo apt-get install python-simplejson
Laurens Rietveld
5
Perhatikan bahwa dalam buku pedoman, Anda juga harus menonaktifkan collect_facts, atau ini akan gagal sebelum menjalankan perintah mentah. (collect_facts: no)
rcreswick
@ Arcreswick Itu adalah masalah saya dan solusi Anda bekerja untuk saya. Terima kasih banyak. Saya meletakkan baris "assemb_facts: no" di file .yml utama saya (setup-ansible.yml) dan menjalankan playbook dengan perintah ini: "ansible-playbook -i hosts setup-ansible.yml --flush-cache -vvvvvv -kK ". Saya menggunakan opsi "-kK" dengan anbook-playbook karena instalasi ubuntu default memerlukan kata sandi untuk melakukan "sudo".
Ali Yousefi Sabzevar
mengapa Anda menginstal simplejson dan bukan pytghon tetapi berbicara tentang cara menginstal python?
Henning
@Henning python-simplejsonditulis dalam Python dan karenanya membutuhkan Python. simplejson juga merupakan persyaratan untuk sebagian besar modul inti Ansible. Dengan menginstal python-simplejsonmelalui apt-get/ yumAnda juga menginstal Python dan karena itu mencakup semua dependensi dasar yang mungkin ...
udondan
18

Untuk meringkas jawaban orang lain, berikut adalah pengaturan gabungan yang berfungsi untuk saya:

 - 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
Polisi
sumber
14

Saya pribadi menemukan 3 solusi yang mungkin untuk masalah ini yang bekerja dengan baik dalam situasi yang berbeda:

Opsi 1 - Tetapkan ansible_python_interpreter: /usr/bin/python3untuk host yang telah python3menginstal secara default

Saya pikir ini adalah metode yang unggul untuk memecahkan masalah jika Anda memiliki cara untuk mengelompokkan host Anda dengan apakah mereka telah python3menginstal secara default atau tidak . Sejauh yang saya ketahui, python3tersedia di semua rilis Ubuntu 16.04 dan lebih tinggi.

  • Jika semua host pasti memilikinya python3, Anda dapat menambahkan variabel ke group_vars/all.yml(atau yang setara) Anda:
# group_vars/all.yml

ansible_python_interpreter: /usr/bin/python3
  • Jika beberapa host Anda tidak memiliki python3dan Anda memiliki cara untuk memberi tag mereka ketika menggunakan inventaris dinamis (mis. Untuk penandaan AWS ec2.py), Anda dapat menerapkan variabel ke host tertentu seperti ini:
# group_vars/tag_OS_ubuntu1804.yml

ansible_python_interpreter: /usr/bin/python3
  • Jika Anda menggunakan inventaris statis dan dapat mengelompokkan host berdasarkan apakah ada python3, Anda dapat melakukan sesuatu seperti ini:
# inventory/hosts

[python2_hosts]
centos7_server

[python3_hosts]
u1804_server

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

Saya paling suka opsi ini karena tidak memerlukan perubahan pada host jarak jauh dan hanya perubahan kecil pada variabel, yang bertentangan dengan opsi 2 dan 3, yang membutuhkan penambahan untuk setiap buku pedoman.

Opsi 2 - Instal Python 2 menggunakan raw

Opsi ini mengharuskan Anda meletakkan permainan di bagian atas setiap buku pedoman gather_facts: falseyang digunakan rawuntuk memasang python:

- 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: truediperlukan jika Anda berencana untuk menjalankan permainan pada host yang belum apt-getmenginstal (misalnya apa pun berbasis RHEL), jika tidak mereka akan kesalahan dalam bermain pertama.

Solusi ini berfungsi, tetapi merupakan yang terendah dalam daftar saya karena beberapa alasan:

  1. Harus ada di bagian atas setiap buku pedoman (sebagai lawan dari opsi 1)
  2. Diasumsikan aptada pada sistem dan mengabaikan kesalahan (tidak seperti opsi 3)
  3. apt-get perintah lambat (tidak seperti opsi 3)

Opsi 3 - /usr/bin/python -> /usr/bin/python3Menggunakan tautanraw

Saya belum melihat solusi yang diusulkan oleh orang lain. Ini tidak ideal, tapi saya pikir itu lebih unggul dari opsi 2 dalam banyak hal. Saran saya adalah menggunakan rawmenjalankan perintah shell untuk symlink /usr/bin/python -> /usr/bin/python3jika python3ada pada sistem dan python tidak:

- 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

Solusi ini mirip dengan opsi 2 di mana kita perlu meletakkannya di bagian atas setiap buku pedoman, tapi saya pikir itu unggul dalam beberapa cara:

  • Hanya membuat symlink dalam kasus khusus yang python3ada dan pythontidak ada - itu tidak akan menimpa Python 2 jika sudah diinstal
  • Tidak berasumsi aptdiinstal
  • Dapat berjalan melawan semua host tanpa penanganan kesalahan khusus
  • Sangat cepat dibandingkan dengan apa pun dengan apt-get

Tentunya jika Anda perlu menginstal Python 2 di /usr/bin/python, solusi ini adalah no go dan opsi 2 lebih baik.

Kesimpulan

  • Saya sarankan menggunakan opsi 1 dalam semua kasus jika Anda bisa.
  • Saya sarankan menggunakan opsi 3 jika inventaris Anda benar-benar besar / kompleks dan Anda tidak memiliki cara untuk dengan mudah mengelompokkan host python3, membuat opsi 1 jauh lebih sulit dan rawan kesalahan.
  • Saya hanya menyarankan opsi 2 di atas opsi 3 jika Anda perlu menginstal Python 2 di /usr/bin/python.

Sumber

percygrunwald
sumber
13

Anda perlu python 2.7 untuk menjalankan Ansible. Di Ubuntu 16.04, Anda dapat menginstalnya melalui perintah ini:

sudo apt-get install python-minimal

Setelah itu, saya bisa lari

ansible-playbook -i inventories/staging playbook.yml

Jalankan dengan sukses

Silakan periksa lebih lanjut di Menggunakan ansible di Ubuntu 16.04

phanvugiap
sumber
12

Apa yang saya gunakan untuk menjalankan ini di ubuntu 15.10 pada tetesan Digital Ocean baru:

# 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

Untuk ubuntu 16.04 pada SSD OVH yang baru, saya harus apt-get upgrade sebelum paket python2 tersedia.

paling mematikan
sumber
8

Saya menemukan bahwa sebenarnya mungkin untuk memiliki beberapa permainan dalam satu buku pedoman, jadi pengaturan saya sekarang berisi permainan "penyediaan ketergantungan" yang berjalan pada semua host, dan drama lain untuk host tertentu. Jadi tidak ada lagi pre_tasks.

Sebagai contoh:

- 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
  # ....
Koen.
sumber
6

Seperti yang orang lain katakan, ini disebabkan oleh hilangnya python2. Jawaban lain di sini memberikan solusi pre_tasksdan gather_facts: no, namun jika Anda menggunakan EC2 dan memutar instance dengan memungkinkan, Anda dapat menggunakan user_dataopsi:

- 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

Maka orang biasanya menunggu ssh tersedia seperti ini:

  - 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

Namun saya telah menemukan, bahwa ini tidak selalu cukup lama karena CloudInit dieksekusi cukup terlambat dalam proses boot sehingga python2 masih mungkin tidak diinstal tepat setelah ssh tersedia. Jadi saya telah menambahkan jeda jika instance baru saja dibuat:

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

Ini akan melakukan pekerjaan dengan sempurna dan sebagai keuntungan Anda tidak memeriksa python2 pada setiap kali menjalankan dan Anda tidak perlu melakukan solusi untuk mengumpulkan fakta nanti.

Saya yakin penyedia cloud lainnya menyediakan fungsionalitas CloudInit yang serupa, jadi sesuaikan untuk kasus penggunaan Anda.

Miroslav
sumber
3

Mereka yang menggunakan Packer dapat menemukan solusi di bawah ini bermanfaat

mari kita asumsikan bahwa Anda menggunakan penyedia pembungkus yang mungkin, konfigurasi Anda mungkin terlihat seperti di bawah ini

Anda dapat menginstal python menggunakan penyedia shell terlebih dahulu kemudian mengkonfigurasi opsi ansible_python_intepreter seperti yang ditunjukkan di bawah ini

"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"
      ]
    },
smakintel.com
sumber
2

Secara default, Ansible membutuhkan Python 2 , namun, Ansible 2.2+ dapat bekerja dengan Python 3 juga.

Jadi instal Python 2 menggunakan rawmodul , mis

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

atau setel ansible_python_interpretervariabel dalam file inventaris, seperti:

[local]
localhost ansible_python_interpreter="env python3"

Untuk Docker, Anda dapat menambahkan baris berikut:

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

atau jalankan sebagai:

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

Menurut Gist ini Anda dapat menginstal Python2 di Ubuntu 16.04 sebagai berikut:

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.
wedesoft
sumber
1

Banyak jawaban .. Terima kasih telah memposting karena saya juga mulai dari halaman ini!

Saya melakukan sedikit penggalian dan solid dengan Ubuntu 14.04LTS, Ubuntu 15.04LTS tampaknya telah menjatuhkan yang terbaru python, dan Ubuntu 16.04LTS tampaknya telah turun aptitude.

Saya melakukan tindakan berikut di bootstrap saya sebelum melakukan aptpanggilan:

- 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

Jika Anda mengelola di becometempat lain, jangan ragu untuk menghapusnya.

Sumber:

sonjz
sumber
1

Saya dapat memperbaiki masalah yang sama dengan menginstal Python pada mesin target yaitu mesin yang ingin kita SSH. Saya telah menggunakan perintah berikut:

sudo apt-get install python-minimal
anshul
sumber
1

@Miroslav, terima kasih telah menunjukkan saya ke arah yang benar. Saya menggunakan user_datadalam ec2_instancemodul juga dan itu berfungsi seperti hadiah.

Yaitu

- 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     
Luuk
sumber
1

Anda dapat menunjukkan ke Ubuntu 18.04 bahwa Anda ingin menggunakan python3 sebagai prioritas pertama /usr/bin/python.

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

Saya memiliki masalah yang sama, sampai saya menyadari Anda juga perlu menginstal python pada host jarak jauh serta mesin lokal Anda sendiri. sekarang berhasil!

GAV
sumber
-2

Kami hanya mengalami ini.

Kami menggunakan ubuntu 16.04 di gelandangan jadi jika Anda tidak menggunakan gelandangan komentar saya tidak ada gunanya.

Kami memasang plugin gelandangan berikut (pemicu, shell-commander) dan kami mendapatkan python 2.7.6 diinstal pada mesin (yang bukan tanpa plugin thioose) dan setelah memungkinkan dapat menggunakan

Itu adalah tes terakhir kami, kalau tidak kami akan memasukkan instalasi ini dalam perintah shell dalam file Vagrant

Semoga bisa membantu seseorang

wadoo
sumber
2
Jika Anda menggunakan Ansible, solusi Ansible di bawah ini adalah perbaikan yang benar. Berharap bahwa Vagrant secara tidak sengaja akan menginstalnya untuk Anda sebagai efek samping dari beberapa plugin sepertinya meminta masalah.
Paul Becotte
Maaf, tapi bagaimana Anda bisa menjalankan pretask yang dapat dilakukan jika belum python ??? Saya mencoba solusinya dan gagal pada pengaturan tugas jadi acara sebelum tugas pra. Perintah shell gelandangan dalam file gelandangan ADALAH cara terbaik untuk melakukan itu (untuk kasus gelandangan tentu saja) tetapi saya hanya melihat bahwa plugin gelandangan saya telah diinstal pada dev saya melakukan pekerjaan. Saya tidak mengandalkan plugin tetapi pada file gelandangan, saya hanya menunjukkan bahwa itu berfungsi juga dengan plugin tetapi file gelandangan adalah pilihan yang lebih baik (juga untuk otomatisasi) karena Anda secara manual tidak perlu melakukan apa pun pada masing-masing menghancurkan / ketentuan
wadoo
1
Saya menyalin blok kode itu persis seperti itu, dan itu berfungsi persis seperti yang dijelaskan tepat sebelum Anda memposting jawaban Anda. Saya percaya Anda mungkin tidak memasukkan gather_facts: nobaris ke dalam- yang membutuhkan python. Kemungkinan lainnya adalah Anda juga perlu python pada mesin host, tetapi saya kira itu akan menyebabkan Anda melakukan kesalahan lebih awal dalam prosesnya.
Paul Becotte
Saya menyalin paste juga, tetapi hari jumat nigth sedang bekerja. Saya tidak dapat dengan sangat ingat ingat jika saya mengambil bagian collect_fact. Pokoknya di komputer lain ifaced lagi pagi ini dan saya baru saja menempatkan perintah di vagrantfile, itu cukup bagi saya sampai kita pergi ke produksi di server nyata. Saya akan menguji lagi dengan pikiran segar (jadi bukan malam Jumat) jawabannya;)
wadoo