it-swarm.com.ru

Сбой Ansible с/bin/sh: 1:/usr/bin/python: не найден

Я сталкиваюсь с ошибкой, которую я никогда не видел прежде. Вот команда и ошибка:

$ 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

Вот файл create_api.yml:

---

- hosts: api
  remote_user: root
  roles:
    - api

И вот файл hosts:

[api]
104.55.47.224

Я могу удалить раздел ролей, и он не попадет в первую ЗАДАЧУ, вместо этого он сделает это только в строке /bin/sh: 1: /usr/bin/python: not found. Что здесь может происходить? 


ПРИМЕЧАНИЕ: Если кто-либо пингует IP-адрес и не может получить ответ, вы должны знать, что я изменил IP-адрес с момента вставки кода.

EDIT python был установлен локально, проблема была в том, что он не был установлен на удаленной машине, на которой работала Ubuntu 15.04

158
jdavis

Я наткнулся на эту ошибку при запуске ansible на сервере Ubuntu 15.10, поскольку он поставляется с Python 3.4.3 и ansible требует Python 2 .

Вот как выглядит мой provision.yml:

- 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
  • Не забудьте опцию -y (ответьте «да» на все вопросы) с помощью apt-get (иначе модуль raw застрянет молча)

  • gather_facts: noline также критична (потому что мы не можем собрать факты без python)

154
lakesare

Ansible 2.2 имеет технический предварительный просмотр поддержки Python 3. Чтобы воспользоваться этим преимуществом (чтобы вам не приходилось устанавливать Python 2 в Ubuntu 16.04), просто установите для параметра конфигурации ansible_python_interpreter значение /usr/bin/python3. Это можно сделать для каждого хоста в файле инвентаризации:

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

Решение 1:

Если вы используете Ansible >2.2.0, вы можете установить для параметра конфигурации ansible_python_interpreter значение /usr/bin/python3:

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

или в вашем инвентарном файле:

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

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

Решение 2:

Если вы используете Ansible <2.2.0, тогда вы можете добавить эти pre_tasks в свою книгу игр:

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

Вы можете использовать модуль raw для установки Python на удаленных хостах:

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

Чтобы суммировать ответы всех остальных, вот комбинированные настройки, которые работали для меня:

 - 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

Вам нужен Python 2.7 для запуска Ansible. В Ubuntu 16.04 вы можете установить его с помощью этой команды:

Sudo apt-get install python-minimal

После этого я мог бежать 

ansible-playbook -i inventories/staging playbook.yml

 Run ansible successfully

Пожалуйста, проверьте больше на Использование ansible в Ubuntu 16.04

13
phanvugiap

То, что я использовал, чтобы это работало на Ubuntu 15.10 над новой каплей Digital Ocean:

# 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

Для Ubuntu 16.04 на новом SSD OVH мне пришлось обновить apt-get до того, как пакеты python2 стали доступны.

11
deadghost

Я обнаружил, что на самом деле можно иметь несколько воспроизведений в одной книге воспроизведения, поэтому в моей настройке теперь есть воспроизведение «обеспечения зависимости», которое выполняется на всех хостах, и другие игры для конкретных хостов. Так что не надо больше pre_tasks.

Например:

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

Я лично нашел 3 возможных решения этой проблемы, которые хорошо работают в разных ситуациях:

Вариант 1. Установите ansible_python_interpreter: /usr/bin/python3 для хостов, на которых по умолчанию установлен python3

Я думаю, что это лучший способ решения проблемы, если у вас есть способ сгруппировать ваши хосты по тому, установлен ли по умолчанию python3 или нет. Насколько я знаю, python3 доступен во всех выпусках Ubuntu 16.04 и выше.

  • Если все ваши хосты определенно имеют python3, вы можете добавить переменную в ваш group_vars/all.yml (или эквивалентный):
# group_vars/all.yml

ansible_python_interpreter: /usr/bin/python3
  • Если некоторые из ваших хостов не имеют python3, и у вас есть возможность пометить их при использовании динамического инвентаризации (например, тегирование AWS для ec2.py), вы можете применить переменную к определенным хостам, например так:
# group_vars/tag_OS_ubuntu1804.yml

ansible_python_interpreter: /usr/bin/python3
  • Если вы используете статическую инвентаризацию и можете группировать хосты в зависимости от того, имеют ли они python3, вы можете сделать что-то вроде этого:
# inventory/hosts

[python2_hosts]
centos7_server

[python3_hosts]
u1804_server

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

Мне больше нравится эта опция, потому что она не требует никаких изменений на удаленном хосте и только незначительные изменения переменных, в отличие от опций 2 и 3, которые требуют дополнений к каждой пьесе.

Вариант 2 - установить Python 2 с помощью raw

Эта опция требует размещения воспроизведения в верхней части каждой книги воспроизведения с gather_facts: false, который использует raw для установки 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: true требуется, если вы планируете запускать воспроизведение на хостах, на которых не установлен apt-get (например, на основе RHEL), в противном случае они выдадут ошибку при первом воспроизведении.

Это решение работает, но является самым низким в моем списке по нескольким причинам:

  1. Нужно идти в начале каждого playbook (в отличие от варианта 1)
  2. Предполагается, что apt находится в системе и игнорирует ошибки (в отличие от варианта 3)
  3. Команды apt-get медленные (в отличие от варианта 3)

Вариант 3 - символическая ссылка /usr/bin/python -> /usr/bin/python3 с использованием raw

Я не видел такого решения, предложенного кем-либо еще. Это не идеал, но я думаю, что он превосходит вариант 2 во многих отношениях. Я предлагаю использовать raw для запуска команды Shell для символической ссылки /usr/bin/python -> /usr/bin/python3, если python3 в системе иpython нет:

- 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

Это решение аналогично варианту 2 в том смысле, что нам нужно ставить его в начале каждого списка игр, но я думаю, что оно превосходит несколько способов:

  • Создает только символическую ссылку в конкретном случае, если python3 присутствует, а python нет - он не будет переопределять Python 2, если он уже установлен
  • Не предполагает, что apt установлен
  • Может работать на всех хостах без специальной обработки ошибок
  • Это супер быстро по сравнению с чем-либо с apt-get

Очевидно, что если вы нужно Python 2, установленный в /usr/bin/python, это решение не подходит, и вариант 2 лучше.

Заключение

  • Я предлагаю использовать option 1 во всех случаях, если можете. 
  • Я предлагаю использовать option 3, если ваш инвентарь действительно большой/сложный, и у вас нет возможности легко сгруппировать хосты с помощью python3, что делает option 1 намного более сложным и подверженным ошибкам.
  • Я только предлагаю option 2 over option 3, если вам нужен Python 2, установленный в /usr/bin/python.

Источники

6
percygrunwald

Как говорили другие, это связано с отсутствием python2. Другие ответы здесь предоставляют обходной путь с pre_tasks и gather_facts: no, однако, если вы используете EC2 и запускаете экземпляр с ansible, вы можете использовать опцию user_data:

- 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

Тогда люди обычно ждут, когда ssh станет доступным вот так: 

  - 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

Однако я обнаружил, что это не всегда достаточно долго, так как CloudInit выполняется довольно поздно в процессе загрузки, поэтому python2 все еще может быть не установлен сразу после того, как ssh станет доступен. Поэтому я добавил паузу на случай, если экземпляр был только что создан:

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

Это отлично сработает, и в качестве преимущества вы не проверяете python2 при каждом запуске, и вам не нужно обходиться, чтобы собрать факты позже.

Я уверен, что другие облачные провайдеры предоставляют аналогичную функциональность CloudInit, поэтому адаптируйтесь к своему варианту использования. 

5
Miroslav

@ Мирослав, спасибо, что указал мне правильное направление. Я также использовал user_data в модуле ec2_instance, и он работает как удовольствие. 

То есть.

- 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

Я смог решить ту же проблему, установив Python на целевой машине, то есть на машине, к которой мы хотим использовать SSH. Я использовал следующую команду:

Sudo apt-get install python-minimal
1
anshul

Много ответов .. Спасибо за сообщение, как я начал с этой страницы тоже!

Я немного покопался, и с Ubuntu 14.04LTS все шло хорошо, Ubuntu 15.04LTS, похоже, отбросил последнюю python, а Ubuntu 16.04LTS, похоже, отбросил aptitude.

Я поместил следующее действие в мой загрузчик перед выполнением любых вызовов apt:

- 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

Если вы управляете become в другом месте, не стесняйтесь лишать его.

Источники:

1
sonjz

Согласно это Gist вы можете установить Python2 на Ubuntu 16.04 следующим образом:

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

По умолчанию Ansible требует Python 2 , однако Ansible 2.2+ может работать и с Python 3 .

Так что либо установите Python 2 с помощью модуля raw , например.

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

или установите переменную ansible_python_interpreter в файле инвентаря, например:

[local]
localhost ansible_python_interpreter="env python3"

Для Docker вы можете добавить следующую строку:

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

или запустите его как:

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

С помощью Packer может оказаться полезным следующее решение

давайте предположим, что вы используете ansible Provider упаковщика, ваш конфиг может выглядеть следующим образом

вы можете сначала установить python с помощью Shell Provider, а затем настроить опцию ansible_python_intepreter, как показано ниже

"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

Вы можете указать Ubuntu 18.04, что вы хотите использовать python3 в качестве первого приоритета для /usr/bin/python.

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

У меня была такая же проблема, пока я не понял, что вам также нужно установить python на удаленном хосте, а также на вашем собственном локальном компьютере. теперь это работает!

0
GAV