You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SaltStack检查Grains列表中的程序版本是否已安装

问题根源与解决方案

你的问题出在Jinja2模板变量的引用方式上——你用单引号包裹了r{{ rv }},导致Jinja2不会解析这个模板变量,而是把它当作一个字面量字符串'r{{ rv }}'来处理。

看你的grains配置里只有r1113,但判断条件里实际检查的是字符串'r{{ rv }}'是否在grains列表里,这个字符串显然不存在,所以不管循环到哪个版本(1113还是1278),条件都会成立,最终触发安装操作。

修正后的状态文件

你可以通过两种方式修复这个问题:

方式1:使用Jinja2字符串拼接运算符~

这种方式更直观,适合处理变量拼接场景:

{% set rvs = ['1113','1278'] %} 
{% for rv in rvs %} 
  {% if ('r' ~ rv not in grains.get('cat12', [])) %}
    cat12-install-{{ rv }}:
      pkg.installed:
        - name: cat12-r{{ rv }}
  {% else %}
    cat12-{{ rv }}-already-present:
      test.nop: []
  {% endif %} 
{% endfor %}

方式2:使用双引号包裹模板变量

Jinja2会解析双引号内的模板变量,所以也能达到目的:

{% set rvs = ['1113','1278'] %} 
{% for rv in rvs %} 
  {% if ("r{{ rv }}" not in grains.get('cat12', [])) %}
    cat12-install-{{ rv }}:
      pkg.installed:
        - name: cat12-r{{ rv }}
  {% else %}
    cat12-{{ rv }}-already-present:
      test.nop: []
  {% endif %} 
{% endfor %}

调试小技巧

如果以后遇到类似的模板解析问题,可以在状态里临时添加一个调试步骤,输出实际的判断值:

{% set rvs = ['1113','1278'] %} 
{% for rv in rvs %} 
  debug-check-{{ rv }}:
    cmd.run:
      - name: echo "Checking for r{{ rv }}. Current grains: {{ grains.get('cat12', []) }}"
  {% if ('r' ~ rv not in grains.get('cat12', [])) %}
    # 安装步骤...
  {% endif %} 
{% endfor %}

执行salt '*' state.apply后,就能看到每个版本的判断逻辑是否符合预期了。

内容的提问来源于stack exchange,提问作者bergwiesel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:12:54