Blob Blame History Raw
#!/bin/sh
#
# This script starts and stops the monotone server.
#
# chkconfig: - 90 10
# description: Monotone netsync protocol server
# processname: monotone-server
# pidfile: /var/run/monotone/monotone-server.pid
# config: /etc/sysconfig/monotone
# config: /etc/monotone/monotonerc
#
### BEGIN INIT INFO
# Provides: monotone
# Required-Start: $local_fs $network $named $time
# Required-Stop: $local_fs $network
# Short-Description: start and stop Monotone netsync protocol server
# Description: Monotone is a free, distributed version control system.
#  It provides fully disconnected operation, manages complete
#  tree versions, keeps its state in a local transactional
#  database, supports overlapping branches and extensible
#  metadata, exchanges work over plain network protocols,
#  performs history-sensitive merging, and delegates trust
#  functions to client-side RSA certificates.
### END INIT INFO

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

# Get configuration settings.
[ -f /etc/sysconfig/monotone ] && . /etc/sysconfig/monotone

# By default it's all good
RETVAL=0

MT=/usr/bin/mtn
MTSERVER=/usr/sbin/monotone-server
MONOTONE_PIDFILE=/var/run/monotone/monotone-server.pid
MONOTONE_LOGFILE=${MONOTONE_LOGFILE:-/var/log/monotone.log}
MONOTONE_OLDDB=/var/db/monotone/server.db
MONOTONE_OLDDBFILE=/var/db/monotone/server.mtn
MONOTONE_OLDPPFILE=/var/db/monotone/passphrase.lua

random_passphrase()
{
	# As of 0.22, 32 chars is the maximum pass phrase length.
	dd if=/dev/urandom bs=32 count=1 2> /dev/null | md5sum |
	{ read sum rest; echo $sum; }
}

umask 077

check_db_version()
{
	db_version=`runuser -s /bin/bash - ${MONOTONE_USER:-monotone} \
			    -c "LC_ALL=C \
	    			$MT $MONOTONE_RCOPTS $MONOTONE_DBOPTS \
				    db version"` || exit 2
	set -- $db_version
	[ "$5" == "(usable)" ]
	return $?
}

# See how we were called.
case "$1" in
  start)
	if [ -e $MONOTONE_OLDDBFILE -a ! -e $MONOTONE_DBFILE ]; then
		echo -n $"Moving" "$MONOTONE_OLDDBFILE" $"to" "$MONOTONE_DBFILE"
		if mv "$MONOTONE_OLDDBFILE" "$MONOTONE_DBFILE"; then
			failure
			echo
			exit
		else
			success
			echo
		fi
		rmdir 2> /dev/null /var/db/monotone
	fi
	if [ -e $MONOTONE_DBFILE ]; then
		check_db_version || $0 migrate
	elif [ -e $MONOTONE_OLDDB ]; then
		echo -n $"Pre-0.26 monotone database must be migrated by hand: "
		failure
		echo
		false
	else
		$0 init
	fi
	RETVAL=$?
	if [ $RETVAL = 0 ] && [ "x`ls $MONOTONE_KEYDIR`" = x ]; then
		$0 genkey
		RETVAL=$?
	fi
	if [ $RETVAL = 0 ]; then
		# Start daemon.
		echo -n $"Starting monotone server: "
		{
		exec 3>> $MONOTONE_LOGFILE &&
		echo >&3 "Server restart at `date`" &&
		daemon --user=${MONOTONE_USER:-monotone} \
		       --pidfile $MONOTONE_PIDFILE \
		       $MTSERVER \
		       $MONOTONE_RCOPTS $MONOTONE_DBOPTS $MONOTONE_PPOPTS \
		       serve --pid-file=$MONOTONE_PIDFILE \
			     "$MONOTONE_SERVE_OPTS" ">&3 2>&3 &"
		} && success || failure
		RETVAL=$?
		echo
	fi
        [ $RETVAL = 0 ] && touch /var/lock/subsys/monotone
        ;;
  stop)
        # Stop daemons.
        echo -n $"Stopping monotone server: "
        killproc -p $MONOTONE_PIDFILE $MTSERVER
        RETVAL=$?
	rm -f $MONOTONE_PIDFILE
        [ $RETVAL = 0 ] && rm -f /var/lock/subsys/monotone
        echo
        ;;
  restart|force-reload)
        $0 stop
        $0 start
        ;;
  condrestart|try-restart)
       [ -e /var/lock/subsys/monotone ] && $0 restart
       ;;
  status)
	status -p $MONOTONE_PIDFILE monotone-server
	RETVAL=$?
	;;
  init)
	echo -n $"Initializing database" "${MONOTONE_DBFILE}: "
	{ [ -d /var/lib/monotone ] ||
 	  /usr/bin/install -o ${MONOTONE_USER:-monotone} \
			   -g ${MONOTONE_GROUP:-monotone} \
			   -m 0770 -d /var/lib/monotone; } &&
	runuser -s /bin/bash - ${MONOTONE_USER:-monotone} -c "umask 007; \
		$MT $MONOTONE_RCOPTS $MONOTONE_DBOPTS db init" &&
		success $"database initialization" ||
		failure $"database initialization"
	RETVAL=$?
	echo
	;;
  genkey)
	MONOTONE_KEYID=${2:-${MONOTONE_KEYID:-monotone@`/bin/hostname -f`}}
	MONOTONE_PPFILE=${MONOTONE_PPFILE:-/etc/monotone/passphrase.lua}
	if [ -s "$MONOTONE_PPFILE" -a -s "$MONOTONE_KEYDIR/$MONOTONE_KEYID" ]
	then
		echo >&2 "$0:" $"Server key already installed"
		echo >&2 "$0:" $"To lose old key remove file" "$MONOTONE_PPFILE"
		exit 1
	fi
	echo -n $"Generating RSA key for server $MONOTONE_KEYID"
	tmp=/tmp/mtserver$$
	if
		passphrase=`random_passphrase` &&
		{ echo $passphrase; echo $passphrase; } |
		(umask 027; $MT $MONOTONE_RCOPTS $MONOTONE_DBOPTS \
				genkey $MONOTONE_KEYID > /dev/null 2>&1) &&
		/bin/chgrp ${MONOTONE_GROUP:-monotone} \
			   "$MONOTONE_KEYDIR/$MONOTONE_KEYID" &&
		/bin/chmod 0640 "$MONOTONE_KEYDIR/$MONOTONE_KEYID" &&
		cat > $tmp <<EOF &&
function get_passphrase(keyid)
  return "$passphrase"
end
EOF
		/usr/bin/install -o root -g ${MONOTONE_GROUP:-monotone} \
				 -m 0440 $tmp ${MONOTONE_PPFILE}
	then
		success $"key generation"
	else
		failure $"key generation"
	fi
	RETVAL=$?
	rm -f $tmp
	echo
	;;
  migrate)
	RETVAL=0
	if [ ! -e $MONOTONE_PPFILE ] && [ -e $MONOTONE_OLDPPFILE ]; then
		echo -n $"Moving old server passphrase file to new location: "
		/usr/bin/install -o root -g ${MONOTONE_GROUP:-monotone} \
				 -m 0440 \
				 $MONOTONE_OLDPPFILE ${MONOTONE_PPFILE} &&
		success $"move passphrase file" ||
		failure $"move passphrase file"
		RETVAL=$?
		echo
	fi
	[ $RETVAL -eq 0 ] || exit $RETVAL
	# Note this must run as root in case migration is writing
	# into /etc/monotone/private-keys.
	echo $"Checking database format in" "${MONOTONE_DBFILE}:"
	(umask 027
	 $MT $MONOTONE_RCOPTS $MONOTONE_DBOPTS $MONOTONE_PPOPTS db migrate &&
	 $MT $MONOTONE_RCOPTS $MONOTONE_DBOPTS $MONOTONE_PPOPTS db regenerate_caches &&
	 /bin/chgrp -R ${MONOTONE_GROUP:-monotone} $MONOTONE_KEYDIR)
		success $"database check" ||
		failure $"database check"
	RETVAL=$?
	echo
	;;
  # Use "monotone pubkey me@my.com | service monotone import"
  # to import the first keys to enable in /etc/monotone/write-permission.
  # Thereafter, those with write permission can add other keys via
  # netsync with "monotone push --key-to-push=IDENT" and then IDENT
  # can be used in the read-permission and write-permission files.
  import)
	echo -n $"Importing packets to monotone database: "
	runuser -s /bin/bash - ${MONOTONE_USER:-monotone} -c "umask 007; \
		$MT $MONOTONE_RCOPTS $MONOTONE_DBOPTS read" &&
		success $"packet import" ||
		failure $"packet import"
	RETVAL=$?
	echo
	;;
  *)
	echo "\
Usage: $0 {start|stop|restart|status|condrestart|init|import|genkey [IDENT]}"
	RETVAL=1
	;;
esac

exit $RETVAL