Скопіюйте кілька файлів за допомогою Ansible


104

Як я можу скопіювати декілька файлів у віддалені вузли за допомогою Ansible у завданні?

Я намагався дублювати рядок модуля копіювання у своєму завданні для визначення файлів, але він копіює лише перший файл.

Відповіді:


131

Ви можете використовувати with_fileglobцикл для цього:

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

3
Цей підхід міг би допомогти мені, якщо я маю всі свої файли в одному корені для копіювання на віддалену машину, як щодо того, щоб мати деякі файли в різних каталогах. Наприклад, я хочу скопіювати 3 файли з 3 різних каталогів
Марк

Гей, я намагаюся перемістити всі файли з мого, /roles/db/filesале я не можу з цим методом працювати. Я спробував, with_fileglob: - /roles/db/file/* але це не вдасться виправити шлях
Бетмен

Великим недоліком цього методу є те, що він вирівнює структуру каталогів.
Квінтін Пар

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

Чи можливо це рішення мати destнабір як змінну? { src: 'containerizers', dest: {{ containerizers }} }.
Гесіас

2
@Gesias, так. Насправді обидві сторони можуть бути змінними:{ src: '{{ source.var }}', dest: '{{ dest.var }}' }
ntwrkguru

16

Для цього ви можете використовувати with_together:

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

Хоча це працює, але це не семантично чисто - є більш чисті варіанти.
plesiv

11

Якщо вам потрібно більше ніж одне місце, вам потрібно більше ніж одне завдання. Одне завдання копіювання може копіювати лише з одного місця (включаючи кілька файлів) в інше на вузлі.

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

- Ім'я: скопіювати file1 копію: SRC = / file1 = Dest / призначення / file1 - ім'я: копія file2 копія: SRC = / file2 = Dest / призначення / file2
Mark

Залежить. Більш простий і, ймовірно, чистіший, але це можна зробити за допомогою складніших структур даних, таких як список анонімних словників із вихідними та цільовими даними, зациклившись з_items. Це так само в будь-якій мові - вам потрібно зробити дзвінок у суді. Бувають випадки, коли функція делегування є більш ефективною та досяжною, ніж довга серія копіювання / вставки, якщо заяви. Я той фрік, який би скоріше підтримував стислий біт добре структурованого коду, ніж довгий і нудний список майже однакових директив, але я не вважаю, що всі згодні. Робіть те, що для вас ретельно.
Пол Ходж

8

Оскільки Ansible 2.5, with_*конструкції застаріли , і loopслід використовувати синтаксис. Простий практичний приклад:

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

лише бічне зауваження, що findмодуль працює лише для ansible 2.x, але не для ansible 1.x
Arbab Nazar

Я зафіксував вашу відповідь, оскільки ви згадали stdout_linesпро зворотне значення, але це не стосується findмодуля. Це тільки є files, examinedі matchedяк повернені значення. Сподіваюся, що допоможе іншим
Арбаб Назар

2
Хто-небудь зміг зробити так, щоб скопіювати файли на віддалені вузли? findтільки здається, що дивиться на віддалену систему, не дозволяючи схопити щось з керуючого вузла. Ці відповіді, використовуючи with_fileglob, здається, більше підходять: stackoverflow.com/a/42290160/272387 , stackoverflow.com/a/36720342/272387 .
Richlv

4

Або ви можете використовувати 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
Хороша відповідь містить не лише код, а й деякі пояснення чи посилання на документацію.
Laurenz Albe

Модулі find, set_fact та копіюються в поясненій документації. Читайте про фільтри, також пояснені в документації з ансибілу, якщо ви хочете дізнатися більше про цей розділ (- "{{find_files.files | map (attribute'path ') | список}}")
Фредрік Андерссон

1

Ви можете переглядати змінну зі списком каталогів:

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

1

Використовуйте наступний вихідний код для копіювання декількох файлів на клієнтській машині.


 - 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

Примітка:

Якщо ви пропускаєте кілька шляхів, використовуючи змінну, тоді

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

Якщо ви проходите шлях, використовуючи змінну для різних елементів, тоді

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


0

copyМодуль - неправильний інструмент для копіювання багатьох файлів та / або структури каталогів, synchronizeзамість цього використовується модуль, який використовується rsyncяк резервний. Зауважте, він вимагає rsyncвстановлення як на контролері, так і на цільовому хості. Це справді потужна, перевіряйте відповідальну документацію .

Приклад - скопіюйте файли з buildкаталогу (з підкаталогами) контролера в /var/www/htmlкаталог на цільовому хості:

synchronize:
  src: ./my-static-web-page/build/
  dest: /var/www/html
  rsync_opts:
    - "--chmod=D2755,F644" # copy from windows - force permissions
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.