#!/bin/sh -
#
#  $Id: autocvsimport,v 1.1 2002/06/11 14:34:05 dgregor Exp $
#
# This script will check the config directory for each LDAP directory
# server instance listed in $instanceroot/prodinstances, and if any
# configuration changes have been made, it will import that config
# directory into CVS.  Rsync is used in verbose mode to copy the
# config directories into a holding directory ($configbackup), and this
# way we can see if any files have changed.  If no files have changed,
# that config directory is not imported into CVS, to save time and
# unneeded tags.
#
# Quick install (using standard directory layout):
#	sudo cp autocvsimport /usr/local/bin/.
#	sudo mkdir /usr/local/configbackup
#	sudo mkdir /usr/local/cvsroot
#	sudo cvs -d /usr/local/cvsroot init
#	sudo /usr/local/bin/autocvsimport
# Then add the following line to root's crontab:
#	* * * * * /usr/local/bin/autocvsimport 2>&1 | tee -a /var/log/autocvsimport.log
#
# Detailed Installation Instructions:
#	- Set instanceroot to the base directory where the slapd-*
#	  directories are located.
#	- Ensure that the prodinstancesfile exists and contains a list
#	  of the production instances on the system, one per line, without
#	  the slapd- prefix.  See the example prodinstances file for details.
#	- Change the location of configbackup, if needed, and create the
#	  configbackup directory.
#  	- Set CVSROOT to be the location of your CVS repository.  If you
#	  don't have a CVS repository, you can create one by creating the
#	  top-level CVSROOT directory and running "cvs -d <CVSROOT> init".
#	- Set cvsbase to be the part of the CVS repository where you want
#	  to import netscape configs.
#	- Lastly, make sure that rsync and cvs are included by the PATH
# 	  statement below.

instanceroot=/opt/netscape/server4
prodinstancesfile=$instanceroot/prodinstances
configbackup=/usr/local/configbackup
CVSROOT=/usr/local/cvsroot; export CVSROOT
cvsbase=netscape-configs
PATH=$PATH:/usr/local/bin	# rsync and cvs should be here

basename=`basename $0`

die() {
	echo "${basename}: $*" >&2
	exit 1
}

warn() {
	echo "${basename}: $*" >&2
}

exec 3<$instanceroot/prodinstances
while read line <&3; do
        set -- `echo "${line}" | sed 's/#.*//;s/^[      ]*$//'`
        instances="$instances $1"
done
exec 3<&-


for instance in $instances; do
	# sanity check: does the config directory exist?
	if [ ! -d ${instanceroot}/slapd-${instance}/config ]; then
		warn "$instance: instance config directory $instanceroot/slapd-${instance}/config does not exist"
		warn "$instance: skipping cvs import for this instance"

		# skip this instance
		continue
	fi

	if [ ! -d ${configbackup}/slapd-${instance} ]; then
		mkdir ${configbackup}/slapd-${instance}
	fi

	if [ ! -d ${configbackup}/slapd-${instance}/config ]; then
		mkdir ${configbackup}/slapd-${instance}/config
	fi

	# Sanity check: does the backup config directory exist?
	if [ ! -d ${configbackup}/slapd-${instance}/config ]; then
		warn "$instance: instance config backup directory $configbackup/slapd-${instance}/config does not exist"
		warn "$instance: skipping cvs import for this instance"

		# skip this instance
		continue
	fi

	# Copy this config directory to the holding area using rsync,
	# checking for output from rsync, ignoring unimportant lines (one's
	# that don't relate to changed files).  
	rsync -av --delete ${instanceroot}/slapd-${instance}/config/ \
		${configbackup}/slapd-${instance}/config/. 2>&1 | \
		egrep -v '^building file list|^wrote [0-9]+ bytes|^total size|^\./' \
		> /dev/null

	egrepret=$?

	# If egrep returns a value greater than one, it is an error we don't
	# know, and we skip this instance.
	if [ $egrepret -gt 1 ]; then
		warn "$instance: unknown return value $egrepret from egrep"
		warn "$instance: skipping cvs import for this instance"

		# skip this instance
		continue
	fi

	# egrep didn't match any lines other than the ones we wanted it to
	# ignore if it returns 1, which means that rsync didn't copy any
	# lines, so we continue.
	if [ $egrepret -eq 1 ]; then
		continue
	fi

	# If we get here, then egrep has returned zero.
	# This means that files were copied by rsync (or our egrep
	# expression doesn't exclude everything that it should--in which
	# case the egrep expression should be updated), and we have
	# to do a cvs import because something has changed.

	tag="AUTOIMPORT_`date +%b_%d_%Y_%H_%M`"
	message="Import of `hostname`:slapd-${instance}/config at `date`"

	cd ${configbackup}/slapd-${instance}/config
	if [ $? -ne 0 ]; then
		warn "$instance: could not change directory to ${configbackup}/slapd-${instance}/config"
		warn "$instance: skipping cvs import for this instance"

		# skip this instance
		continue
	fi

	# The current tag is used below because we never actually delete
	# any old files during an import.  We would have to rsync -C into
	# a checked-out copy of the repository, do a commit, and come up
	# good way to delete files that are no longer in the config
	# directory.  Hmm... this wouldn't be too much more work.

	# Import the current instance directory under the new tag.
	cvs -Q import -d -m "$message" \
		$cvsbase/`hostname`/slapd-${instance}/config \
		NETSCAPE_CONFIGS_${instance} $tag

	# Remove the old "current" tag from all files, including files in
	# the Attic.
	cvs -Q rtag -d -a current \
		$cvsbase/`hostname`/slapd-${instance}/config

	# Add a new "current" tag to all files with our recently-imported
	# time-based tag.
	cvs -Q rtag -F -r $tag current \
		$cvsbase/`hostname`/slapd-${instance}/config
done
