#!/bin/bash
#------------------------------------------------------------------------------
set -u
function msg () { echo -e "$*"; }
function errmsg () { msg "\\nError: ${1:-Unknown Error}\\n"; ErrorCount+=1; }
function warnmsg () { msg "\\nWarning: ${1:-Unknown Warning}\\n"; WarningCount+=1; }
function bail () { errmsg "${1:-Unknown Error}"; exit "${2:-1}"; }
declare Version="1.0.6"
declare ThisScript="${0##*/}"
declare ThisHost="${HOSTNAME%%.*}"
declare SDPInstance=1
declare SDPEnvFile="/p4/common/bin/p4_vars"
declare P4BrokerCfg=
declare P4DInitScript="/p4/${SDP_INSTANCE}/bin/p4d_${SDP_INSTANCE}_init"
declare P4DSystemdServiceFile="/etc/systemd/system/p4d_${SDP_INSTANCE}.service"
declare P4BrokerInitScript="/p4/${SDP_INSTANCE}/bin/p4broker_${SDP_INSTANCE}_init"
declare P4BrokerSystemdServiceFile="/etc/systemd/system/p4broker_${SDP_INSTANCE}.service"
declare DoPreflightOnly=0
declare -i PreflightCheckCount=0
declare -i ErrorCount=0
declare -i WarningCount=0
declare H1="\\n=============================================================================="
declare H2="\\n------------------------------------------------------------------------------"
#==============================================================================
# Local Functions
#------------------------------------------------------------------------------
# Function: usage (required function)
#
# Input:
# $1 - style, either -h (for short form) or -man (for man-page like format).
# The default is -h.
#
# $2 - error message (optional). Specify this if usage() is called due to
# user error, in which case the given message displayed first, followed by the
# standard usage message (short or long depending on $1). If displaying an
# errror, usually $1 should be -h so that the longer usage message doesn't
# obsure the error message.
#
# Sample Usage:
# usage
# usage -h
# usage -man
# usage -h "Incorrect command line usage."
#------------------------------------------------------------------------------
function usage
{
declare style=${1:--h}
declare errorMessage=${2:-Unset}
if [[ $errorMessage != Unset ]]; then
echo -e "\n\nUsage Error:\n\n$errorMessage\n\n"
fi
echo -e "USAGE for $ThisScript v$Version:
$ThisScript [-i <sdp_instance>] [-n] [-D]
or
$ThisScript [-h|-man|-V]
"
if [[ $style == -man ]]; then
echo -e "
DESCRIPTION:
This script install Component Based Development (CBD) scripts
on top of an existing SDP installation.
The CBD mechanism requires SDP Standard Perl and Python to be
installed. Preflight checks ensure they are installed.
Once preflight checks pass, the following steps are done:
Step 0: Do Preflight Checks.
Step 1: Add CBD_HOME to p4_vars.
Step 2: Install SDP SetWsOpts triggers.
Step 3: Install CBD SSTemplateUpdate trigger.
Step 4: Configure CBD Broker.
Step 5: Install CBD files.
Step 6: Cycle p4d and p4broker processes.
This script is safe to run multiple times. Before performing
each of the above steps, it first checks to be sure it is
necessary, and only changes the existing configuration if
necessary.
OPTIONS:
-i <instance>
Specify the SDP instance. The default is 1.
The shell environment is established using standard SDP mechansim
for setting shell environment, i.e. by doing something like:
source $SDPEnvFile 1
-D Set extreme debugging verbosity.
HELP OPTIONS:
-h Display short help message
-man Display man-style help message
-V Dispay version info for this script and its libraries.
PREP AND SETUP:
1. If on SuSE Linux, SuSE-specific Helix Installer workarounds must
done first, as root, to ensure the 'perforce' user also has the
'perforce' group:
groupadd perforce
useradd -g perforce perforce
mkdir /home/perforce
chown perforce:perforce /home/perforce
2. Run the Helix Installer, as per: https://swarm.workshop.perforce.com/projects/perforce_software-helix-installer
(but make adjustments per above).
3. Get sdp_reader ticket into /p4/1/.p4tickets.
As root, after running the Helix Installer, do:
cp ~root/.p4tickets /tmp/.p4tickets.root
chmod 777 /tmp/.p4tickets.root
As perforce, do: modify /p4/1/.p4tickets, and append
contents of /tmp/.p4tickets to the end of /p4/1/.p4tickets
4. Get CBD, as perforce:
mkdir /hxdepots/cbd
cd /hxdepots/cbd
export P4CONFIG=.p4config.cbd
p4 -u sdp_reader clone -p public.perforce.com:1666 -r perforce_software-cbd_dev
5. Run this script:
./install_cbd.sh 2>&1 | tee install_cbd.log
"
fi
exit 1
}
#==============================================================================
# Command Line Processing
declare -i shiftArgs=0
set +u
while [[ $# -gt 0 ]]; do
case $1 in
(-i) SDPInstance="$2"; shiftArgs+=1;;
(-p) DoPreflightOnly=1;;
(-h) usage -h;;
(-man) usage -man;;
(-V) msg "$ThisScript v$Version"; exit 1;;
(-D) set -x;; # Debug; use 'set -x' mode.
(*) usage -h "Unknown arg ($1).";;
esac
# Shift (modify $#) the appropriate number of times.
shift; while [[ $shiftArgs -gt 0 ]]; do
[[ $# -eq 0 ]] && usage -h "Incorrect number of arguments."
shiftArgs=$shiftArgs-1
shift
done
done
set -u
#==============================================================================
# Command Line Verification
#==============================================================================
# Main Program
msg "${H1}\\nStarted $ThisScript v$Version at $(date).\\nOverlaying CBD on SDP Instance $SDPInstance."
[[ -r "$SDPEnvFile" ]] || \
bail "Missing SDP Environment file: $SDPEnvFile\\nAborting."
msg "Loading SDP shell environment for instance $SDPInstance."
source "$SDPEnvFile" "$SDPInstance"
source "$P4CBIN/ps_functions.sh" ||\
bail "Failed to load $P4CBIN/ps_functions.sh."
#------------------------------------------------------------------------------
msg "${H2}\\nStep 0: Do Preflight Checks."
if [[ -x "/p4/common/perl/bin/perl" ]]; then
msg "Verified: SDP standard Perl exists."
PreflightCheckCount+=1
else
errmsg "Missing expected SDP standard Perl in /p4/common/perl."
fi
if [[ -x "/p4/common/python/bin/python3" ]]; then
msg "Verified: SDP standard Python exists."
PreflightCheckCount+=1
else
errmsg "Missing expected SDP standard Python in /p4/common/python."
fi
if [[ -x "$P4DInitScript" ]]; then
msg "Verified: P4D Init script exists and is executable."
PreflightCheckCount+=1
else
errmsg "P4D Init script is missing or not executable: $P4DInitScript"
fi
if [[ "$($P4BIN -ztag -F %serverVersion% -p $P4PORT info -s)" == "P4D/"* ]]; then
msg "Verified: p4d is running on P4PORT $P4PORT."
PreflightCheckCount+=1
else
errmsg "Could not verify p4d is available on P4PORT $P4PORT."
fi
if [[ "$($P4BIN -ztag -F %brokerVersion% -p $P4BROKERPORT info -s)" == "P4BROKER/"* ]]; then
msg "Verified: p4broker is running on P4PORT $P4BROKERPORT."
PreflightCheckCount+=1
else
errmsg "Could not verify p4broker is available on P4PORT $P4BROKERPORT."
fi
if [[ "$ErrorCount" -eq 0 ]]; then
msg "\\nAll $PreflightCheckCount preflight checks passsed."
else
bail "\\nAborting due to failures in preflight checks."
fi
if [[ "$DoPreflightOnly" -eq 1 ]]; then
msg "Would continue due to success of preflight checks, but stopping due to '-p'."
exit 0
fi
#------------------------------------------------------------------------------
msg "${H2}\\nStep 1: Add CBD_HOME to p4_vars."
if grep CBD_HOME "$SDPEnvFile" > /dev/null 2>&1; then
warnmsg "CBD_HOME defined in p4_vars. Skipping this step."
else
sed 's:export P4CBIN=/p4/common/bin:export P4CBIN=/p4/common/bin\nexport CBD_HOME=$P4CBIN/cbd:g' "${SDPEnvFile}" > "$P4TMP/${SDPEnvFile##*/}.new"
msg "Added CBD_HOME setting to p4_vars:"
diff "${SDPEnvFile}" "$P4TMP/${SDPEnvFile##*/}.new" &&\
bail "No diff detected; update of p4_vars failed. Aborting."
mv -f "$P4TMP/${SDPEnvFile##*/}.new" "${SDPEnvFile}" ||\
errmsg "Failed to replace SDP Environment file."
fi
#------------------------------------------------------------------------------
msg "${H2}\\nStep 2: Install SDP SetWsOpts triggers."
p4 triggers -o | grep -v '^#' | egrep -v '^$' > "$P4TMP/triggers.$$.txt"
if grep SetWsOpts "$P4TMP/triggers.$$.txt" > /dev/null 2>&1; then
warnmsg "Triggers table already references SetWsOpts trigger. Skipping this step."
else
echo -e "\\tSetWsOpts form-out client \"/p4/common/bin/triggers/SetWsOptions.py %formfile%\"" >> "$P4TMP/triggers.$$.txt"
p4 -s triggers -i < "$P4TMP/triggers.$$.txt" ||\
bail "Failed to update triggers table from this file: $P4TMP/triggers.$$.txt\\nAborting."
rm -f "$P4TMP/triggers.$$.txt"
fi
#------------------------------------------------------------------------------
msg "${H2}\\nStep 3: Install CBD SSTemplateUpdate trigger."
p4 triggers -o | grep -v '^#' | egrep -v '^$' > "$P4TMP/triggers.$$.txt"
if grep SSTemplateUpdate "$P4TMP/triggers.$$.txt" > /dev/null 2>&1; then
warnmsg "Triggers table already references SSTemplateUpdate trigger. Skipping this step."
else
echo -e "\\tSSTemplateUpdate change-content //....cbdsst \"/p4/common/bin/cbd/triggers/SSTemplateUpdate.py %changelist%\"" >> "$P4TMP/triggers.$$.txt"
p4 -s triggers -i < "$P4TMP/triggers.$$.txt" ||\
bail "Failed to update triggers table from this file: $P4TMP/triggers.$$.txt\\nAborting."
rm -f "$P4TMP/triggers.$$.txt"
fi
#------------------------------------------------------------------------------
msg "${H2}\\nStep 4: Configure CBD Broker."
P4BrokerCfg="$P4CCFG/$P4SERVER.broker.cfg"
if [[ -r "$P4CCFG/${P4SERVER}.broker.${ThisHost}.cfg" ]]; then
P4BrokerCfg="$P4CCFG/${P4SERVER}.broker.${ThisHost}.cfg"
else
P4BrokerCfg="$P4CCFG/${P4SERVER}.broker.cfg"
fi
if [[ ! -e "$P4BrokerCfg" ]]; then
msg "No broker config exists. Creating one."
$P4CBIN/gen_default_broker_cfg.sh $SDPInstance > $P4BrokerCfg ||\
bail "Failed to generate broker config."
fi
msg "Modifying broker config file: $P4BrokerCfg"
if grep wssync.sh "$P4BrokerCfg" > /dev/null 2>&1; then
warnmsg "Broker already configured for CBD. Skipping this step."
else
msg "Appending broker/p4broker.txt"
if [[ ! -w "$P4BrokerCfg" ]]; then
msg "Broker config not writable, doing chmod +w."
chmod +w $P4BrokerCfg ||\
errmsg "Failed to make broker congfig writable."
fi
cat broker/p4broker.txt >> $P4BrokerCfg ||\
bail "Failed to append CBD broker config to $P4BrokerCfg. Aborting."
fi
#------------------------------------------------------------------------------
msg "${H2}\\nStep 5: Install CBD files."
if [[ "$PWD" == "/p4/common/bin/cbd" ]]; then
warnmsg "Already in /p4/common/bin/dbd. Skipping this step."
else
msg "Updating files in /p4/common/bin/cbd from $PWD"
rsync -av --delete --exclude=.p4root --exclude=.p4config.cbd --exclude=.p4ignore --exclude=.*.swp $PWD/ /p4/common/bin/cbd ||\
errmsg "Updating /p4/common/bin/cbd via rsync failed."
fi
#------------------------------------------------------------------------------
msg "${H2}\\nStep 6: Cycle p4d and p4broker processes."
if [[ -x "$P4BrokerInitScript" && -r "$P4BrokerCfg" ]]; then
msg "Checking p4broker status."
$P4BrokerInitScript status
if [[ $? -eq 0 ]]; then
msg "Shutting down p4broker."
if [[ -r "$P4BrokerSystemdServiceFile" ]]; then
sudo systemctl stop ${P4BROKERBIN##*/} ||\
bail "Failed to execute: sudo systemctl stop ${P4BROKERBIN##*/}"
else
$P4BrokerInitScript stop
fi
else
msg "Verified: p4broker is down."
fi
fi
msg "Checking p4d status."
P4DPids=$(get_pids "$P4DBIN")
if [[ -n "$P4DPids" ]]; then
msg "Shutting down p4d."
if [[ -r "$P4DSystemdServiceFile" ]]; then
sudo systemctl stop ${P4DBIN##*/} ||\
bail "Failed to execute: sudo systemctl stop ${P4DBIN##*/}"
else
$P4DInitScript stop
fi
else
msg "Verified: No processes are running for: $P4DBIN"
fi
msg "Delaying briefly before server restart."
sleep 5
msg "Starting p4d."
if [[ -r "$P4DSystemdServiceFile" ]]; then
sudo systemctl start ${P4DBIN##*/} ||\
errmsg "Failed to execute: sudo systemctl start ${P4DBIN##*/}"
else
$P4DInitScript start
fi
if [[ -x "$P4BrokerInitScript" && -r "$P4BrokerCfg" ]]; then
if [[ -r "$P4BrokerSystemdServiceFile" ]]; then
msg "Starting broker."
sudo systemctl start ${P4BROKERBIN##*/} ||\
errmsg "Failed to execute: sudo systemctl start ${P4BROKERBIN##*/}"
else
msg "NOT stating broker. Start it manually when ready with:\n\t$P4BrokerInitScript start\n"
fi
fi
if [[ $ErrorCount -eq 0 ]]; then
msg "\\nAll processing completed successfully, with $WarningCount warnings.\\n"
else
msg "\\nProcessing completed, but with $ErrorCount errors and $WarningCount warnings. Scan above output carefully.\\n"
fi
msg "That took $(($SECONDS/3600)) hours $(($SECONDS%3600/60)) minutes $(($SECONDS%60)) seconds.\n"
# See the terminate() function, which is really where this script exits.
exit $ErrorCount
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #6 | 25197 | sdp_reader |
Enhanced to due the necessary cycling of p4d and p4broker processes needed after setting CBD_HOME. Added '-p' flag to do only preflight tests. |
||
| #5 | 25186 | sdp_reader |
Added SDP SetWsOpts trigger. Enhanced docs. |
||
| #4 | 25185 | sdp_reader |
Added logic to add CBD logic to broker config. Added essential broker config snippet file. |
||
| #3 | 25184 | sdp_reader | Added logic to install trigger. | ||
| #2 | 25183 | sdp_reader | Added logic to add CBD_HOME to p4_vars. | ||
| #1 | 25182 | sdp_reader |
Start of script to install CBD on SDP after running Helix Installer for a demo setup. |