Skip to content

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

@gordonwwang

Description

@gordonwwang

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugbroken, incorrect, or confusing behaviorneeds-triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions