Say I have a cmd.wait script that watches a managed git repository for changes. What’s the best way to trigger that script even if the repo hasn’t changed?
Here's the scenario:
my-repo:
git.latest:
- name: git@github.com:my/repo.git
- rev: master
- target: /opt/myrepo
- user: me
- require:
- pkg: git
syncdb:
cmd.run:
- name /opt/bin/syncdb.sh
load-resources:
cmd.wait:
- name: /opt/bin/load_script.py /opt/myrepo/resources.xml
- require:
- cmd: syncdb
- watch:
- git: my-repo
index-resources:
cmd.wait:
- name: /opt/bin/indexer.sh
- watch:
- cmd: load-resources
Say that I run this state, but syncdb
fails. load-resources
and index-resources
fail as well because of missing prerequisites. But my-repo
succeeded, and now has the latest checkout of the repository.
So I go ahead and fix the problem that was causing syncdb
to fail, and it succeeds. But now my cmd.watch
scripts won't run, because my-repo
isn't reporting any changes.
I need to trigger, just once, load-resources
, and going forward I want it to only trigger when the repo changes. Now, I could just change it to use cmd.run
, but in actuality I have a bunch of these cmd.wait
scripts in a similar state, and I really don't want to have to go through and switch them all and then switch them back. The same goes for introducing artificial changes into the git repo. There are multiple repos involved and that's annoying in many ways. Finally, I can foresee something like this happening again, and I want a sure solution for handling this case that doesn't involve a bunch of error-prone manual interventions.
So, is there a way to trigger those cmd.watch
scripts manually? Or is there a clever way to rearrange the dependencies so that a manual triggering is possible?
Assuming the above sls lives in: /srv/salt/app.sls
then you should be able to execute load-resources
by doing this:
$: salt '*appserver*' state.sls_id load-resources app base
That said, there are surely many better ways to do this, so that you don't have to manually handle failures.
You could change your load-resources
to use cmd.run
with unless
command that actually checks whether the resources have been loaded or not. If that's not possible to do in business terms (i.e. no easy way to check), then something generic could do, this can be as simple as a file you create at the end of load_script.py
. The file can contain the commit id of the git repo at the time of the import, and if the file doesn't exist or the commit id in the file is different than that of the current git repo, you know you have to re-import.
A better variation would be to even bake the unless
logic into load_script.py
, which would make that script idempotent. Just like all salt modules. Your SLS file would be even simpler then.