#!/bin/bash
#
# Change the first three variables below to match the volume names on the machine
# you are configuring the SDP on. 
# Set the remaining variables appropriately. The meaning of each should be obvious.
#
# In the SDP variable below, the sdp directory needs to contain the contents of:
# //guest/perforce_software/sdp/main/...
#
# Run this script as root, and pass in the name of the config file copied from template.mkdirs.cfg.
# If you do not have root access, then some commands will be skipped, and you will
# need to have the defined $P4DIR directory already existing (created
# by the root user and the ownership changed to the OS user that you are planning
# to run Perforce under). The Metadata, Depots and Logs volumes will also need
# to be owned by the OS user as well in order for the script to work. You can then
# run this script as the OS user for Perforce and everything should work fine.
#
# This script creates an init script in the $P4DIR/$SDP_INSTANCE/bin directory. You
# can use it from there if you are configuring a cluster, or you can link it in
# /etc/init.d if you are setting up a stand alone machine.  Sample systemd service
# files are included.
#
# After running this script, you also need to set up the crontab based on files
# in $P4DIR/common/etc/cron.d.  For convenience, crontab files are copied to 
# $P4DIR/p4.crontab.new which you need to copy over to p4.crontab and then run'
# crontab p4.crontab
#
# Now, put the license file in place and launch the server with the init script.
#
# Then run $P4DIR/common/bin/p4master_run <instance> $P4DIR/common/bin/live_checkpoint.sh
# and then run both the daily_checkpoint.sh and recreate_db_checkpoint.sh to
# make sure everything is working before setting up the crontab.
#
# Also run $P4DIR/common/bin/p4master_run <instance> $P4DIR/common/bin/p4review.py <instance>
# to make sure the review script is working properly.  If you intend to use Swarm,
# you can skip configuration of the review daemon, and instead configure Swarm to
# handle review-style email notifications.
#
# UPGRADING SDP
# Specify the -test parameter to the script.
# In this case the script will NOT make the various directories under $P4DIR, but will instead
# create /tmp/p4 directory structure with the various files processed via templates etc.
# You can then manually compare this directory structure with your existing $P4DIR structure
# and manually copy the various files into it.
#

set -u

bail() {
   declare msg=$1
   echo -e "$msg\n\n" >&2
   exit 1
}

if [ $# -lt 1 ] || [ $# -gt 2 ]; then
   echo "Usage: $0 <name_of_config_file> [-test]"
   exit 1
fi

# Note that if the following is set to 1 then a trial run is done, into /tmp/p4
TEST=0
if [[ $# -gt 1 ]] && [[ "$2" = "-test" ]]; then
   TEST=1
fi

# The config file is passed in as the first variable to this script.
mkdirs_config=$1
source $mkdirs_config || bail "Error: failed to source $mkdirs_config"

P4DIR=/p4
P4SERVER=p4_$SDP_INSTANCE

export AWK=awk
export ID=id
export MAIL=mail

if [[ `$ID -u` -eq 0 ]]; then
   echo "Verified: Running as root."
elif [[ `whoami` == $OSUSER ]]; then
   echo -e "\nWarning:  Not running as root; chown commands will be skipped and basic directories should exist.\n"
else
   echo -e "\nError: $0 must be run as as root or $OSUSER.\n"
   exit 1
fi

if [[ $TEST -eq 1 ]]; then
  DD=tmp
  MD=tmp
  LG=tmp
  CN=tmp
  P4DIR=/tmp/p4
  echo -e "\n*********  -test specified - will install to $DD/p4  *********\n"
fi

SDP_COMMON=$SDP/Server/Unix/p4/common

[[ -f $SDP_COMMON/bin/p4 ]] || { echo "No p4 in $SDP_COMMON/bin" ; exit 1 ;}
[[ -f $SDP_COMMON/bin/p4d ]] || { echo "No p4d in $SDP_COMMON/bin" ; exit 1 ;}

chmod 755 $SDP_COMMON/bin/p4
chmod 700 $SDP_COMMON/bin/p4d

[[ -f $SDP_COMMON/bin/p4broker ]] && chmod 700 $SDP_COMMON/bin/p4broker
[[ -f $SDP_COMMON/bin/p4p ]] && chmod 700 $SDP_COMMON/bin/p4p

# Make sure you update the p4 and p4d versions in the sdp/Server/Unix/p4/common/bin directory when making
# new instances at a later date.

P4RELNUM=`$SDP_COMMON/bin/p4 -V | grep -i Rev. | $AWK -F / '{print $3}'`
P4BLDNUM=`$SDP_COMMON/bin/p4 -V | grep -i Rev. | $AWK -F / '{print $4}' | $AWK '{print $1}'`
P4DRELNUM=`$SDP_COMMON/bin/p4d -V | grep -i Rev. | $AWK -F / '{print $3}'`
P4DBLDNUM=`$SDP_COMMON/bin/p4d -V | grep -i Rev. | $AWK -F / '{print $4}' | $AWK '{print $1}'`

[[ -d $P4DIR ]] || mkdir $P4DIR

[[ -d /$DD/p4 ]] || mkdir /$DD/p4
[[ -d /$DB1/p4 ]] || mkdir /$DB1/p4
[[ -d /$DB2/p4 ]] || mkdir /$DB2/p4
[[ -d /$LG/p4 ]] || mkdir /$LG/p4

mkdir -p /$LG/p4/$SDP_INSTANCE/bin
mkdir -p /$DD/p4/$SDP_INSTANCE/tmp
mkdir -p /$DD/p4/$SDP_INSTANCE/depots

CKPDIR=checkpoints.${MASTER_ID}

mkdir -p /$CKP/p4/$SDP_INSTANCE/${CKPDIR}

[[ -d $P4DIR/ssl ]] || mkdir -p $P4DIR/ssl
[[ -d $P4DIR/$SDP_INSTANCE ]] || mkdir -p $P4DIR/$SDP_INSTANCE
[[ -f $SDP/Server/Unix/p4/ssl/config.txt ]] && cp $SDP/Server/Unix/p4/ssl/config.txt $P4DIR/ssl/
[[ -d /$CN/p4/common/bin ]] || mkdir -p /$CN/p4/common/bin
[[ -d /$CN/p4/common/config ]] || mkdir -p /$CN/p4/common/config

mkdir -p /$DB1/p4/$SDP_INSTANCE/db1/save
mkdir -p /$DB2/p4/$SDP_INSTANCE/db2/save
mkdir -p /$LG/p4/$SDP_INSTANCE/journals.rep
mkdir -p /$LG/p4/$SDP_INSTANCE/journals.rotated
mkdir -p /$LG/p4/$SDP_INSTANCE/logs

cd /$P4DIR/$SDP_INSTANCE

if [[ $TEST -eq 0 ]]; then
    [[ -L bin ]] || ln -s /$LG/p4/$SDP_INSTANCE/bin
    [[ -L journals.rep ]] || ln -s /$LG/p4/$SDP_INSTANCE/journals.rep
    [[ -L logs ]] || ln -s /$LG/p4/$SDP_INSTANCE/logs
    [[ -L checkpoints ]] || ln -s /$CKP/p4/$SDP_INSTANCE/${CKPDIR} checkpoints
    [[ -L journals.rotated ]] || ln -s /$LG/p4/$SDP_INSTANCE/journals.rotated
    [[ -L depots ]] || ln -s /$DD/p4/$SDP_INSTANCE/depots
    [[ -L tmp ]] || ln -s /$DD/p4/$SDP_INSTANCE/tmp
    [[ -L root ]] || ln -s /$DB1/p4/$SDP_INSTANCE/db1 root
    [[ -L offline_db ]] || ln -s /$DB2/p4/$SDP_INSTANCE/db2 offline_db
    cd $P4DIR
    unlink sdp >> /dev/null 2>&1
    ln -s $SDP $P4DIR/sdp
    [[ -L common ]] || ln -s /$CN/p4/common
fi

case "$SERVER_TYPE" in
    (p4d_master|p4d_edge) SERVERID=$MASTER_ID;;
    (*) SERVERID=$REPLICA_ID;;
esac
echo $SERVERID > $P4DIR/$SDP_INSTANCE/root/server.id
echo $SERVER_TYPE > $P4DIR/$SDP_INSTANCE/root/sdp_server_type.txt

cp -fR $SDP_COMMON/bin/* /$CN/p4/common/bin

cd /p4/$SDP_INSTANCE/bin
rm -f p4d_${SDP_INSTANCE} > /dev/null 2>&1
rm -f p4_${SDP_INSTANCE}  > /dev/null 2>&1
rm -f p4d_${SDP_INSTANCE}_bin  > /dev/null 2>&1
rm -f p4*_20* > /dev/null 2>&1
[[ -f /p4/$SDP_INSTANCE/bin/p4_$P4RELNUM.$P4BLDNUM ]] || cp $SDP_COMMON/bin/p4 /p4/$SDP_INSTANCE/bin/p4_$P4RELNUM.$P4BLDNUM
[[ -f /p4/$SDP_INSTANCE/bin/p4d_$P4DRELNUM.$P4DBLDNUM ]] || cp $SDP_COMMON/bin/p4d /p4/$SDP_INSTANCE/bin/p4d_$P4DRELNUM.$P4DBLDNUM
ln -s p4_$P4RELNUM.$P4BLDNUM p4_${SDP_INSTANCE}
ln -s p4d_$P4DRELNUM.$P4DBLDNUM p4d_${SDP_INSTANCE}_bin

if [[ $CASE_SENSITIVE -eq 1 ]]; then
  ln -s /p4/${SDP_INSTANCE}/bin/p4d_${SDP_INSTANCE}_bin p4d_$SDP_INSTANCE
else
  echo '#!/bin/bash' > p4d_$SDP_INSTANCE
  echo P4D=/p4/${SDP_INSTANCE}/bin/p4d_${SDP_INSTANCE}_bin >> p4d_$SDP_INSTANCE
  echo 'exec $P4D -C1 "$@"' >> p4d_$SDP_INSTANCE
  chmod +x p4d_$SDP_INSTANCE
fi

echo $P4ADMINPASS > /$CN/p4/common/config/.p4passwd.${P4SERVER}.admin

# Create broker links if broker exists
if [[ -f $SDP_COMMON/bin/p4broker ]]; then 
  P4BRELNUM=`$SDP_COMMON/bin/p4broker -V | grep -i Rev. | $AWK -F / '{print $3}'`
  P4BBLDNUM=`$SDP_COMMON/bin/p4broker -V | grep -i Rev. | $AWK -F / '{print $4}' | $AWK '{print $1}'`
  cp $SDP_COMMON/bin/p4broker /p4/${SDP_INSTANCE}/bin/p4broker_$P4BRELNUM.$P4BBLDNUM
  [[ -L p4broker_${SDP_INSTANCE} ]] && unlink p4broker_${SDP_INSTANCE} 
  ln -s p4broker_$P4BRELNUM.$P4BBLDNUM p4broker_${SDP_INSTANCE} 
  sed "s/REPL_SDP_INSTANCE/${SDP_INSTANCE}/g" $SDP_COMMON/etc/init.d/p4broker_instance_init.template > p4broker_${SDP_INSTANCE}_init
  chmod +x p4broker_${SDP_INSTANCE}_init
fi

# Create p4p links if p4p exists
if [[ -x $SDP_COMMON/bin/p4p ]]; then 
  P4PRELNUM=`$SDP_COMMON/bin/p4p -V | grep -i Rev. | $AWK -F / '{print $3}'`
  P4PBLDNUM=`$SDP_COMMON/bin/p4p -V | grep -i Rev. | $AWK -F / '{print $4}' | $AWK '{print $1}'`
  cp $SDP_COMMON/bin/p4p /p4/${SDP_INSTANCE}/bin/p4p_$P4PRELNUM.$P4PBLDNUM
  [[ -L p4p_${SDP_INSTANCE} ]] && unlink p4p_${SDP_INSTANCE} 
  ln -s p4p_$P4PRELNUM.$P4PBLDNUM p4p_${SDP_INSTANCE}
  sed -e "s/REPL_SDP_INSTANCE/${SDP_INSTANCE}/g" \
    -e "s/REPL_DNSNAME/${P4DNSNAME}/g" \
    $SDP_COMMON/etc/init.d/p4p_instance_init.template > p4p_${SDP_INSTANCE}_init
  chmod +x p4p_${SDP_INSTANCE}_init
  mkdir -p /$DD/p4/$SDP_INSTANCE/cache
fi

sed "s/REPL_SDP_INSTANCE/${SDP_INSTANCE}/g" \
  $SDP_COMMON/etc/init.d/p4d_instance_init.template > p4d_${SDP_INSTANCE}_init
chmod +x p4d_${SDP_INSTANCE}_init

# Moved the less commonly used, but always created init scripts to an init directory.
[[ -d init ]] || mkdir init
cd init

sed "s/REPL_SDP_INSTANCE/${SDP_INSTANCE}/g" \
  $SDP_COMMON/etc/init.d/p4dtg_instance_init.template > p4dtg_${SDP_INSTANCE}_init
chmod +x p4dtg_${SDP_INSTANCE}_init

cd $P4DIR/common/config

sed -e "s/REPL_MASTER_ID/${MASTER_ID}/g" \
  -e "s/REPL_OSUSER/${OSUSER}/g" \
  -e "s/REPL_ADMINUSER/${ADMINUSER}/g" \
  -e "s/REPL_SSLPREFIX/${SSL_PREFIX}/g" \
  -e "s/REPL_P4PORT/${P4_PORT}/g" \
  -e "s/REPL_SHAREDDATA/${SHAREDDATA}/g" \
  -e "s/REPL_P4BROKERPORT/${P4BROKER_PORT}/g" \
  -e "s/REPL_SSLPREFIX/${SSL_PREFIX}/g" \
  -e "s/REPL_P4BROKERPORT/${P4BROKER_PORT}/g" \
  -e "s/REPL_DNSNAME/${P4DNSNAME}/g" \
  $SDP_COMMON/config/serverid.vars.template > $SERVERID.vars

sed -e "s/REPL_MAILTO/${MAILTO}/g" \
  -e "s/REPL_MAILFROM/${MAILFROM}/g" \
  -e "s/REPL_COMMIT/${P4COMMITSERVER}/g" \
  $SDP_COMMON/config/instance_vars.template > p4_${SDP_INSTANCE}.vars

sed -e "s/REPL_ADMINISTRATOR/${MAILTO}/g" \
  -e "s/REPL_COMPLAINFROM/${COMPLAINFROM}/g" \
  -e "s/REPL_MAILHOST/${MAILHOST}/g" \
  -e "s/REPL_DNSNAME/${P4DNSNAME}/g" \
  $SDP_COMMON/config/p4review.cfg.template > p4_${SDP_INSTANCE}.p4review.cfg

cd $P4DIR/sdp/Maintenance

sed -e "s/REPL_ADMINISTRATOR/${MAILTO}/g" \
  -e "s/REPL_COMPLAINFROM/${COMPLAINFROM}/g" \
  -e "s/REPL_MAILHOST/${MAILHOST}/g" \
  -e "s/REPL_DOMAIN/${DOMAIN}/g" \
  template.maintenance.cfg > maintenance.cfg

cd $P4DIR
rm -f ${P4DIR}/p4.crontab.new > /dev/null 2>&1
CRONTAB_NAME=p4.crontab.new

sed -e "s/REPL_MAILTO/${MAILTO}/g" \
    -e "s/REPL_MAILFROM/${MAILFROM}/g" \
    -e "s/REPL_INSTANCE/${SDP_INSTANCE}/g" \
    $SDP_COMMON/etc/cron.d/template.crontab > ${CRONTAB_NAME} 

sed -e "s/REPL_MAILTO/${MAILTO}/g" \
    -e "s/REPL_MAILFROM/${MAILFROM}/g" \
    -e "s/REPL_INSTANCE/${SDP_INSTANCE}/g" \
    $SDP_COMMON/etc/cron.d/proxy.crontab > proxy.crontab 

cd $P4DIR/${SDP_INSTANCE}/bin

if [[ `$ID -u` -eq 0 ]]; then
   if [[ $TEST -eq 0 ]]; then
      chown $OSUSER:$OSGROUP /$DD
      chown $OSUSER:$OSGROUP /$LG
      chown $OSUSER:$OSGROUP /$DB1
      chown $OSUSER:$OSGROUP /$DB2
   fi
   chown $OSUSER:$OSGROUP /$DD/p4
   chown $OSUSER:$OSGROUP /$LG/p4
   chown $OSUSER:$OSGROUP /$DB1/p4
   chown $OSUSER:$OSGROUP /$DB2/p4
  
   chown -h $OSUSER:$OSGROUP $P4DIR
   chown -h $OSUSER:$OSGROUP $P4DIR/$SDP_INSTANCE
   chown -h $OSUSER:$OSGROUP $P4DIR/$SDP_INSTANCE/*
   chown -h $OSUSER:$OSGROUP $P4DIR/common
   chown -h $OSUSER:$OSGROUP $P4DIR/sdp
   chown $OSUSER:$OSGROUP $P4DIR/*
   chown $OSUSER:$OSGROUP $P4DIR/ssl/*
   chown -h $OSUSER:$OSGROUP /$DD/p4/$SDP_INSTANCE
   chown -h $OSUSER:$OSGROUP /$DD/p4/$SDP_INSTANCE/*

   chown -Rh $OSUSER:$OSGROUP $P4DIR/common
   chown -Rh $OSUSER:$OSGROUP $SDP
   chown -Rh $OSUSER:$OSGROUP /$CN/p4/common
   chown -Rh $OSUSER:$OSGROUP /$DB1/p4/$SDP_INSTANCE/db*
   chown -Rh $OSUSER:$OSGROUP /$DB2/p4/$SDP_INSTANCE/db*
   chown -Rh $OSUSER:$OSGROUP /$LG/p4/$SDP_INSTANCE
   chown -Rh $OSUSER:$OSGROUP /$CKP/p4/$SDP_INSTANCE/${CKPDIR}

   owner=$(ls -l /p4/1/depots | awk '{print $3}')
   if [[ "$owner" != "$OSUSER" ]]; then
     if [[ "$SHAREDDATA" == "FALSE" || "$SERVER_TYPE" == p4d_master ]]; then
        echo "Setting ownership on depot files - this may take some time ..."
        chown -Rh $OSUSER:$OSGROUP /$DD/p4/$SDP_INSTANCE/depots
        echo "Setting permissions on depot files - this may take some time ..."
        chmod -R 700 /$DD/p4/$SDP_INSTANCE/depots
     fi
   fi
   chmod -R 700 /$DB1/p4/$SDP_INSTANCE/db*
   chmod -R 700 /$DB2/p4/$SDP_INSTANCE/db*
else
   echo "Not running as root, so chown commands and some chmod commands were skipped."
fi

chmod 700 /$DB1/p4
chmod 700 /$DB2/p4
chmod 700 /$DD/p4
chmod 700 /$LG/p4

chmod -R 700 /$CN/p4/common
chmod -R 700 /$LG/p4/$SDP_INSTANCE
chmod 700 /$DD/p4/$SDP_INSTANCE
chmod 700 /$CKP/p4/$SDP_INSTANCE/${CKPDIR}
chmod 700 /$DD/p4/$SDP_INSTANCE/tmp

if [[ $SDP_INSTANCE != $MASTERINSTANCE ]]; then
  if [[ -f $P4DIR/$MASTERINSTANCE/root/license ]]; then
    ln -s $P4DIR/$MASTERINSTANCE/root/license $P4DIR/$SDP_INSTANCE/root/license
    chown -h $OSUSER:$OSGROUP $P4DIR/$SDP_INSTANCE/root/license
  fi
fi

chmod 755 $P4DIR/${SDP_INSTANCE}/bin/*_init
chmod 755 $P4DIR/${SDP_INSTANCE}/bin/init/*_init
chmod 600 /$CN/p4/common/config/.p4passwd.${P4SERVER}.admin
[[ -e /$CN/p4/common/bin/*.cfg ]] && chmod 600 /$CN/p4/common/bin/*.cfg
[[ -e /$CN/p4/common/bin/*.html ]] && chmod 600 /$CN/p4/common/bin/*.html
chmod 700 $P4DIR/ssl
[[ -e $P4DIR/ssl/* ]] && chmod 600 $P4DIR/ssl/*

if [[ $TEST -eq 1 ]]; then
  echo ""
  echo "This was done in TEST mode - please run the following command to see any changes should be"
  echo "applied to your live environment (manually):"
  echo ""
  echo "  diff -r /p4/$SDP_INSTANCE/bin $P4DIR/$SDP_INSTANCE/bin"
  echo "  diff -r /p4/common $P4DIR/common"
  echo ""
  echo "If upgrading an older SDP version then be careful to ensure files in /p4/common/config are correct"
  echo "and update that /p4/common/bin/p4_vars is appropriate."
  echo ""
fi

exit 0

