12

I want to do something like that:

if file A exists or there is no symlink B, I want to create a symlink B -> A.

For now I have:

 B:
   file:
    - symlink:
       - target: A
    - exists:
        - name: A

But this is bad it checks not the thing I want. How can I achive this simple thing in salt ?

Adam Michalik
  • 9,678
  • 13
  • 71
  • 102
Darek
  • 2,861
  • 4
  • 29
  • 52
  • 1
    Note that there’s a chance your state will be inconsistent. We cannot have more than one function call from the same state module. (e.g. `file`). Under the identifier B, you can’t have `file.symlink` AND `file.exists` because both functions are part of the same state module. This is caused by the way Salt handles the lists internally, it’ll be eventually have only one left. – renoirb Apr 22 '15 at 15:54

3 Answers3

44

We can use file.directory_exists

{% if not salt['file.directory_exists' ]('/symlink/path/A') %}
symlink:
  file.symlink:
    - name: /path/to/A
    - target: /symlink/path/A
{% endif %}
Abhilash Joseph
  • 1,196
  • 1
  • 14
  • 28
11

You should use Dan Garthwaite's excellent answer here as a basis for how to check for the existence of a file. I have modified his solution to answer your question.

{% if 1 == salt['cmd.retcode']('test -f /path/to/A') %}
/path/to/A:
  file.symlink:
    - target: /symlink/path/A
{% endif %}
Community
  • 1
  • 1
Jason Zhu
  • 2,194
  • 3
  • 23
  • 27
  • Please see the other answer for a better solution: http://stackoverflow.com/a/30454953/13713 – Joel Nov 21 '16 at 23:28
  • The downside of this solution is that, although you won't have any failed state because of this, you may have some extras errors messages in your salt output when the file /path/to/A doesn't exist. – Pedreiro May 24 '17 at 01:24
  • I just stumbled across this five years later and there I am answering myself 5 years in the past. – Dan Garthwaite Oct 22 '19 at 00:57
2
/path/to/symlink/B:
  file.symlink:
    - target: /path/to/target/A
    - onlyif:
      - test -f /path/to/target/A      # check that the target exists
      - test ! -L /path/to/symlink/B   # check that B is not a symlink

This will require both conditions to be True for the symlink to be created. Note that -L will also return 1 (False) if the file exists but is not a symlink.

From the docs:

The onlyif requisite specifies that if each command listed in onlyif returns True, then the state is run. If any of the specified commands return False, the state will not run.

NOTE: Under the hood onlyif calls cmd.retcode with python_shell=True. This means the commands referenced by onlyif will be parsed by a shell, so beware of side-effects as this shell will be run with the same privileges as the salt-minion. Also be aware that the boolean value is determined by the shell's concept of True and False, rather than Python's concept of True and False.

bgdnlp
  • 1,031
  • 9
  • 12