#!/bin/bash
#==============================================================================
# Copyright and license info is available in the LICENSE file included with
# the Server Deployment Package (SDP), and also available online:
# https://swarm.workshop.perforce.com/projects/perforce-software-sdp/view/main/LICENSE
#------------------------------------------------------------------------------
# validate_sdp.sh
# Validates current SDP environment according to current version of SDP
#==============================================================================
# Declarations and Environment
export SDP_ENV=/p4/common/bin/p4_vars
export SDP_INSTANCE=${SDP_INSTANCE:-Unset}
export SDP_INSTANCE=${1:-$SDP_INSTANCE}
if [[ $SDP_INSTANCE == Undefined ]]; then
echo "Instance parameter not supplied."
echo "You must supply the Perforce instance as a parameter to this script."
exit 1
fi
declare StatusMessage="OK: All checks completed OK."
declare -i ExitCode=0
declare -i ShowLog=1
declare Log=Unset
declare Version=5.0.1
#==============================================================================
# Local Functions
# Micro-functions, one-liners used to avoid external dependencies.
function msg () { if [[ $Log != Unset ]]; then echo -e "$*" >> $Log; else echo -e "$*"; fi; }
function bail () { msg "\nError: ${1:-Unknown Error}"; exit ${2:-1}; }
function cmd ()
{
tmpf=/tmp/t_verify.$$
msg "$*" >> $Log
"$*" > $tmpf 2>&1
status=$?
rm -f $tmpf
return $status
}
#------------------------------------------------------------------------------
# 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 -man
# usage -h "Incorrect command line usage."
#
# This last example generates a usage error message followed by the short
# '-h' usage summary.
#------------------------------------------------------------------------------
function usage
{
declare style=${1:--h}
declare errorMessage=${2:-Unset}
if [[ $errorMessage != Unset ]]; then
echo -e "\n\nUsage Error:\n\n$errorMessage\n\n" >&2
fi
echo "USAGE for validate_sdp.sh v$Version:
validate_sdp.sh [<instance>]
or
validate_sdp.sh -h|-man
"
if [[ $style == -man ]]; then
echo -e "DESCRIPTION:
This script validates the current SDP setup for the specified instance.
Useful if you change anything, particularly after an upgrade.
OPTIONS:
<instance>
Specify the SDP instances. If not specified, the SDP_INSTANCE
environment variable is used instead. If the instance is not
defined by a parameter and SDP_INSTANCE is not defined,
exits immediately with an error message.
-L <log>
Specify the log file to use. The default is /p4/N/logs/validate_SDP.log
-D Set extreme debugging verbosity.
HELP OPTIONS:
-h Display short help message
-man Display man-style help message
EXAMPLES:
This script is typically called after SDP update with only the instance
paramter as an argument, e.g.:
validate_SDP.sh N
LOGGING:
This script generates no output by default. All (stdout and stderr) is
logged to /p4/N/logs/validate_SDP.log.
The exception is usage errors, which result an error being sent to
stderr followed usage info on stdout, followed by an immediate exit.
If the '-v' flag is used, the contents of the log are displayed to
stdout at the end of processing.
EXIT CODES:
An exit code of 0 indicates no errors were encounted attempting to
perform validations.
"
fi
exit 1
}
#==============================================================================
# Command Line Processing
declare -i shiftArgs=0
set +u
while [[ $# -gt 0 ]]; do
case $1 in
(-h) usage -h;;
(-man) usage -man;;
(-v) ShowLog=1;;
(-L) Log=$2; shiftArgs=1;;
(-D) set -x;; # Debug; use 'set -x' mode.
(-*) usage -h "Unknown command line option ($1).";;
(*) export SDP_INSTANCE=$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
[[ $SDP_INSTANCE == Unset ]] && \
bail "The \$SDP_INSTANCE setting is not defined. It must be defined by doing:\n\n\tsource /p4/common/bin/p4_vars <instance>\n\nor by passing in the instance name as a parameter to this script.\n"
checkfile () {
local file=$1
local err_msg=$2
msg "Checking existence of file $file"
[[ -f $file ]] && return
msg "$file does not exist! $err_msg"
ExitCode=1
}
check_val () {
local configurables=$1
local val=$2
msg "Checking existence of configurable $val"
[[ -f $file ]] && return
msg "Expected configurable $val not set!"
ExitCode=1
}
# Check the key configurables
check_configurables () {
configurables=`$P4 configure show`
# for cfg in server.depot.root journalPrefix; do
# # TODO:
# # Check present
# # Check values and warn if not expected ones
# done
}
#==============================================================================
# Main Program
source "$SDP_ENV" "$SDP_INSTANCE" ||\
bail "Failed to load SDP environment for instance $SDP_INSTANCE."
source "$P4CBIN/backup_functions.sh" ||\
bail "Failed to load backup_functions.sh."
[[ $Log == Unset ]] && Log="$LOGS/validate_SDP.log"
# This is needed because everything in backup_functions.sh uses LOGFILE including the mail_log_file function.
LOGFILE="$Log"
rotate_log_file $LOGFILE ".gz"
msg "${0##*/} v$Version Starting validation at $(date +'%a %Y-%m-%d %H:%M:%S %Z')."
msg "If you have any questions about the output from this script, contact support@perforce.com"
check_vars
set_vars
check_dirs
# Check db files exist
file=db.counters
for dir in $P4ROOT $OFFLINE_DB; do
checkfile "$dir/$file" "Expected database file doesn't exist"
done
checkfile "$OFFLINE_DB/offline_db_usable.txt" "Offline database not in a usable state."
checkfile "$P4BIN" "p4 binary doesn't exist"
checkfile "$RC" "init script doesn't exist"
checkfile "$P4TICKETS" "tickets file doesn't exist"
P4="$P4BIN -p $P4PORT -u $P4USER"
$P4CBIN/p4login
# TODO:
# - links all present and correct for instance
# - db files present (and quick validation OK)
# - offline db usable (and quick validation OK)
# - offline db directories named appropriately (e.g. db1/db2)
# - crontab includes at least daily_checkpoint.sh
# - checkpoints dir contains a checkpoint or two
# - admin password validated
# - service password validated for a replica
# - configurables should include:
# journalPrefix
# server.depot.root
msg "Completed validation at $(date)."
[[ $ShowLog -eq 1 && -s $Log ]] && cat "$Log"
exit $ExitCode