#!/bin/bash
#==============================================================================
# Copyright and license info is available in the LICENSE file included with
# the Server Deployment Package (SDP), and also available online:
# https://workshop.perforce.com/view/p4-sdp/main/LICENSE
#------------------------------------------------------------------------------
set -u
# This script acquires Perforce P4 binaries from the Perforce FTP server.
# For documentation, run: get_p4_binaries.sh -man
# Typical usage:
# cd /p4/sdp/p4_binaries
# ./get_p4_binaries.sh
#==============================================================================
# Declarations and Environment
# Version ID Block. Relies on +k filetype modifier.
#------------------------------------------------------------------------------
# shellcheck disable=SC2016
declare VersionID='$Id: //p4-sdp/main/p4_binaries/get_p4_binaries.sh#1 $ $Change: 33433 $'
declare VersionStream=${VersionID#*//}; VersionStream=${VersionStream#*/}; VersionStream=${VersionStream%%/*};
declare VersionCL=${VersionID##*: }; VersionCL=${VersionCL%% *}
declare Version=${VersionStream}.${VersionCL}
[[ "$VersionStream" == r* ]] || Version="${Version^^}"
declare ThisScript=${0##*/}
declare ThisUser=
declare ThisHost=${HOSTNAME%%.*}
declare -i Debug=${SDP_DEBUG:-0}
declare -i NoOp=0
declare -i ErrorCount=0
declare -i WarningCount=0
declare -i RetryCount=0
declare -i RetryMax=2
declare -i RetryDelay=2
declare -i RetryOK=0
declare -i DownloadAPIs=0
declare P4Version=
declare DefaultP4Version=r26.1
declare DefaultBinList="p4 p4d p4broker p4p"
declare StageBinDir=
declare BinList=
declare Platform=
declare UserPlatform=
declare PerforceFTPBaseURL="https://ftp.perforce.com/perforce"
declare BinURL=
declare APIURL=
declare APIDirURL=
declare APIDirHTML=
declare APIFiles=
declare Cmd=
declare Cmd2=
declare VersionCheckFile=
declare OSArch=
declare OSName=
declare OSVersionString=
declare OSMajorVersion=
declare OSMinorVersion=
#==============================================================================
# Local Functions
function msg () { echo -e "$*"; }
function dbg () { [[ "$Debug" -eq 0 ]] || msg "DEBUG: $*"; }
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}"; }
#------------------------------------------------------------------------------
# Function: get_binary_version
#
# Extract the version from the downloaded binary. Use '-V' option; if that
# fails try using 'what' on the binary (useful, for example, if you're on a
# Mac downloading Linux binaries.
#
# Arguments:
# $1 - binary name, p4, p4d, p4broker, p4p
# $2 - title to display for the binary if version can be extracted, e.g.
# "New version of $binary" or "Old version of binary."
#
# Exit Codes:
# Return a happy 0 if version can be extracted with '-V' or 'what', else 1.
function get_binary_version () {
local binary=${1:-}
local title=${2:-}
local versionCheckFile=
versionCheckFile=$(mktemp)
"./$binary" -V > "$versionCheckFile" 2>&1
if grep -q Rev "$versionCheckFile"; then
msg "$title: $(grep Rev "$versionCheckFile")"
else
# If we cannot get the version information from the binary on the disk at the
# start of processing with './p4d -V', try using 'what'.
what "./$binary" > "$versionCheckFile" 2>&1
dbg "Output of what ./$binary: $(cat "$versionCheckFile")"
if grep -q "${binary^^}/" "$versionCheckFile"; then
msg "$title: $(grep "${binary^^}/" "$versionCheckFile" | awk '{print $1}')"
else
return 1
fi
fi
rm -f "$versionCheckFile"
return 0
}
#------------------------------------------------------------------------------
# Function: set_platform
#
# Determine the <Platform> value to used in the URL for the FTP server.
#
# Set value for global $Platform
#------------------------------------------------------------------------------
function set_platform () {
local binary=${1:-}
local osCompatName osMajorVersionCompat osMinorVersionCompat
local jsonFile=
local binDir=
local platformsAvailable=
Platform="PlatformUnsetForBinary-$binary"
# If the 'jq' utility is available, parse the json files to verify that there
# is a build available for the detected platform, by parsing the P4*.json
# release list files.
if [[ -n "$(command -v jq)" ]]; then
# If the '-sbd <StageBinDir>' option was used, search for the P4*.json
# in that directory. Otherwise, use the standard SDP location.
if [[ -n "$StageBinDir" ]]; then
binDir="$StageBinDir"
else
binDir="${SDP_INSTALL_ROOT:-/p4}/sdp/p4_binaries"
fi
case "${binary:-unset}" in
(p4) jsonFile=${binDir}/P4.json;;
(p4d) jsonFile=${binDir}/P4D.json;;
(p4broker) jsonFile=${binDir}/P4Broker.json;;
(p4p) jsonFile=${binDir}/P4Proxy.json;;
(unset) bail "Bad call to set_platform(); parameter 1 (binary) required.";;
esac
if [[ -n "$jsonFile" ]]; then
if [[ -r "$jsonFile" ]]; then
platformsAvailable=$(jq -r '.versions[].platform' "$jsonFile" | tr '\n' ' ')
else
warnmsg "Cannot read the versions json file: $jsonFile"
fi
else
warnmsg "Could not determine versions json file for binary $binary."
fi
else
dbg "The 'jq' utility is not available. Consider installing it to verify platform availability and suggest alternate platform options."
fi
# Static configuration for P4D OS Version compatibility. This supports only
# a subset of possible OS/platforms for p4d, to include all versions supported
# by OS installation packages.
case "$OSName" in
(Linux)
osCompatName=linux
osMajorVersionCompat=2
osMinorVersionCompat=6
;;
(Darwin)
osCompatName=macosx
if (( OSMajorVersion >= 12 )); then
osMajorVersionCompat=12
osMinorVersionCompat=
elif (( OSMajorVersion == 11 )); then
osMajorVersionCompat=11
osMinorVersionCompat=01
elif (( OSMajorVersion == 10 )); then
if (( OSMinorVersion >= 15 )); then
osMajorVersionCompat=10
osMinorVersionCompat=15
elif (( OSMinorVersion >= 10 )); then
osMajorVersionCompat=10
osMinorVersionCompat=10
else
osMajorVersionCompat=10
osMinorVersionCompat=5
fi
fi
;;
(*)
osCompatName=linux
osMajorVersionCompat=2
osMinorVersionCompat=6
warnmsg "Could not determine OS version compatibility for this OS: $OSName. Using default [$osCompatName$osMajorVersionCompat$osMinorVersionCompat]."
;;
esac
dbg "
OSArch: $OSArch
OSName: $OSName
osCompatName: $osCompatName
OSVersionString: $OSVersionString
OSMajorVersion: $OSMajorVersion
OSMinorVersion: $OSMinorVersion
osMajorVersionCompat: $osMajorVersionCompat
osMinorVersionCompat: $osMinorVersionCompat
"
# shellcheck disable=SC2071
if (( OSMajorVersion < osMajorVersionCompat )); then
warnmsg "OS Kernel Major Version ($OSMajorVersion) is less than P4 OS major version compatibility for $OSName, ($osMajorVersionCompat). The downloaded binary may not be suitable for this platform."
elif (( OSMajorVersion == osMajorVersionCompat )) && (( OSMinorVersion < osMinorVersionCompat )); then
warnmsg "OS Kernel Minor Version ($OSMajorVersion.$OSMinorVersion) is less than P4 OS minor version compatibility for $OSName, ($osMajorVersionCompat.$osMinorVersionCompat). The downloaded binary may not be suitable for this platform."
fi
# Platform should look like linux26x86_64, macosx1015x86_64
Platform="${osCompatName}${osMajorVersionCompat}${osMinorVersionCompat}${OSArch}"
# If the jq utility is available and a list of platforms could be determined, use that
# information to verify that a build is available for the detected platform.
if [[ -n "$platformsAvailable" ]]; then
if [[ "$platformsAvailable" =~ $Platform ]]; then
dbg "Verified: A build is available for detected platform [$Platform]."
else
dbg "No build available for detected platform [$Platform]. Checking fallback options ..."
# Hard-coded enumeration of cases where, for the p4* binaries, a good fallback option
# exists.
case "$Platform" in
(macosx12x86_64) Platform=macosx1015x86_64; dbg "Using alternate platform: $Platform";;
(*) warnmsg "There does not appear to be a build available for detected platform [$Platform].";;
esac
fi
else
dbg "Platform available list was empty."
fi
msg "Using $binary build for platform: $Platform"
}
#------------------------------------------------------------------------------
# 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
# error, usually $1 should be -h so that the longer usage message doesn't
# obscure 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
msg "\\n\\nUsage Error:\\n\\n$errorMessage\\n\\n"
fi
msg "USAGE for $ThisScript version $Version:
$ThisScript [-r <P4MajorVersion>] [-b <Binary1>,<Binary2>,...] [-api] [-sbd <StageBinDir>] [-p <platform>] [-n] [-d|-D]
or
$ThisScript -h|-man"
if [[ $style == -man ]]; then
msg "
DESCRIPTION:
This script acquires Perforce P4 binaries from the Perforce FTP server.
The four P4 binaries that can be acquired are:
* p4, the command line client
* p4d, the P4 Server
* p4p, the P4 Proxy
* p4broker, the P4 Broker
In addition, P4API, the C++ client API, can be downloaded.
This script gets the latest patch of binaries for the current major P4
version. It is intended to acquire the latest patch for an existing
install, or to get initial binaries for a fresh new install. It must
be run from the /p4/sdp/p4_binaries directory in order for the upgrade.sh
script to find the downloaded binaries.
The p4_binaries directory is used for staging binaries for later upgrade
with the SDP 'upgrade.sh' script (documented separately). This p4_binaries
directory is used to stage binaries on the current machine, while the
'upgrade.sh' script uses the downloaded binaries to upgrade a single SDP
instance (of which there might be several on a machine).
The p4_binaries directory must NOT be in the PATH. As a safety feature,
the 'verify_sdp.sh' will report an error if the 'p4d' binary is found outside
/p4/common/bin in the PATH. The SDP 'upgrade.sh' check uses 'verify_sdp.sh'
as part of its preflight checks, and will refuse to upgrade if any 'p4d' is
found in the PATH outside /p4/common/bin.
When a newer major version of P4 binaries is needed, this script should not
be modified directly. Instead, get the latest version of SDP first, which will
included a newer version of this script, as well as the latest 'upgrade.sh'
The 'upgrade.sh' script is updated with each major SDP version to be aware of
any changes in the upgrade procedure for the corresponding p4d version.
Upgrading SDP first ensures you have a version of the SDP that works with
newer versions of p4d and other P4 binaries.
PLATFORM DETECTION
The 'uname' command is used to determine the architecture for the current
machine on which this script is run.
This script and supporting P4*.json release list files know what platforms
for which builds are available for each P4 binary (p4, p4d, p4broker,
p4p). If the 'jq' utility is available, this script uses the P4*.json files
to verify that a build is available for the current platform, and in some
cases selects an alternate compatible platform if needed. For example, if
the detected platform is for OSX 12+ for the x86_64 architecture, no build
is available for binaries such as p4d for that platform, so a compatible
alternative is used instead, in this case macosx1015x86_64.
This script handles only the UNIX/Linux platforms (to include OSX).
RELEASE LIST FILES:
For each binary, there is a corresponding release list file (in json format)
that indicates the platforms available for the given binary. These files are:
P4.json (for the 'p4' binary)
P4D.json (for the 'p4d' binary)
P4Broker.json (for the 'p4broker' binary)
P4Proxy.json (for the 'p4p' binary)
These P4*.json release list files are aware of a wide list of supported
platforms for a range of P4 binaries.
These release list files are packaged with the SDP, and updated for each
major release.
OPTIONS:
-r <P4MajorVersion>
Specify the P4 Version, using the short form. The form is rYY.N, e.g. r21.2
to denote the 2021.2 release. The default: is $DefaultP4Version
The form of 'rYY.N', e.g. 'r25.1', is the default form of the version, matching
what is used in URLS on the Perforce P4 FTP server. For flexibility, similar
forms that clearly convent the intended version are also accepted. For example:
'-r 23.1' is implicitly converted to '-r r23.1'.
'-r 2023.1' is implicitly converted to ' -r r23.1'.
-b <Binary1>[,<Binary2>,...]
Specify a comma-delimited list of P4 binaries. The default is: $DefaultBinList
Alternately, specify '-b none' in conjunction with '-api' to download only APIs
and none of the p4* binaries.
-api
Specify '-api' to download P4API, the C++ client API. This will acquire one or
more client API tarballs, depending on the current platform. The API files will
look something like these examples:
* p4api-glibc2.3-openssl1.1.1.tgz
* p4api-glibc2.3-openssl3.tgz
* p4api-glibc2.12-openssl1.1.1.tgz
* p4api-glibc2.12-openssl3.tgz
* p4api-openssl1.1.1.tgz
* p4api-openssl3.tgz
All binaries that match 'p4api*tgz' in the relevant directory on the Perforce
FTP server for the current architecture and P4 version are downloaded.
Unlike binary downloads, the old versions are not checked, because file names are
fixed as they are with binaries.
APIs are not needed for normal operations, and are only downloaded if requested
with the '-api' option. They may be useful for developing custom automation such
as custom triggers. Be warned, custom triggers are not supported by Perforce Support.
-sbd <StageBinDir>
Specify the staging directory to install downloaded binaries.
By default, this script downloads files into the current directory, which
is expected and required to be /p4/sdp/p4_binaries. Documented workflows
for using this script involve first cd'ing to that directory. Using this
option disables the expected directory check and allows binaries to be
installed in any directory, which may be useful if this script is used
as a standalone script outside the SDP (e.g. for setting up test
environments or enabling P4 native DVCS features by installing binaries
into /usr/local/bin on a non-SDP machine.
This option also sets the location in which this script searches for the
P4*.json release list files.
-p <Platform>
Specify the platform in the format used on the Perforce FTP server, e.g.
linux26x86_64 or macosx12arm64. This option is typically unnecessary,
as the current platform is reliably detected by the script. This option
is used if running on one platform (e.g. a Mac) and and pulling binaries
for another platform (say linux26x86_64). If '-p' is omitted, the
platform will be detected separately for each binary based on available
binaries (per the *.json files).
-n Specify the '-n' (No Operation) option to show the commands needed
to fetch the P4 binaries from the Perforce FTP server without attempting
to execute them.
-d Set debugging verbosity.
-D Set extreme debugging verbosity using bash 'set -x' mode. Implies '-d'.
HELP OPTIONS:
-h Display short help message
-man Display this manual page
EXAMPLES:
Example 1 - Typical Usage with no arguments:
cd /p4/sdp/p4_binaries
./get_p4_binaries.sh
This acquires the latest patch of all 4 binaries for the $DefaultP4Version
release (aka 20${DefaultP4Version#r}).
This will not download APIs, which are not needed for general operation.
Example 2 - Specify the major version:
cd /p4/sdp/p4_binaries
./get_p4_binaries.sh -r r25.2
This gets the latest patch of for the 2023.2 release of all 4 binaries.
Note: Only supported P4 binaries are guaranteed to be available from the
Perforce FTP server.
Note: Only the latest patch for any given major release is available from the
Perforce FTP server.
Example 3 - Get r25.2 and skip the proxy binary (p4p):
cd /p4/sdp/p4_binaries
./get_p4_binaries.sh -r r25.2 -b p4,p4d,p4broker
Example 4 - Download r25.2 binaries in a non-default directory.
cd /any/directory/you/want
./get_p4_binaries.sh -r r25.2 -sbd .
or:
/p4/sdp/p4_binaries/get_p4_binaries.sh -r r25.2 -sbd /any/directory/you/want
Example 5 - Download C++ client API only:
cd /p4/sdp/p4_binaries
./get_p4_binaries.sh -r r25.2 -b none -api
DEPENDENCIES:
This script requires outbound internet access. Depending on your environment,
it may also require HTTPS_PROXY to be defined, or may not work at all.
If this script doesn't work due to lack of outbound internet access, it is
still useful illustrating the locations on the Perforce FTP server where
P4 binaries can be found. If outbound internet access is not
available, use the '-n' flag to see where on the Perforce FTP server the
files must be pulled from, and then find a way to get the files from the
Perforce FTP server to the correct directory on your local machine,
/p4/sdp/p4_binaries by default.
EXIT CODES:
An exit code of 0 indicates no errors were encountered. An
non-zero exit code indicates errors were encountered.
"
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;;
(-r) P4Version="${2:-}"; shiftArgs=1;;
(-b) BinList="${2:-}"; shiftArgs=1;;
(-api) DownloadAPIs=1;;
(-sbd) StageBinDir="${2:-}"; shiftArgs=1;;
(-p) UserPlatform="${2:-}"; shiftArgs=1;;
(-n) NoOp=1;;
(-d) Debug=1;;
(-D) Debug=1; set -x;; # Debug; use 'set -x' mode.
(-*) usage -h "Unknown option [$1].";;
(*) usage -h "Unknown command line fragment [$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
if [[ -n "$P4Version" ]]; then
# Verify values provided for the P4Version. By default we use the form
# used in URLs on the Perforce FTP server, which is where this script pulls
# binaries from. That form is 'rYY.N', e.g. 'r25.2' for the 2025.2 release.
# If P4Version looks like 'YY.N', convert to 'rYY.N'.
if [[ "$P4Version" =~ ^[0-9]{2}[.]{1}[0-9]{1}$ ]]; then
P4Version="r$P4Version"
dbg "P4Version value implicitly converted to $P4Version."
# If P4Version looks like 'YYYY.N', convert to 'rYY.N', but
# first check if the YYYY is valid.
elif [[ "$P4Version" =~ ^[0-9]{4}[.]{1}[0-9]{1}$ ]]; then
YYYY=$(echo "$P4Version" | cut -c 1-4)
case "$YYYY" in
199*) : ;;
200*) : ;;
201*) : ;;
2020) : ;;
2021) : ;;
2022) : ;;
2023) : ;;
2024) : ;;
*) usage -h "No P4 version was released in the year ($YYYY) specified with '-r $P4Version'.";;
esac
P4Version=r$(echo "$P4Version" | cut -c 3-)
dbg "P4Version value implicitly converted to $P4Version."
# If P4Version looks like 'rYY.N', no conversion needed.
elif [[ "$P4Version" =~ ^r[0-9]{2}[.]{1}[0-9]{1}$ ]]; then
:
else
usage -h "The format of the P4 Version specified with '-r $P4Version' is invalid. The expected form is '-r rYY.N'. For example, use '-r r23.2' to specify the 2023.2 release."
fi
else
P4Version="$DefaultP4Version"
fi
[[ -n "$BinList" ]] || BinList="$DefaultBinList"
# If '-b none' was specified and '-api' was not, give a usage error.
[[ "$BinList" == none && "$DownloadAPIs" -eq 0 ]] && \
usage -h "Nothing to download; '-b none' was specified and '-api' was not. Did you mean '-b none -api'?"
# If '-b none' was specified, clear the BinList.
[[ "$BinList" == none ]] && BinList=
if [[ -n "$StageBinDir" ]]; then
cd "$StageBinDir" || bail "Could not do: cd \"$StageBinDir\""
else
[[ "$PWD" == *"/sdp/p4_binaries" ]] || bail "This $ThisScript script is being run from directory $PWD, not /p4/sdp/p4_binaries, and '-sbd <staging_dir>' was not specified."
fi
if [[ ! "$P4Version" =~ ^r[0-9]{2}\.[0-9]{1}$ ]]; then
usage -h "\\n\\tThe P4 Version specified with '-r $P4Version' is invalid.\\n\\tIt should look like: $DefaultP4Version\\n"
fi
#==============================================================================
# Main Program
ThisUser=$(id -n -u)
msg "\\nStarted $ThisScript version $Version as $ThisUser@$ThisHost at $(date)."
OSArch=$(uname -m)
OSName=$(uname -s)
OSVersionString=$(uname -r)
OSMajorVersion=${OSVersionString%%.*}
OSMinorVersion=${OSVersionString%.*}
OSMinorVersion=${OSMinorVersion#*.}
VersionCheckFile=$(mktemp)
for binary in $(echo "$BinList"|tr ',' ' '); do
msg "\\nGetting $binary ..."
if [[ -n "$UserPlatform" ]]; then
Platform="$UserPlatform"
else
set_platform "$binary" || bail "Could not determine platform for binary $binary."
fi
BinURL="${PerforceFTPBaseURL}/${P4Version}/bin.${Platform}/$binary"
if [[ -f "$binary" ]]; then
chmod +x "$binary"
get_binary_version "$binary" "Old version of $binary" ||\
warnmsg "In $PWD, could not extract version information from old/existing $binary binary with './$binary -V' or 'what ./$binary'."
if [[ "$NoOp" -eq 0 ]]; then
rm -f "$binary"
fi
fi
Cmd="curl -s -O $BinURL"
if [[ "$NoOp" -eq 1 ]]; then
msg "NoOp: Would run: $Cmd"
continue
else
msg "Running: $Cmd"
fi
if $Cmd; then
chmod +x "$binary"
get_binary_version "$binary" "New version of $binary" ||\
errmsg "In $PWD, could not extract version information from newly downloaded $binary binary with './$binary -V' or 'what ./$binary'."
else
# Replace the '-s' silent flag with '-v' after we have had an error, to
# help with debugging.
Cmd="curl -v -O $BinURL"
warnmsg "Failed to download $binary with this URL: $BinURL\\nRetrying ..."
RetryCount=0
while [[ "$RetryCount" -le "$RetryMax" ]]; do
RetryCount+=1
sleep "$RetryDelay"
msg "Retry $RetryCount of $binary with command: $Cmd"
if $Cmd; then
chmod +x "$binary"
if get_binary_version "$binary" "New version of $binary"; then
RetryOK=1
break
fi
else
warnmsg "Retry $RetryCount failed again to download $binary with this URL: $BinURL"
fi
done
if [[ "$RetryOK" -eq 0 ]]; then
errmsg "Failed to download $binary with this URL: $BinURL"
rm -f "$binary"
fi
fi
done
if [[ "$DownloadAPIs" -eq 1 ]]; then
msg "Downloading P4API."
set_platform "p4" || bail "Could not determine platform for binary p4."
APIDirURL="${PerforceFTPBaseURL}/${P4Version}/bin.${Platform}"
APIDirHTML=$(mktemp)
Cmd="curl -L -s -o $APIDirHTML $APIDirURL"
msg "Getting list of APIs for ${P4Version}/bin.${Platform}."
msg "Running: $Cmd"
# Note: We attempt to get the list of APIs even in NoOp mode.
if $Cmd; then
APIFiles=$(grep 'href="p4api' "$APIDirHTML" | sed -E -e 's|^.* href="||g' -e 's|".*$||g')
[[ -n "$APIFiles" ]] || bail "No APIs found for $P4Version/bin.${Platform}."
for apiFile in $APIFiles; do
APIURL="$APIDirURL/$apiFile"
Cmd2="curl -s -O $APIURL"
if [[ "$NoOp" -eq 1 ]]; then
msg "NoOp: Would run: $Cmd2"
continue
else
msg "Running: $Cmd2"
fi
if $Cmd2; then
tar -tzf "$apiFile" | head -1 | cut -d '/' -f 1 > "$VersionCheckFile"
# If we cannot get the version information from the newly downloaded API, report an error.
if grep -q p4api- "$VersionCheckFile"; then
msg "New version of $apiFile: $(cat "$VersionCheckFile")"
else
errmsg "Could not extract version information from newly downloaded API tarball: tar -tzf $apiFile"
fi
else
errmsg "Could not download API with this command: $Cmd2"
fi
done
else
errmsg "Failed to download API dir info with this URL: $APIDirURL. Aborting."
fi
fi
rm -f "$VersionCheckFile"
if [[ "$ErrorCount" -eq 0 ]]; then
msg "\\nDownloading of Perforce P4 files completed OK."
else
errmsg "\\nThere were $ErrorCount errors and $WarningCount warnings attempting to acquire Perforce P4 binaries."
fi
exit "$ErrorCount"
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #1 | 33433 | Claude (AI Agent by Anthropic) |
Copy Up from //p4-sdp/dev into //p4-sdp/main. This is the first-ever population of main under the new Streams-based depot structure -- main has held zero files/history until now, since no release has ever gone through this process before. 463 files, covering the entire 2026.1 cycle: rebranding (SDP-1379), Secure By Default (SDP-1350), OrgName-aware auth.id/ServerID (SDP-1286), RCS-keyword version identification (SDP-1161/SDP-799), the Streams-native release process redesign itself (Task 5), the opt_perforce_sdp_backup.sh false-error fix, the P4D 2026.1 test-suite targeting, refreshed P4*.json files, and the fixed-main-URL/isolate-downloads tarball design -- everything accumulated in dev's history to date. Isolated paths (ai_dev_support/, Version, doc/*.html, doc/*.pdf, doc/gen/*.man.txt, doc/gen/sdp_install.cfg, Unsupported/doc/*.html, Unsupported/doc/*.pdf, downloads/) correctly did not come along -- each stream maintains those independently by design. Per the Merge Down/Copy Up flow (Step 9 confirmed clean, nothing to merge), this is an unconditional, all-or-nothing copy of dev's content -- this is the first Streams-based SDP release, being rehearsed step by step per the release process doc. Agent: Claude Code, Model: Claude Sonnet 5 (claude-sonnet-5), operating as bot_Claude_Anthropic. |
||
| //p4-sdp/dev/p4_binaries/get_p4_binaries.sh | |||||
| #1 | 33409 | Claude (AI Agent by Anthropic) |
Copy Up from //p4-sdp/dev_rebrand into //p4-sdp/dev. This is the first promotion of dev_rebrand's work into dev since dev_rebrand was created (2025-05-24) -- 303 files, covering the entire 2026.1 rebranding effort (SDP-1379), the Secure By Default adaptation (SDP-1350), OrgName-aware auth.id/ServerID (SDP-1286), RCS-keyword version identification (SDP-1161/SDP-799), and the Streams-native release process redesign (Task 5) done this session, plus everything else accumulated in dev_rebrand's history before this session. Per the Merge Down/Copy Up flow, this is intentionally a full, unconditional blast-replace of dev's content from dev_rebrand -- all selectivity/care happened in the preceding Merge Down (dev -> dev_rebrand, changes 33407-33408), which absorbed Robert Cowham's independent dev-side work first so nothing of his is lost by this Copy Up. Two files are worth calling out since they might look alarming in isolation: - tools/mdcu.sh is deleted -- intentional, retired this session in favor of the two direct Streams commands now documented in doc/ReleaseProcessOverview.md. - tools/ReleaseProcessOverview.md is deleted -- this is a stale relic of a file move dev_rebrand made back in 2025-05-24 (tools/ -> doc/) that was never previously propagated to dev; the current, fully-rewritten doc/ReleaseProcessOverview.md is added/updated correctly by this same changelist. |
||
| //p4-sdp/dev/helix_binaries/get_helix_binaries.sh | |||||
| #3 | 32480 | C. Thomas Tyler |
Routine merge for SDP from Classic to Streams, done with: p4 merge -b SDP_Classic_to_Streams p4 resolve -as The automatic-safe resolve handled all files; neither '-am' nor interative resolves were needed. |
||
| #2 | 31688 | C. Thomas Tyler |
Merged changes from SDP 2025.1 release to //p4-sdp/dev stream. p4 merge -b SDP_Classic_to_Streams p4 resolve -as |
||
| #1 | 31397 | C. Thomas Tyler | Populate -b SDP_Classic_to_Streams -s //guest/perforce_software/sdp/...@31368. | ||
| //guest/perforce_software/sdp/dev/helix_binaries/get_helix_binaries.sh | |||||
| #20 | 31016 | C. Thomas Tyler |
Changed default Helix Core version to r24.2. Improved documentation and error messages in get_helix_binaries.sh. |
||
| #19 | 30625 | C. Thomas Tyler | Refined get_helix_binaries.sh to handle format of '-r rYY.N' that needs no conversion. | ||
| #18 | 30532 | C. Thomas Tyler |
In get_helix_binaries.sh, enhanced error message for bad format of of '-r'. #review-30533 |
||
| #17 | 30402 | C. Thomas Tyler | Fixed issue if USER environment variable is not defined by the shell. | ||
| #16 | 30328 | C. Thomas Tyler |
get_helix_binaries.sh: Added support for acquiring P4API files. Use the new '-api' option to acquire whatever p4api.* files are available for your Helix version and platform. The '-b' option now allows '-b none', so you can donwload only APIs with '-b none -api' #review-30329 |
||
| #15 | 30320 | C. Thomas Tyler |
Added multi-platform support to include aarch64, and some modern OSX variants. Updated default Helix binary version to r24.1, which adds aarch64 builds. Design Goals (achieved): * No operational procedure changes required, so users on existing platforms don't need to learn new tricks. * Changes to support multiple platforms/OS architectures are contained entirely within the /p4/sdp/helix_binaries directory. The rest of the SDP can remain blissfully unaware of platform specifics. New capabilities: * Uses 'uname' to detect current OS platform, mapping it to available Helix builds for each binary. * Uses 'jq' if available to parse P4*.json release list files to determine if a build is available for the detected platform. * Adds fallback logic. For example, there is an aarch64 build for OSX 12+, but not for x86_64. So if on OSX 12+ on x86_64, use the older-but-compatible OSX 10.15 build for x86_64. * Adds a new '-d' debug mode option, as the script gets complex. New Files: * Added P4*.json release list files to SDP package in /p4/sdp/helix_binaries. These *.json files are updated as part of the Helix Core release process for p4, p4d, p4broker, and p4p (and also P4V and others not relevant to this script). Bonus Content: * Silently/harmlessly introduces as-yet-unused SDP_INSTALL_ROOT variable, a prelude to future SDP refactoring. Tested Platforms: * linux26x86_64 * linux26aarch64 * macosx12arm64 * macosx12x86_64; exercises fallback to maxosx1015x86_64 #review-30313 @robert_cowham @mark_zinthefer @will_kreitzmann |
||
| #14 | 30221 | C. Thomas Tyler |
In get_helix_binaries.sh, add '-sbd <StageBinDir>' option to get bins in any dir. This supports alternate usages of this script outside documented workflows. #review-30222 |
||
| #13 | 29996 | C. Thomas Tyler |
Changed DefaultHelixVersion from r23.1 -> r23.2, in preparation for the coming SDP 2023.2 release. #review-29997 |
||
| #12 | 29558 | C. Thomas Tyler | Updated default Helix Core version from 22.2 -> r23.1. | ||
| #11 | 29218 | C. Thomas Tyler |
Prep for SDP r22.2 release. Changed default p4d version in get_helix_binaries.sh to prefer r22.2. |
||
| #10 | 28848 | C. Thomas Tyler |
Adjusted get_helix_binaries.sh ftp.perforce.com rather than cdist2.perforce.com. This fixes a hang issue when running get_helix_binaries.sh. #review-28849 |
||
| #9 | 28838 | C. Thomas Tyler | Updated default p4d version to r22.1. | ||
| #8 | 28376 | C. Thomas Tyler | In get_helix_binaries.sh, changed default version to r21.2. | ||
| #7 | 27892 | C. Thomas Tyler |
Fixed typo and updated Version identifier. Thanks, Adam! #review-27893 @amo |
||
| #6 | 27890 | C. Thomas Tyler |
Updated Release Notes and SDP Guide to clarify SDP r20.1 supports Helix Core binaries up to r21.1, in advance of the coming SDP r21.1 release that will make it more obvious. In get_helix_binaries.sh: * Changed default Helix Core binary version to r21.1. * Changed examples of getting a different version to reference r20.2. #review-27891 @amo |
||
| #5 | 27722 | C. Thomas Tyler |
Refinements to @27712: * Resolved one out-of-date file (verify_sdp.sh). * Added missing adoc file for which HTML file had a change (WorkflowEnforcementTriggers.adoc). * Updated revdate/revnumber in *.adoc files. * Additional content updates in Server/Unix/p4/common/etc/cron.d/ReadMe.md. * Bumped version numbers on scripts with Version= def'n. * Generated HTML, PDF, and doc/gen files: - Most HTML and all PDF are generated using Makefiles that call an AsciiDoc utility. - HTML for Perl scripts is generated with pod2html. - doc/gen/*.man.txt files are generated with .../tools/gen_script_man_pages.sh. #review-27712 |
||
| #4 | 27510 | C. Thomas Tyler |
get_helix_binaries.sh: Added '-n' and '-D' options to usage summary. Doc only; non-functional change. |
||
| #3 | 27030 | C. Thomas Tyler |
Updated get_helix_binaries.sh v1.2.0: * Completed documentation. * Added command line verifications. - Must be run from */sdp/helix_binaries directory. - Format of '-r HelixVersion' value checked. * Internal code improvements. |
||
| #2 | 27027 | C. Thomas Tyler |
Fixed command line handling bug. Invalid fragments result in usage error. Changed variable name 'bin' -> 'binary' for clarity. |
||
| #1 | 27022 | C. Thomas Tyler | Changed 'exes' to 'helix_binaries' in folder and script name, per review. | ||
| //guest/perforce_software/sdp/dev/exes/get_latest_exes.sh | |||||
| #5 | 27003 | Robert Cowham | Work around timing issues for tests. | ||
| #4 | 27000 | C. Thomas Tyler |
Tweak so 'curl' command uses '-s' silent mode for normal operation, and drops '-s' only on retry attempts in event of an initial failure. |
||
| #3 | 26998 | C. Thomas Tyler | Fixed issue with existing files causing curl command to fail. | ||
| #2 | 26993 | C. Thomas Tyler | Added retry logic to get_latest_exes.sh. | ||
| #1 | 26982 | C. Thomas Tyler |
mkdirs.sh v4.1.0: * Accounted for directory structure change of Maintenance to Unsupported. * Added standard command line processing with '-h' and '-man' doc flags, and other flags (all documented). * Added in-code docs and updated AsciiDoc. * Enhanced '-test' mode to simulate /hx* mounts. * Enhanced preflight testing, and fixed '-test' mode installs. * Added support for installing to an alternate root directory. * Added '-s <ServerID>' option to override REPLICA_ID. * Added '-S <TargetServerID>' used for replicas of edge servers. * Added '-t <server_type>' option to override SERVER_TYPE. * Added '-M' option to override mount points. * Added '-f' fast option to skip big chown/chmod commands, and moved those commands near the end as well. verify_sdp.sh v5.9.0: * Added check for /p4/Version file, and checked that other legacy SDP methods of checking version * Added sanity check for crontab. * Added 'test skip' mechanism to skip certain tests: - crontab: Skip crontab check. Use this if you do not expect crontab to be configured, perhaps if a different scheduler is used. - license: Skip license related checks. - version: Skip version checks. - excess: Skip checks for excess copies of p4d/p4p/p4broker in PATH. * Added VERIFY_SDP_SKIP_TEST_LIST setting ton instance_vars.template, to define a standard way to have verify_sdp.sh always skip certain tests for a site. * Extended '-online' checks to check for bogus P4MASTERPORT, a common config error. Update test_SDP.py: * Adjusted test suite to account for various changes in mkdirs.sh. * Added 'dir' parameter to run_cmd() and sudo_cmd(), to run a command from a specified directory (as required to test new mkdirs.sh) * Added check_links() similar to existing check_dirs() function. === Upgrade Process Changes === Made /p4/common/bin/p4d/p4/p4broker/p4p shell script rather than binary. This changes the way SDP new binaries are staged for upgrade. For safety, exes are now staged to a director outside the PATH, the /p4/sdp/exes folder. A new 'get_latest_exes.sh' script simplifies the task of pulling executables from the Perforce FTP server. This can be used 'as is' for environments with outbound internet access, and is useful in any case to describe now to acquire binaries. This addresses an issue where a p4d binary staged for a future upgrade might be called before the actual upgrade is performed. upgrade.sh v4.0.0: * All preflight checks are now done first. Added '-p' to abort after preflight. * Added '-n' to show what would be done before anything is executed. * Minimalist logic to start/stop only servers that are upgrade, and apply upgrades only as needed. * Staging of exes for upgrade is now separate from /p4/common/bin * Improved in-code docs, added '-h' and '-man' options. * Retained pre/post P4D 2019.1 upgrade logic. |
||