Ansible ile birden fazla dosyayı kopyalayın


105

Bir görevde Ansible ile birden fazla dosyayı uzak düğümlere nasıl kopyalayabilirim?

Dosyaları tanımlamak için görevimdeki kopyalama modülü satırını çoğaltmaya çalıştım, ancak yalnızca ilk dosyayı kopyalıyor.

Yanıtlar:


131

with_fileglobDöngüyü bunun için kullanabilirsiniz :

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

3
Uzak makineye kopyalamak için tüm dosyalarım aynı kökte olsaydı, çeşitli dizinlerde bazı dosyalara sahip olsaydım, bu yaklaşım bana yardımcı olabilir. Örneğin, 3 farklı
Mark

Hey, tüm dosyaları kendimden taşımaya çalışıyorum /roles/db/filesama bu yöntemle çalışmasını sağlayamıyorum. Denedim with_fileglob: - /roles/db/file/* ama yolu
Batman

Bu yöntemin en büyük dezavantajı, dizin yapısını düzleştirmesidir.
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

Bu çözüme destdeğişken olarak set ile sahip olmak mümkün müdür ? { src: 'containerizers', dest: {{ containerizers }} }.
Gesias

2
@Gesias, evet. Aslında, her iki taraf da değişken olabilir:{ src: '{{ source.var }}', dest: '{{ dest.var }}' }
ntwrkguru

16

With_to Together'ı bu amaçla kullanabilirsiniz:

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

Çalışmasına rağmen, bu anlamsal olarak temiz değildir - daha temiz seçenekler vardır.
plesiv

11

Birden fazla konuma ihtiyacınız varsa, birden fazla göreve ihtiyacınız vardır. Bir kopyalama görevi, yalnızca bir konumdan (birden çok dosya dahil) düğümdeki diğerine kopyalayabilir.

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

- isim: dosya1 kopya copy: src = / dosya1 varış = / Hedef / Dosya1 - adını: copy file2 kopya: src = / Dosya2 varış = / Hedef / Dosya2
Mark

Bağlı olmak. Daha basit ve büyük olasılıkla daha temiz, ancak öğelerle döngülü kaynak ve hedef verilerle anonim sözlükler listesi gibi daha karmaşık veri yapıları kullanılarak yapılabilir. Herhangi bir dilde aynı - bir karar vermelisiniz. Yetki verme işlevinin uzun bir dizi kopyala / yapıştır if deyiminden daha verimli ve sürdürülebilir olduğu durumlar vardır. Neredeyse aynı direktiflerin uzun ve sıkıcı bir listesinden çok, iyi yapılandırılmış kodun kısa ve öz kısmını korumayı tercih eden o ucubeyim, ancak herkesin aynı fikirde olduğunu sanmıyorum. Sizin için bakımı yapılabilir olanı yapın.
Paul Hodges

8

Ansible 2.5'ten bu yana with_*yapılar kullanımdan kaldırılmıştır ve loopsözdizimi kullanılmalıdır. Basit bir pratik örnek:

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

bir yan not findmodülün yalnızca yanıtlanabilir 2.x için çalıştığını, ancak yanıtlanabilir 1.x için çalışmadığını unutmayın
Arbab Nazar

stdout_linesDönüş değerinde bahsettiğiniz için cevabınızı düzelttim ancak findmodül için geçerli değil . Sadece bir tane files, examinedve matcheddönüş değerleri olarak. Umarım başkalarına yardım eder
Arbab Nazar

2
Dosyaları uzak düğümlere kopyalamak için bu çalışmayı yapan oldu mu? findsadece uzaktaki sisteme bakar, yönetim düğümünden herhangi bir şey almaya izin vermez. Bu cevapların kullanılması with_fileglobdaha uygun görünüyor: stackoverflow.com/a/42290160/272387 , stackoverflow.com/a/36720342/272387 .
Richlv

4

Veya with_items kullanabilirsiniz:

- 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
İyi bir cevap yalnızca kodu değil, aynı zamanda bazı açıklamalar veya belge referanslarını da içerir.
Laurenz Albe

Find, set_fact ve copy modüllerinin tümü yanıtlanabilir belgelerde açıklanmıştır. Daha bu bölümde hakkında bilmek whant eğer da yanıtlayıcı 'belgelerinde açıklandığı, filtrelerle ilgili Oku (- "{{find_files.files | harita (attribute'path') | liste}}")
Fredric Andersson

1

Dizin listesiyle değişkenler arasında geçiş yapabilirsiniz:

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

1

İstemci makinenizde birden çok dosyayı kopyalamak için aşağıdaki kaynak kodunu kullanı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

Not:

Değişken kullanarak birden çok yolu geçiyorsanız

src: "/ root / {{öğe}}"

Farklı öğeler için bir değişken kullanarak yolu geçiyorsanız,

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


0

copymodül, birçok dosyayı ve / veya dizin yapısını kopyalamak için yanlış bir araçtır, synchronizebunun yerine rsyncarka uç olarak kullanan modülü kullanın . Unutmayın rsync, hem denetleyiciye hem de hedef ana bilgisayara yüklenmesi gerekir . Gerçekten güçlü, yanıtlanabilir belgeleri kontrol edin .

Örnek - dosyaları builddenetleyicinin dizininden (alt dizinlerle) /var/www/htmlhedef ana bilgisayardaki dizine kopyalayın :

synchronize:
  src: ./my-static-web-page/build/
  dest: /var/www/html
  rsync_opts:
    - "--chmod=D2755,F644" # copy from windows - force permissions
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.