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:
pathexists and is a directory: Fail.pathexists and is a file: Fail.pathexists 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.