#!/bin/sh
#
# Unified Plone installer build script
# Author: Kamal Gill (kamalgill at mac.com)
#
# Note: this script must be run as root
#

# Configure Plone installation options
PLONE_HOME=/opt/Plone-2.5.2
#
PY_HOME=$PLONE_HOME/Python-2.4.4
PY=$PY_HOME/bin/python
SITE_PACKAGES=$PY_HOME/lib/python2.4/site-packages
ZEOCLUSTER_HOME=$PLONE_HOME/zeocluster
PRODUCTS_HOME=$ZEOCLUSTER_HOME/Products
ZEOSERVER_HOME=$ZEOCLUSTER_HOME/server
ZEOCLIENT1_HOME=$ZEOCLUSTER_HOME/client1
ZEOCLIENT2_HOME=$ZEOCLUSTER_HOME/client2
PWFILE=$PLONE_HOME/adminPassword.txt
ZEO_STARTUP_SCRIPT=$ZEOCLUSTER_HOME/bin/startcluster.sh
ZEO_SHUTDOWN_SCRIPT=$ZEOCLUSTER_HOME/bin/shutdowncluster.sh
ZEO_RESTART_SCRIPT=$ZEOCLUSTER_HOME/bin/restartcluster.sh
RECEIPTS_HOME=$PLONE_HOME/receipts
 
# This script should be run as root from the directory with the tarballs
# Include the following tarballs in the packages/ directory in the bundle...
PYTHON_TB=Python-2.4.4.tgz
PYTHON_DIR=Python-2.4.4
PYXML_TB=PyXML-0.8.4.tar.gz
PYXML_DIR=PyXML-0.8.4
REPLAB_TB=ReportLab_2_0.tgz
REPLAB_DIR=reportlab_2_0
JPEG_TB=jpegsrc.v6b.tar.gz
JPEG_DIR=jpeg-6b
ZLIB_TB=zlib-1.2.3.tar.gz 
ZLIB_DIR=zlib-1.2.3
PIL_TB=Imaging-1.1.6.tar.gz
PIL_DIR=Imaging-1.1.6
ZOPE_TB=Zope-2.9.6-final.tgz
ZOPE_DIR=Zope-2.9.6-final
PLONE_TB=Plone-2.5.2.tar.gz
PLONE_DIR=Plone-2.5.2-1
TXNG3_TB=TextIndexNG3-3.1.14.tar.gz
TXNG3_DIR=TextIndexNG3
HSCRIPTS_TB=HelperScripts.tgz
HSCRIPTS_DIR=HelperScripts
ETREE_TB=elementtree-1.2.6-20050316.tar.gz
ETREE_DIR=elementtree-1.2.6-20050316


# Capture current working directory for build script
PWD=`pwd`
CWD="$PWD"

PACKAGES_DIR=packages
PKG=$CWD/$PACKAGES_DIR


##############################################################
# Exit if potential conflict with other install at $PLONE_HOME
if [ -e $PLONE_HOME ]
then
    echo ""
    echo "An existing install was detected at $PLONE_HOME."
    echo "Install aborted"
    exit 1
fi


#############################
# Preflight dependency checks
#
# Abort install if not running as root
if [ `whoami` != root ]
then
    echo "This install script must be run as root.  Usage: sudo ./install.sh  ( or su ; ./install.sh )."
    exit 1
fi

# Abort install if no gcc
if [ ! -e /usr/bin/gcc ]
then
	echo "Note: gcc is required for the install. Exiting now."
	exit 1
fi

# Abort install if no g++
if [ ! -e /usr/bin/g++ ]
then
    echo "Note: g++ is required for the install. Exiting now."
    exit 1
fi

# Abort install if no make
if [ ! -e /usr/bin/make ]
then
    echo "Note: make is required for the install. Exiting now."
    exit 1
fi

# Abort install if this script is not run from within it's parent folder
if [ ! -e $PACKAGES_DIR ]
then
	echo "Note: This install script must be run within it's working directory.  Usage: sudo ./install.sh  (or su ; ./install.sh)"
	exit 1
fi


#################################
# Install will begin in 3 seconds
echo ""
echo "Installing Plone 2.5.2 at $PLONE_HOME"
sleep 3
echo ""


##################
# build zlib 1.2.3
echo "Compiling and installing zlib ..."
cd $PKG
tar -zxf $ZLIB_TB
chmod -R 775 $ZLIB_DIR
cd $ZLIB_DIR
./configure -s
make test
make install
cd $PKG
if [ -d $ZLIB_DIR ]
then
    rm -rf $ZLIB_DIR
fi

  
######################################
# Build Python (with readline support)
# note: Install readline before running this script
echo "Installing Python 2.4.4..."
cd $PKG
tar -zxf $PYTHON_TB
chmod -R 775 $PYTHON_DIR
cd $PYTHON_DIR
./configure --prefix=$PY_HOME --with-readline --with-zlib
make
make install
cd $PKG
if [ -d $PYTHON_DIR ]
then
	rm -rf $PYTHON_DIR
fi


#########################
# install ReportLab 2.0
echo "Installing ReportLab (PDF toolkit)..."
cd $PKG
tar -zxf $REPLAB_TB
mv $REPLAB_DIR/reportlab $SITE_PACKAGES/reportlab
cd $PKG
if [ -d $REPLAB_DIR ]
then
	rm -rf $REPLAB_DIR
fi


###################
# build PyXML 0.8.4
echo "Compiling and installing PyXML ..."
cd $PKG
tar -zxf $PYXML_TB
chmod -R 775 $PYXML_DIR
cd $PYXML_DIR
$PY ./setup.py build
$PY ./setup.py install
cd $PKG
if [ -d $PYXML_DIR ]
then
	rm -rf $PYXML_DIR
fi


###################
# build libjpeg v6b
echo "Compiling and installing jpeg libraries ..."
cd $PKG
tar -zxf $JPEG_TB
chmod -R 775 $JPEG_DIR
cd $JPEG_DIR
if [ ! -e /usr/local/man/man1 ]
then
    mkdir /usr/local/man/man1
fi
./configure CFLAGS='-fPIC'
make
make install
ranlib libjpeg.a
cp libjpeg.a /usr/local/lib
cp *.h /usr/local/include
cd $PKG
if [ -d $JPEG_DIR ]
then
	rm -rf $JPEG_DIR
fi


#################
# build PIL 1.1.6
echo "Compiling and installing PIL ..."
cd $PKG
tar -zxf $PIL_TB
chmod -R 775 $PIL_DIR
cd $PIL_DIR
$PY ./setup.py build_ext -i
$PY ./selftest.py
$PY ./setup.py install
cd $PKG
if [ -d $PIL_DIR ]
then
	rm -rf $PIL_DIR
fi


#####################
# install ElementTree
echo "Installing ElementTree ..."
cd $PKG
tar -zxf $ETREE_TB
chmod -R 775 $ETREE_DIR
cd $ETREE_DIR
$PY ./setup.py build
$PY ./setup.py install
cd $PKG
if [ -d $ETREE_DIR ]
then
        rm -rf $ETREE_DIR
fi


##################
# build Zope 2.9.6
echo "Compiling and installing Zope 2.9.6 ..."
cd $PKG
tar -zxf $ZOPE_TB
chmod -R 775 $ZOPE_DIR
cd $ZOPE_DIR
./configure --with-python=$PY --prefix=$PLONE_HOME
make
make install
cd $PKG
if [ -d $ZOPE_DIR ]
then
	rm -rf $ZOPE_DIR
fi


######################
# Postinstall steps
######################


##########################
# Generate random password
echo "Generating random password ..."
cd $PKG
tar -zxf $HSCRIPTS_TB
chmod -R 775 $HSCRIPTS_DIR
cd $HSCRIPTS_DIR
PASSWORD_SCRIPT=./generateRandomPassword.py
PASSWORD=`$PY $PASSWORD_SCRIPT`
cd $PKG


####################
# Create ZEO Cluster
echo "Creating Zope Enterprise Cluster ..."
chmod -R 775 $PLONE_HOME/bin
echo "Creating ZEO server on port 8100 ..."
$PLONE_HOME/bin/mkzeoinstance.py $ZEOSERVER_HOME 8100
echo "Creating ZEO client1 ..."
$PLONE_HOME/bin/mkzopeinstance.py --dir=$ZEOCLIENT1_HOME --user=admin:$PASSWORD
echo "Creating ZEO client2 ..."
$PLONE_HOME/bin/mkzopeinstance.py --dir=$ZEOCLIENT2_HOME --user=admin:$PASSWORD


#########################################
# Configure ZEO clients to use ZEO server
# Configure client1 to connect to server
mv $ZEOCLIENT1_HOME/etc/zope.conf $ZEOCLIENT1_HOME/etc/zope.conf.tmp
cat $ZEOCLIENT1_HOME/etc/zope.conf.tmp | sed 's/^.*<filestorage>.*$/  <zeoclient>\
    server localhost:8100\
    storage 1\
    name zeostorage\
    var \$INSTANCE\/var/g; s/^.*<\/filestorage>.*$/  <\/zeoclient>/g; s/^.*path.*\$INSTANCE\/var\/Data.fs.*$//g' > $ZEOCLIENT1_HOME/etc/zope.conf
rm $ZEOCLIENT1_HOME/etc/zope.conf.tmp

# Configure client2 to connect to server
mv $ZEOCLIENT2_HOME/etc/zope.conf $ZEOCLIENT2_HOME/etc/zope.conf.tmp
cat $ZEOCLIENT2_HOME/etc/zope.conf.tmp | sed 's/^.*<filestorage>.*$/  <zeoclient>\
    server localhost:8100\
    storage 1\
    name zeostorage\
    var \$INSTANCE\/var/g; s/^.*<\/filestorage>.*$/  <\/zeoclient>/g; s/^.*path.*\$INSTANCE\/var\/Data.fs.*$//g' > $ZEOCLIENT2_HOME/etc/zope.conf
rm $ZEOCLIENT2_HOME/etc/zope.conf.tmp


#####################################
# Set effective-user in etc/zope.conf
# set user in ZEO server
mv $ZEOSERVER_HOME/etc/zeo.conf $ZEOSERVER_HOME/etc/zeo.conf.tmp
cat $ZEOSERVER_HOME/etc/zeo.conf.tmp | sed 's/^.*#.*user.*$/  user plone/g' > $ZEOSERVER_HOME/etc/zeo.conf 
rm $ZEOSERVER_HOME/etc/zeo.conf.tmp

# set user in ZEO client1
mv $ZEOCLIENT1_HOME/etc/zope.conf $ZEOCLIENT1_HOME/etc/zope.conf.tmp
cat $ZEOCLIENT1_HOME/etc/zope.conf.tmp | sed 's/^.*#.*effective-user.*chrism.*$/effective-user plone/g' > $ZEOCLIENT1_HOME/etc/zope.conf
rm $ZEOCLIENT1_HOME/etc/zope.conf.tmp

# set user in ZEO client2 (and change http port to 8081)
mv $ZEOCLIENT2_HOME/etc/zope.conf $ZEOCLIENT2_HOME/etc/zope.conf.tmp
cat $ZEOCLIENT2_HOME/etc/zope.conf.tmp | sed 's/^.*#.*effective-user.*chrism.*$/effective-user plone/g; s/^.*address.*8080.*$/  address 8081/g' > $ZEOCLIENT2_HOME/etc/zope.conf
rm $ZEOCLIENT2_HOME/etc/zope.conf.tmp


#########################################################
# Pre-initialize log file and set appropriate permissions
# (if unset, ZEO server refuses to start as an unprivileged user via 'zeoctl start')
touch $ZEOSERVER_HOME/log/zeo.log
chmod 775 $ZEOSERVER_HOME/log/zeo.log


###############################################################
# Extract and move Plone tarball to Products folder of Instance
echo "Extracting Plone tarball ..."
cp $PKG/$PLONE_TB $PLONE_HOME/$PLONE_TB
cd $PLONE_HOME
tar -zxf ./$PLONE_TB 
rm $PLONE_HOME/$PLONE_TB
mv $PLONE_HOME/$PLONE_DIR $PRODUCTS_HOME
chmod -R 775 $PRODUCTS_HOME
cd $PKG


###############################################
# Create common Products folder for ZEO cluster
echo "Configuring Products directory ..."
# remove Products directories to set up symlinks
if [ -e $ZEOCLIENT1_HOME/Products ]
then
    rm -rf $ZEOCLIENT1_HOME/Products
fi
if [ -e $ZEOCLIENT2_HOME/Products ]
then
    rm -rf $ZEOCLIENT2_HOME/Products
fi
# set up symlinks for shared Products folder
ln -s $PRODUCTS_HOME $ZEOCLIENT1_HOME/Products
ln -s $PRODUCTS_HOME $ZEOCLIENT2_HOME/Products


###############################################
# Move CacheFu products to appropriate location
echo "Moving CacheFu products to proper location ..."
mv $PRODUCTS_HOME/CacheFu/CacheSetup $PRODUCTS_HOME/CacheSetup
mv $PRODUCTS_HOME/CacheFu/CMFSquidTool $PRODUCTS_HOME/CMFSquidTool
mv $PRODUCTS_HOME/CacheFu/PageCacheManager $PRODUCTS_HOME/PageCacheManager
mv $PRODUCTS_HOME/CacheFu/PolicyHTTPCacheManager $PRODUCTS_HOME/PolicyHTTPCacheManager


######################
# Install TextIndexNG3
echo "Installing TextIndexNG3"
cp $PKG/$TXNG3_TB $PRODUCTS_HOME
cd $PRODUCTS_HOME
tar -zxf ./$TXNG3_TB
chmod -R 775 ./$TXNG3_DIR
rm $PRODUCTS_HOME/$TXNG3_TB
cd $PRODUCTS_HOME/$TXNG3_DIR/extension_modules
$PY ./setup.py install
cd $PKG


########################
# Write password to file
echo "Writing random password to file ..."
touch $PWFILE
# Write admin password and startup/shutdown info to password file
echo "Use the account information below to log into the Zope Management Interface" >> "$PWFILE"
echo "The account has full 'Manager' privileges." >> "$PWFILE"
echo " " >> "$PWFILE"
echo "  Username: admin" >> "$PWFILE"
echo "  Password: $PASSWORD" >> "$PWFILE"
echo " " >> "$PWFILE"
echo "Before you start Plone, you should review the settings in:" >> "$PWFILE"
echo " " >> "$PWFILE"
echo "  $ZEOSERVER_HOME/etc/zeo.conf" >> "$PWFILE"
echo " and" >> "$PWFILE"
echo "  $ZEOCLIENT1_HOME/etc/zope.conf" >> "$PWFILE"
echo " and" >> "$PWFILE"
echo "  $ZEOCLIENT2_HOME/etc/zope.conf" >> "$PWFILE"
echo " " >> "$PWFILE"
echo "Adjust the ports Plone uses before starting the site, if necessary" >> "$PWFILE"
echo " " >> "$PWFILE"
echo "To start Plone, issue the following command in a Terminal window:" >> "$PWFILE"
echo " " >> "$PWFILE"
echo "  sudo $ZEO_STARTUP_SCRIPT" >> "$PWFILE"
echo " " >> "$PWFILE"
echo "To stop Plone, issue the following command in a Terminal window:" >> "$PWFILE"
echo " " >> "$PWFILE"
echo "  sudo $ZEO_SHUTDOWN_SCRIPT" >> "$PWFILE"
echo " " >> "$PWFILE"


####################################################
# Write ZEO startup/shutdown/restart scripts to file
# Create bin folder in zeocluster
mkdir $ZEOCLUSTER_HOME/bin

# Write startup script
echo "Writing startup script to file ..."
touch $ZEO_STARTUP_SCRIPT
echo "#!/bin/sh" >> "$ZEO_STARTUP_SCRIPT"
echo "#" >> "$ZEO_STARTUP_SCRIPT"
echo "# ZEO cluster startup script" >> "$ZEO_STARTUP_SCRIPT"
echo "#" >> "$ZEO_STARTUP_SCRIPT"
echo "echo 'Starting ZEO server...'" >> "$ZEO_STARTUP_SCRIPT"
echo "$ZEOSERVER_HOME/bin/zeoctl start" >> "$ZEO_STARTUP_SCRIPT"
echo "sleep 1" >> "$ZEO_STARTUP_SCRIPT"
echo "echo 'Starting ZEO client1...'" >> "$ZEO_STARTUP_SCRIPT"
echo "$ZEOCLIENT1_HOME/bin/zopectl start" >> "$ZEO_STARTUP_SCRIPT"
echo "sleep 1" >> "$ZEO_STARTUP_SCRIPT"
echo "echo 'Starting ZEO client2...'" >> "$ZEO_STARTUP_SCRIPT"
echo "$ZEOCLIENT2_HOME/bin/zopectl start" >> "$ZEO_STARTUP_SCRIPT"

# Write shutdown script
echo "Writing shutdown script to file ..."
touch $ZEO_SHUTDOWN_SCRIPT
echo "#!/bin/sh" >> "$ZEO_SHUTDOWN_SCRIPT"
echo "#" >> "$ZEO_SHUTDOWN_SCRIPT"
echo "# ZEO cluster shutdown script" >> "$ZEO_SHUTDOWN_SCRIPT"
echo "#" >> "$ZEO_SHUTDOWN_SCRIPT"
echo "echo 'Stopping ZEO server...'" >> "$ZEO_SHUTDOWN_SCRIPT"
echo "$ZEOSERVER_HOME/bin/zeoctl stop" >> "$ZEO_SHUTDOWN_SCRIPT"
echo "sleep 1" >> "$ZEO_SHUTDOWN_SCRIPT"
echo "echo 'Stopping ZEO client1...'" >> "$ZEO_SHUTDOWN_SCRIPT"
echo "$ZEOCLIENT1_HOME/bin/zopectl stop" >> "$ZEO_SHUTDOWN_SCRIPT"
echo "sleep 1" >> "$ZEO_SHUTDOWN_SCRIPT"
echo "echo 'Stopping ZEO client2...'" >> "$ZEO_SHUTDOWN_SCRIPT"
echo "$ZEOCLIENT2_HOME/bin/zopectl stop" >> "$ZEO_SHUTDOWN_SCRIPT"

# Write restart script
echo "Writing restart script to file ..."
touch $ZEO_RESTART_SCRIPT
echo "#!/bin/sh" >> "$ZEO_RESTART_SCRIPT"
echo "#" >> "$ZEO_RESTART_SCRIPT"
echo "# ZEO cluster restart script" >> "$ZEO_RESTART_SCRIPT"
echo "#" >> "$ZEO_RESTART_SCRIPT"
echo "echo 'Restarting ZEO server...'" >> "$ZEO_RESTART_SCRIPT"
echo "$ZEOSERVER_HOME/bin/zeoctl restart" >> "$ZEO_RESTART_SCRIPT"
echo "sleep 1" >> "$ZEO_RESTART_SCRIPT"
echo "echo 'Restarting ZEO client1...'" >> "$ZEO_RESTART_SCRIPT"
echo "$ZEOCLIENT1_HOME/bin/zopectl restart" >> "$ZEO_RESTART_SCRIPT"
echo "sleep 1" >> "$ZEO_RESTART_SCRIPT"
echo "echo 'Restarting ZEO client2...'" >> "$ZEO_RESTART_SCRIPT"
echo "$ZEOCLIENT2_HOME/bin/zopectl restart" >> "$ZEO_RESTART_SCRIPT"


#########################################################
# Fix path for Zope command line utils (repozo.py et.al.)
echo "Writing restart script to file ..."
echo "$PLONE_HOME/lib/python" > "$SITE_PACKAGES/zope.pth"


#####################################
# Clean up any .DS_Store files (OS X)
find $PLONE_HOME -name '.DS_Store' -delete


################################################
# Add user account via platform-specific methods
echo "Adding user account 'plone' to system ..."
# Add unprivileged user account via 'useradd', if exists (Linux)
if [ -e /usr/sbin/useradd ]
then
	/usr/sbin/useradd plone
# Add unprivileged user account via 'adduser', if exists (*BSD)
elif [ -e /usr/sbin/adduser ]
then
	/usr/sbin/adduser -f $PKG/$HSCRIPTS_DIR/adduser.txt
fi

# Add plone user to NetInfo if we're on Mac OS X
if [ -e /usr/bin/niutil ]
then
	niutil -readprop -t localhost/local /users/plone uid
	if [ "$?" != "0" ]
	then
		# Add plone user to NetInfo, with a uid below 500
		echo Creating plone user
		uiddef="50"
		niutil -readprop -t localhost/local /users/uid=$uiddef name
		while [ "$?" = "0" ]
		do
			if [ "$uiddef" = "500" ]
			then
				echo Failed to find available uid below 500.  Exiting.
				exit 1
			else
				uiddef=`echo $uiddef + 1 | bc`
				niutil -readprop -t localhost/local /users/uid=$uiddef name
			fi
		done
		#
		echo Creating user plone with uid $uiddef...
		niutil -create  -t localhost/local /users/plone
		if [ "$?" = "0" ]
		then
			niutil -createprop -t localhost/local /users/plone realname "Plone Administration"
			niutil -createprop -t localhost/local /users/plone uid $uiddef
			niutil -createprop -t localhost/local /users/plone gid 20
			niutil -createprop -t localhost/local /users/plone home "$PLONE_HOME"
			niutil -createprop -t localhost/local /users/plone name plone
			niutil -createprop -t localhost/local /users/plone passwd '*'
			niutil -createprop -t localhost/local /users/plone shell /bin/tcsh
			niutil -createprop -t localhost/local /users/plone _writers_passwd plone
		else
			echo "Creating user plone failed"
			exit 1
		fi
	fi
fi


###########################################
# Clean up helper scripts directory
cd $PKG
if [ -d $HSCRIPTS_DIR ]
then
    rm -rf $HSCRIPTS_DIR
fi


###########################################
# Set appropriate ownership and permissions
echo "Setting appropriate file ownership and permissions ..."
chmod -R 775 $PLONE_HOME
chown -R plone $PLONE_HOME
chmod 660 "$PWFILE"


#######################
# Conclude installation
if [ -d $PLONE_HOME ]
    then
    mkdir $RECEIPTS_HOME
    echo "Plone 2.5.2 install completed on" `date` > $RECEIPTS_HOME/installReceipt-2.5.2.txt
    echo " "
    echo "#####################################################################"
    echo "######################  Installation Complete  ######################"
    echo " "
    cat $PLONE_HOME/adminPassword.txt
    echo " "
    echo "Plone successfully installed at $PLONE_HOME"
    echo "See $PLONE_HOME/adminPassword.txt for password and startup instructions"
    echo " "
    echo "Submit feedback and report errors at http://dev.plone.org/plone"
    echo " "
    echo "This installer is maintained by Kamal Gill (kamalgill at mac.com)"
    echo " "
else
    echo "There were errors during the install.  Please read readme.txt and try again."
    echo "To report errors with the installer, visit http://dev.plone.org/plone"
fi
