Làm thế nào để tạo một tệp trống với Ansible?


115

Cách dễ nhất để tạo một tệp trống bằng Ansible là gì? Tôi biết tôi có thể lưu một tệp trống vào filesthư mục và sau đó sao chép nó vào máy chủ từ xa, nhưng tôi thấy điều đó hơi không thỏa đáng.

Một cách khác là chạm vào tệp trên máy chủ từ xa:

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

Nhưng sau đó tập tin bị chạm vào mỗi lần, hiển thị như một dòng màu vàng trong nhật ký, điều này cũng không đạt yêu cầu ...

Có giải pháp nào tốt hơn cho vấn đề đơn giản này không?

Câu trả lời:


189

Tài liệu của mô-đun tệp cho biết

Nếu state=file, tệp sẽ KHÔNG được tạo nếu nó không tồn tại, hãy xem mô-đun sao chép hoặc mẫu nếu bạn muốn hành vi đó.

Vì vậy, chúng tôi sử dụng mô-đun sao chép, sử dụng force=nođể tạo một tệp trống mới chỉ khi tệp chưa tồn tại (nếu tệp tồn tại, nội dung của nó được giữ nguyên).

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

Đây là một giải pháp khai báo và thanh lịch.


15
@ ÁkosVandra: Thực ra thì không. Xem: force: no.
palacsint

Cảm ơn - đây là một giải pháp tốt hơn nhiều so với tệp / cảm ứng hoặc câu trả lời thống kê / tệp được chấp nhận và dễ thực hiện với "with_items"
Realist

Câu trả lời tuyệt vời, bạn tò mò về cách tạo hai tệp trống bằng cách sử dụng cùng một cấu trúc mà bạn đã cung cấp?
Tasdik Rahman

Có cách nào để thực hiện việc này tạo thư mục mẹ nếu nó không tồn tại, hay tôi cần làm điều đó riêng lẻ?
falsePockets

Bạn cần đảm bảo thư mục mẹ tồn tại và có thể ghi được. Xem stackoverflow.com/questions/22844905/…
René Pijl

37

Một cái gì đó như thế này ( stattrước tiên sử dụng mô-đun để thu thập dữ liệu về nó và sau đó lọc bằng cách sử dụng điều kiện) sẽ hoạt động:

- 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

Ngoài ra, bạn có thể tận dụng changed_whenchức năng này.


20
có lẽ nó nên là: "when: not p.stat.exists"
piro

28

Một tùy chọn khác, sử dụng mô-đun lệnh:

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

Đối số 'create' đảm bảo rằng hành động này không được thực hiện nếu tệp tồn tại.


5
Bạn nên tránh lệnh càng nhiều càng tốt vì nó không phải là idmpotent. ryaneschinger.com/blog/…
redshark1802

4
@ redshark1802 Đồng ý. Mặc dù trong trường hợp này, nhiệm vụ là không quan trọng, vì nó sẽ không được thực thi nếu "/ path / to / file" đã tồn tại. Tôi nghĩ rằng giải pháp René PIJL là các Ansible giống như nhiều trong số ba đầu câu trả lời, và chắc chắn một trong những bạn nên sử dụng nếu bạn cần phải sở hữu bộ, chế độ, vv
Leynos

15

Dựa trên câu trả lời được chấp nhận, nếu bạn muốn tệp được kiểm tra quyền mỗi lần chạy và những quyền này được thay đổi tương ứng nếu tệp tồn tại hoặc chỉ tạo tệp nếu tệp không tồn tại, bạn có thể sử dụng cách sau:

- 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
Câu trả lời này thật tuyệt vời vì tính linh hoạt mà nó mang lại cho bạn trong việc xác định các thuộc tính tệp của tệp nếu tệp đó không tồn tại.
Dejay Clayton

10

file: path=/etc/nologin state=touch

Hoàn toàn tương đương với cảm ứng (mới trong 1.4+) - sử dụng chỉ số nếu bạn không muốn thay đổi dấu thời gian của tệp.


3
Nó không phải là không quan trọng, ngày tệp sẽ được sửa đổi khi thực thi eachexible của playbook ansible.
Jérôme B

3
@ Jérôme B Mới trong Ansible 2.7: bạn có thể làm cho nó trở nên lý tưởng với file: path=/etc/nologin state=touch modification_time=preserve access_time=preserve.
GregV

8

mô-đun tệp cung cấp cách để chạm vào tệp mà không sửa đổi thời gian của nó.

- 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

Tham khảo: https://docs.ansible.com/ansible/latest/modules/file_module.html


Đây là câu trả lời chính xác cho ansible 2.7+, tuy nhiên thông tin quan trọng bị thiếu trong đó.
Honza

3

Hóa ra tôi không có đủ danh tiếng để đưa điều này làm bình luận, đó sẽ là một nơi thích hợp hơn cho việc này:

Re. Câu trả lời của AllBlackt, nếu bạn thích định dạng đa dòng của Ansible, bạn cần phải điều chỉnh báo giá cho state(Tôi đã dành vài phút để giải quyết vấn đề này, vì vậy hy vọng điều này sẽ tăng tốc cho người khác),

- 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

Để tạo tệp trong máy từ xa bằng lệnh ad-hoc

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

Xin vui lòng sửa cho tôi nếu tôi sai


0

Đã thay đổi nếu tệp không tồn tại. Tạo tệp trống.

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

0

Sự kết hợp của hai câu trả lời, với một sự thay đổi. Mã sẽ được phát hiện là đã thay đổi, khi tệp được tạo hoặc quyền được cập nhật.

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

và một phiên bản cũng sửa chủ sở hữu và nhóm và phát hiện nó đã thay đổi khi nó sửa những điều này:

- 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

ansible 2.7+ chỉ - điều đó nên được đề cập.
Honza
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.