Salin banyak file dengan Ansible


104

Bagaimana cara menyalin lebih dari satu file ke node jarak jauh oleh Ansible dalam tugas?

Saya sudah mencoba menduplikasi baris modul salin dalam tugas saya untuk menentukan file tetapi itu hanya menyalin file pertama.

Jawaban:


131

Anda dapat menggunakan with_fileglobloop untuk ini:

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

3
Pendekatan ini dapat membantu saya jika saya memiliki semua file saya di root yang sama untuk disalin ke mesin jarak jauh, bagaimana dengan memiliki beberapa file di berbagai direktori. Misalnya, saya ingin menyalin 3 file dari 3 direktori berbeda
Tandai

Hei, saya mencoba memindahkan semua file dari saya /roles/db/filestetapi saya tidak bisa membuatnya berfungsi dengan metode ini. Saya sudah mencoba with_fileglob: - /roles/db/file/* tetapi tidak akan baik-baik saja jalannya
Batman

Kerugian besar dengan metode ini adalah meratakan struktur direktori.
Quintin Par

115
- 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

Apakah mungkin memiliki solusi ini dengan desthimpunan sebagai variabel? { src: 'containerizers', dest: {{ containerizers }} }.
Gesias

2
@ Gesias, ya. Sebenarnya, kedua sisi bisa menjadi variabel:{ src: '{{ source.var }}', dest: '{{ dest.var }}' }
ntwrkguru

16

Anda dapat menggunakan with_together untuk tujuan ini:

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

Meskipun berhasil, ini tidak bersih secara semantik - ada opsi yang lebih bersih.
plesiv

11

Jika Anda membutuhkan lebih dari satu lokasi, Anda memerlukan lebih dari satu tugas. Satu tugas salin hanya dapat menyalin dari satu lokasi (termasuk beberapa file) ke lokasi lain di node.

- 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/*

- nama: salin file1 salin: src = / file1 tujuan = / tujuan / file1 - nama: salin file2 salin: src = / file2 tujuan = / tujuan / file2
Tandai

Tergantung. Lebih sederhana dan mungkin lebih bersih, tetapi dapat dilakukan dengan menggunakan struktur data yang lebih kompleks, seperti daftar kamus anonim dengan data sumber dan target, yang diulang dengan_item. Itu sama dalam bahasa apa pun - Anda harus membuat keputusan. Ada kasus di mana fungsi delegasi lebih efisien dan dapat dipelihara daripada rangkaian panjang pernyataan copy / paste if. Saya orang aneh yang lebih suka mempertahankan sedikit kode terstruktur dengan baik daripada daftar panjang dan membosankan dari arahan yang hampir identik, tapi saya tidak berasumsi semua orang setuju. Lakukan apa yang bisa dipertahankan untuk Anda.
Paul Hodges

8

Karena Ansible 2.5, with_*konstruksi tidak digunakan lagi , dan loopsintaks harus digunakan. Contoh praktis sederhana:

- 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


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 }}"

hanya catatan tambahan bahwa findmodul hanya bekerja untuk kemungkinan 2.x tetapi tidak untuk kemungkinan 1.x
Arbab Nazar

Saya telah memperbaiki jawaban Anda karena Anda telah menyebutkan stdout_linesnilai kembali tetapi tidak berlaku untuk findmodul. Itu hanya memiliki files, examineddan matchedsebagai nilai kembali. Harapan yang membantu orang lain
Arbab Nazar

2
Adakah yang bisa membuat ini berfungsi untuk menyalin file ke node jauh? findtampaknya hanya melihat sistem jarak jauh, tidak memungkinkan untuk mengambil apa pun dari node pengelola. Jawaban ini, menggunakan with_fileglob, tampaknya lebih cocok: stackoverflow.com/a/42290160/272387 , stackoverflow.com/a/36720342/272387 .
Richlv

4

Atau Anda dapat menggunakan 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
Jawaban yang baik tidak hanya berisi kode, tetapi juga beberapa penjelasan atau referensi dokumentasi.
Laurenz Albe

Modul find, set_fact, dan copy semuanya dijelaskan dalam dokumentasi yang memungkinkan. Baca tentang filter, juga dijelaskan dalam dokumentasi yang memungkinkan jika Anda ingin tahu lebih banyak tentang bagian ini (- "{{find_files.files | map (attribute'path ') | list}}")
Fredric Andersson

1

Anda dapat melakukan perulangan melalui variabel dengan daftar direktori:

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

1

Gunakan kode sumber berikut untuk menyalin beberapa file di komputer klien Anda.


 - 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

catatan:

Jika Anda melewati beberapa jalur dengan menggunakan variabel kemudian

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

Jika Anda melewati jalur dengan menggunakan variabel untuk item yang berbeda maka

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


0

copymodul adalah alat yang salah untuk menyalin banyak file dan / atau struktur direktori, gunakan synchronizemodul sebagai gantinya yang digunakan rsyncsebagai backend. Pikiran Anda, itu perlu rsyncdiinstal pada pengontrol dan host target. Ini sangat kuat, periksa dokumentasi yang memungkinkan .

Contoh - salin file dari builddirektori (dengan subdirektori) pengontrol ke /var/www/htmldirektori pada host target:

synchronize:
  src: ./my-static-web-page/build/
  dest: /var/www/html
  rsync_opts:
    - "--chmod=D2755,F644" # copy from windows - force permissions
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.