saltstack / saltstack/salt

[BUG] `prereq`'d state with `onlyif`/`unless` + `fun`: onlyif requisite ignored

Open
#65,283 7 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Description
A state that is prerequired and itself has an onlyif (or unless) requisite that calls an execution module will run regardless of outcome of the onlyif evaluation.

Setup

  • on-prem machine
  • VM (Virtualbox, KVM, etc. please specify)
  • VM running on a cloud service, please be explicit and add details
  • container (Kubernetes, Docker, containerd, etc. please specify)
  • or a combination, please be explicit
  • jails if it is FreeBSD
  • classic packaging
  • onedir packaging
  • used bootstrap to install

Steps to Reproduce the behavior

Copy stuff:
  file.copy:
    - name: /tmp/aa
    - source: /tmp/a
    - onlyif:
      - fun: file.file_exists
        path: /tmp/a

Do sth else:
  cmd.run:
    - name: true
    - prereq:
      - Copy stuff

Expected behavior

local:
----------
          ID: Do sth else
    Function: cmd.run
      Result: True
     Comment: No changes detected
     Started: 06:41:33.485261
    Duration: 0.007 ms
     Changes:
----------
          ID: Copy stuff
    Function: file.copy
        Name: /tmp/aa
      Result: True
     Comment: onlyif condition is false
     Started: 06:41:33.485360
    Duration: 8.103 ms
     Changes:

Summary for local
------------
Succeeded: 2
Failed:    0
------------
Total states run:     2
Total run time:   8.110 ms

Screenshots

[WARNING ] no `fun` argument in onlyif: OrderedDict([('path', '/tmp/a')])
[ERROR   ] Source file "/tmp/a" is not present
local:
----------
          ID: Do sth else
    Function: cmd.run
      Result: True
     Comment: No changes detected
     Started: 06:37:15.121723
    Duration: 0.008 ms
     Changes:
----------
          ID: Copy stuff
    Function: file.copy
        Name: /tmp/aa
      Result: False
     Comment: Source file "/tmp/a" is not present
     Started: 06:37:15.121817
    Duration: 80.259 ms
     Changes:

Summary for local
------------
Succeeded: 1
Failed:    1
------------
Total states run:     2
Total run time:  80.267 ms

Versions Report

salt --versions-report (Provided by running salt --versions-report. Please also mention any differences in master/minion versions.)
Salt Version:
          Salt: 3006.3

Python Version:
        Python: 3.10.13 (main, Sep  6 2023, 02:11:27) [GCC 11.2.0]

Dependency Versions:
          cffi: 1.14.6
      cherrypy: unknown
      dateutil: 2.8.1
     docker-py: Not Installed
         gitdb: Not Installed
     gitpython: Not Installed
        Jinja2: 3.1.2
       libgit2: Not Installed
  looseversion: 1.0.2
      M2Crypto: Not Installed
          Mako: Not Installed
       msgpack: 1.0.2
  msgpack-pure: Not Installed
  mysql-python: Not Installed
     packaging: 22.0
     pycparser: 2.21
      pycrypto: Not Installed
  pycryptodome: 3.9.8
        pygit2: Not Installed
  python-gnupg: 0.4.8
        PyYAML: 6.0.1
         PyZMQ: 23.2.0
        relenv: 0.13.10
         smmap: Not Installed
       timelib: 0.2.4
       Tornado: 4.5.3
           ZMQ: 4.3.4

System Versions:
          dist: rocky 9.2 Blue Onyx
        locale: utf-8
       machine: x86_64
       release: 5.14.0-284.18.1.el9_2.x86_64
        system: Linux
       version: Rocky Linux 9.2 Blue Onyx

Additional context
The prereq results in the state to be run twice. During the first run, fun (and args) is popped from the passed-in lowstate chunk and is thus unavailable for the second (non-test) run:

https://github.com/saltstack/salt/blob/fb717a8d4bea3d48c596ae8dda313b7639c23dc6/salt/state.py#L1028-L1034

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 in salt/state.py around lines 1028-1034 and trace how prereq states are evaluated twice. Reproduce the YAML example with an onlyif fun requisite, then inspect the lowstate chunk across the test and non-test runs. Done means the onlyif result is honored and fun and args remain available when the state executes normally.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devops
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.