Моя рабочая среда:
- Ubuntu 14.04
- Ansible 2.6.3
- Ansible Playbook 2.6.3
- Python 2.7.6
Я пишу сборник пьес Ansible, в котором содержится задача, которая создает символическую ссылку, указывающую на каталог где-то еще.В задании используется модуль file
(я упростил код для удобства обсуждения):
- name: Link the app configuration.
file:
path: "/home/username/appConfig.lnk"
src: "/usr/share/app_name/appConfig"
state: link
force: no
become: no
Если задание выполнено успешно, создается символическая ссылка /home/username/appConfig.lnk
иуказывает на каталог /usr/share/app_name/appConfiig
.
Однако в реальном случае пользователь может изменить appConfig.lnk
, чтобы указать на что-то еще, что является настраиваемой конфигурацией, соответствующей его потребностям. Это ожидаемое и действительное при нашем использовании, и /usr/share/app_name/appConfig
только пытается предоставить пригодную для использования начальную конфигурацию.
Следовательно, Я хочу, чтобы задача playbook толькосоздайте appConfig.lnk
, когда он НЕ существует вообще.Если путь /home/username/appConfig.lnk
уже существует, независимо от того, является ли он символической ссылкой на конфигурацию по умолчанию, символической ссылкой на какую-либо другую настраиваемую конфигурацию, файл или каталог, Я хочу пропустить создание.
Однако модуль file
с force
, установленным на no
, ведет себя так:
path
существует и является каталогом: Fail . path
существует и является файлом: Fail . path
существует и является символической ссылкой, указывающей на другое местоположение, отличное от src
: Автоматическое воссоздание ссылки, указывающей на src
.
Чтобы обойти эту проблему, я добавил задачу для вызова stat
module перед:
- name: Get the app configuration status.
stat:
path: "/home/username/appConfig.lnk"
register: stat_config
become: no
- name: Link the app configuration.
when: not stat_config.stat.exists # <-- New condition
file:
path: "/home/username/appConfig.lnk"
src: "/usr/share/app_name/appConfig"
state: link
force: no
become: no
Но я думаю, что это приводит к проблеме ToCToU , поскольку, хотя и маловероятно, appConfig.lnk
может быть удалено сразу после вызова stat
, поэтому file
модуль пропущен, и я получаю систему, которая говорит, что все было сделано успешно, но ссылка НЕ созданаТед.
Итак Мне интересно, есть ли способ реализовать то, что я хочу, но избежать возможной проблемы ToCToU.