为什么我的 Ansible 任务挂起?
Why does my Ansible task hang?
我有以下 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 小时后它仍然挂起。为什么我会得到如此不同的行为?有什么方法可以控制它吗?
此问题可能是由于 /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 就不会在播放过程中多次更新存储库了。
由于您最后看到的是 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
我有以下 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 小时后它仍然挂起。为什么我会得到如此不同的行为?有什么方法可以控制它吗?
此问题可能是由于 /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 就不会在播放过程中多次更新存储库了。
由于您最后看到的是 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