Using Subversion to version control /etc

I use svn to version control my /etc directory and I should say it has proven to be very useful and mostly practical.

Why

The why is simple to answer. Almost all of us have either

  • Accidentally messed up our config file(s) and suffered hours of rework
  • Or have created a plethora of config.bak, config.orig, etc files and have no idea if/when to clean them up
  • Worse of all, remember using a certain configuration in the past, but can't quite get it to work again

If any of these resembles your thoughts/actions then you will benefit from version controlling your config files.

How

Note: Before you start typing in the commands scroll down for either the command list or for a script!

Create the SVN repository. One usual location is /var, but this can be anywhere

# cd /var

Create a top level directory to hold all repositories

# mkdir svn-repos

Change directory

# cd svn-repos

Create a repository (which creates a directory) to hold /etc's repository

# svnadmin create svn-etc

Make it root access only

# chmod 700 svn-etc

Let's go and add the files in /etc to version control

# cd /etc

Now /etc is not an empty directory and already has the files we want to version control. However SVN is very friendly and will not complain making a current directory with files as the SVN working directory.

So let's checkout the empty repository to establish /etc as the working directory for the repository.

# svn checkout file:///var/svn-repos/svn-etc /etc

Let's check the status of our new working directory. It should list all the files inside /etc as unknown status (?)

# svn status

Now we need to check in the files and put them on version control. The command below should generate the “svn add” commands to check them all in

# ls -l|awk '{print “svn add ” $8}'

Execute the output of command above

Or just run the single command:
# svn status | grep -v “ \.” | grep “^\?” | awk '{print $2}' | xargs svn add

The grep -v command is used to eliminate files starting with . such as .pwd.lock

Or even better:

svn add * --force

However, I believe this might check files starting with dot (such as .pwd.lock). If that happens remove these before commit. This can be done with the

# svn revert <path/to/file>

Let's commit the checked in files

# svn commit -m “Initial Version”

All steps together

cd /var
mkdir svn-repos
cd svn-repos
svnadmin create svn-etc
chmod 700 svn-etc
cd /etc
svn checkout file:///var/svn-repos/svn-etc /etc
#svn status
svn add * --force
#svn revert <path/to/file>
svn commit -m "Initial Version"

Other considerations

There are a number of other considerations to think about when doing VC for /etc (and elsewhere). If not this will become of those things that was a great idea to start off and then has no meaning.

/etc is not just all config

Although /etc is for saving configurations files, it is NOT purely a settings only directory. It does have other transient files. It is best to either not include them in the VC or not restore the checked in version. Commits are ok, but they will add space with no real value. Having said that, it might give you some history on these files that will help with knowledge about these files.

Moving/Deleting files in /etc

If ever you decide to MOVE files, remember to use the svn command and not the Linux/UNIX mv. Do an “svn move <source> <target>”. If not you will end up just copying rather than moving. If that happens, you will have to just do an SVN delete of the original file. The same goes for delete. Just do an SVN delete rather than a regular rm.

Piece meal commits

Another advantage of SVN is that you can commit individual directories or sub-directories. So if you are working on changing multiple config files you can commit just the ones that you want to version control at the moment. It also helps with keeping each revision number linked only to one set of configuration changes.

Other advantages

There are more advantages to just “saving” your files against accidental modifications. VC also gives you the advantage of identifying what is getting changed outside of your preview. Outside of MY preview? Yes, every time you install something (usually with apt-get) a lot of things can happen and you may not be aware of all of them. When I installed john (the ripper) the other day I realized that it has also added (a niced) cron job to regularly (as in daily!) check for passwords to crack. Now while this is great, not so for a system where I don't have anyone except me! So I instantly commented out the cron. You might want to make it monthly or yearly depending on your case. So there you go, I could VC /etc just for this reason alone. So periodically do a

# svn status

to see what is uncommited out there

Commit regularly

It's easy to “forget” that /etc is in version control and have a ton of uncommitted configuration. This is actually a pain point if you do not pay attention to this often. You might end up modifying files that have not been committed and permanently loose changes. Or you might have such a long list that you might commit them all together and not really document the changes (which might come in handy days/weeks/months/years from now)

One way to keep reminded is to have a cron count “svn status” output and email it to you if it exceeds some threshold or if there are uncommitted changes that are a few days or more old.

Backup your SVN repository

Make backup of your SVN repository daily. svn-fast-backup is a great python script that can be scheduled daily to keep your svn repos backed up - and only backed up if they change. Google svn-fast-backup to find the latest version.

To quickly add new files

Use this command snippet to quick add all the new files. If you want to undo the add operation do an “svn revert /path/to/file”

svn status|grep "?"|awk '{print $2}'|xargs svn add

Script to do it all

Below is a script that you can use to do the steps fast for this or any other repository

# New respository creation - modify the 1st two lines
#
# Name of the repository
REPO_NAME=svn-etc
# The directory that will be going into the repository
WDIR_PATH=/etc
# The location of the repository (make sure directory is already created)
REPO_LOCA=/var/svn-repos
#
mkdir -p $REPO_LOCA
cd $REPO_LOCA
# Create the repository
svnadmin create $REPO_NAME
chmod 700 $REPO_NAME
#
cd $WDIR_PATH
SVNFILE="file://${REPO_LOCA}/$REPO_NAME"
svn checkout $SVNFILE $WDIR_PATH
echo "Run thes two commands to add all files and commit"
echo "svn add * --force"
echo 'svn commit -m "Initial Version"'
#
svn status
#
# To update repo.db - This is a text file to keep track of created repositories
# If repo.db does not already exist create it with these two lines below (without the #)
#SVN_Repository                     | Location | Working_Dir_Path        | Notes
#----------------------------------------------------------------------------------------------
#
echo "${REPO_LOCA}/$REPO_NAME | LOCAL? | $WDIR_PATH | SOME NOTES" >> $REPO_LOCA/repo.db

Repeat above for a different directory to come under version control

# New respository creation - modify the 1st two lines
REPO_NAME=svn-www-common-vcs
WDIR_PATH=/www/common/vcs
#
etc .....

Things to Watch out for

Invariably there are always issues when stepping away from the normal (as in here, it is uncommon to put /etc on VCS). Any time you create a new user, the .svn directory in /etc/skel will get copied over! So remember to delete it!


Refer to: VCS of web directory for considerations on using VC for web folders.


QR Code
QR Code tech:svn:using_subversion_to_version_control_etc (generated for current page)