Ansible 文本文件忙错误

Ansible text file busy error

我在 Windows 主机上设置了 Vagrant / Ansible。 Ansible 在 Ubuntu 来宾上设置为 运行,因为 Vagrant up 执行一个 shell 脚本,该脚本将 provisioning yml 文件复制到来宾并在上安装 Ansible客人。

脚本 运行 使用以下命令在客户机上设置 Ansible:

# Ansible installations
sudo apt-get install -y ansible

# Copy all Ansible scripts to the ubuntu guest
sudo cp -rf -v /vagrant/provisioning /home/vagrant/

# cp /vagrant/hosts /home/vagrant/
sudo chmod 666 /home/vagrant/provisioning/hosts

# Install roles
sudo ansible-playbook /home/vagrant/provisioning/local.yml -i /home/vagrant/provisioning/hosts --connection=local

Ansible 配置过程中的一个步骤是在 /var/www 目录中设置 Laravel 的新副本。拉入 Laravel 后,我的脚本会复制并编辑文档根目录 (/var/www) 中的 .env 文件。

但这就是问题所在,它失败并显示 text file busy 消息。这是作为源和目标在来宾上发生的副本,所以我想与 VBox 无关。感觉跟文件名太不寻常有关,但我还没找到答案。

我 Laravel 的 task.yml 文件是:

---
- name: Clone git repository
  git: >
      dest=/var/www
      repo=https://github.com/laravel/laravel.git
      update=no
  sudo: yes
  sudo_user: www-data
  register: cloned

- name: copy .env file
  copy: src=env.j2 dest={{ conf_file }}

- name: set APP_DOMAIN={{ server_name }}
  lineinfile: dest=/var/www/.env regexp='^APP_DOMAIN=' line=APP_DOMAIN={{ server_name }}

我也试过用模板方法也有同样的错误:

- name: copy .env file
  template: src=env.j2 dest={{ conf_file }}

我的配置文件包含:

conf_file: /var/www/.env

复制步骤失败如下:

==> default: TASK: [laravel | copy .env file] **********************************************
==> default: failed: [10.0.1.10] => {"failed": true, "md5sum": "a380715fa81750708f7b9b6fea1a48fe"}
==> default: msg: Could not replace file: /root/.ansible/tmp/ansible-tmp-1441176559.19-197929606462535/source to /var/www/.env: [Errno 26] Text file busy
==> default:
==> default: FATAL: all hosts have already failed -- aborting
==> default:
==> default: PLAY RECAP ********************************************************************
==> default:            to retry, use: --limit @/root/local.retry
==> default:
==> default: 10.0.1.10                  : ok=21   changed=18   unreachable=0    failed=1
The SSH command responded with a non-zero exit status. Vagrant
assumes that this means the command failed. The output for this command
should be in the log above. Please read the output to determine what
went wrong.

.env 源文件位于 Laravel 任务文件夹外的一个名为 files 的文件夹中,与我配置的其他项目一样工作正常。失败后在www文件夹中找不到文件.env,所以不复制它。

在 Virtualbox 共享文件夹上使用 Ansible "copy" 模块显然存在一些问题(参见 https://github.com/ansible/ansible/issues/9526)- /var/www/ 目录是 Vagrant 设置的共享文件夹吗?

也许尝试 touch 先创建文件,然后复制它:

变化:

- name: copy .env file
  copy: src=env.j2 dest={{ conf_file }}

进入:

- name: create .env file
  shell: touch {{ conf_file }}
- name: copy .env file
  copy: src=env.j2 dest={{ conf_file }}

编辑: 此文件复制错误已在 Ansible 1.9.3 版本(2015 年 7 月 19 日)中针对某些用户修复,但对于 Windows hosts 运行 Virtualbox(与 vboxsf 共享有关)截至 2016-06-14。 GitHub 问题仍然关闭,但人们仍在评论并且似乎正在提供可能的修复。

下面链接的解决方案似乎适用于大多数人(多次赞成)。它建议将 Ansible remote_tmp 配置设置添加到您的本地 ~/.ansible.cfg,它指示 Ansible 使用目标(共享)文件系统上的临时文件夹:

https://github.com/ansible/ansible/issues/9526#issuecomment-199443969

对于 ansible 2.2 你也可以设置 unsafe_writes=yes