How to version control server configuration files that are changed at application runtime, using git or another VCS

gitrevision-control

I'm running a Minecraft server (craftbukkit) and I have several other admins who want access to modifying server configuration files. It is important that I track all their changes, so naturally, git seems like a good choice.

Please note that this question could pertain to many situations, it is not specific to Minecraft.

Several tutorials exist on using git to manage websites. The most common solutions seems to be using the post-receive hook to run a checkout operation to the web directory. However, in my situation this poses a few issues.

First, some files admins would need to edit are changed by the server at runtime. I'm assuming this would confuse git if I made the server directory itself into the repository. Using the post-receive checkout solution, this would be less problematic, if I am correct (I am still learning git).

I also would need changes made by the server to be pushed into the repo, so admins can fetch those changes down to their local repos. I've seen solutions using inotifywait but these all seem only to account for single file changes. My server has 50-80 config files that I would need to track and autocommit when the server runtime changes them. What would be the best way to handle this?

Note that using git is not a requirement. I simply like what I've used of it so far. If there is a better tool for the job, I am open to using it, so long as it is user-friendly. Note that my server admins are not coders, nor are they Linux power users, so user-friendliness helps.

I originally posted this on StackOverflow, but was told it was better suited for here.

Best Answer

This isn't a complete answer, but hopefully some useful thoughts:

inotifywait will work happily with multiple files and can recursively set watchpoints on directories. For example, I can run:

inotifywait -m -r -e close_write /etc

And get the following log after editing /etc/passwd and /etc/postfix/main.cf:

/etc/ CLOSE_WRITE,CLOSE .passwd.swpx
/etc/ CLOSE_WRITE,CLOSE .passwd.swp
/etc/ CLOSE_WRITE,CLOSE 4913
/etc/ CLOSE_WRITE,CLOSE passwd
/etc/ CLOSE_WRITE,CLOSE .passwd.swp
/etc/postfix/ CLOSE_WRITE,CLOSE .main.cf.swx
/etc/postfix/ CLOSE_WRITE,CLOSE .main.cf.swp
/etc/postfix/ CLOSE_WRITE,CLOSE 4913
/etc/postfix/ CLOSE_WRITE,CLOSE main.cf
/etc/postfix/ CLOSE_WRITE,CLOSE .main.cf.swp

You could very easily work this into a script that, upon each close_write event, would commit the file to the local repository and push the changes to a remote server.

Also note that incron is a nifty tool for automating this sort of inotify-based workflow (but wouldn't substantially change the nature of the solution).

You're going to run into difficulties if your admins will be editing the same files that get updated by the server at runtime. This suggests that you're going to have to set up some sort of automatic conflict resolution on the server, which will invariably result in losing some information (well, apparent loss, at least, you can obviously preserve conflicting changes in two distinct branches of the repository but the server only gets to see one branch).

I don't think any parts of this problem or solution are particular to git. You're going to run into these issues with any sort of distributed, asynchronously synchronized shared maintenance of files.