代码之家  ›  专栏  ›  技术社区  ›  yaobin Anycorn

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

  •  0
  • yaobin Anycorn  · 技术社区  · 8 年前

    我的工作环境:

    • Ubuntu 14.04
    • Ansible 2.6.3
    • Python 2.7.6

    我正在写一个Ansible playbook,其中包含一个任务,创建一个指向其他地方目录的符号链接。任务使用 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 仅尝试提供可用的初始配置。

    因此 我想要 playbook任务只创建 appConfig。lnk 当它发生的时候 不 根本不存在。如果这条路 /home/username/appConfig。lnk 已经存在,无论它是指向默认配置的符号链接,还是指向其他自定义配置、文件或目录的符号链接, 我想跳过创作。

    然而 文件 模块,带 force 开始 no ,其行为如下:

    • 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 可能会在 斯达 这么说吧 文件 模块被跳过,我最终得到一个系统,该系统表示所有操作都已成功完成,但没有创建链接。

    所以 我想知道是否有办法实现我想要的,但避免可能的ToCToU问题。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Vladimir Botka    8 年前

    一个选项是使用“command creates”构造。

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

    关于命令模块的讨论如下: here

    推荐文章