【发布时间】:2018-09-20 13:15:52
【问题描述】:
我的工作环境:
- Ubuntu 14.04
- Ansible 2.6.3
- Ansible 剧本 2.6.3
- Python 2.7.6
我正在编写一个 Ansible 剧本,其中包含一个任务,该任务创建一个指向其他地方的目录的符号链接。任务使用file module(为了讨论方便,我简化了代码):
- 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 仅尝试提供可用的初始配置。
因此,我希望剧本任务仅在它确实不存在时创建appConfig.lnk。如果路径/home/username/appConfig.lnk 已经存在,无论它是指向默认配置的符号链接、指向其他自定义配置、文件或目录的符号链接,我想跳过创建。
但是,file 模块将force 设置为no,其行为如下:
-
path存在并且是一个目录:失败。 -
path存在并且是一个文件:失败。 -
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 issue,因为虽然不太可能,但appConfig.lnk 可能会在stat 调用之后立即被删除,因此file 模块被跳过,我最终得到一个系统,上面写着一切都已成功完成,但未创建链接。
所以我想知道是否有办法实现我想要的但避免可能的 ToCToU 问题。
【问题讨论】:
-
我认为使用
shell:而不是模块可能会让您最开心,因为您描述的逻辑是如此复杂