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

复用Salt State代码片段:寻求非Python实现的自定义状态方案

Hey there! I totally get wanting to avoid writing custom Python modules when you’ve got repetitive repo and GPG key configs in your Salt States. Let’s dive into some solid non-Python approaches to abstract that code:

1. Use Jinja Macros (Most Straightforward)

Jinja macros are perfect for wrapping reusable chunks of Salt State code. You define a macro once, then call it with different parameters wherever you need it.

First, create a macro file (e.g., salt://_macros/repo_setup.sls) with your reusable repo/GPG logic:

{% macro setup_repo(repo_name, repo_url, gpg_key_url) %}
{{ repo_name }}_repository:
  pkgrepo.managed:
    - humanname: {{ repo_name }} Official Repository
    - name: deb {{ repo_url }} {{ grains['oscodename'] }} main
    - file: /etc/apt/sources.list.d/{{ repo_name }}.list
    - gpgcheck: 1
    - key_url: {{ gpg_key_url }}

{{ repo_name }}_gpg_key:
  file.managed:
    - name: /usr/share/keyrings/{{ repo_name }}-archive-keyring.gpg
    - source: {{ gpg_key_url }}
    - mode: '0644'
{% endmacro %}

Then, in any State file where you need to set up a repo, import the macro and call it with your specific values:

{% from '_macros/repo_setup.sls' import setup_repo %}

# Set up Nginx repo
{{ setup_repo('nginx', 'https://nginx.org/packages/mainline/debian', 'https://nginx.org/keys/nginx_signing.key') }}

# Set up Docker repo
{{ setup_repo('docker', 'https://download.docker.com/linux/debian', 'https://download.docker.com/linux/debian/gpg') }}

2. Pillar-Driven Configuration with Jinja Loops

If you want to manage all your repo configs in a centralized place, store them in Pillar and use a Jinja loop to render the States dynamically.

First, add your repo configs to your Pillar data (e.g., pillar/repos.sls):

repo_configs:
  nginx:
    url: https://nginx.org/packages/mainline/debian
    gpg_key_url: https://nginx.org/keys/nginx_signing.key
  docker:
    url: https://download.docker.com/linux/debian
    gpg_key_url: https://download.docker.com/linux/debian/gpg
  nodejs:
    url: https://deb.nodesource.com/node_20.x
    gpg_key_url: https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key

Then, create a State file that loops through the Pillar data to generate the repo/GPG states:

{% for repo_name, config in pillar.get('repo_configs', {}).items() %}
{{ repo_name }}_repository:
  pkgrepo.managed:
    - humanname: {{ repo_name }} Repository
    - name: deb {{ config.url }} {{ grains['oscodename'] }} main
    - file: /etc/apt/sources.list.d/{{ repo_name }}.list
    - gpgcheck: 1
    - key_url: {{ config.gpg_key_url }}

{{ repo_name }}_gpg_key:
  file.managed:
    - name: /usr/share/keyrings/{{ repo_name }}-archive-keyring.gpg
    - source: {{ config.gpg_key_url }}
    - mode: '0644'
{% endfor %}

Now, adding a new repo just requires updating your Pillar data—no need to touch the State file!

3. Parameterized SLS Files with Includes

You can also create a generic State file that pulls values from Pillar, then include it multiple times with different Pillar parameters for each repo.

Create a generic repo State file (e.g., salt://repo/init.sls):

{{ pillar.get('repo_name') }}_repository:
  pkgrepo.managed:
    - humanname: {{ pillar.get('repo_name') }} Repository
    - name: deb {{ pillar.get('repo_url') }} {{ grains['oscodename'] }} main
    - file: /etc/apt/sources.list.d/{{ pillar.get('repo_name') }}.list
    - gpgcheck: 1
    - key_url: {{ pillar.get('gpg_key_url') }}

{{ pillar.get('repo_name') }}_gpg_key:
  file.managed:
    - name: /usr/share/keyrings/{{ pillar.get('repo_name') }}-archive-keyring.gpg
    - source: {{ pillar.get('gpg_key_url') }}
    - mode: '0644'

Then, in your main State file, include it multiple times with different Pillar overrides:

# Set up Nginx repo
include:
  - repo

pillar:
  repo_name: nginx
  repo_url: https://nginx.org/packages/mainline/debian
  gpg_key_url: https://nginx.org/keys/nginx_signing.key

# Set up Docker repo
include:
  - repo

pillar:
  repo_name: docker
  repo_url: https://download.docker.com/linux/debian
  gpg_key_url: https://download.docker.com/linux/debian/gpg

Final Notes

All these methods let you reuse your repo/GPG config logic without writing a single line of Python. Jinja macros are great for explicit, one-off reuse, while the Pillar-driven approach is ideal for centralized, scalable management.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:01:05