saltstack / saltstack/salt

[BUG] When prereq is used in file.line, test=True becomes invalid

Open
#67,987 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-triage
Dominant language
Python
Stars
15.7k
Forks
5.6k
Avg merge
2d 44m
Merged PRs (30d)
80

Description

Description
According to the document, prereq only executes test=True and does not actually apply the configuration.
But I found that when prereq is used for file.line, the configuration will really be applied.

This will lead to two problems:

  1. The file had already been modified during the backup. Backup failed
  2. When we execute file.line to modify the problem, satl will prompt "no changes need to xxx".

Setup
pillar contents:

pam:
  security_limits:
    conf_path: /etc/security/limits.conf
    add_lines:
      - content: '@student        -       maxlogins       4'
        after: '#@student        -       maxlogins       4'
    conf_cmd:
      - lss -hl

state file:

{% set backup_dir = '/root/' %}

{% for pam_item, pam_data in pillar.get('pam', {}).items() %}
  {% set full_path = pam_data.get('conf_path', '') %}  
  {% set safe_path = full_path  | replace('/', '_') | replace('.', '_') %}
  {% set backup_file = 'pam_' ~ pam_item ~ '_' ~ safe_path ~ '.backup' %}
  {% set backup_path = backup_dir + backup_file %}

debug_file_content_before_backup:
  cmd.run:
    - name: echo "===BEFORE backup===" && cat {{ full_path }} | grep -C1 "#@student"

# backup file
backup_content_{{ pam_item }}:
  cmd.run:
    - name: |
        cp -aL {{ full_path }} {{ backup_path }}
        echo "备份创建于$(date +'%Y-%m-%d %H:%M:%S.%N')"
        echo "===WHEN backup===" && cat {{ full_path }} | grep -C1 "#@student"
    - prereq:
      {% for line in pam_data.get('add_lines', []) %}
      - file: pam_{{ pam_item }}_add_line_{{ loop.index }}
      {% endfor %}

debug_file_content_before:
  cmd.run:
    - name: echo "===BEFORE CHANGES===" && cat {{ full_path }} | grep -C1 "#@student"

  # add line
  {% for line in pam_data.get('add_lines', []) %}
  {% set line_state = 'pam_' + pam_item + '_add_line_' + loop.index|string %}

{{ line_state }}:
  file.line:
    - name: {{ full_path }}
    - content: "{{ line['content'] }}"
    - mode: ensure
    #- backup: '.bak'
    - match: "{{ line.get('match', line['content']) }}"
    {% if line.get('before') %}
    - before: "{{ line['before'] }}"
    {% endif %}
    {% if line.get('after') %}
    - after: "{{ line['after'] }}"
    {% endif %}

  {% endfor %}

  # remove line...

{% endfor %}

Steps to Reproduce the behavior
execute salt-call --local state.apply , output as fellow:

local:
----------
          ID: debug_file_content_before_backup
    Function: cmd.run
        Name: echo "===BEFORE backup===" && cat /etc/security/limits.conf | grep -C1 "#@student"
      Result: True
     Comment: Command "echo "===BEFORE backup===" && cat /etc/security/limits.conf | grep -C1 "#@student"" run
     Started: 09:16:17.821768
    Duration: 3.737 ms
     Changes:   
              ----------
              pid:
                  116855
              retcode:
                  0
              stderr:
              stdout:
                  ===BEFORE backup===
                  --
                  #ftp             hard    nproc           0
                  #@student        -       maxlogins       4
----------
          ID: backup_content_security_limits
    Function: cmd.run
        Name: cp -aL /etc/security/limits.conf /root/pam_security_limits__etc_security_limits_conf.backup
echo "备份创建于$(date +'%Y-%m-%d %H:%M:%S.%N')"
echo "===WHEN backup===" && cat /etc/security/limits.conf | grep -C1 "#@student"

      Result: True
     Comment: Command "cp -aL /etc/security/limits.conf /root/pam_security_limits__etc_security_limits_conf.backup
              echo "备份创建于$(date +'%Y-%m-%d %H:%M:%S.%N')"
              echo "===WHEN backup===" && cat /etc/security/limits.conf | grep -C1 "#@student"
              " run
     Started: 09:16:17.833017
    Duration: 6.487 ms
     Changes:   
              ----------
              pid:
                  116858
              retcode:
                  0
              stderr:
              stdout:
                  备份创建于2025-04-10 09:16:17.836633182
                  ===WHEN backup===
                  --
                  #ftp             hard    nproc           0
                  #@student        -       maxlogins       4
                  @student        -       maxlogins       4
----------
          ID: debug_file_content_before
    Function: cmd.run
        Name: echo "===BEFORE CHANGES===" && cat /etc/security/limits.conf | grep -C1 "#@student"
      Result: True
     Comment: Command "echo "===BEFORE CHANGES===" && cat /etc/security/limits.conf | grep -C1 "#@student"" run
     Started: 09:16:17.839617
    Duration: 2.635 ms
     Changes:   
              ----------
              pid:
                  116863
              retcode:
                  0
              stderr:
              stdout:
                  ===BEFORE CHANGES===
                  --
                  #ftp             hard    nproc           0
                  #@student        -       maxlogins       4
                  @student        -       maxlogins       4
  Name: /etc/security/limits.conf - Function: file.line - Result: Clean - Started: 09:16:17.842445 - Duration: 0.968 ms

Summary for local
------------
Succeeded: 4 (changed=3)
Failed:    0
------------
Total states run:     4
Total run time:  13.827 ms

Expected behavior
before backup, output:

                  ===BEFORE backup===
                  --
                  #ftp             hard    nproc           0
                  #@student        -       maxlogins       4

when backup, output:

                  ===WHEN backup===
                  --
                  #ftp             hard    nproc           0
                  #@student        -       maxlogins       4

Screenshots
If applicable, add screenshots to help explain your problem.

Image

Versions Report

salt --versions-report (Provided by running salt --versions-report. Please also mention any differences in master/minion versions.)
# salt-call --version
salt-call 3006.8 (Sulfur)

Additional context
Add any other context about the problem here.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the interaction between prereq and file.line with the provided pillar and state example using salt-call --local state.apply. Trace how file.line behaves during prereq evaluation, then verify that the backup output remains unchanged before the actual modification and that the expected state results are reported.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.