Mercurial for Tracking Cisco Configs

As I have been working with different routers I have squired a small repository of configuration files that I use for examples, backups, and ways of remembering the way the network was set up before a change. At the start I maintained each config as a separate file, usually containing the date (i.e. router1-071012.cfg). While that worked for a while it got cumbersome when I wanted to track more than one legacy version of a config file. After a while I found out how to use CVS to track a file and its history, but setting things up was a bit cumbersome especially when I wanted to move or organize files. Next I discovered SVN which let me rename files and organize them better among other things. However I would occasionally run into odd issue and commits would sometimes break in weird ways, however It worked much better than CVS. Not being totally content with SVN, I kept an eye on some of the other solutions out there. When I decided to pursue using another versioning system I did some research to figure out which drcs(distributed revision control system), I decided on Mercurial. I chose Mercurial over Git for various reasons, including that it was used natively for python and that bitbucket allowed users to have small private repositories with their free account. I have found this to be a very useful way to track router configurations. Note that all the examples I use are on an Ubuntu Linux based system using the CLI, there are other interfaces available but I will not detail them here.

I created an initial repository on a flash drive.
cd /media/flash/
hg init configs

Note that Mercurial tracks files and does not actually track folders so empty folders do not get tracked by the repository. In other words, if you need a folder to exist in the repository make sure it contains a file that is being tracked. In my repository I have folders named for the customer location, you may decided on a different convention. Since you can move files to different names/locations you can change your mind later, if you decide to use a different format. I used tftp/ftp/scp to copy the running configuration of a router to my box. I name the file after the device fqdn for simplicity. For example lets say I add the config for gw.customer1.net I would do the following in the /media/flash/configs folder

mkdir customer1
cat ~/gw.customer1.net > gw.customer1.net

now if I do an hg stat I see my file listed with a question mark in front of it.

braaen@brian:/media/keys/configs/customer1$ hg stat
? customer1/gw.customer1.net

This means that there is an unknown/untracked file in the repository, note that the path is part of the file identity relative to the root of the repository even though I am in the customer1 folder. To add the file to the repository I do the following hg add gw.customer1.net. Now if I do an hg stat I see an “A” in front of the file which means It will be added to the next commit.


braaen@brian:/media/keys/configs/customer1$ hg stat
A customer1/gw.customer1.net

To actually add the file to the reposity and “commit” the change I would use a hg commit. Lets add this file with hg commit -m "Added Initial verison of Customer1 gateway". Note that comments are required to make the commit (it really helps to use something descriptive for later reference). Now what if I want to make some changes to the router config and add a switch config.


braaen@brian:/media/keys/configs/customer1$ cat ~/gw.customer1.net > gw.customer1.net
braaen@brian:/media/keys/configs/customer1$ cat ~/sw.customer1.net > sw.customer1.net
braaen@brian:/media/keys/configs/customer1$ hg add sw.customer1.net
braaen@brian:/media/keys/configs/customer1$ hg stat
M customer1/gw.customer1.net
A customer1/sw.customer1.net

Now we see and “M” for modified on the stat for gw. What if we want to see the changes we can do a hg di gw.customer1 and get a diff of that changes.

braaen@brian:/media/keys/configs/customer1$ hg diff gw.customer1.net
diff -r e5168c46c61c customer1/gw.customer1.net
--- a/customer1/gw.customer1.net Tue Jul 10 10:46:38 2012 -0400
+++ b/customer1/gw.customer1.net Tue Jul 10 13:07:58 2012 -0400
@@ -8,7 +8,7 @@
no service pad
service timestamps debug datetime msec
service timestamps log datetime msec
-no service password-encryption
+service password-encryption
!
hostname gw.customer1.net
!

Again we commit the changes with a commit.

hg commit -m "Added Switch and modified Router"

Now what if we change both the router config and the switch config?

braaen@brian:/media/keys/configs/customer1$ cat ~/gw.customer1.net > gw.customer1.net
braaen@brian:/media/keys/configs/customer1$ cat ~/sw.customer1.net > sw.customer1.net
braaen@brian:/media/keys/configs/customer1$ hg stat
M customer1/gw.customer1.net
M customer1/sw.customer1.net

if we just for an hg di without specifying a file we see the diffs for both files.
braaen@brian:/media/keys/configs/customer1$ hg di
diff -r 1bc48f053ee9 customer1/gw.customer1.net
--- a/customer1/gw.customer1.net Tue Jul 10 13:08:47 2012 -0400
+++ b/customer1/gw.customer1.net Tue Jul 10 13:10:57 2012 -0400
@@ -8,7 +8,7 @@
no service pad
service timestamps debug datetime msec
service timestamps log datetime msec
-service password-encryption
+no service password-encryption
!
hostname gw.customer1.net
!
diff -r 1bc48f053ee9 customer1/sw.customer1.net
--- a/customer1/sw.customer1.net Tue Jul 10 13:08:47 2012 -0400
+++ b/customer1/sw.customer1.net Tue Jul 10 13:10:57 2012 -0400
@@ -7,7 +7,7 @@
no service pad
service timestamps debug datetime localtime
service timestamps log datetime localtime
-no service password-encryption
+service password-encryption
!
hostname sw.customer1.net
!

There are many other things that mercurial can be used for besides router configs, but this intoduction was just intended to demonstraigt a few advantages of using Mercurial to track configuration changes. For a more through introduction to Mercurial you can visit hginit.com or the Mercurial homepage. You can find Mercurial hosting plans at Bitbucket.

2 Replies to “Mercurial for Tracking Cisco Configs”

    1. Yes, I actually got our company to set up rancid. It is a great program, but has some shortcomings. Even though we use rancid, I still use Mercurial to suppliment rancid. First, It allows me more fine grained commits of individual snapshots of the changes with comments where I can put my notes. Second, it allows me to change the hostname using an hg mv and keep then entire history of the device. Branching also allows me to track parallel history for a replacement device that will replace the production device.

      I tend to use the strengths of each method to compensate for the weaknesses of the other. Thanks for the link though, I meant to include some info on rancid and forgot.

Leave a Reply to Brian Christopher Raaen Cancel reply

Your email address will not be published.