poundifdef
poundifdef

Reputation: 19353

Python Saltstack: How can I manage a file which is in a git repo?

I have a configuration file, config.py in my git repository. It has dev-specific configuration settings.

I also have that same file as a managed file in salt, which has production-specific configurations.

The configuration directive for that file looks like this:

python_config:
  file.managed:
    - name: /opt/github/python_config/config.py
    - source: salt://configs/config.py
    - makedirs: True

Because /opt/github is a git repository, whenever I try to update that directory, I get an error: "You local changes to python_config/config.py would be overwritten by merge."

Here is what my salt directive for that github repo looks like:

code:
    git.latest:
        - name: {{ pillar['git_repo'] }}
        - rev: {{ pillar['git_rev'] }}
        - target: {{ pillar['source_path'] }}
        - force: True
        - require:
            - pkg: app-pkgs
            - file: deploykey
            - file: publickey
            - file: ssh_config

This error makes sense - I've checked out the repository, made a change (via my managed file), so new changes to that dev-specific config file cause issues.

How can I force salt to perform tasks in a specific order? (eg, issue a git checkout config.py before proceeding with with the git pull?)

Alternately, is there a better/different way I should manage this prod-vs-dev configuration in salt?

Upvotes: 4

Views: 6314

Answers (3)

Colton Myers
Colton Myers

Reputation: 1341

If you want to just run the checkout command before you do git.latest on state.highstate:

  1. Add an additional cmd.run state
  2. Require that state in your git.latest state
  3. Require the git.latest state in your file.managed state

Then when you run state.highstate, it will run your git checkout command, then update your repo to latest, then make sure the file looks like it should.

It's less than ideal in that it will always be reporting that the file has changed in your file.managed state (because you'll check it out every time), but it will accomplish what you set out to do.

If you didn't want to check it out every time, you could craft some command to check if there are upstream changes to your git repo, and use the onlyif arg to cmd.run to only run git checkout if you are actually going to pull new changes. This would make your state.highstate output cleaner (in that it will not have changes as often) but is more complex, which is not ideal.

Keep me posted if you'd like further clarification.

Upvotes: 1

Utah_Dave
Utah_Dave

Reputation: 4581

Your best bet here would probably be to use the gitfs backend.

Docs can be found here: http://docs.saltstack.com/topics/tutorials/gitfs.html

This allows you to use git as a backend for your file_roots.

Each git branch and tag becomes a Salt environment, which will map nicely to your production and dev configurations.

This will remove the need for your git.latest state declaration.

python_config:
  file.managed:
    - name: /opt/github/python_config/config.py
    - source: salt://configs/config.py
    - makedirs: True

Upvotes: 4

Andenthal
Andenthal

Reputation: 869

This sounds more like a git issue, than a salt issue.

Look into using git stash (possibly git stash --keep-index).
(Then git stash pop)

I would only use this on that one config file though, as you can easily run into merge conflicts when doing this on files bound for upstream on a multi user repo.

Upvotes: 0

Related Questions