我的工作环境:
我正在写一本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
的{{1}}模块的行为如下:
no
存在,并且是一个目录:失败。path
存在并且是一个文件:失败。path
存在,并且是指向path
以外的其他位置的符号链接:自动重新创建链接以指向src
。要解决此问题,我添加了一个任务,要在之前致电stat
module:
src
但是我认为这引入了ToCToU issue,因为尽管极不可能,但- 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
可能在调用appConfig.lnk
之后被删除,因此stat
模块被跳过了,我最终得到一个系统,该系统说所有操作均已成功完成,但未创建链接。
所以我想知道是否有一种方法可以实现我想要的但避免了可能的ToCToU问题。
答案 0 :(得分:0)
一种选择是使用“命令创建”构造。
- name: Create link
command: ln -s /usr/share/app_name/appConfig /home/username/appConfig.lnk
args:
creates: /home/username/appConfig.lnk
关于命令模块的讨论是here