Sao chép nhiều tệp với Ansible


103

Làm cách nào tôi có thể sao chép nhiều hơn một tệp vào các nút từ xa bằng Ansible trong một tác vụ?

Tôi đã cố gắng sao chép dòng mô-đun sao chép trong nhiệm vụ của mình để xác định tệp nhưng nó chỉ sao chép tệp đầu tiên.

Câu trả lời:


131

Bạn có thể sử dụng with_fileglobvòng lặp cho việc này:

- copy:
    src: "{{ item }}"
    dest: /etc/fooapp/
    owner: root
    mode: 600
  with_fileglob:
    - /playbooks/files/fooapp/*

3
Cách tiếp cận này có thể giúp tôi nếu tôi có tất cả các tệp của mình trong cùng một thư mục gốc để sao chép vào máy từ xa, vậy còn việc có một số tệp trong các thư mục khác nhau thì sao. Ví dụ: tôi muốn sao chép 3 tệp từ 3 thư mục khác nhau
Đánh dấu

Này, tôi đang cố gắng di chuyển tất cả các tệp khỏi của tôi /roles/db/filesnhưng tôi không thể làm cho nó hoạt động với phương pháp này. Tôi đã thử with_fileglob: - /roles/db/file/* nhưng nó sẽ không ổn với con đường
Batman

Nhược điểm lớn của phương pháp này là nó làm phẳng cấu trúc thư mục.
Quintin Par

114
- name: Your copy task
  copy: src={{ item.src }} dest={{ item.dest }}
  with_items:
    - { src: 'containerizers', dest: '/etc/mesos/containerizers' }
    - { src: 'another_file', dest: '/etc/somewhere' }
    - { src: 'dynamic', dest: '{{ var_path }}' }
  # more files here

Có thể có giải pháp này với desttập hợp là một biến? { src: 'containerizers', dest: {{ containerizers }} }.
Gesias

2
@Gesias, vâng. Trên thực tế, hai bên có thể biến:{ src: '{{ source.var }}', dest: '{{ dest.var }}' }
ntwrkguru

16

Bạn có thể sử dụng with_together cho mục đích này:

- name: Copy multiple files to multiple directories
  copy: src={{ item.0 }} dest={{ item.1 }}
  with_together:
    - [ 'file1', 'file2', 'file3' ]
    - [ '/dir1/', '/dir2/', '/dir3/' ]

Mặc dù nó hoạt động, nhưng điều này không rõ ràng về mặt ngữ nghĩa - có những tùy chọn rõ ràng hơn.
plesiv

11

Nếu bạn cần nhiều vị trí, bạn cần nhiều hơn một nhiệm vụ. Một tác vụ sao chép chỉ có thể sao chép từ một vị trí (bao gồm nhiều tệp) sang một vị trí khác trên nút.

- copy: src=/file1 dest=/destination/file1
- copy: src=/file2 dest=/destination/file2

# copy each file over that matches the given pattern
- copy: src={{ item }} dest=/destination/
  with_fileglob:
    - /files/*

- name: copy file1 copy: src = / file1 dest = / destination / file1 - tên: copy file2 copy: src = / file2 dest = / destination / file2
Đánh dấu

Phụ thuộc. Đơn giản hơn và có thể gọn gàng hơn, nhưng có thể được thực hiện bằng cách sử dụng các cấu trúc dữ liệu phức tạp hơn, chẳng hạn như danh sách các từ điển ẩn danh với dữ liệu nguồn và đích, được lặp với_items. Nó giống nhau trong bất kỳ ngôn ngữ nào - bạn phải đưa ra phán quyết. Có những trường hợp một hàm ủy quyền hiệu quả hơn và dễ bảo trì hơn một chuỗi dài các câu lệnh if được sao chép / dán. Tôi là một kẻ kỳ quặc muốn duy trì một chút ngắn gọn của mã có cấu trúc tốt hơn là một danh sách dài và tẻ nhạt của các chỉ thị gần giống nhau, nhưng tôi không cho rằng mọi người đều đồng ý. Làm những gì có thể bảo trì cho bạn.
Paul Hodges

7
- hosts: lnx
  tasks:
    - find: paths="/appl/scripts/inq" recurse=yes patterns="inq.Linux*"
      register: file_to_copy
    - copy: src={{ item.path }} dest=/usr/local/sbin/
      owner: root
      mode: 0775
      with_items: "{{ files_to_copy.files }}"

chỉ là một mặt lưu ý rằng findmô-đun chỉ làm việc cho 2.x ansible nhưng không phải cho 1.x ansible
Arbab Nazar

Tôi đã sửa câu trả lời của bạn vì bạn đã đề cập đến stdout_linesgiá trị trả về nhưng không áp dụng cho findmô-đun. Nó chỉ có files, examinedmatchedgiá trị trả về. Hy vọng rằng giúp đỡ người khác
Arbab Nazar

2
Có ai có thể làm cho điều này hoạt động để sao chép tệp vào các nút từ xa không? finddường như chỉ nhìn vào hệ thống từ xa, không cho phép lấy bất cứ thứ gì từ nút quản lý. Các câu trả lời này, bằng cách sử dụng with_fileglob, có vẻ phù hợp hơn: stackoverflow.com/a/42290160/272387 , stackoverflow.com/a/36720342/272387 .
Richlv

7

Vì Ansible 2.5 nên các with_*cấu trúc không được dùng nữaloopnên sử dụng cú pháp. Một ví dụ thực tế đơn giản:

- name: Copy CA files
  copy:
    src: '{{item}}'
    dest: '/etc/pki/ca-trust/source/anchors'
    owner: root
    group: root
    mode: 0644
  loop:
    - symantec-private.crt
    - verisignclass3g2.crt


4

Hoặc bạn có thể sử dụng with_items:

- copy:
    src: "{{ item }}"
    dest: /etc/fooapp/
    owner: root
    mode: 600
  with_items:
    - dest_dir

3
- name: find inq.Linux*
  find:  paths="/appl/scripts/inq" recurse=yes patterns="inq.Linux*"
  register: find_files


- name: set fact
  set_fact:
    all_files:
      - "{{ find_files.files | map(attribute='path') | list }}"
  when: find_files > 0


- name: copy files
  copy:
    src: "{{ item }}"
    dest: /destination/
  with_items: "{{ all_files }}"
  when: find_files > 0

6
Một câu trả lời tốt không chỉ chứa mã, mà còn chứa một số giải thích hoặc tài liệu tham khảo.
Laurenz Albe

Các mô-đun find, set_fact và copy đều được giải thích trong tài liệu ansible. Tìm hiểu về bộ lọc, cũng giải thích trong tài liệu ansible nếu bạn whant để biết thêm về phần này (- "{{find_files.files | bản đồ (attribute'path ') | list}}")
Fredric Andersson

1

Bạn có thể lặp qua biến với danh sách các thư mục:

- name: Copy files from several directories
  copy:
    src: "{{ item }}"
    dest: "/etc/fooapp/"
    owner: root
    mode: "0600"
  loop: "{{ files }}"
  vars:
    files:
      - "dir1/"
      - "dir2/"

1

Sử dụng mã nguồn sau để sao chép nhiều tệp trên máy khách của bạn.


 - name: Copy data to the client machine
   hosts: hostname
   become_method: sudo
   become_user: root
   become: true
   tasks: 
     # Copy twice as sometimes files get skipped (mostly only one file skipped from a folder if the folder does not exist)
     - name: Copy UFO-Server 
       copy:
         src: "source files path"
         dest: "destination file path"
         owner: root
         group: root
         mode: 0644
         backup: yes
       ignore_errors: true

Ghi chú:

Nếu bạn đang chuyển nhiều đường dẫn bằng cách sử dụng biến thì

src: "/ root / {{item}}"

Nếu bạn đang chuyển đường dẫn bằng cách sử dụng một biến cho các mục khác nhau thì

src: "/ root / {{item.source_path}}"


0

copymô-đun là một công cụ sai để sao chép nhiều tệp và / hoặc cấu trúc thư mục, synchronizethay vào đó hãy sử dụng mô-đun được sử dụng rsynclàm phụ trợ. Xin lưu ý bạn, nó yêu cầu rsynccài đặt trên cả bộ điều khiển và máy chủ đích. Nó thực sự mạnh mẽ, hãy kiểm tra tài liệu rõ ràng .

Ví dụ - sao chép tệp từ buildthư mục (với thư mục con) của bộ điều khiển vào /var/www/htmlthư mục trên máy chủ đích:

synchronize:
  src: ./my-static-web-page/build/
  dest: /var/www/html
  rsync_opts:
    - "--chmod=D2755,F644" # copy from windows - force permissions
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.