My work environment:
- Ubuntu 14.04
- Ansible 2.6.3
- Ansible Playbook 2.6.3
- Python 2.7.6
I'm writing an Ansible playbook which contains a task that creates a symbolic link that points to a directory somewhere else. The task uses the file
module (I simplified the code for convenience of discussion):
- name: Link the app configuration.
file:
path: "/home/username/appConfig.lnk"
src: "/usr/share/app_name/appConfig"
state: link
force: no
become: no
If the task is executed successfully, a symbolic link /home/username/appConfig.lnk
is created and points to the directory /usr/share/app_name/appConfiig
.
However, in the real use case, the user is likely to modify the appConfig.lnk
to point to something else which is the customized configuration that suits their needs. This is expected and valid in our use, and the /usr/share/app_name/appConfig
only tries to provide a usable initial configuration.
Therefore, I want the playbook task to only create the appConfig.lnk
when it does NOT exist at all. If the path /home/username/appConfig.lnk
exists already, regardless if it's a symbolic link to the default configuration, a symbolic link to some other customized configuration, a file, or a directory, I want to skip the creation.
However, the file
module, with force
set to no
, behaves like this:
path
exists and is a directory: Fail.path
exists and is a file: Fail.path
exists and is a symbolic link pointing to some other location other thansrc
: Automatically recreate the link to point tosrc
.
To workaround this issue, I added a task to call stat
module before:
- 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
But I think this introduces the ToCToU issue, because, although highly unlikely, the appConfig.lnk
may be deleted right after the stat
call so the file
module is skipped and I end up with a system that says everything has been done successfully but the link is NOT created.
So I'm wondering if there is a way to implement what I want but avoid the possible ToCToU issue.