Revision control and distribution of home configuration files with Bash and git

For year, I managed different copies of home configuration files over different hosts with some revision control,  but however better are modern system like git in comparison to old CVS, it would still be quite unpractical to put your whole home directory within one single repository:

  • for obvious reason, there are only a few files that you can actually move around carelessly and put on gitlab for instance; but these files are actually nice to have there, so you can retrieve them whenever and wherever you want;
  • even if you could/would made the rest of your home directory public, most of the configuration files cannot adjust to each host they are run onto; you can obviously adjust a ~/.bashrc according to $HOSTNAME, but it gets a bit more annoying for, say, ~/.Xdefaults;

I am quite sure most people using many different hosts have all their own way to deal with that. There are too many use cases for one solution to be practical for everybody.

I already made public a small script to distributed SSH public keys, that I was using for quite a while before. Next is the script I am using now to distribute home configuration files among hosts: it needs to be added within a git repository (in my case, gitlab “rc” repository), from there, based on a pre-decided list of files or directories:

  • keep a copy of each file/directory per hostname (ex: bashrc.$HOSTNAME, config/awesome.$HOSTNAME);
  • default can be set by renaming $item.$HOSTNAME to $item.default of such file/directory (ex: bashrc.default);

It obeys to the following general rules:

  • it wont copy symlinks but their content;
  • if we only have a local file, save it in the repository;
  • if we have a local file and a repository copy, and if there is a difference, update the repository;
  • if we only have a repository copy, no local file, create the local file with a warning;

Regarding $item.default:

  • $item.default  be will used only unless a $item.$HOSTNAME exists;
  • $item.default will never be updated automatically: if the local copy based on the default is modified, then a $item.$HOSTNAME will be created instead; if it is to made default, you’ll need to rename $item.$HOSTNAME to $item.default; alternatively, you could edit $item.default first and remove the local file at once;
  • similarly, $item.default will never overwrite a local file: to use it on other hosts after an update, the local file will need to be removed;

I admit this $item.default handling is a bit cumbersome but these files update presents risk (lockout, security, etc).

If updaterc exists in the same directory, it will be sourced. It is convenient way to change the $ITEMS variable without editing the script itself.

To use it, you just need to set up and clone some git repository and, within this repository:

wget https://gitlab.com/yeupou/rc/raw/master/update.sh
chmod +x update.sh
# eventually create a custom list of items
echo 'ITEMS="bashrc config/awesome"' > updaterc
# run
./update.sh

The task can be automated by a cronjob, add the following to a call to crontab -e:

3 12 * * * ~/.rc/update.sh >/dev/null 2>/dev/null

(side note: that won’t work properly if one of your hosts is named “default”)

Advertisements

Managing an SSH public keys ring with git

Using ssh-updatekeys, you can set up and maintain ~/.ssh/authorized_keys with specific sets on the fly.

You just have  to put your public keys on a public git repository. The script will fetch the keys, either by git + SSH (for write access) or just git + https (for read access).

It can handle different sets of keys (for instance you may want to differenciate keys with or without passphrares). In the git repository, any directory with a name starting by set (set0, setA, setTest, etc) will be treated as a set.

(ssh-updatekeys.sh is part of my -utils package).

Update : you can now grab it with the command

wget ssh.rien.pl -O ssh-updatekeys.sh

Apt-get this /scratch (apt/steam cache, exim greylist, owncloud, tumblr daily post, etc)

 

I conveniently use, since more than 10 years, one debian package to distribute over different computers some scripts, notably all the ones published here and on github (except rawdog and pxe setup – but that could change). While it’s practical for me, it’s not for anyone else since the package content is overly random.

Someone using the apt/steam cache as described on this blog can easily end up with out-of-date scripts – unless he fetch updates from git directly.

I decided to split this big package into multiples and improve the conffiles so they are more or less zeroconf.

The result is:

  • -keyring: Keyring used to signed packages along with repository set-up
  • -utils-cache-apt: APT downloads cache setup
  • -utils-cache-steam: Steam downloads cache setup
  • -utils-cloud: Owncloud setup and apps
  • -utils-exim: Exim greylist, bogofilter and spamassassin setup
  • -utils-torrent: Manage transmission via NFS/Samba
  • -utils-tumblr: Automated image post on tumblr
  • -utils-webmail: Roundcube setup and plugins
  • and some others packages that these depends on.

 

The easiest way to get anything is to first install the keyring package and then directly apt-get:

  	# wget http://apt.attique.org/stalag13-keyring.deb
	# dpkg -i stalag13-keyring.deb
	# apt-get update
	# apt-get install stalag13-...