System Configurations: Difference between revisions

From SubversionWiki
Jump to navigation Jump to search
m Typos
TkeXwy (talk | contribs)
mNo edit summary
Line 76: Line 76:
You can then create additinal directories for other machines and check them out to their root directory.
You can then create additinal directories for other machines and check them out to their root directory.
Let's suppose you are working on a machine called <tt>maschine</tt>. You could do the following:
Let's suppose you are working on a machine called <tt>maschine</tt>. You could do the following:
  svn mkdir ssh+svn://root@macchina/svn/configs/maschine
  svn mkdir ssh svn://root@macchina/svn/configs/maschine
  svn checkout ssh+svn://root@macchina/svn/configs/maschine /
  svn checkout ssh svn://root@macchina/svn/configs/maschine /


= Advanced tricks for multiple administrators ''and'' machines =
= Advanced tricks for multiple administrators ''and'' machines =
Line 88: Line 88:


On every machine where you want to manage the configuration using svn,
On every machine where you want to manage the configuration using svn,
first create the following file named <tt>/usr/local/bin/svn+sysadmin</tt>
first create the following file named <tt>/usr/local/bin/svn sysadmin</tt>
  #!/bin/bash
  #!/bin/bash
  # Taken from http://www.orcaware.com/svn/wiki/System_Configurations
  # Taken from http://www.orcaware.com/svn/wiki/System_Configurations
  if <nowiki>[[ -z $SYSADMIN ]]</nowiki>; then
  if <nowiki>[[ -z $SYSADMIN ]]</nowiki>; then
   SYSADMIN=$(
   SYSADMIN=$(
     read -p "Your (non-root) login name: " NAME </dev/tty >/dev/tty && \
     read -p "Your (non-root) login name: " NAME </dev/tty >/dev/tty
    echo "$NAME"
  )
fi
if <nowiki>[[ -z $SYSADMIN ]]</nowiki>; then
  echo "You need to give your name!" >/dev/tty
  exit 1
fi
exec /usr/bin/ssh -l sysadmin-svn "$@" --tunnel-user="${SYSADMIN}"
 
Make it executable:
chmod a+x /usr/local/bin/svn+sysadmin
 
Register it in the <tt><nowiki>[tunnels]</nowiki></tt> section of your <tt>~/.subversion/config</tt>:
[tunnels]
sysadmin = /usr/local/bin/svn+sysadmin
 
On the machine where the reporitory is, create a new user named <tt>sysadmin-svn</tt>
and make it owner of the repository:
chown -R sysadmin-svn /svn/configs
 
To allow access to the repository, it is probably most convenient to create
a ssh public key for root on each machine (using <tt>ssh-keygen</tt>).
I would consider it safe enough to not use a passphrase,
as this key only protects access to the repository and
if someone unauthorized managed to become root you are in trouble anyway.
You can then register all those keys in <tt>~sysadmin-svn/.ssh/authorized_keys</tt>
on the machine with the repository to allow them all access to that account.
 
Now you can move your machine config to this new scheme:
svn switch --relocate ssh+svn://root@macchina/svn/configs/maschine ssh+sysadmin://macchina/svn/configs/maschine /
 
'''Take care''' not to combine a <tt>switch --relocate</tt> (to change scheme)
and a simple <tt>switch</tt> (to change repository subtree) into a single step,
as I could imagine there would be trouble if you did so.
 
Because you changed ownership of the repository,
it is probably easiest to access the repository through the <tt>ssh+sysadmin://</tt> scheme
even on the machine where the repository lies.
This way you get the same behaviour no matter what machine you are on.
 
Now whenever you access the configuration file repository,
you will asked your login name unless you set the <tt>SYSADMIN</tt> environment variable.
Some commands like checkout make multiple connections,
so you'll have to provide your name multiple times.
 
= Making use of the information =
 
So what can you do now your files are under revision control?
 
Suppose you are looking at some configuration file and want to know why some setting is the way it is.
You'd [http://svnbook.red-bean.com/nightly/en/svn.ref.svn.c.blame.html svn blame]
the file authors to see who edited it (that's what the user name logging is for)
and in which revision it was last modified.
You can then use [http://svnbook.red-bean.com/nightly/en/svn.ref.svn.c.log.html svn log]
to have a look at the message of that revision to get a clue why it was modified.
You can use [http://svnbook.red-bean.com/nightly/en/svn.ref.svn.c.cat.html svn cat]
or [http://svnbook.red-bean.com/nightly/en/svn.ref.svn.c.diff.html svn diff]
to have a look at its previous setting.
And of course you can do [http://svnbook.red-bean.com/nightly/en/svn.ref.svn.c.revert.html svn revert]
to undo changes you have not yet comitted and
[http://svnbook.red-bean.com/nightly/en/svn.ref.svn.c.merge.html svn merge]
to undo changes already comitted to the repository.
 
= Sharing between machines =
 
Above we were assuming completely independently configured machines.
 
The opposite, completely identical machines, is almost as easy.
You remove any existing local config files and then check out a new copy of the tree.
You can then propagate configuration changes by comitting them on one machine and updating on all the others.
Whenever you put a file under revision control that existed on the machines before
you'll have to remove them before updating, which can be somewhat annoying.
I don't know any nice solution for this yet.
 
How about mixed situations where some files are the same, but some others are not?
I would think it best to have two trees, one shared and one independent, checked out on each machine.
Of course only one of them can be the root.
Usually I'd make this the independent tree unless you have very few differences.
You can then add symlinks from one tree to the other to get each configuration file from the correct tree.
 
In case you made the independent tree your main working copy, you can graft the common tree using
[http://svnbook.red-bean.com/nightly/en/svn.advanced.externals.html svn:externals].
This way you model the tree composition in the repository as well,
not only in your layout of checked out working copies.
This has the advantage that many svn commands treat the whole thing as a single working copy.

Revision as of 09:03, 14 July 2007

This page is about how to manage configuration files (like /etc/*) on your machine(s) using subversion.

Simple case

Let's start off simple. I assume you are root, as you are the one modifying the configuration files. You first create a repository:

svnadmin create /svn/configs

Then you can make your root directory a working copy of this (so far empty) repository:

svn checkout file:///svn/configs /

Now you can start adding things you want to keep under revision control. When adding directories, make sure to use the -N (= --non-recursive) flag to add only the directory itself and not all its contents. And add directories before any files therein, although you may add both in the same command.

svn add -N /etc /etc/fstab

Now we want to have a look at what we modified so far. A simple svn stat will tell you all the things that are not under revision control so far. When working with configuration files where you are not interested in many of them this is usually not what you want. Using the -q (= --quiet) flag suppresses those unmanaged files.

svn stat -q /

Now we are ready to commit our configurations to the repository. It is usually a good idea to add and commit files before you modify them for the first time. This way you can always compare any revision of the file to its "virgin" form supplied by your distribution. And always write informative messages so you can later figure out not only what was changed but also why you changed it. Remember to set EDITOR for the root account as well if you do not supply the comment from the command line.

svn commit / -m "vanilla files"

You may want to have a list of all the files under version control. Luckily you can combine the -q flag with -v (= --verbose) to get just that:

svn stat -qv /

The basic work cycle probably is like this:

  1. if you modify file for the first time:
    1. add all parent dirs and the file itself
    2. commit
  2. edit the file
  3. check your modification works as expected, otherwise revert
  4. list all modifications
  5. commit modifications, including message about the reason for this change

Basic concepts for multiple administrators or machines

Maybe you are not the only one administrating the machine. Assume there are several people who can become root and tweak the config files. You would then want to know who changed what. If you are accessing the repository using the file:// scheme you can simply provide --username yourName to provide this name for the record. It does not even have to correspond to an existing system account.

svn --username john commit /

Maybe you decide to manage the configuration files for several machines in a single repository. For the moment I'll consider the machines rather independent from one another, so that you manage them in completely distinct trees of your repository. Having them in the same repository still helps when diffing them, applying changesets from one machine to another and so on, so it's preferable to rather have subtrees in a single repository than different repositories.

Now let's create a directory for a single machine in the above repository. Note that we create dir directly in the repository, not in any checked out working copy.

svn mkdir file:///svn/configs/macchina

If you start off like this, you can simply check out the empty directory to the root directory of your machine, instead of checking out the repository root as described above. In case you started like described above and only later thought about adding other machines, you'll need to move your existing contents to the new location:

svn move file:///svn/configs/etc file:///svn/configs/macchina/etc
svn switch file:///svn/configs/macchina /

Make sure to first move the contents in the repository and only then switch your working copy, because otherwise you might switch to an empty tree and all your versioned files would be deleted.

You can then create additinal directories for other machines and check them out to their root directory. Let's suppose you are working on a machine called maschine. You could do the following:

svn mkdir ssh svn://root@macchina/svn/configs/maschine
svn checkout ssh svn://root@macchina/svn/configs/maschine /

Advanced tricks for multiple administrators and machines

Note that the trick for logging the user by passing --username to each command only works reasonably well with the file:// scheme. It won't work with ssh access to another machine. And it is easy enough to forget to provide your name. We can solve all this and more by (ab)using the svn facility for defining tunnel applications.

On every machine where you want to manage the configuration using svn, first create the following file named /usr/local/bin/svn sysadmin

#!/bin/bash
# Taken from http://www.orcaware.com/svn/wiki/System_Configurations
if [[ -z $SYSADMIN ]]; then
  SYSADMIN=$(
    read -p "Your (non-root) login name: " NAME </dev/tty >/dev/tty