#!/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. |