Як створити порожній файл за допомогою 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

Спасибі - це набагато приємніше рішення, ніж файл / touch або прийнята відповідь stat / file, і це легко зробити з "with_items"
Realist

Чудова відповідь, цікаво було, як можна створити два порожні файли за допомогою тієї ж конструкції, яку ви надали?
Тасдік Рахман

Чи є спосіб зробити це створити батьківський каталог, якщо він не існує, або мені потрібно це робити окремо?
falsePockets

Потрібно переконатися, що батьківський каталог існує та є доступним для запису. Див stackoverflow.com/questions/22844905 / ...
Рене 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

Аргумент 'create' гарантує, що ця дія не виконується, якщо файл існує.


5
Вам слід максимально уникати команд, оскільки це не є безсильним. ryaneschinger.com/blog/…
redshark1802

4
@ redshark1802 Погоджено. Хоча в цьому випадку завдання ідентичне, оскільки воно не буде виконано, якщо "/ шлях / до / файл" вже існує. Я думаю, що рішення Рене Пійла - це більш відповідне з трьох найкращих відповідей, і, безумовно, той, який вам слід використовувати, якщо вам потрібно встановити право власності, режим тощо
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+) - використовуйте stat, якщо ви не хочете змінювати часову позначку файлу.


3
Це не є ідентичним, дата файлу буде змінена під час виконання анкейної книги.
Jérôme B

3
@ Jérôme B Нове у відповіді 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+, однак, що в ньому відсутня важлива інформація.
Гонза

3

Виявляється, мені не вистачає репутації, щоб поставити це як коментар, що було б більш підходящим місцем для цього:

Re. Відповідь 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

Щоб створити файл на віддаленій машині за допомогою спеціальної команди

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

лише ansible 2.7+ - це слід зазначити.
Гонза
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.