为什么我的Ansible任务挂起?

时间:2016-08-01 14:06:39

标签: ansible ansible-playbook

我有以下ansible剧本:

- hosts: node1
  sudo: yes
  gather_facts: no

  tasks:
  - name: update apt
    apt: update_cache=yes
  - name: install python-setuptools
    apt: name=python-setuptools update_cache=yes
  - name: easy_install pexpect module
    easy_install: name=pexpect state=latest
  - name: add geonode repo
    apt_repository: repo='ppa:geonode/stable' state=present
  - name: update apt
    apt: update_cache=yes
  - name: install geonode
    apt: name=geonode update_cache=yes
  - expect:
        command: geonode createsuperuser
        responses:
          (?i)username: 'test'
          (?i)email: 'test@test.com'

当我跑步时,我得到:

PLAY [node1] *******************************************************************

TASK [update apt] **************************************************************
ok: [node1]

TASK [install python-setuptools] ***********************************************
changed: [node1]

TASK [easy_install pexpect module] *********************************************
changed: [node1]

TASK [add geonode repo] ********************************************************
changed: [node1]

TASK [update apt] **************************************************************
ok: [node1]

TASK [install geonode] *********************************************************

然后它无限期地挂起。 在远程节点(node1)中,我检查了目录

  

/home/vagrant/.ansible/tmp/ansible-tmp-1470059145.13-122191240803512 /

在里面运行文件以查看我的任务挂起的原因

  

vagrant @ node1:〜/ .ansible / tmp / ansible-tmp-1470059145.13-122191240803512 $ python apt

并获得:

{"msg": "Failed to lock apt for exclusive operation", "failed": true, "invocation": {"module_args": {"dpkg_options": "force-confdef,force-confold", "autoremove": false, "force": false, "name": "geonode", "install_recommends": null, "package": ["geonode"], "purge": false, "allow_unauthenticated": false, "state": "present", "upgrade": null, "update_cache": true, "default_release": null, "only_upgrade": false, "deb": null, "cache_valid_time": null}}}

你有什么见解吗?

编辑1:

我一整天都在推出这个脚本,但从来没有让它发挥作用。当我发布这个问题时,很明显,脚本在15分钟内成功执行到最后。我今天午饭之前推出它,1小时后它仍然挂着。为什么我会有这样不同的行为?有没有办法控制它?

2 个答案:

答案 0 :(得分:2)

此问题可能是由空/var/lib/apt folder

引起的

Vagrant可能需要一段时间来填充这些可能导致apt锁定的文件夹。

由于多次使用update_cache,因此剧本效率低下。我建议使用这样的东西:

- hosts: node1
  sudo: yes
  gather_facts: no

  tasks:
    # Pause for 5 minutes to make sure vagrant does not hold apt lock.
    - pause:
        minutes: 5

    - name: add geonode repo
      apt_repository:
        repo: 'ppa:geonode/stable'
        state: present

    - name: Install apt packages.
      apt:
        name: "{{ item }}"
        state: present
        update_cache: true
      with_items:
        - python-setuptools
        - geonode

  - name: Create geonode superuser.
    expect:
      command: geonode createsuperuser
      responses:
        (?i)username: 'test'
        (?i)email: 'test@test.com'        

这样,Ansible在游戏过程中不会多次更新存储库。

答案 1 :(得分:0)

因为你看到的最后一件事是TASK [install geonode],所以它就会陷入困境。

您要求它运行您希望导致提示输入用户名和密码的geonode createsuperuser

但可能发生的是该命令产生错误,expect任务没有处理错误,只是挂起。

您可以登录到运行此服务器的服务器并手动运行geonode createsuperuser命令以查看正在生成的错误。

就我而言,由于我已经在这台机器上成功运行了命令,因此已经使用了用户名。

Error: That username is already taken.

即使使用echo: yes参数,ansible也似乎没有传递响应,以明确发生了什么。并且它不接受ignore_errors,因此似乎无法处理expect模块的错误。

要解决此问题,我在createsuperuser任务之后添加了另一个任务,该任务在项目中放置一个文件,表明用户已创建一次,然后将creates: {{ path }}/superuser_exists.txt添加到createsuperuser任务以便赢得如果该文件已经存在,则运行。

这是一个hack,但是很简单,直到模块获得更好的错误处理,它才能运行得很好。

- name: Create the django superuser
  expect:
    command: "{{ virtualenv_path }}/bin/python3 {{ project_path }}/{{ api_app_name }}/manage.py createsuperuser"
    creates: "{{ project_path }}/{{ api_app_name }}/superuser_exists.txt"
    responses:
      (?i)username: "{{ superuser_username }}"
      (?i)email: "{{ superuser_email }}"
      (?i)password: "{{ superuser_password }}"
      (?i)again: "{{ superuser_password }}"

- name: Create a file to indicate that the superuser was already created
  file: path="{{ project_path }}/{{ api_app_name }}/superuser_exists.txt" state=touch