จะสร้างไฟล์เปล่าด้วย Ansible ได้อย่างไร?


115

วิธีที่ง่ายที่สุดในการสร้างไฟล์เปล่าโดยใช้ Ansible คืออะไร? ฉันรู้ว่าฉันสามารถบันทึกไฟล์เปล่าลงในfilesไดเร็กทอรีจากนั้นคัดลอกไปยังโฮสต์ระยะไกล แต่ฉันพบว่าค่อนข้างไม่น่าพอใจ

อีกวิธีหนึ่งคือการแตะไฟล์บนโฮสต์ระยะไกล:

- name: create fake 'nologin' shell
  file: path=/etc/nologin state=touch owner=root group=sys mode=0555

แต่แล้วไฟล์ก็ถูกแตะทุกครั้งโดยแสดงเป็นเส้นสีเหลืองในบันทึกซึ่งก็ไม่น่าพอใจ ...

มีวิธีแก้ไขปัญหาง่ายๆนี้ที่ดีกว่านี้หรือไม่?

คำตอบ:


189

เอกสารประกอบของโมดูลไฟล์ระบุว่า

ถ้าstate=fileไฟล์จะไม่ถูกสร้างขึ้นหากไม่มีอยู่ให้ดูโมดูลการคัดลอกหรือเทมเพลตหากคุณต้องการลักษณะการทำงานนั้น

ดังนั้นเราจึงใช้โมดูลการคัดลอกโดยใช้force=noเพื่อสร้างไฟล์ว่างใหม่เฉพาะเมื่อไฟล์นั้นยังไม่มีอยู่ (หากมีไฟล์อยู่เนื้อหาของไฟล์จะถูกเก็บรักษาไว้)

- name: ensure file exists
  copy:
    content: ""
    dest: /etc/nologin
    force: no
    group: sys
    owner: root
    mode: 0555

นี่เป็นวิธีการที่เปิดเผยและสง่างาม


15
@ ÁkosVandra: จริงๆแล้วมันไม่ได้ ดู: force: no.
palacsint

ขอบคุณ - นี่เป็นโซลูชันที่ดีกว่า file / touch หรือคำตอบ stat / file ที่ยอมรับและทำได้ง่ายด้วย "with_items"
Realist

คำตอบที่ดีคืออยากรู้ว่าเราจะสร้างไฟล์เปล่าสองไฟล์โดยใช้โครงสร้างเดียวกันกับที่คุณให้มาได้อย่างไร?
Tasdik Rahman

มีวิธีทำให้สิ่งนี้สร้างไดเร็กทอรีพาเรนต์ถ้าไม่มีอยู่หรือฉันต้องทำแยกต่างหาก
falsePockets

คุณต้องแน่ใจว่าไดเร็กทอรีหลักมีอยู่และสามารถเขียนได้ ดูstackoverflow.com/questions/22844905/…
René Pijl

37

สิ่งนี้ (โดยใช้statโมดูลก่อนเพื่อรวบรวมข้อมูลเกี่ยวกับมันจากนั้นกรองโดยใช้เงื่อนไข) ควรใช้งานได้:

- stat: path=/etc/nologin
  register: p

- name: create fake 'nologin' shell
  file: path=/etc/nologin state=touch owner=root group=sys mode=0555
  when: p.stat.exists is defined and not p.stat.exists

คุณอาจสามารถใช้ประโยชน์จากchanged_whenฟังก์ชันการทำงานได้


20
อาจจะเป็น: "เมื่อ: ไม่ใช่ p.stat.exists"
piro

28

อีกทางเลือกหนึ่งโดยใช้โมดูลคำสั่ง:

- name: Create file
  command: touch /path/to/file
  args:
    creates: /path/to/file

อาร์กิวเมนต์ "สร้าง" ทำให้มั่นใจได้ว่าจะไม่มีการดำเนินการนี้หากมีไฟล์อยู่


5
คุณควรหลีกเลี่ยงคำสั่งให้มากที่สุดเนื่องจากไม่ใช่คำสั่ง ryaneschinger.com/blog/…
redshark1802

4
@ redshark1802 เห็นด้วย แม้ว่าในกรณีนี้งานจะไม่ถูกต้องเนื่องจากจะไม่ถูกดำเนินการหากมี "/ path / to / file" อยู่แล้ว ฉันคิดว่าโซลูชันของRené Pijl เป็นคำตอบที่เหมือน Ansible มากกว่าในสามคำตอบยอดนิยมและแน่นอนว่าคุณควรใช้หากคุณต้องการตั้งค่าความเป็นเจ้าของโหมด ฯลฯ
Leynos

15

จากคำตอบที่ยอมรับหากคุณต้องการให้ไฟล์ได้รับการตรวจสอบสิทธิ์ในการรันทุกครั้งและสิ่งเหล่านี้จะเปลี่ยนไปตามนั้นหากไฟล์นั้นมีอยู่หรือเพียงแค่สร้างไฟล์หากไม่มีอยู่คุณสามารถใช้สิ่งต่อไปนี้:

- stat: path=/etc/nologin
  register: p

- name: create fake 'nologin' shell
  file: path=/etc/nologin 
        owner=root
        group=sys
        mode=0555
        state={{ "file" if  p.stat.exists else "touch"}}

3
คำตอบนี้ยอดเยี่ยมเนื่องจากความยืดหยุ่นที่ให้คุณในการกำหนดแอตทริบิวต์ไฟล์ของไฟล์หากไม่มีอยู่
Dejay Clayton

10

file: path=/etc/nologin state=touch

เทียบเท่าเต็มรูปแบบของการสัมผัส (ใหม่ใน 1.4+) - ใช้สถิติหากคุณไม่ต้องการเปลี่ยนการประทับเวลาของไฟล์


3
ไม่ใช่สิ่งที่สำคัญวันที่ของไฟล์จะถูกแก้ไขใน eachexecution ของ playbook แบบ ansible
Jérôme B

3
@ Jérôme B ใหม่ใน Ansible 2.7: คุณสามารถทำให้เป็นเอกลักษณ์ด้วยfile: path=/etc/nologin state=touch modification_time=preserve access_time=preserve.
GregV

8

โมดูลไฟล์ให้วิธีการสัมผัสไฟล์โดยไม่ต้องปรับเปลี่ยนเวลา

- name: Touch again the same file, but dont change times this makes the task idempotent
  file:
    path: /etc/foo.conf
    state: touch
    mode: u+rw,g-wx,o-rwx
    modification_time: preserve
    access_time: preserve

อ้างอิง: https://docs.ansible.com/ansible/latest/modules/file_module.html


นี่เป็นคำตอบที่ถูกต้องสำหรับ ansible 2.7+ แต่ข้อมูลสำคัญหายไป
Honza

3

ปรากฎว่าฉันไม่มีชื่อเสียงมากพอที่จะแสดงความคิดเห็นซึ่งจะเป็นสถานที่ที่เหมาะสมกว่าสำหรับสิ่งนี้:

เรื่อง คำตอบของ AllBlackt หากคุณชอบรูปแบบหลายบรรทัดของ Ansible คุณต้องปรับการอ้างอิงstate(ฉันใช้เวลาสองสามนาทีในการทำสิ่งนี้ดังนั้นหวังว่าจะทำให้คนอื่นเร็วขึ้น)

- stat:
    path: "/etc/nologin"
  register: p

- name: create fake 'nologin' shell
  file:
    path: "/etc/nologin"
    owner: root
    group: sys
    mode: 0555
    state: '{{ "file" if  p.stat.exists else "touch" }}'

0

เพื่อสร้างไฟล์ในเครื่องระยะไกลด้วยคำสั่ง ad-hoc

ansible client -m file -a"dest=/tmp/file state=touch"

กรุณาแก้ไขฉันถ้าฉันผิด


0

เปลี่ยนแปลงหากไม่มีไฟล์ สร้างไฟล์เปล่า

- name: create fake 'nologin' shell
  file:
    path: /etc/nologin
    state: touch
  register: p
  changed_when: p.diff.before.state == "absent"

0

การรวมกันของสองคำตอบด้วยการบิด รหัสจะถูกตรวจพบว่ามีการเปลี่ยนแปลงเมื่อสร้างไฟล์หรืออัปเดตสิทธิ์

- name: Touch again the same file, but dont change times this makes the task idempotent
  file:
    path: /etc/foo.conf
    state: touch
    mode: 0644
    modification_time: preserve
    access_time: preserve
  changed_when: >
    p.diff.before.state == "absent" or
    p.diff.before.mode|default("0644") != "0644"

และเวอร์ชันที่แก้ไขเจ้าของและกลุ่มและตรวจพบว่ามีการเปลี่ยนแปลงเมื่อแก้ไขสิ่งเหล่านี้:

- name: Touch again the same file, but dont change times this makes the task idempotent
  file:
    path: /etc/foo.conf
    state: touch
    state: touch
    mode: 0644
    owner: root
    group: root
    modification_time: preserve
    access_time: preserve
  register: p
  changed_when: >
    p.diff.before.state == "absent" or
    p.diff.before.mode|default("0644") != "0644" or
    p.diff.before.owner|default(0) != 0 or
    p.diff.before.group|default(0) != 0

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