Kopieren Sie mehrere Dateien mit Ansible


103

Wie kann ich in einer Aufgabe mehr als eine einzelne Datei von Ansible auf Remote-Knoten kopieren?

Ich habe versucht, die Kopiermodulzeile in meiner Aufgabe zu duplizieren, um Dateien zu definieren, aber es wird nur die erste Datei kopiert.

Antworten:


131

Sie können die with_fileglobSchleife dafür verwenden:

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

3
Dieser Ansatz könnte mir helfen, wenn ich alle meine Dateien zum Kopieren auf einen Remotecomputer im selben Stammverzeichnis habe. Wie wäre es, wenn sich einige Dateien in verschiedenen Verzeichnissen befinden? Zum Beispiel möchte ich 3 Dateien aus 3 verschiedenen Verzeichnissen kopieren
Mark

Hey, ich versuche alle Dateien von meinem zu verschieben, /roles/db/filesaber ich kann es mit dieser Methode nicht zum Laufen bringen. Ich habe es versucht, with_fileglob: - /roles/db/file/* aber es wird den Weg nicht gut
Batman

Der große Nachteil dieser Methode ist, dass sie die Verzeichnisstruktur abflacht.
Quintin Par

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

Ist es möglich, diese Lösung mit der destMenge als Variable zu haben? { src: 'containerizers', dest: {{ containerizers }} }.
Gesias

2
@Gesias, ja. Eigentlich können beide Seiten Variablen sein:{ src: '{{ source.var }}', dest: '{{ dest.var }}' }
ntwrkguru

16

Sie können with_together für diesen Zweck verwenden:

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

Obwohl es funktioniert, ist dies nicht semantisch sauber - es gibt sauberere Optionen.
Bitte

11

Wenn Sie mehr als einen Standort benötigen, benötigen Sie mehr als eine Aufgabe. Eine Kopieraufgabe kann nur von einem Speicherort (einschließlich mehrerer Dateien) an einen anderen auf dem Knoten kopiert werden.

- 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 Kopie: src = / file1 dest = / Ziel / file1 - Name: Kopieren file2 Kopie: src = / file2 dest = / Ziel / file2
Mark

Hängt davon ab. Einfacher und wahrscheinlich sauberer, kann jedoch mithilfe komplexerer Datenstrukturen durchgeführt werden, z. B. einer Liste anonymer Wörterbücher mit Quell- und Zieldaten, die mit_items wiederholt werden. In jeder Sprache ist es das gleiche - Sie müssen ein Urteil fällen. Es gibt Fälle, in denen eine Delegierungsfunktion effizienter und wartbarer ist als eine lange Reihe von kopierten / eingefügten if-Anweisungen. Ich bin dieser Freak, der lieber das prägnante Stück gut strukturierten Codes beibehalten möchte als eine lange und langwierige Liste nahezu identischer Anweisungen, aber ich gehe nicht davon aus, dass alle zustimmen. Tun Sie, was für Sie wartbar ist.
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 }}"

nur eine Randnotiz, dass findModul nur für ansible 2.x funktioniert, aber nicht für ansible 1.x
Arbab Nazar

Ich habe Ihre Antwort korrigiert, da Sie die stdout_linesim Rückgabewert angegeben haben, sie jedoch nicht für das findModul gilt. Es hat nur files, examinedund matchedals Rückgabewert. Hoffe, dass anderen helfen
Arbab Nazar

2
Hat es jemand geschafft, Dateien zum Kopieren auf entfernte Knoten zum Laufen zu bringen? findscheint nur auf das entfernte System zu schauen und erlaubt nicht, irgendetwas vom verwaltenden Knoten zu holen. Diese Antworten with_fileglobscheinen passender zu sein: stackoverflow.com/a/42290160/272387 , stackoverflow.com/a/36720342/272387 .
Richlv

6

Seit Ansible 2.5 sind die with_*Konstrukte veraltet und die loopSyntax sollte verwendet werden. Ein einfaches praktisches Beispiel:

- 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

Oder Sie können with_items verwenden:

- 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
Eine gute Antwort enthält nicht nur Code, sondern auch einige Erklärungen oder Dokumentationsreferenzen.
Laurenz Albe

Die Module find, set_fact und copy werden in der ansible-Dokumentation erläutert. Lesen Sie mehr über Filter, die auch in der Ansible-Dokumentation erläutert werden, wenn Sie mehr über diesen Abschnitt erfahren möchten (- "{{find_files.files | map (attribute'path ') | list}}")
Fredric Andersson

1

Sie können eine Variable mit einer Liste von Verzeichnissen durchlaufen:

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

1

Verwenden Sie den folgenden Quellcode, um mehrere Dateien auf Ihren Clientcomputer zu kopieren.


 - 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

Hinweis:

Wenn Sie mehrere Pfade mithilfe von Variablen übergeben, dann

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

Wenn Sie den Pfad übergeben, indem Sie eine Variable für verschiedene Elemente verwenden, dann

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


0

copyModul ist ein falsches Tool zum Kopieren vieler Dateien und / oder Verzeichnisstrukturen. Verwenden Sie synchronizestattdessen das Modul, das rsyncals Backend verwendet wird. Allerdings muss es rsyncsowohl auf dem Controller als auch auf dem Zielhost installiert sein. Es ist wirklich mächtig, überprüfen Sie ansible Dokumentation .

Beispiel - Kopieren Sie Dateien aus dem buildVerzeichnis (mit Unterverzeichnissen) des Controllers in das /var/www/htmlVerzeichnis auf dem Zielhost:

synchronize:
  src: ./my-static-web-page/build/
  dest: /var/www/html
  rsync_opts:
    - "--chmod=D2755,F644" # copy from windows - force permissions
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.