Какой простой способ автоматически создать несуществующий каталог в недоступном


117

В моей пьесе Ansible много раз мне нужно создать там файл

 - name: Copy file
   template:
     src: code.conf.j2
     dest: "{{project_root}}/conf/code.conf"

теперь много раз confdir отсутствует. Затем мне нужно создать еще одну задачу, чтобы сначала создать этот каталог.

Есть ли простой способ автоматически создать каталог, если он не существует с какой-либо опцией



Я не могу поверить, что это все еще проблема в Ansible 2.9. Насколько сложно для этих модулей иметь переключатель создания каталога, по умолчанию отключенный. Это сэкономило бы столько мусора в сценариях, поскольку пришлось бы иметь дело с предварительными тестами, такими как ответы ниже
krad

Ответы:


139

Прямо сейчас это единственный способ

- name: Ensures {{project_root}}/conf dir exists
  file: path={{project_root}}/conf state=directory
- name: Copy file
  template:
    src: code.conf.j2
    dest: "{{project_root}}/conf/code.conf"

2
Я думаю, что «гарантировать» - правильное слово здесь. Заверьте: «скажите кому-нибудь что-нибудь положительное, чтобы развеять любые сомнения», убедитесь: «убедитесь, что (что-то) произойдет или будет так».
Дэниел Комптон

Кажется, это проверяет, существует ли директория, но, похоже, не создает ее.
Мэтт

8
Следует отметить, что вы можете добавить recurse=yesк fileвызову mkdir -pповедение типа
Митч

1
Еще одна часть головоломки, которая может быть полезна, - это специальный dirnameфильтр ansible для получения каталога, в котором находится файл.
Caspar

1
@radtek файловый модуль уже делает это с state = directory. Это не сработает, если невозможно гарантировать, что предложенный путь к файлу указывает на каталог.
Александр Жардим

21

Чтобы обеспечить успех с полным путем, используйте recurse = yes

- name: ensure custom facts directory exists
    file: >
      path=/etc/ansible/facts.d
      recurse=yes
      state=directory

2
Согласно документации (и моим тестам) подкаталоги создаются всегда и recurse=yesтолько рекурсивно применяют разрешения. Однако в документации указано, что это происходит автоматически, начиная с версии 1.7, поэтому recurseвполне может быть устаревшим.
Кому 마 SE

16

Если вы используете Ansible> = 2.0, существует также фильтр dirname, который вы можете использовать для извлечения части каталога из пути. Таким образом, вы можете просто использовать одну переменную для хранения всего пути, чтобы обе задачи никогда не выходили из синхронизации.

Так, например, если у вас есть playbook с dest_pathопределенной в такой переменной, вы можете повторно использовать ту же переменную:

- name: My playbook
  vars:
    dest_path: /home/ubuntu/some_dir/some_file.txt
  tasks:

    - name: Make sure destination dir exists
      file:
        path: "{{ dest_path | dirname }}"
        state: directory
        recurse: yes

    # now this task is always save to run no matter how dest_path get's changed arround
    - name: Add file or template to remote instance
      template: 
        src: foo.txt.j2
        dest: "{{ dest_path }}"

1
хотя это решение все еще многословно, я думаю, что оно ближе всего к замыслу автора. Мне бы очень понравилось, если бы был простой параметр makedirs, такой как у Salt: docs.saltstack.com/en/latest/ref/states/all/…
lsh

7

AFAIK, единственный способ это может быть сделано с помощью state=directoryопции. Хотя templateмодуль поддерживает большинство copyпараметров, которые, в свою очередь, поддерживают большинство fileпараметров, вы не можете использовать state=directoryс ним что-то подобное . Более того, это может сбить с толку (будет ли это означать, что {{project_root}}/conf/code.confэто каталог? Или это означает, что он {{project_root}}/conf/должен быть создан первым.

Поэтому я не думаю, что сейчас это возможно без добавления предыдущей fileзадачи.

- file: 
    path: "{{project_root}}/conf"
    state: directory
    recurse: yes

7

Согласно последнему документу, когда состояние установлено как каталог, вам не нужно использовать параметр recurse для создания родительских каталогов, об этом позаботится файловый модуль.

- name: create directory with parent directories
  file:
    path: /data/test/foo
    state: directory

этого достаточно, чтобы создать данные родительских каталогов и протестировать их с помощью foo

обратитесь к описанию параметра - " состояние " http://docs.ansible.com/ansible/latest/modules/file_module.html


Пожалуйста, добавьте сюда решение вместо ссылки, которая может быть повреждена в будущем.
Игнасио Ара

@IgnacioAra спасибо за ценный комментарий, я добавил решение.
Alby

1

вы можете создать папку, используя следующее, в зависимости от вашей доступной версии.

Последняя версия 2 <

- name: Create Folder
  file: 
   path: "{{project_root}}/conf"
   recurse: yes
   state: directory

Старая версия:

- name: Create Folder
  file: 
      path="{{project_root}}/conf"
      recurse: yes
      state=directory

Обратитесь - http://docs.ansible.com/ansible/latest/file_module.html


1

модуль копирования создает каталог, если его там нет. В этом случае он создал каталог resolved.conf.d

- name: put fallback_dns.conf in place                                                                 
  copy:                                                                                                
    src: fallback_dns.conf                                                                             
    dest: /etc/systemd/resolved.conf.d/                                                                
    mode: '0644'                                                                                       
    owner: root                                                                                        
    group: root                                                                                        
  become: true                                                                                         
  tags: testing
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.