Jak stworzyć pusty plik w Ansible?


115

Jaki jest najłatwiejszy sposób utworzenia pustego pliku za pomocą Ansible? Wiem, że mogę zapisać pusty plik wfiles katalogu, a następnie skopiować go do zdalnego hosta, ale wydaje mi się to niezadowalające.

Innym sposobem jest dotknięcie pliku na zdalnym hoście:

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

Ale potem plik jest dotykany za każdym razem, pokazując żółtą linię w dzienniku, co również jest niezadowalające ...

Czy istnieje lepsze rozwiązanie tego prostego problemu?

Odpowiedzi:


189

Dokumentacja modułu plików mówi

Jeśli state=fileplik NIE zostanie utworzony, jeśli nie istnieje, zobacz moduł kopiowania lub szablonu, jeśli chcesz to zachowanie.

Używamy więc modułu kopiowania, używając force=nodo tworzenia nowego pustego pliku tylko wtedy, gdy plik jeszcze nie istnieje (jeśli plik istnieje, jego zawartość jest zachowana).

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

To deklaratywne i eleganckie rozwiązanie.


15
@ ÁkosVandra: Właściwie nie. Zobacz: force: no.
— palacsint

Dzięki - jest to o wiele lepsze rozwiązanie niż plik / dotyk lub akceptowana stat / odpowiedź z pliku i jest łatwe do zrobienia z "with_items"
— Realist

Świetna odpowiedź, byłeś ciekawy, jak można utworzyć dwa puste pliki przy użyciu tej samej konstrukcji, którą podałeś?
— Tasdik Rahman

Czy istnieje sposób, aby utworzyć katalog nadrzędny, jeśli nie istnieje, czy też muszę to zrobić osobno?
— falsePockets

Musisz upewnić się, że katalog nadrzędny istnieje i umożliwia zapis. Zobacz stackoverflow.com/questions/22844905/…
— René Pijl

37

Coś takiego (użycie statmodułu najpierw do zebrania danych o nim, a następnie filtrowanie za pomocą warunku) powinno działać:

- 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

Alternatywnie możesz wykorzystać tę changed_whenfunkcjonalność.


20
może powinno być: "when: not p.stat.exists"
— piro

28

Inna opcja, korzystając z modułu poleceń:

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

Argument „tworzy” zapewnia, że ​​ta akcja nie zostanie wykonana, jeśli plik istnieje.


5
Należy unikać poleceń tak bardzo, jak to możliwe, ponieważ nie jest to idempotentne. ryaneschinger.com/blog/…
— redshark1802

4
@ redshark1802 Zgoda. Chociaż w tym przypadku zadanie jest idempotentne, ponieważ nie zostanie wykonane, jeśli „/ ścieżka / do / pliku” już istnieje. Myślę, że rozwiązanie René Pijl jest bardziej podobne do Ansible z trzech najpopularniejszych odpowiedzi i zdecydowanie tym, którego powinieneś użyć, jeśli chcesz ustawić własność, tryb itp.
— Leynos

15

Opierając się na zaakceptowanej odpowiedzi, jeśli chcesz, aby plik był sprawdzany pod kątem uprawnień przy każdym uruchomieniu, a te zmieniły się odpowiednio, jeśli plik istnieje, lub po prostu utwórz plik, jeśli nie istnieje, możesz użyć następującego:

- 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
Ta odpowiedź jest niesamowita ze względu na elastyczność, jaką daje w definiowaniu atrybutów pliku, jeśli nie istnieje.
— Dejay Clayton

10

file: path=/etc/nologin state=touch

Pełny odpowiednik dotyku (nowość w 1.4+) - użyj stat, jeśli nie chcesz zmieniać znacznika czasu pliku.


3
To nie jest idempotentne, data pliku zostanie zmodyfikowana po wykonaniu eacheracji playbooka ansibla.
— Jérôme B

3
@ Jérôme B Nowość w Ansible 2.7: możesz sprawić, że będzie to idempotentne file: path=/etc/nologin state=touch modification_time=preserve access_time=preserve.
— GregV

8

moduł plików zapewnia sposób na dotknięcie pliku bez modyfikowania jego czasu.

- 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

Źródła: https://docs.ansible.com/ansible/latest/modules/file_module.html


To jest prawidłowa odpowiedź dla ansibla 2.7+, jednak brakuje w nim ważnych informacji.
— Honza,

3

Okazuje się, że nie mam wystarczającej reputacji, aby zamieścić to jako komentarz, co byłoby bardziej odpowiednim miejscem do tego:

Re. Odpowiedź AllBlackta, jeśli wolisz format wielowierszowy Ansible, musisz dostosować cytowanie state(spędziłem kilka minut na pracy nad tym, więc mam nadzieję, że przyspieszy to kogoś innego),

- 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

Aby utworzyć plik na zdalnym komputerze za pomocą polecenia ad-hoc

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

Proszę, popraw mnie jeśli się mylę


0

Zmienione, jeśli plik nie istnieje. Utwórz pusty plik.

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

0

Połączenie dwóch odpowiedzi z niespodzianką. Kod zostanie wykryty jako zmieniony po utworzeniu pliku lub zaktualizowaniu uprawnień.

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

oraz wersję, która również poprawia właściciela i grupę oraz wykrywa je jako zmienione, gdy koryguje te:

- 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

Tylko ansibl 2.7+ - to należy wspomnieć.
— Honza,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.