盐文件服务器 "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
有一个用户列表。这个想法是,如果 userX
在 files/
下有一个目录,该目录子树应该部署到 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 %}
经过相当多的调试(这对于弄清楚上面的问题是相当必要的),我发现这是一个先有鸡还是先有蛋的情况,即:
file.directory_exists
测试是 运行 小兵(这很公平)
- salt 文件服务器似乎有一个优化,它只部署到 minion(到
/var/cache/salt/minion/file
下的本地缓存)在状态中引用的项目(更有可能的是,minions 只请求他们的东西参见引用)。
- 所以除非
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 个地方跟踪数据,但你可以利用已经构建的状态文件获得好处。
我正在尝试让 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
有一个用户列表。这个想法是,如果 userX
在 files/
下有一个目录,该目录子树应该部署到 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 %}
经过相当多的调试(这对于弄清楚上面的问题是相当必要的),我发现这是一个先有鸡还是先有蛋的情况,即:
file.directory_exists
测试是 运行 小兵(这很公平)- salt 文件服务器似乎有一个优化,它只部署到 minion(到
/var/cache/salt/minion/file
下的本地缓存)在状态中引用的项目(更有可能的是,minions 只请求他们的东西参见引用)。 - 所以除非
users/files/userX
的目录子树已经存在于 minion 上,file.directory_exists
returnsFalse
,这意味着以 [=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 个地方跟踪数据,但你可以利用已经构建的状态文件获得好处。