Skopiuj wiele plików za pomocą Ansible


104

Jak mogę skopiować więcej niż jeden plik do zdalnych węzłów przez Ansible w zadaniu?

Próbowałem zduplikować wiersz modułu kopiowania w moim zadaniu, aby zdefiniować pliki, ale kopiuje tylko pierwszy plik.

Odpowiedzi:


131

Możesz użyć with_fileglobpętli do tego:

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

3
Takie podejście mogłoby mi pomóc, gdybym miał wszystkie moje pliki w tym samym katalogu głównym do kopiowania na zdalną maszynę, a co z posiadaniem niektórych plików w różnych katalogach. Na przykład chcę skopiować 3 pliki z 3 różnych katalogów
Mark

Hej, próbuję przenieść wszystkie pliki z mojego, /roles/db/filesale nie mogę uruchomić tej metody. Próbowałem, with_fileglob: - /roles/db/file/* ale to nie wystarczy
Batman

Dużą wadą tej metody jest to, że spłaszcza strukturę katalogów.
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

Czy można mieć to rozwiązanie ze destzbiorem jako zmienną? { src: 'containerizers', dest: {{ containerizers }} }.
Gesias

2
@Gesias, tak. Właściwie obie strony mogą być zmiennymi:{ src: '{{ source.var }}', dest: '{{ dest.var }}' }
ntwrkguru

16

W tym celu możesz użyć with_together:

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

Chociaż to działa, nie jest to semantycznie czyste - istnieją opcje czystsze.
plesiv

11

Jeśli potrzebujesz więcej niż jednej lokalizacji, potrzebujesz więcej niż jednego zadania. Jedno zadanie kopiowania można skopiować tylko z jednej lokalizacji (w tym wielu plików) do innej w węźle.

- 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 - name: copy file2 copy: src = / file2 dest = / destination / file2
Mark

Zależy. Prostsze i prawdopodobnie czystsze, ale można to zrobić przy użyciu bardziej złożonych struktur danych, takich jak lista anonimowych słowników z danymi źródłowymi i docelowymi, zapętlona za pomocą atrybutu_items. Tak samo jest w każdym języku - musisz dokonać oceny. Istnieją przypadki, w których funkcja delegowania jest bardziej wydajna i łatwiejsza w utrzymaniu niż długa seria instrukcji kopiowania / wklejania if. Jestem tym dziwakiem, który wolałby zachować zwięzły fragment dobrze skonstruowanego kodu niż długą i żmudną listę prawie identycznych dyrektyw, ale nie zakładam, że wszyscy się z tym zgadzają. Zrób to, co jest dla ciebie możliwe do utrzymania.
Paul Hodges,

8

Od wersji Ansible 2.5 with_*konstrukcje są przestarzałe i loopnależy używać składni. Prosty praktyczny przykład:

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

tylko na marginesie, że findmoduł działa tylko dla ansibl 2.x, ale nie dla ansibl 1.x
Sredniowieczna kusza Nazar

Poprawiłem twoją odpowiedź, ponieważ wspomniałeś o stdout_lineswartości zwracanej, ale nie ma ona zastosowania do findmodułu. To tylko files, examinedi matchedjako wartości zwracane. Mam nadzieję, że pomoże to innym
Arbab Nazar

2
Czy ktoś był w stanie zmusić to do kopiowania plików do zdalnych węzłów? findwydaje się tylko patrzeć na system zdalny, nie pozwalając na pobranie czegokolwiek z węzła zarządzającego. Te odpowiedzi, używając with_fileglob, wydają się być bardziej odpowiednie: stackoverflow.com/a/42290160/272387 , stackoverflow.com/a/36720342/272387 .
Richlv

4

Lub możesz użyć 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
Dobra odpowiedź zawiera nie tylko kod, ale także wyjaśnienia lub odniesienia do dokumentacji.
Laurenz Albe,

Moduły find, set_fact i copy są wyjaśnione w dokumentacji ansibli. Przeczytaj o filtrach, również wyjaśnionych w dokumentacji ansibli, jeśli chcesz dowiedzieć się więcej o tej sekcji (- "{{find_files.files | map (attribute'path ') | list}}")
Fredric Andersson

1

Możesz przeglądać zmienną z listą katalogów:

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

1

Użyj następującego kodu źródłowego do kopiowania wielu plików na komputerze klienckim.


 - 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

Uwaga:

Jeśli przekazujesz wiele ścieżek przy użyciu zmiennej to

src: „/ root / {{item}}”

Jeśli przekazujesz ścieżkę, używając zmiennej dla różnych elementów, to

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


0

copymodule jest złym narzędziem do kopiowania wielu plików i / lub struktury katalogów, synchronizezamiast tego użyj modułu, który używa rsyncjako zaplecza. Pamiętaj, że wymaga rsynczainstalowania zarówno na kontrolerze, jak i na hoście docelowym. To naprawdę potężne, sprawdź dokumentację ansibli .

Przykład - skopiuj pliki z buildkatalogu (z podkatalogami) kontrolera do /var/www/htmlkatalogu na hoście docelowym:

synchronize:
  src: ./my-static-web-page/build/
  dest: /var/www/html
  rsync_opts:
    - "--chmod=D2755,F644" # copy from windows - force permissions
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.