I’ve been hacking code todays quite efficiently… my “layered subversion” client is coming along nicely.

You’ll probably wonder what “layered subversion” is supposed to be.

Basically it’s an overlay of multiple subversion repositories, the same thing you would get by exporting them and then copying them over each other.

Except that I want to be able to check-in my changes to the repository where the file came from…

So I e.g. have a configuration like this:

Configuration 'Host foo /etc' has the following layers:
Layer ID: 'base' is 'http://confighost/svn/layers/base'
Layer ID: 'selinux' is 'http://confighost/svn/layers/selinux'
Layer ID: 'firewall' is 'http://confighost/svn/layers/firewall'
Layer ID: 'foo' is 'http://confighost/svn/layers/foo'

I have a set of configuration files common for all my servers. These files are stored in the base layer, and when I update my machines I want to recieve the latest updates.

Then I have the SELinux layer, which e.g. contains policies, but also overrides some of the default init scripts (removing stuff which won’t work on SELinux due to security restrictions, e.g. updatedb)

The third layer is shared for my firewall boxes, whereas the fourth layer contains e.g. /etc/hostname which is unique for this host.

Now assume I’ve changed some files in my configuration (e.g. by runing apt-get upgrade), I now want to commit these changes to their respective layers. While I could do this manually, or by merging somehow etc. I want this to be automated as far as possible. In most cases, files won’t move from one layer to another; even the case where a file exists in multiple layers (the SELinux cronjob example above) is very rare.

Here’s an output of my current “laysvn status” command:

M foo   fstab
? ---   foobargnarf
M base  magic
? ---   foo

First I’ve modified the fstab, which is in the foo layer (the topmost). I’ve created a new file named “foobargnarf” which is new, so the tool doesn’t know in which layer to place it into. The file “magic” is from the base layer, while the folder “foo” with some contents is new, too.

There is still lots of stuff missing. Some of the code is also rather ugly, it’s more of a hack into the python subversion API: the only way I’ve found to query whether a (not yet existant) file is to be ignored (in which case I will not look in lower layers, so I can “delete” files in upper layers!) or if it is just a new file is really odd in pysvn: a new file will give an empty result for the status() call, whereas an ignored file actually is found as ignored… it would be nice to get a proper “404” return code in the first case.

I have no idea yet of the semantics to be used in conflicts, or which issues will arise with the “update” call. I have a rather clear view of the latter through…

When I’m at a point where I can use this tool for my needs I’ll release it, and hope that someone else picks it up and adds the functionality to either regular subversion or svk… ;-) Long live OpenSource!