盐文件服务器 "lazy copy" 到 minions 行为/测试 file/directory 存在

Salt file server "lazy copy" to minions behaviour / testing a file/directory exists

我正在尝试让 salt 自动将文件部署到用户的主目录(在创建它们之后)。目录结构(file_roots下)如下:

users/
  init.sls
  user_list.jinja
  files/
      userX/
        some_dir_I_want_deployed_to_userX_homedir/
          some_script_I_want_deployed.sh
          etc

user_list.jinja 有一个用户列表。这个想法是,如果 userXfiles/ 下有一个目录,该目录子树应该部署到 userX 的主目录。但是,我宁愿不必为 userY 等创建空目录,如果它们没有任何要部署的东西,所以我正在尝试测试该目录的存在以避免错误。

这是来自 users/init.sls 的相关摘录:

{% from "users/user_list.jinja" import users with context %}
{% for name, user in users.items() %}
   {% set files_path = '{0}/files/{1}'.format(salt['file.dirname'](tplpath), name) %}

   {% if salt['file.directory_exists'](files_path) %}
     {{ user.home }}:
       file.recurse:
         - source: salt://users/files/{{ name }}
         - user: {{ name }}
         - group: {{ name }}
   {% endif %}
{% endfor %}

经过相当多的调试(这对于弄清楚上面的问题是相当必要的),我发现这是一个先有鸡还是先有蛋的情况,即:

  1. file.directory_exists 测试是 运行 小兵(这很公平)
  2. salt 文件服务器似乎有一个优化,它只部署到 minion(到 /var/cache/salt/minion/file 下的本地缓存)在状态中引用的项目(更有可能的是,minions 只请求他们的东西参见引用)。
  3. 所以除非 users/files/userX 的目录子树已经存在于 minion 上,file.directory_exists returns False,这意味着以 [=25= 开头的整个部分] 在 Jinja 渲染期间被抑制;因此它没有被引用并且副本(到 minion 的本地缓存)永远不会发生。

如果我在 minion 上手动为 users/files/userX 创建一个空目录结构,一切都会开始工作。这告诉我我的理论至少部分正确。

我可以"feel"我这里做错了(整个事情感觉太程序化了)。实现这一目标的最佳方法是什么?要求本身似乎牵强。

更简单的方法是在支柱数据中获取一些数据并检查该密钥是否存在。类似于 user.enabled。但是,这将需要您将设置保留在 2 个位置,即 pillar 和 file_roots.

您不想检查 minion 服务器上的目录是否存在,您想要检查文件根目录中的文件是否存在。

不幸的是,我认为在 salt:// 方案下检查文件是否存在是不可能的。如果我错了,那么您所要做的就是将检查目录是否存在的语法替换为检查 file_root 文件是否存在。

更salt-ish的方法是在pillar data中定义每台机器上的哪些用户enabled/disabled,并使用用户模块将他们添加到系统中。

https://github.com/saltstack-formulas/users-formula

您可以添加到标准用户公式给出的标准支柱,并放置一个同步文件的键

#pillar
users:
  ausername:
    fullname: A User
    syncfiles: True
  busername:
    fullname:  B User
    syncfiles: False



#state
{% for name, user in pillar.get('users', {}).items() if user.absent is not defined or not user.absent %}
   {% if user.syncfiles %}
     /home/{{ user.username }}:
       file.recurse:
         - source: salt://users/files/{{ user.username }}
         - user: {{ user.username }}
         {% if user.prime_group %}
         - group: {{ user.prime_group.name }}
         {% endif %}
   {% endif %}
{% endfor %}

实际上,标准用户公式已经处理了文件预填充。我只会使用那个公式。我知道它在 2 个地方跟踪数据,但你可以利用已经构建的状态文件获得好处。