使用Ansible的文件模块时如何防止ToCToU问题?

时间:2018-09-19 18:25:50

标签: ansible tocttou

我的工作环境:

  • Ubuntu 14.04
  • Ansible 2.6.3
  • Ansible Playbook 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的{​​{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问题。

1 个答案:

答案 0 :(得分:0)

一种选择是使用“命令创建”构造。

- name: Create link
  command: ln -s /usr/share/app_name/appConfig /home/username/appConfig.lnk
  args:
    creates: /home/username/appConfig.lnk

关于命令模块的讨论是here