#!/bin/bash
#
# sxpsql-set-vacuum
#
# Enables Postgres auto-vacuuming.
# It does this either by enabling the 'vacuumdb' client(*) (pre-v8.1)   --or--
# by switching on the appropriate parameters in the server config file.
#
# Usage: sxpsql-set-vacuum -n pg-major-version pg-minor-version
#  e.g.:
#        sxpsql-set-vacuum -n 7 4   # major-version = 7, minor = 4
#
# (*) Notes on 'vacuumdb' client
#     This will be set up to run via root's crontab.  It must be root as
#     it requires access to the 'platform.properties' file to gain access
#     to the database connection details.
#     For this to work, two things need to happen:
#		1) The Postgres client access file "ph_hba.conf" must be amended
#		   to allow local connections - see 'sxpsql-whitelist'
#		2) A ".pgpass" file will need to be created in ~root, containing 
#		   the DB username/password etc.  Unfortunately 'platform.properties'
#		   is not available at the time the scalix-postgres RPM is installed,
#		   so the cron job must check for the ".pgpass" file at run-time and
#		   create it if necessary (see 'sxpsql-vacuum').
#

ME=$(basename $0)

# Pull in common routines
#
. /opt/scalix-postgres/bin/common-conf-file.sh
. /opt/scalix-postgres/bin/common-cron.sh

GETINSTDIR="/opt/scalix-postgres/bin/sxpsql-get-inst-dir"

usage() {
	echo "Usage: $ME -n pg-major-version-number pg-minor-version-number"
	exit 1
}


#------------------------------------------------------------------------------
# writeVacuumCrontabEntry                                                     #
#------------------------------------------------------------------------------
#
# Creates the crontab entry for the account
# Returns:
#	0=OK / 1=ERR
#	Nothing via STDOUT
#
writeVacuumCrontabEntry() {
	ACCOUNT=$1

	CRONTAB=/tmp/sxpsql-set-vacuum-crontab.$$
	ERRS=/tmp/sxpsql-set-vacuum-crontab-errs.$$
	TMP=/tmp/sxpsql-set-vacuum.$$

	crontab -u $ACCOUNT -l > $CRONTAB 2> $ERRS
	if [ $? -ne 0 -a "$(cat $ERRS)" != "no crontab for $ACCOUNT" ]; then
		echo "Error - Unable to read ${ACCOUNT}'s crontab."
		rm -f $CRONTAB $ERRS
		return 1
	fi
	
	grep "scalix-vacuumdb-start" $CRONTAB > /dev/null 2>&1
	if [ $? -eq 0 ]; then
		# crontab already contains this entry - do nothing
		rm -f $CRONTAB $ERRS
		return 0
	fi
		
	ENTRY="#--scalix-vacuumdb-start ---------------- DO NOT DELETE THIS LINE --
#
# SCALIX - Postgres DB maintenance (nightly standard & weekly full scans).
#
00 0 * *  *  /opt/scalix-postgres/bin/sxpsql-vacuum -f
30 0 * * sun /opt/scalix-postgres/bin/sxpsql-vacuum -f -F
#--scalix-vacuumdb-end ------------------ DO NOT DELETE THIS LINE --
"
	echo "$ENTRY" >> $CRONTAB  # add new entry

	# Update the crontab
	crontab -u $ACCOUNT $CRONTAB > $TMP 2> $ERRS
	if [ $? -ne 0 ]; then
		echo "Error - Unable to update ${ACCOUNT}'s crontab: $(cat $ERRS)"
		rm -f $CRONTAB $ERRS $TMP
		return 1
	fi

	rm -f $CRONTAB $ERRS $TMP
	return 0
}


# Main
#
if [ $(whoami) != "root" ]; then
	echo "Please run $ME as root."
	exit 1
fi

echo "SCALIX Postgres auto-vacuum reconfiguration started."

# Get args
#
[ $# -ne 3 ] && usage
[ "$1" != "-n" ] && usage
PG_MAJOR=$2
PG_MINOR=$3

/etc/init.d/scalix-postgres status >/dev/null 2>/dev/null
POSTGRES_RUNNING=$?

ERRS=0
if [ $PG_MAJOR -ge 8 -a $PG_MINOR -ge 1 ]; then
	#
	# As of v8.1, auto-vacuum was moved into the server, so configure it 
	# there by updating key parameters in "postgresql.conf"
	#

	# Back up config file
	#
	CONF=$($GETINSTDIR)/data/postgresql.conf
	BACKUP_CONF=$(backupConfigFile $CONF)
	if [ $? -eq 0 ]; then
		echo "$(basename $CONF) backed up to $(basename $BACKUP_CONF)"
	else
		echo "Error - unable to back up $CONF : ${BACKUP_CONF}. Stop."
		exit 1
	fi

	( ! setConfParam "autovacuum"            "on"   $CONF ) && let ERRS=ERRS+1
	( ! setConfParam "autovacuum_naptime"    "600"  $CONF ) && let ERRS=ERRS+1

	if [ $PG_MINOR -lt 3 ]; then
		( ! setConfParam "stats_start_collector" "on" $CONF ) && let ERRS=ERRS+1
		( ! setConfParam "stats_row_level"       "on" $CONF ) && let ERRS=ERRS+1
	else
		( ! setConfParam "track_activities"   "on"   $CONF ) && let ERRS=ERRS+1
		( ! setConfParam "track_counts"       "on"   $CONF ) && let ERRS=ERRS+1
	fi

	echo -n "Postgres v${PG_MAJOR}.${PG_MINOR}: ScalixDB auto-vacuum "
	if [ $ERRS -eq 0 ]; then
		echo "enabled."
		[ $POSTGRES_RUNNING -eq 0 ] && /etc/init.d/scalix-postgres restart

	else
		cat $BACKUP_CONF > $CONF   # preserve owner/group/perms
		echo "Error encountered - original config file restored."
	fi
else
	#
	# Pre-8.1, configure a vacuumdb client instead, using cron.
	#

	ACCOUNT="root"
	PG_LOG=$($GETINSTDIR)/pgactivity.log

	STATUS_MSG=$(writeVacuumCrontabEntry $ACCOUNT)
	if [ $? -ne 0 ]; then
		M="*WARNING* - The SCALIX Postgres reconfiguration script could not
            deploy 'sxpsql-vacuum' via cron because it could not add an entry
            to ${ACCOUNT}'s crontab.
            Manual reconfiguration is therefore required if you want to run 
            vacuumdb(1) (recommended)."
		echo "$M" >> $PG_LOG
		echo "$M"
		echo "$STATUS_MSG"   # error message from writeVacuumCrontabEntry()
		exit 1
	fi
	
	echo -n "Postgres v${PG_MAJOR}.${PG_MINOR} - vacuumdb client enabled "
	echo    "via ${ACCOUNT}'s crontab."
fi

echo "SCALIX Postgres auto-vacuum reconfiguration completed."
exit $ERRS
