In this article I will describe how I setup a central repository to store my configuration files and shell scripts, and a quick process to bring new computers into the system and continue propagating configuration changes as I make them. To use the centralized repository approach, you need to have an account on a file/shell account server somewhere that’s online at least most of the time.
I have about three and a half Linux hosts that I use on at least a semi-regular basis, depending on how you count:
- Thinkpad Tablet (keyboard, pointing stick, and stylus + touch screen)
- non-Tablet Thinkpad
- ancient (circa 2000) Thinkpad
- virtual machine that’s always running on my Windows 7 work PC , so I always have a Linux environment at work
For this project, I wanted to learn how to use the Bazaar version control system. I have much experience with Subversion at work and personally, keeping my office projects and personal notebooks in Subversion repositories, but I find Subversion takes more time than I’d like to perform a synchronization. Bazaar has some neato features that appeal even to people who are working on personal data and not collaborating, such as easier merging of parallel changes (compared to Subversion) and offline commits. Other next-generation distributed version control systems improve upon Subversion’s non-distributed architecture, but my casual research shows that Bazaar is one of the more newbie-friendly choices. Your mileage may vary.
Step 1: Initialize your repository
On the central SERVER:
mkdir ~/etc/config cd ~/etc/config bzr init bzr checkout
Step 2: Move config files into into the repository
My concept is to keep all shared configuration files under ~/etc/config/PATH/FILE where PATH is the original path under ~ and FILE[/file] is the file name. This makes it easy to keep only the shared files in your Bazaar repository while ignoring all other config and data files.
mkdir ~/etc/config/etc mv ~/etc/brendan.jpg ~/etc/config/etc/ # profile photo for social web sites mv ~/etc/buddy-icon* ~/etc/config/etc/ # IM buddy icon (various formats) mkdir ~/etc/config/bin mv ~/bin/mount-* ~/etc/config/bin/ mv ~/bin/weather ~/etc/config/bin/ mv ~/bin/mailpda ~/etc/config/bin/ mkdir ~/etc/config/.config mkdir ~/etc/config/.config/fish # Fish is my chosen command line shell mv ~/.config/fish/config.fish ~/etc/config/.config/fish/ mkdir ~/etc/config/.config/fish/functions mv ~/.config/fish/functions/* ~/etc/config/.config/functions/ mkdir ~/etc/config/.config/Terminal # XFCE Terminal mv ~/etc/.config/Terminal/terminalrc ~/etc/config/.config/Terminal # et cetera!
I hope you get the idea.
Step 3: Create a script to install symbolic links to all your shared config files
Of course you need to access these files in their original locations. Linux’s symbolic links come in really handy here. (Why does Windows still not have symlinks? :^( )
#!/usr/bin/fish # install-shared-config # # This script installs links to ~/... from ~/etc/config/..., which is # kept in version control. # You'll need fish <http://www.fishshell.org/> to run this script # -- or translate it into bash if you wish. cd $HOME/etc/config for i in (find . -not -path "./.bzr*" -type f -printf "%Pn") set d (dirname $i) echo $i mkdir --parents "$HOME/$d" ln --symbolic "$HOME/etc/config/$i" "$HOME/$i" 2>/dev/null end
# make the script executable chmod +x ~/etc/config/bin/install-shared-config
Then run the script and all your shared files will once again be available from their original locations.
Step 4: Check in your shared files
cd ~/etc/config bzr add bzr commit -m "Initial checkin"
Checking out the files on a remote host
Here’s how you add another host to the system — your laptop that you do most of your work on, for example:
mkdir ~/etc/config cd ~/etc/config bzr checkout bzr+ssh://USERNAME@SERVER/home/USERNAME/etc/config . # Manually remove any already-local copies of config files found in # the shared repository. The install script doesn't do this for you! ~/etc/config/bin/install-shared-config
Syncing a remote host
cd ~/etc/config # Download upstream changes bzr update # What's new locally? bzr stat # Did you add new files since the last checkin? Run this to add all new files: bzr add # Did you rename files since your last checkin?... bzr mv OLDNAME NEWNAME # Did you delete files?... bzr rm DEADFILE # Done! bzr commit -m "SUMMARY OF CHANGES"
Some notes about Opera web browser
Be careful what you put into your version control repository. For example, ~/.opera/opera6.ini would be problematic for at least two reasons: my username is embedded in it (my username is not consistent from one host to another), and transient stuff like window positions and recently used files are stored in it. I think it’s best to recreate my Opera configuration individually on each host.
I have a CSS file in ~/etc/user.css (which is a symlink to ~/etc/config/etc/user.css of course) that adds a thin yellow border around all links instead of whatever the site designer chose, so I can’t miss links. This file is installed using the Opera setting UserPrefs|LocalCSSFile.
Other applications you use might require similar specific tweaking.
More to come?
I’m just getting used to Bazaar for now, and my config files are a good low-risk data set to play around with. In the future, I will probably transition my Zim notebooks from Subversion to Bazaar and document it here. Using Bazaar should make it relatively easy to store an encrypted backup of my Notebooks repository on some public host, and keep it up today with a daily cron job; this way I will always have access to an up-to-date copy in case I’m on a host that is terribly out of sync — even if my main file server is offline!