Skip to content

Instantly share code, notes, and snippets.

@louiszuckerman
Created September 27, 2012 19:28
Show Gist options
  • Save louiszuckerman/3795948 to your computer and use it in GitHub Desktop.
Save louiszuckerman/3795948 to your computer and use it in GitHub Desktop.
savn -- brings version controlled order to chaotic system configurations
#!/bin/bash
# This script is meant to make it easy for a system administrator to archive and restore important system files.
# Design:
# A central repository holds archived config files for all servers, with a directory for each server. Individual
# servers check out their subdirectory to a local working copy. Files are archived by hard-linking into the local
# working copy and then committing to the central repo.
# Prerequisites:
# A network-accessible Subversion repository. Set the URL for the server in SVN_URL and the repo name in SVN_REPO.
# Also set the path to the local working copy root directory in SVN_WD. Be sure the directory exists and permissions
# allow writing to it.
# Usage:
# To avoid having multiple versions of this script installed on the various servers it is intended to be pulled from
# the repo at runtime. This behavior can be automated with the following shell alias:
# alias savn='svn cat <SAVN_URL> | sh -s - '
# Once the alias is in place usage is as follows:
#
# savn [ --refresh | <file1> [ <file2> ... ] ]
#
# A list of files can be supplied to add to the version control archive.
# Files can be either absolute paths or filenames in the current directory.
# CAVEAT: savn does NOT currently support filenames with spaces!
#
# Running without any parameters will archive current versions of all previously archived files
#
# The parameter "--refresh" can be substituted for a list of files. This will refresh the hard-links for
# all files in version control on the current host.
# Changing the Hostname:
# To change a hostname while preserving the configurations in version control, rename the branch for the local host:
# svn move svn://svn_server/savn_repo/old_hostname svn://svn_server/savn_repo/new_hostname
# Proceed to change the local hostname, then run:
# savn --refresh
# Finally, the old local working copy (/var/local/svn/old_hostname) can be deleted.
# Elements
SVN_WD="/var/local/svn"
SVN_URL="svn://svn.server.addr"
SVN_REPO="reponame"
SVN_DIR=`hostname -s`
# Compounds
MY_BRANCH=$SVN_REPO"/"$SVN_DIR
MY_URL=$SVN_URL"/"$MY_BRANCH
MY_WD=$SVN_WD"/"$MY_BRANCH
# Bootstrap: [ [ Create folder for host in repo. ] Checkout branch to local working copy. ]
if [ ! -d $MY_WD ]; then
sudo mkdir -p $SVN_WD
svn mkdir $MY_URL -m "savn (bootstrap) `date`: $SSH_CONNECTION $SUDO_USER $USER"
sudo svn checkout $MY_URL $MY_WD
fi
# Refresh hard-links
if [ "$1" = "--refresh" ]; then
cutparam=`echo $MY_WD | wc -m - | tr -d ' '`
savnlist=$(find $MY_WD -name .svn -prune -o \( -type f -print \) | cut -c $cutparam | xargs)
else
savnlist="$@"
fi
# Save: [ Link target file(s) into local working copy. ] Rescan local working copy. Commit local working copy.
for i in $savnlist; do
sudo cp -lavf --parents -t "$MY_WD/" "`readlink -nf "$i"`"
# canonicalize filenames to full paths and link file under parent directory subtree of $MY_WD
done
sudo svn add --force --no-auto-props $MY_WD/*
sudo svn commit $MY_WD -m "savn $1 `date`: $SSH_CONNECTION $SUDO_USER $USER"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment