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

时间:2015-09-06 23:23:38

标签: 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

这是create_api.yml文件:

---

- hosts: api
  remote_user: root
  roles:
    - api

这是主机文件:

[api]
104.55.47.224

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

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

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

20 个答案:

答案 0 :(得分:161)

我偶然发现在 Ubuntu 15.10 服务器上运行ansible时出现此错误,因为它附带 Python 3.4.3 ansible requires 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
  • 不要忘记使用apt-get 的-y(对所有问题说“是”)选项(或原始模块会默默地卡住)

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

答案 1 :(得分:113)

Ansible 2.2具有Python 3支持的技术预览。 To take advantage of this(因此您不必在Ubuntu 16.04上安装Python 2),只需将ansible_python_interpreter配置选项设置为/usr/bin/python3即可。这可以在您的库存文件中基于每个主机完成:

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

答案 2 :(得分:82)

解决方案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

答案 3 :(得分:32)

您可以使用raw module在远程主机上安装Python:

- raw: sudo apt-get install python-simplejson

答案 4 :(得分: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

答案 5 :(得分:13)

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

sudo apt-get install python-minimal

之后,我可以运行

ansible-playbook -i inventories/staging playbook.yml

Run ansible successfully

请在Using ansible on Ubuntu 16.04

查看更多内容

答案 6 :(得分: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

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

答案 7 :(得分:11)

我个人发现了针对此问题的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,并且您可以在使用动态清单时对它们进行标记(例如,对ec2.py进行AWS标记),则可以将变量应用于某些主机,例如这个:
# 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-使用raw

安装Python 2

此选项要求将带有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的主机)上运行该播放,则

apt是必需的,否则它们将在第一次播放中出错。 >

此解决方案有效,但由于某些原因,它是我列出的最低解决方案:

  1. 需要置于每个剧本的顶部(而不是选项1)
  2. 假设apt-get在系统上并且忽略错误(与选项3相反)
  3. /usr/bin/python -> /usr/bin/python3命令很慢(与选项3相反)

选项3-使用raw的符号链接raw

我没有看到任何其他人提出过这种解决方案。这并不理想,但我认为它在很多方面都优于选项2。我的建议是,如果/usr/bin/python -> /usr/bin/python3在系统上并且 python3不在系统上,则使用python运行shell命令以符号链接- 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

python3

此解决方案与选项2相似,因为我们需要将其放在每本剧本的顶部,但我认为它在某些方面具有优越性:

  • 仅在存在python而没有apt的特定情况下创建符号链接-如果已经安装,它将不会覆盖Python 2
  • 不假定已安装apt-get
  • 可以在没有任何特殊错误处理的情况下针对所有主机运行
  • /usr/bin/python相比,它超级快

很明显,如果您需要python3安装了Python 2,则此解决方案是不可行的,选项2更好。

结论

  • 如果可以的话,我建议在所有情况下都使用选项1
  • 我建议您使用选项3 ,如果您的库存确实很大/很复杂,并且您无法通过/usr/bin/python轻松地将主机分组,则使选项1 变多了更困难,更容易出错。
  • 如果您需要在{{1}}安装Python 2,我只建议选项2 胜过选项3

来源

答案 8 :(得分:8)

我发现实际上可以在一个剧本中进行多次播放,所以我的设置现在包含一个“依赖配置”播放,它在所有主机上运行,​​而其他播放则在特定主机上播放。所以不再orgnl_pk type text 1 one • Line One • Line Two • Line Three 1 two • Line One 3 one • Line One 3 two • Line One • Line Two

例如:

pre_tasks

答案 9 :(得分: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

然后人们通常会等待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在启动过程中很晚才执行,所以在ssh可用之后仍然可能没有安装python2。所以我在刚刚创建实例的时候添加了一个暂停:

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

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

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

答案 10 :(得分:2)

默认情况下,Ansible requires Python 2也是Ansible 2.2+ can work with Python 3

所以要么使用raw module安装Python 2,例如

replpad

或在清单文件中设置ansible_python_interpreter variable,例如:

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

对于Docker,您可以添加以下行:

[local]
localhost ansible_python_interpreter="env python3"

或以:

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

答案 11 :(得分:1)

我能够通过在目标计算机上安装Python来解决同样的问题,即我们想要SSH的机器。我使用了以下命令:

sudo apt-get install python-minimal

答案 12 :(得分:1)

使用Packer的人可能会发现以下解决方案很有帮助

假设您使用了打包程序的Ansible Provisioner,则您的配置可能如下所示

您可以先使用Shell Provisioner安装python,然后按如下所示配置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"
      ]
    },

答案 13 :(得分:1)

您可以向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

答案 14 :(得分:1)

@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     

答案 15 :(得分:1)

很多答案..感谢您在本页开始发帖!

我做了一些挖掘,并且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,请随意将其删除。

来源:

答案 16 :(得分:1)

根据this Gist,您可以在Ubuntu 16.04上安装Python2,如下所示:

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.

答案 17 :(得分:0)

我遇到了同样的问题,直到我意识到你还需要在远程主机和你自己的本地机器上安装python。现在它有效!

答案 18 :(得分:0)

如果您对 localhost 运行 ansible(换句话说,尝试配置自己的机器),您可以执行以下操作。

获取路径 python3

$ which python3
/usr/bin/python3

更新 ansible.cfg 文件与 interpreter_python 设置为 python3 路径.

# ansible.cfg
[defaults]
interpreter_python  = /usr/bin/python3
transport           = local

答案 19 :(得分:-2)

我们碰到了这个。

我们在流浪汉上部署ubuntu 16.04,所以如果你不使用流浪汉,我的评论毫无意义。

我们安装了以下vagrant插件(触发器,shell-commander),我们在机器上安装了python 2.7.6(不是没有thioose插件),并且在ansible可以部署之后

这是我们的最后一次测试,否则我们将把这个安装包含在Vagrant文​​件中的shell命令中

希望它可以帮助某人