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.