盐文件服务器"lazy copy"工作节点行为/测试文件/目录是否存在



我正在尝试让 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有一个用户列表。 这个想法是,如果在files/下有一个userX目录,该目录子树应该部署到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 文件服务器似乎有一个优化,它只部署到在状态中引用的 minon(/var/cache/salt/minion/file 下的本地缓存)项目(更有可能的是,工作节点只请求他们看到引用的内容)。
  3. 因此,除非工作节点上已经存在users/files/userX的目录子树,否则file.directory_exists返回 False ,这意味着在 Jinja 渲染期间,以 {{ user.home }} 开头的整个部分被抑制;因此它不会被引用,并且副本(到工作节点的本地缓存)永远不会发生。

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

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

更咸的方法是在支柱数据中有一些数据并检查该键是否存在。 类似于 user.enabled 的东西。 但是,这需要您将设置保留在 2 个位置,柱子和file_roots。

您不想检查工作节点服务器上是否存在该目录,而是要检查文件根目录中是否存在该文件。

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

更咸的方法是在支柱数据中定义在每台计算机上启用/禁用哪些用户,并使用用户模块将他们添加到系统中。

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 个地方跟踪数据,但您可以利用已经构建的状态文件获得好处。

最新更新