คัดลอกไฟล์หลายไฟล์ด้วย Ansible


108

ฉันจะคัดลอกไฟล์มากกว่าหนึ่งไฟล์ไปยังโหนดระยะไกลโดย Ansible ในงานได้อย่างไร

ฉันพยายามทำสำเนาบรรทัดโมดูลการคัดลอกในงานของฉันเพื่อกำหนดไฟล์ แต่จะคัดลอกเฉพาะไฟล์แรกเท่านั้น

คำตอบ:


138

คุณสามารถใช้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/* แต่มันก็ไม่ดีไป
Batman

ข้อเสียใหญ่ของวิธีนี้คือทำให้โครงสร้างไดเรกทอรีแบน
Quintin Par

119
- 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 }} }.
Gesias

2
@ เจเซียสใช่ จริงๆแล้วทั้งสองด้านสามารถเป็นตัวแปรได้:{ 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

12

หากคุณต้องการมากกว่าหนึ่งตำแหน่งคุณต้องมีงานมากกว่าหนึ่งงาน งานการคัดลอกหนึ่งงานสามารถคัดลอกจากตำแหน่งเดียวเท่านั้น (รวมถึงไฟล์หลายไฟล์) ไปยังอีกที่หนึ่งบนโหนด

- 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
ทำเครื่องหมาย

ขึ้นอยู่กับ ง่ายกว่าและน่าจะสะอาดกว่า แต่สามารถทำได้โดยใช้โครงสร้างข้อมูลที่ซับซ้อนมากขึ้นเช่นรายการพจนานุกรมที่ไม่ระบุชื่อที่มีข้อมูลต้นทางและเป้าหมายวนซ้ำกับ_items มันเหมือนกันในทุกภาษา - คุณต้องเรียกร้องการตัดสิน มีบางกรณีที่ฟังก์ชันการมอบหมายมีประสิทธิภาพและดูแลรักษาได้ดีกว่าชุดคำสั่งคัดลอก / วางแบบยาว ฉันเป็นคนประหลาดที่ค่อนข้างจะคงความกระชับของโค้ดที่มีโครงสร้างที่ดีมากกว่ารายการคำสั่งที่เกือบเหมือนกันและน่าเบื่อ แต่ฉันไม่คิดว่าทุกคนจะเห็นด้วย ทำสิ่งที่สามารถรักษาได้สำหรับคุณ
Paul Hodges

10

เนื่องจาก 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


8
- 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โมดูลใช้งานได้กับ 2.x ที่ตอบได้เท่านั้น แต่ไม่สามารถตอบสนองได้ 1.x
Arbab Nazar

ฉันได้แก้ไขคำตอบของคุณแล้วเนื่องจากคุณได้กล่าวถึงstdout_linesในค่าส่งคืน แต่ไม่สามารถใช้ได้กับfindโมดูล มันมีเพียงfiles, examinedและmatchedเป็นค่าผลตอบแทน หวังว่าจะช่วยผู้อื่น
Arbab Nazar

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 และ copy ทั้งหมดได้อธิบายไว้ในเอกสารที่สามารถตอบได้ อ่านเกี่ยวกับตัวกรองและอธิบายไว้ในเอกสารที่ตอบได้หากคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับส่วนนี้ (- "{{find_files.files | map (attribute'path ') | list}}")
Fredric Andersson

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.