4

Given three states, /root/a, /root/b and /root/c, I want /root/c to execute before /root/b, and /root/b to execute before /root/a.

Given a Salt SLS file salt://ordertest/init.sls:

/root/a:
  file.managed:
    - source: salt://ordertest/a
    - user: root
    - group: root
    - mode: 600 

/root/b:
  file.managed:
    - source: salt://ordertest/b
    - user: root
    - group: root
    - mode: 600 

/root/c:
  file.managed:
    - source: salt://ordertest/c
    - user: root
    - group: root
    - mode: 600

I can test to see the order in which the listed states would be applied. You'll see /root/a precede /root/b, and /root/b preceed /root/c.

$ salt my-minion-id state.apply ordertest test=True
my-minion-id:
----------
          ID: /root/a
    Function: file.managed
      Result: None
     Comment: The file /root/a is set to be changed
     Started: 13:54:23.538144
    Duration: 31.765 ms
     Changes:
----------
          ID: /root/b
    Function: file.managed
      Result: None
     Comment: The file /root/b is set to be changed
     Started: 13:54:23.570065
    Duration: 16.632 ms
     Changes:
----------
          ID: /root/c
    Function: file.managed
      Result: None
     Comment: The file /root/c is set to be changed
     Started: 13:54:23.586831
    Duration: 17.124 ms
     Changes:

Summary for my-minion-id
------------
Succeeded: 3 (unchanged=3)
Failed:    0
------------
Total states run:     3
Total run time:  65.521 ms

If we use require to directly tell /root/b to require /root/, and /root/c to require /root/b:

/root/a:
  file.managed:
    - source: salt://ordertest/a
    - user: root
    - group: root
    - mode: 600
    - require:
      - /root/b

/root/b:
  file.managed:
    - source: salt://ordertest/b
    - user: root
    - group: root
    - mode: 600
    - require:
      - /root/c

/root/c:
  file.managed:
    - source: salt://ordertest/c
    - user: root
    - group: root
    - mode: 600

We get the ordering we want:

$ salt my-minion-id state.apply ordertest test=True
my-minion-id:
----------
          ID: /root/c
    Function: file.managed
      Result: None
     Comment: The file /root/c is set to be changed
     Started: 13:32:33.624165
    Duration: 31.807 ms
     Changes:
----------
          ID: /root/b
    Function: file.managed
      Result: None
     Comment: The file /root/b is set to be changed
     Started: 13:32:33.656166
    Duration: 17.247 ms
     Changes:
----------
          ID: /root/a
    Function: file.managed
      Result: None
     Comment: The file /root/a is set to be changed
     Started: 13:32:33.673589
    Duration: 17.126 ms
     Changes:

Summary for my-minion-id
------------
Succeeded: 3 (unchanged=3)
Failed:    0
 ------------
Total states run:     3
Total run time:  66.180 ms

But if we try to use require_in to have /root/c place itself before /root/b:

/root/a:
  file.managed:
    - source: salt://ordertest/a
    - user: root
    - group: root
    - mode: 600
    - require:
      - /root/b

/root/b:
  file.managed:
    - source: salt://ordertest/b
    - user: root
    - group: root
    - mode: 600

/root/c:
  file.managed:
    - source: salt://ordertest/c
    - user: root
    - group: root
    - mode: 600
    - require_in:
      - /root/b

It doesn't work; /root/c stays at the end of the sequence:

my-minion-id:
----------
          ID: /root/b
    Function: file.managed
      Result: None
     Comment: The file /root/b is set to be changed
     Started: 13:36:54.037214
    Duration: 32.401 ms
     Changes:
----------
          ID: /root/a
    Function: file.managed
      Result: None
     Comment: The file /root/a is set to be changed
     Started: 13:36:54.069797
    Duration: 16.968 ms
     Changes:
----------
          ID: /root/c
    Function: file.managed
      Result: None
     Comment: The file /root/c is set to be changed
     Started: 13:36:54.086908
    Duration: 17.349 ms
     Changes:

Summary for my-minion-id
------------
Succeeded: 3 (unchanged=3)
Failed:    0
------------
Total states run:     3
Total run time:  66.718 ms

Here, you can see that /root/b was ordered before /root/a as appropriate, but /root/c did not get ordered before /root/b.

So how can I get this to work? I could use order instead of require and require_in, but that would mean I couldn't use require targeting any state that uses order, which could get quite messy and poorly-defined.

Michael Mol
  • 1,045
  • 1
  • 8
  • 19

1 Answers1

5

This turns out to be a known issue:

The require_in requisite does not support everything that require does, mainly id does not support sls or state_id without specifying a state module.

So by modifying our SLS file to include the state module (specifying file: /root/b as the require_in target instead of simply /root/b), we get the correct result.

I don't know if the other requisite injectors (watch_in, etc.) have the same limitations, so I will likely standardize my coding style on explicitly including module names in such identifiers.

Michael Mol
  • 1,045
  • 1
  • 8
  • 19