【问题标题】:How to prevent ToCToU issue when using Ansible's file module?使用 Ansible 的文件模块时如何防止 ToCToU 问题?
【发布时间】: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: 而不是模块可能会让您最开心,因为您描述的逻辑是如此复杂

标签: ansible tocttou


【解决方案1】:

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

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

关于命令模块的讨论是here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    相关资源
    最近更新 更多