Ansible失败了/ bin/sh:1:/ usr/bin/python:找不到

jda*_*vis 184 ansible ansible-playbook

我遇到了一个我以前从未见过的错误.这是命令和错误:

$ 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
Run Code Online (Sandbox Code Playgroud)

这是create_api.yml文件:

---

- hosts: api
  remote_user: root
  roles:
    - api
Run Code Online (Sandbox Code Playgroud)

这是hosts文件:

[api]
104.55.47.224
Run Code Online (Sandbox Code Playgroud)

我可以删除角色部分,它不会进入第一个任务,它将使它只会使它成为行/bin/sh: 1: /usr/bin/python: not found.这可能会发生什么?


注意:如果有人正在ping IP地址并且没有得到响应,您应该知道自从粘贴代码后我已经更改了IP地址.

编辑 python是在本地安装的,问题是它没有安装在运行Ubuntu 15.04的远程机器上

lak*_*are 167

我偶然发现在Ubuntu 15.10服务器上运行ansible时出现这个错误,因为它附带了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
Run Code Online (Sandbox Code Playgroud)
  • 不要忘记使用apt-get的-y(对所有问题都是肯定的)选项(或者原始模块会默默地卡住)

  • gather_facts: no line也很关键(因为我们不能在没有python的情况下收集事实)

  • 请注意,'gather_facts:no'行也是*关键. (16认同)
  • 那么后来的角色就不能使用事实...有没有办法再次收集事实?啊哈,http://stackoverflow.com/questions/31054453/ansible-actions-before-gathering-facts (12认同)
  • @ surfer190很棒找!我还发现添加`action:setup`作为最终的pre_task也很有效:) (6认同)
  • 也可能需要一个`sudo apt-get update` (2认同)

jam*_*mix 118

Ansible 2.2具有Python 3支持的技术预览.要利用这一点(因此您不必在Ubuntu 16.04上安装Python 2),只需将ansible_python_interpreterconfig选项设置为/usr/bin/python3.这可以在您的库存文件中基于每个主机完成:

[db]
123.123.123.123 ansible_python_interpreter=/usr/bin/python3
Run Code Online (Sandbox Code Playgroud)


Arb*_*zar 94

解决方案1:

如果您正在使用Ansible >2.2.0,可以将ansible_python_interpreter配置选项设置为/usr/bin/python3:

ansible my_ubuntu_host -m ping -e 'ansible_python_interpreter=/usr/bin/python3'
Run Code Online (Sandbox Code Playgroud)

或在您的库存文件中:

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

[ubuntu_hosts:vars]
ansible_python_interpreter=/usr/bin/python3
Run Code Online (Sandbox Code Playgroud)

解决方案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
Run Code Online (Sandbox Code Playgroud)

  • 我有`ansible 2.3.0.0`并且开箱即用.与OP发布的错误相同. (16认同)

udo*_*dan 32

您可以使用原始模块在远程主机上安装Python:

- raw: sudo apt-get install python-simplejson
Run Code Online (Sandbox Code Playgroud)

  • 要确保在角色中的任务之前以及元文件中的任何依赖项之前调用它,请将它添加到您的playbook中:```pre_tasks: - raw:sudo apt-get install python-simplejson``` (11认同)
  • 请注意,在Playbook中,您必须*还*禁用gather_facts,否则在运行raw命令之前这将失败.(gather_facts:不) (5认同)

小智 18

总结其他人的答案,以下是适合我的组合设置:

 - 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
Run Code Online (Sandbox Code Playgroud)


pha*_*iap 13

你需要python 2.7来运行Ansible.在Ubuntu 16.04上,您可以通过以下命令安装它:

sudo apt-get install python-minimal

在那之后,我可以跑了

ansible-playbook -i inventories/staging playbook.yml

成功运行ansible

有关更多信息,请参阅Ubuntu 16.04上的使用ansible


小智 13

我个人发现了3个可能解决这个问题的方法,它在不同情况下运行良好:

选项1 - ansible_python_interpreter: /usr/bin/python3python3默认安装的主机设置

我认为这是解决问题的最佳方法,如果您有办法按主机是否python3默认安装主机.据我所知,python3所有Ubuntu版本均可在16.04及更高版本上使用.

  • 如果所有主机肯定都有python3,您可以将变量添加到您的group_vars/all.yml(或等效的):
# group_vars/all.yml

ansible_python_interpreter: /usr/bin/python3
Run Code Online (Sandbox Code Playgroud)
  • 如果您的某些主机没有,python3并且您在使用动态库存(例如AWS标记ec2.py)时可以标记它们,则可以将变量应用于某些主机,如下所示:
# group_vars/tag_OS_ubuntu1804.yml

ansible_python_interpreter: /usr/bin/python3
Run Code Online (Sandbox Code Playgroud)
  • 如果您使用静态库存并且能够根据它们是否具有主机python3,则可以执行以下操作:
# inventory/hosts

[python2_hosts]
centos7_server

[python3_hosts]
u1804_server

[python3_hosts:vars]
ansible_python_interpreter=/usr/bin/python3
Run Code Online (Sandbox Code Playgroud)

我最喜欢这个选项,因为它不需要对远程主机进行任何更改,只需要对变量进行微小的更改,而不是选项2和3,这需要添加到每个playbook.

选项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
Run Code Online (Sandbox Code Playgroud)

ignore_errors: true如果您计划在未apt-get安装的主机上运行播放(例如基于RHEL的任何内容),则需要它,否则它们将在第一次播放时出错.

此解决方案有效,但由于以下几个原因,我的列表中最低:

  1. 需要在每个剧本的顶部(与选项1相对)
  2. 假设apt在系统上并忽略错误(与选项3相反)
  3. apt-get 命令很慢(与选项3相反)

选项3 - /usr/bin/python -> /usr/bin/python3使用符号链接raw

我没有看到其他人提出的这个解决方案.这并不理想,但我认为它在很多方面都优于选项2.我的建议是使用如果在系统上raw运行shell命令到符号链接不是:/usr/bin/python -> /usr/bin/python3python3 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
Run Code Online (Sandbox Code Playgroud)

这个解决方案类似于选项2,因为我们需要将它放在每个剧本的顶部,但我认为它在某些方面更胜一筹:

  • 仅在特定情况下创建符号链接,python3python不是 - 如果已经安装,它将不会覆盖Python 2
  • 不假设apt已安装
  • 可以针对所有主机运行而无需任何特殊错误处理
  • 与任何事物相比都是超级快速的 apt-get

显然,如果你需要安装Python 2 /usr/bin/python,这个解决方案是不行的,选项2更好.

结论

  • 如果可以的话,我建议在所有情况下使用选项1.
  • 我建议使用选项3,如果您的库存非常庞大/复杂且您无法轻松地对主机进行分组python3,那么选项1将变得更加困难且容易出错.
  • 如果你需要安装Python 2,我只建议选项2而不是选项3/usr/bin/python.

来源


dea*_*ost 12

我曾经在新鲜的数字海洋液滴上使用ubuntu 15.10进行此操作:

# 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
Run Code Online (Sandbox Code Playgroud)

对于ubuntu 16.04在新的OVH SSD上,我必须在python2包可用之前进行apt-get升级.


Koe*_*en. 8

我发现实际上可以在一个剧本中进行多次播放,所以我的设置现在包含一个"依赖配置"播放,它在所有主机上运行,​​而其他播放则在特定主机上播放.所以没有了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
  # ....
Run Code Online (Sandbox Code Playgroud)


Mir*_*lav 6

正如其他人所说,这是由于缺少python2.其他答案在这里提供一个解决办法有pre_tasksgather_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
Run Code Online (Sandbox Code Playgroud)

然后人们通常会等待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
Run Code Online (Sandbox Code Playgroud)

但是我发现,这并不总是足够长,因为CloudInit在启动过程中很晚执行,所以在ssh可用之后仍然可能没有安装python2.所以我添加了一个暂停,以防刚刚创建实例:

  - name: "Wait for cloud init on first boot"
    pause: minutes=2
    when: ec2|changed
Run Code Online (Sandbox Code Playgroud)

这将完美地完成工作,并且作为一个优势,您不会在每次运行时检查python2,并且您不必再做任何变通方法来收集事实.

我确信其他云提供商提供类似的CloudInit功能,因此请根据您的使用情况进行调整.