Jinja variables are set before the state will be executed - vise versa possible?

649 views
Skip to first unread message

Daniel Schröter

unread,
Oct 9, 2014, 8:49:04 AM10/9/14
to salt-...@googlegroups.com
Minion OS: Windows Server 2008 R2
Master OS: CenotOS 6
Salt version: 2014.1.10

I figured out that the jinja variables are not set in the defined state formula order. They will be set before all states in the states file will be executed on the minion. 

If you have static variables with previously known values or basic system parameters like hostname or IP it is not tragic that all jinja variables will be set at the beginning. But if you have a dynamic value which is created by an installation routine after the state is executed salt is not able anymore to set or refresh this variable even if I move the {% set variable = ... part after the installation/configuration routine in the state formula.

The installation/configuration routine will create in the first step a random not predictable folder (e.g. "C:/installdir/tib/tct/admin/651651876321") and if I execute the following dir command ("dir /B /AB C:/installdir/tib/tct/admin") in windows, I can get this new generated foldername, but not if I set a jinja variable with the same command to get this new folder name for a more specific configuration part in for later stage.

{% set tctdir = salt['cmd.run']('dir /B /AD C:/installdir/tib/tct/admin') %}

In windows command prompt I receive the name of the new generated folder but not under salt, because this jinja set variable will executed BEFORE the installation/configuration routine is completed.

How can I force jinja to set this variable after a specific installation/configuration routine state is completed? Or do you have an alternative easy solution to get the random generated folder name as variable for later use in the same state file.

Thanks!

Daniel

Colton Myers

unread,
Nov 12, 2014, 5:31:30 PM11/12/14
to salt-...@googlegroups.com
First, sorry for the late reply, I'm going through old unreplied threads.

Here's the problem: the jinja is resolved completely, in order to reveal the YAML which is then compiled into state data and executed. There's no way to wait on pieces of the jinja, because we must parse the entire file into YAML for the state compiler to execute it.

This means that we must fetch the required data during the state run, after the requisite states have executed. The best way to do this is by writing a custom state or module which runs the `cmd.run` that you need, and then feeds that data into the state/module that you *actually* wanted to run.

More information on custom execution modules here: http://docs.saltstack.com/en/latest/ref/modules/


Keep me posted if you have further questions.

--
Colton Myers (basepi)
Platform Engineer, SaltStack

--
You received this message because you are subscribed to the Google Groups "Salt-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to salt-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

signature.asc

Rohit Sood

unread,
May 28, 2015, 9:29:25 AM5/28/15
to salt-...@googlegroups.com
What if the output of the cmd.run is repeatedly needed in other states ?
I have a similar requirement where i need to find the path of an msi file after a package is downloaded and unzipped.
I wrote a custom state to execute the cmd.run and set a grain (grain.present) to the msi path in a custom module.
A state to call my custom module is defined in the sls file.
Downstream dependent states now would like to leverage the grain value. However the only way to derefrence is to use the Jinja syntax {{ salt['grains.get'] ('my-custom-grain' ) }} .
Which leads us back to the pre-parsing situation described above.

Is there an alternative ?

thanks,
Rohit

Colton Myers

unread,
Jun 4, 2015, 6:49:23 PM6/4/15
to salt-...@googlegroups.com
You could split the run into separate pieces using the state.orchestrate runner. The first set of states would generate and set the grain, then the second set of states would utilize the grain. Separate state runs in a state.orchestrate run will not be rendered at the same time, they'll be rendered when the orchestrate runner gets to them.

Hope that helps.

--
Colton Myers
Platform Engineer, SaltStack
@basepi on Twitter/Github/IRC

Rohit Sood

unread,
Jun 18, 2015, 5:02:58 PM6/18/15
to salt-...@googlegroups.com

I ended up splitting the state and invoking as below. However the pillars dont get passed to individual states.

 salt-run state.orchestrate tssaOrchestrate pillar='{"VERSION":"3.2.0","BUILD":"V15", "TARGET":"test-1"}'


{% set tssaVersion = salt['pillar.get']('VERSION')|default('3.2.0', true) %}
{% set tssaBuild = salt['pillar.get']('BUILD')|default('LatestOfficial', true) %}

{% set target = salt['pillar.get']('TARGET') %}

seed_installer_path:
  salt.state:
    - sls:
      - tssa.seedInstallerPath
    - tgt : {{ target }}
    - pillar:
        'VERSION': {{ tssaVersion }}
        'BUILD': {{ tssaBuild }}


run_tssa_installer:
  salt.state:
    - sls: tssa
    - tgt : {{ target }}
    - pillar:
        'VERSION': {{ tssaVersion }}
        'BUILD': {{ tssaBuild }}
    - require:
      - salt: seed_installer_path

Rohit Sood

unread,
Jun 23, 2015, 5:52:20 PM6/23/15
to salt-...@googlegroups.com

Removing the space between the key name and : fixed it.

- tgt : {{ target }} ----> - tgt: {{ target }}
Reply all
Reply to author
Forward
0 new messages