如何将基础值合并到grains.filter_by?SaltStack包公式合并异常
问题:SaltStack packages公式无法合并基础包与OS相关包
在使用SaltStack的packages公式时,需要部署两类包:无需过滤的基础包,以及基于osfinger grain的OS专属依赖包。但执行状态后,仅能看到OS专属的包;移除merge参数后,才能显示基础包。
相关代码文件
1. 入口文件:system/packages/test.sls
{% from "system/packages/map.jinja" import packages with context %} {%- set wanted_packages = packages.pkgs.wanted %} print_variable: cmd.run: - name : echo {{ wanted_packages }} > /tmp/list_package.txt
2. system/packages/map.jinja
{%- import_yaml 'system/packages/pkgs-base.yaml' as defaults %} {%- import_yaml 'system/packages/pkgs-filterby-osfinger.yaml' as osfingermap %} {%- set packages = salt['grains.filter_by']( defaults, merge = salt['grains.filter_by']( osfingermap, grain='osfinger'), base='packages') %}
3. system/packages/pkgs-base.yaml
# -*- coding: utf-8 -*- # vim: ft=yaml packages: pkgs: wanted: ['rsync', 'pigz', 'redhat-lsb-core', 'redhat-lsb', 'dos2unix', 'rng-tools', 'zip', 'unzip', 'ksh']
4. system/packages/pkgs-filterby-osfinger.yaml
# -*- coding: utf-8 -*- # vim: ft=yaml CentOS Linux-7: pkgs: wanted: ['python36-lxml', 'pyOpenSSL'] CentOS Linux-8: pkgs: wanted: ['python3-lxml', 'python3-pyOpenSSL', 'policycoreutils-python-utils', 'cifs-utils']
问题原因
salt['grains.filter_by']的merge参数采用浅合并策略:当合并的字典中存在相同层级的键时,会直接用新值覆盖旧值,而非合并列表。这里OS专属配置里的pkgs.wanted列表直接覆盖了基础配置中的对应列表,导致基础包丢失。
解决方案
修改map.jinja,手动合并基础包列表与OS专属包列表,替换原有的filter_by合并逻辑:
{%- import_yaml 'system/packages/pkgs-base.yaml' as defaults %} {%- import_yaml 'system/packages/pkgs-filterby-osfinger.yaml' as osfingermap %} # 获取当前OS对应的专属包配置 {%- set os_specific_pkgs = salt['grains.filter_by'](osfingermap, grain='osfinger') %} # 合并基础包与OS专属包列表 {%- set merged_wanted_pkgs = defaults.packages.pkgs.wanted + os_specific_pkgs.pkgs.wanted %} # 构造最终的packages字典 {%- set packages = { 'pkgs': { 'wanted': merged_wanted_pkgs } } %}
执行salt-call state.sls system.packages.test后,/tmp/list_package.txt中会同时包含基础包和CentOS Linux-8对应的专属包。
内容的提问来源于stack exchange,提问作者Sokatoha
相关产品推荐
相关产品推荐

