Copia più file con Ansible


104

Come posso copiare più di un singolo file in nodi remoti da Ansible in un'attività?

Ho provato a duplicare la riga del modulo di copia nella mia attività per definire i file, ma copia solo il primo file.

Risposte:


131

Puoi usare il with_fileglobciclo per questo:

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

3
Questo approccio potrebbe aiutarmi se avessi tutti i miei file nella stessa radice per la copia su una macchina remota, che dire se avessi alcuni file in varie directory. Ad esempio, voglio copiare 3 file da 3 directory diverse
— Mark

Ehi, sto cercando di spostare tutti i file dal mio /roles/db/filesma non riesco a farlo funzionare con questo metodo. Ho provato with_fileglob: - /roles/db/file/* ma non andrà bene il percorso
— Batman

Il grande svantaggio di questo metodo è che appiattisce la struttura della directory.
— 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

È possibile avere questa soluzione con l' destinsieme come variabile? { src: 'containerizers', dest: {{ containerizers }} }.
— Gesias

2
@Gesias, sì. In realtà, entrambi i lati possono essere variabili:{ src: '{{ source.var }}', dest: '{{ dest.var }}' }
— ntwrkguru

16

Puoi usare with_together per questo scopo:

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

Sebbene funzioni, non è semanticamente pulito: ci sono opzioni più pulite.
— plesiv

11

Se hai bisogno di più di una posizione, hai bisogno di più di un'attività. Un'attività di copia può copiare solo da una posizione (inclusi più file) a un'altra sul nodo.

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

- nome: copia file1 copia: src = / file1 dest = / destinazione / file1 - nome: copia file2 copia: src = / file2 dest = / destinazione / file2
— Contrassegna

Dipende. Più semplice e probabilmente più pulito, ma può essere fatto utilizzando strutture di dati più complesse, come un elenco di dizionari anonimi con dati di origine e di destinazione, in loop with_items. È lo stesso in qualsiasi lingua: devi fare un giudizio. Ci sono casi in cui una funzione di delega è più efficiente e gestibile di una lunga serie di istruzioni if ​​copiate / incollate. Sono quel mostro che preferirebbe mantenere il pezzo conciso di codice ben strutturato piuttosto che un lungo e noioso elenco di direttive quasi identiche, ma non presumo tutti siano d'accordo. Fai ciò che è mantenibile per te.
— Paul Hodges

8

A partire da Ansible 2.5 i with_*costrutti sono deprecati e loopdovrebbe essere usata la sintassi. Un semplice esempio pratico:

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

solo una nota finda margine che il modulo funziona solo per ansible 2.x ma non per ansible 1.x
— Arbab Nazar

Ho corretto la tua risposta perché hai menzionato il stdout_linesvalore di ritorno ma non è applicabile per il findmodulo. Si hanno solo files, examinede matchedcome valori di ritorno. Spero che questo aiuti gli altri
— Arbab Nazar

2
Qualcuno è riuscito a farlo funzionare per copiare file su nodi remoti? findsembra solo guardare il sistema remoto, non permettendo di afferrare nulla dal nodo di gestione. Queste risposte, utilizzando with_fileglob, sembrano essere più adatte: stackoverflow.com/a/42290160/272387 , stackoverflow.com/a/36720342/272387 .
— Richlv

4

Oppure puoi usare 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
Una buona risposta contiene non solo codice, ma anche alcune spiegazioni o riferimenti alla documentazione.
— Laurenz Albe

I moduli find, set_fact e copy sono tutti spiegati nella documentazione ansible. Leggi i filtri, spiegati anche nella documentazione ansible se vuoi saperne di più su questa sezione (- "{{find_files.files | map (attribute'path ') | list}}")
— Fredric Andersson

1

Puoi scorrere la variabile con l'elenco delle directory:

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

1

Usa il seguente codice sorgente per copiare più file sul tuo computer client.


 - 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

Nota:

Se stai passando più percorsi usando la variabile allora

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

Se stai passando percorso utilizzando una variabile per elementi diversi, allora

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


0

copymodule è uno strumento sbagliato per copiare molti file e / o strutture di directory, usa synchronizeinvece module che usa rsynccome backend. Intendiamoci, richiede l' rsyncinstallazione sia sul controller che sull'host di destinazione. È davvero potente, controlla la documentazione ansible .

Esempio: copia i file dalla builddirectory (con le sottodirectory) del controller alla /var/www/htmldirectory sull'host di destinazione:

synchronize:
  src: ./my-static-web-page/build/
  dest: /var/www/html
  rsync_opts:
    - "--chmod=D2755,F644" # copy from windows - force permissions
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.