I have to execute a state only once. I couldn't find a simple way to do this.
Now, the context
I install two MySQL servers through salt. I want to make one a slave of the other.
In order to setup the slave, I need to get the master status informations at the end of the master installation:
SHOW MASTER STATUS;
Now, I can use a custom state executing the mysql.query
function to get it.
mysql_master_status:
mystate.query:
- query: SHOW MASTER STATUS
But it will be executed every time the highstate is executed for my server. Thus giving different master information every time.
I tried to use a file existence as a flag:
/tmp/only_once:
file.missing: []
mysql_master_status:
mystate.query:
- query: SHOW MASTER STATUS
- require:
- file: /tmp/only_once
It's working but I was not happy since I now have two failing states every time.
My custom solution
I ended with a new parameter for mystate
, flag
that create a flag file the first time it is executed, and returns with success if the file exists:
mysql_master_status:
mystate.query:
- query: SHOW MASTER STATUS
- flag: /tmp/only_once
And the question again
Still, I'd like to know if, and how, one would execute a state only once.
You can set a grain on the minion that indicates if the MySQL-State has run before. Just add this to your State:
Then you can wrap things in your State you only want to run once between an if Statement:
The advantage of this method is that you can now also keep track of your Minions who are MySQL-Masters. The downside is that you have to keep an eye on your grains so that the information won't get lost.
I think the easiest way would be to put this state into another state file (mysql_master_status.sls) and not referencing it in the top.sls. Instead you execute this state once using salt 'target' state.sls mysql_master_status
Thomas