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