假设目录如下:
- etc/nginx/sites-available/
- hostA
- hostB
- hostC
在哪里主机A和主机B是由盐创造的。主机C之前也由 salt 创建,但从那时起它就从 pillar 中移除,不再需要。我希望目录只包含代表当前状态的文件。有一个选项可以让目录带有clean: True
,但这会导致看到目录的完整差异每次我进行高状态时 - 在我们的例子中,每次高状态都会创建 30 个不同的文件。这使得检查发生的更改变得非常困难。有什么办法可以解决这个问题吗?
更新:当前输出(伪 yaml)
- directory
- deleted:
- file: hostA
- file: hostB
- file: hostC
- file
- new file: hostA
- file
- new file: hostB
我希望
- directory:
- deleted:
- file: hostC
答案1
您可以通过调用模块获取所需目录的列表file.find
,并且由于您拥有要管理的文件列表,因此您可以删除不在要管理的文件列表中的文件。
以下是根据我必须管理的状态文件 /etc/yum.repos.d 改编的一些代码。我假设您要管理的文件来自 pillar,它们是字典的键,值是用于呈现文件的其余数据。
{% set site_dir = '/etc/nginx/sites-available/' %}
{% set sites = salt['pillar.get']('nginx_sites',{}) %}
{% set site_files = salt['file.find'](site_dir,type='f',print='name',maxdepth=0) %}
{% for site_file in site_files %}
{% if site_file not in sites %}
delete-old-{{ site_file }}:
file.absent:
- name: {{ site_dir }}/{{ site_file }}
{% endif %}
{% endfor %}
{# then go through the sites and manage the files... #}
{% for site in sites %}
manage-site-file-{{ site_file }}:
file.managed:
- name: {{ site_dir }}/{{ site }}
- source: salt://nginx/files/site-file.conf
- template: jinja
{% endfor %}
答案2
可以选择将目录设置为 clean: True,但这会导致每次我执行 highstate 时都会看到目录的完整差异 - 在我们的例子中,每次执行 highstate 时都会创建 30 个不同的文件。这使得检查发生的更改变得非常困难。有什么办法可以解决这个问题吗?
是的,方法是使用“require: - your_file_states”或“require_in: - directory_state”。file.directory 将删除除必需文件之外的所有文件。
/etc/nginx/sites-available/:
file.directory:
- clean: True
/etc/nginx/sites-available/hostA:
file.managed:
- require:
- /etc/nginx/sites-available/
/etc/nginx/sites-available/hostB:
file.managed:
- require:
- /etc/nginx/sites-available/
答案3
这就是配置管理工具的“问题”。你定义了现有事物的状态,但如果你删除了某些对象的跟踪,自动化工具将不会执行任何操作。例如,创建用户时也存在类似的问题。如果你从工具中删除用户,它不会将其从服务器中删除。
解决方案是为您想要存在的事物创建对象定义,并为您想要删除的事物创建黑名单。我正在使用支柱管理用户。如果我想要一个新用户,我会将用户添加到支柱中的列表中。但如果我想删除一个用户,我会为用户创建一个黑名单。
另一种选择是,将整个站点放在同一个文件中。如果删除一些虚拟主机,文件将被更新,Nginx 将被重新启动。当您手动管理服务器时,每个站点一个文件是有意义的,但使用配置管理工具,我认为这并不重要。
答案4
file.recurse
实际上,2015.8 中的操作正是您想要的- clean: True
。它只会删除不是在源路径中,仅输出它删除的不需要的文件。