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

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

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

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

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


person user1994660    schedule 18.03.2014    source источник
comment
Возможный дубликат Как создать каталог с помощью Ansible?   -  person BMitch    schedule 22.06.2016
comment
Я не могу поверить, что это все еще проблема в Ansible 2.9. Насколько сложно для этих модулей иметь переключатель создания каталога, по умолчанию отключенный. Это сэкономило бы так много мусора в учебниках, имея дело с предварительными тестами, такими как ответы ниже   -  person krad    schedule 04.02.2020


Ответы (7)


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

- 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"
person Alexander Jardim    schedule 18.03.2014
comment
Я думаю, что «гарантировать» - правильное слово здесь. Уверенность: скажите кому-нибудь что-нибудь положительное, чтобы развеять любые сомнения, убедитесь: убедитесь, что (что-то) произойдет или будет так. - person Daniel Compton; 05.01.2016
comment
Кажется, это проверяет, существует ли директория, но, похоже, не создает ее. - person hookenz; 10.02.2016
comment
Следует отметить, что вы можете добавить recurse=yes к вызову file, чтобы получить поведение типа mkdir -p. - person Mitch; 10.02.2016
comment
Еще одна часть головоломки, которая может оказаться полезной, - это фильтр dirname, специфичный для ansible , чтобы получить каталог, в котором находится файл. - person Caspar; 04.03.2016
comment
Лучше всего сначала указать каталог, чтобы узнать, существует ли он? - person radtek; 26.10.2017
comment
@radtek файловый модуль уже делает это с state = directory. Это не сработает, если невозможно гарантировать, что предложенный путь к файлу указывает на каталог. - person Alexander Jardim; 07.11.2017

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

- name: ensure custom facts directory exists
    file: >
      path=/etc/ansible/facts.d
      recurse=yes
      state=directory
person Ian T Price    schedule 14.12.2015
comment
Согласно документации (и моим тестам) подкаталоги создаются всегда, и recurse=yes применяет разрешения только рекурсивно. Однако в документации указано, что это происходит автоматически, начиная с версии 1.7, поэтому recurse вполне может быть устаревшим. - person To마SE; 25.10.2016
comment
recurse=yes имеет плохой побочный эффект: если вы укажете режим, файлы тоже получат этот режим (например, 0755). Также не требуется: If directory, all intermediate subdirectories will be created if they do not exist. Since Ansible 1.7 they will be created with the supplied permissions. - person nyet; 20.08.2020

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

Так, например, если у вас есть 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

    # 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 }}"
person Stefan Horning    schedule 05.06.2018
comment
хотя это решение по-прежнему многословно, я думаю, что оно ближе всего к замыслу автора. Мне бы понравилось, если бы был простой параметр makedirs, такой как у Salt: docs.saltstack.com/en/latest/ref/states/all/ - person lsh; 16.08.2018
comment
Избегайте recurse (см. Мой комментарий выше относительно прав доступа к файлам) - person nyet; 20.08.2020
comment
внес изменения, чтобы удалить recurse, этот ответ кажется мне лучшим, если не считать этого - person Andrew Spencer; 15.06.2021

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

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

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

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

person Alby    schedule 23.04.2018
comment
Добавьте сюда решение вместо ссылки, которая может быть повреждена в будущем. - person Ignacio Ara; 23.04.2018
comment
@IgnacioAra спасибо за ценный комментарий, я добавил решение. - person Alby; 23.04.2018
comment
И действительно, в текущей документации (v2.10) значение по умолчанию для recurse теперь ложно. - person Scott Buchanan; 16.12.2020

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
person leucos    schedule 18.03.2014

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

Последняя версия 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 < / а>

person Chathuranga Abeyrathna    schedule 01.08.2017

модуль копирования создает каталог, если его там нет. В этом случае он создал каталог 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
person Patrick Brunswyck    schedule 01.04.2020
comment
Из модуля copy: если src и dest - файлы, родительский каталог dest не создается, и задача не выполняется, если он еще не существует. - person xref; 20.08.2020
comment
@xref задается вопрос, как создать несуществующий целевой каталог, а не файл, как вы говорите. - person Patrick Brunswyck; 17.10.2020