Ansible:将目录内容复制到另一个目录

Ansible: copy a directory content to another directory

我正在尝试将 dist 目录的内容复制到 nginx 目录。

- name: copy html file
  copy: src=/home/vagrant/dist/ dest=/usr/share/nginx/html/

但是当我执行剧本时它抛出一个错误:

TASK [NGINX : copy html file] **************************************************
fatal: [172.16.8.200]: FAILED! => {"changed": false, "failed": true, "msg": "attempted to take checksum of directory:/home/vagrant/dist/"}

如何复制一个目录,其中包含另一个目录和一个文件?

编辑:这个解决方案在发布问题时有效。后来 Ansible 弃用了 remote_src

的递归复制

Ansible Copy 模块默认将 files/dirs 从控制机器复制到远程机器。如果你想在远程机器上复制 files/dirs 并且你有 Ansible 2.0,请将 remote_src 设置为 yes

- name: copy html file
  copy: src=/home/vagrant/dist/ dest=/usr/share/nginx/html/ remote_src=yes directory_mode=yes

已解决的答案: 要将目录的内容复制到另一个目录,我使用下一个:

- name: copy consul_ui files
  command: cp -r /home/{{ user }}/dist/{{ item }} /usr/share/nginx/html
  with_items:
   - "index.html"
   - "static/"

它将两个项目复制到另一个目录。在该示例中,其中一项是目录,而另一项不是。它完美运行。

Ansible remote_src 不支持递归 copying.See remote_src description in Ansible copy docs

要递归复制文件夹的内容并确保任务保持幂等,我通常这样做:

- name: get file names to copy
  command: "find /home/vagrant/dist -type f"
  register: files_to_copy

- name: copy files
  copy:
    src: "{{ item }}" 
    dest: "/usr/share/nginx/html"
    owner: nginx
    group: nginx
    remote_src: True
    mode: 0644
  with_items:
   - "{{ files_to_copy.stdout_lines }}"

缺点是 find 命令仍然显示为 'changed'

您可以使用 synchronize 模块。文档中的示例:

# Synchronize two directories on one remote host.
- synchronize:
    src: /first/absolute/path
    dest: /second/absolute/path
  delegate_to: "{{ inventory_hostname }}"

这有一个额外的好处,它可以更有效地处理 large/many 个文件。

下面对我有用,

-name: Upload html app directory to Deployment host
 copy: src=/var/lib/jenkins/workspace/Demoapp/html dest=/var/www/ directory_mode=yes

我发现复制文件夹的 内容 而不复制文件夹本身的最简单的解决方案是使用以下方法:

- name: Move directory contents
  command: cp -r /<source_path>/. /<dest_path>/

这解决了@surfer190的后续问题:

Hmmm what if you want to copy the entire contents? I noticed that * doesn't work – surfer190 Jul 23 '16 at 7:29

* 是一个 shell glob,因为它依赖于您的 shell 在 之前枚举文件夹中的所有文件 运行 cp,而 . 直接指示 cp 获取目录内容(参见 https://askubuntu.com/questions/86822/how-can-i-copy-the-contents-of-a-folder-to-another-folder-in-a-different-directo

我找到了一个将文件从 Ansible 服务器复制到远程的理想解决方案。

正在复制 yaml 文件

- hosts: localhost
  user: {{ user }}
  connection: ssh
  become: yes
  gather_facts: no
  tasks:
   - name: Creation of directory on remote server
     file:
       path: /var/lib/jenkins/.aws
       state: directory
       mode: 0755
     register: result
   - debug: 
       var: result

   - name: get file names to copy
     command: "find conf/.aws -type f"
     register: files_to_copy

   - name: copy files
     copy:
      src: "{{ item }}" 
      dest: "/var/lib/jenkins/.aws"
      owner: {{ user }}
      group: {{ group }}
      remote_src: True
      mode: 0644
     with_items:
      - "{{ files_to_copy.stdout_lines }}"

我找到了从远程到远程递归复制的解决方法:

- name: List files in /usr/share/easy-rsa
  find:
    path: /usr/share/easy-rsa
    recurse: yes
    file_type: any
  register: find_result

- name: Create the directories
  file:
    path: "{{ item.path | regex_replace('/usr/share/easy-rsa','/etc/easy-rsa') }}"
    state: directory
    mode: "{{ item.mode }}"
  with_items:
    - "{{ find_result.files }}"
  when:
    - item.isdir

- name: Copy the files
  copy:
    src: "{{ item.path }}"
    dest: "{{ item.path | regex_replace('/usr/share/easy-rsa','/etc/easy-rsa') }}"
    remote_src: yes
    mode: "{{ item.mode }}"
  with_items:
    - "{{ find_result.files }}"
  when:
    - item.isdir == False

我也参与了一整天!最后在 shell 命令中找到了解决方案,而不是 copy:command: 如下:

- hosts: remote-server-name
  gather_facts: no
  vars:
    src_path: "/path/to/source/"
    des_path: "/path/to/dest/"
  tasks:
  - name: Ansible copy files remote to remote
    shell: 'cp -r {{ src_path }}/. {{ des_path }}'

严格注意: 1. src_path 和 des_path 以 / 符号结尾 2. 在 shell 命令中 src_path 以 . 结束,显示目录的所有内容 3. 我在 hosts: 中使用了我的 remote-server-name 并执行 shell 詹金斯的一部分,而不是剧本中的 remote_src: 说明符。

我想在 jenkins 的执行 Shell 部分下面的命令 运行 中,这是一个很好的建议:

ansible-playbook  copy-payment.yml -i remote-server-name

要将一个目录的内容复制到另一个目录,您可以使用 ansibles copy 模块:

- name: Copy content of directory 'files'
  copy:
    src: files/    # note the '/' <-- !!!
    dest: /tmp/files/

来自docs about the src parameter

如果 (src!)path 是一个目录,它被递归复制...
... 如果路径以“/”结尾,则仅将该目录的内部内容复制到目标
... 如果不以“/”结尾,则复制目录本身及其所有内容。

如何将目录和子目录和文件从 ansible 服务器复制到远程主机

- name: copy nmonchart39 directory  to {{ inventory_hostname }}
  copy:
    src: /home/ansib.usr.srv/automation/monitoring/nmonchart39
    dest: /var/nmon/data


Where:
copy entire directory: src: /automation/monitoring/nmonchart39
copy directory contents src: nmonchart39/

ansible 文档非常清楚 https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html 对于参数 src,它说明如下:

Local path to a file to copy to the remote server.
This can be absolute or relative.
If path is a directory, it is copied recursively. In this case, if path ends with "/", 
only inside contents of that directory are copied to destination. Otherwise, if it 
does not end with "/", the directory itself with all contents is copied. This behavior 
is similar to the rsync command line tool.

所以您需要跳过 src 路径末尾的 /。

- name: copy html file
  copy: src=/home/vagrant/dist dest=/usr/share/nginx/html/