configure_new_server.sh #1

  • //
  • p4-sdp/
  • r26.1.0.BETA/
  • Server/
  • setup/
  • configure_new_server.sh
  • View
  • Commits
  • Open Download .zip Download (39 KB)
#!/bin/bash
set -u
#==============================================================================
# This script serves as a guide defining best-practice configurables for a
# production environment.  See documentation regarding configurables here:
# https://help.perforce.com/helix-core/server-apps/cmdref/current/Content/CmdRef/configurables.alphabetical.html
#
# 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 P4PORT and P4USER and run p4 login before running this script.

declare ThisScript=${0##*/}
declare ThisUser=
declare Args="$*"
declare CmdLine="$0 $Args"
declare ThisHost=${HOSTNAME%%.*}

#------------------------------------------------------------------------------
# Version ID Block. Relies on +k filetype modifier.
# shellcheck disable=SC2016
declare VersionID='$Id: //p4-sdp/r26.1.0.BETA/Server/setup/configure_new_server.sh#1 $ $Change: 33444 $'
declare VersionStream=${VersionID#*//}; VersionStream=${VersionStream#*/}; VersionStream=${VersionStream%%/*};
declare VersionCL=${VersionID##*: }; VersionCL=${VersionCL%% *}
declare Version=${VersionStream}.${VersionCL}
[[ "$VersionStream" == r* ]] || Version="${Version^^}"

declare SpecFile=
declare ProtectsFile=
declare ProtectsTemplate=
declare ChangeCounter=
declare ChangeCounterLine=
declare AccessLevel=
declare DiskSpaceAvail=
declare MinKBFor5GLimits=7340032
declare CleartextPasswordFile=
declare EncryptedPasswordFile=
declare TmpFile=
declare UserCount=
declare SDPRoot=${SDP_ROOT:-/p4}
declare SDPCommon="$SDPRoot/common"
declare SDPCommonBin="$SDPCommon/bin"
declare SDPCommonLib="$SDPCommon/lib"
declare SDPEnv="$SDPCommonBin/p4_vars"
declare SDPCommonCfg="$SDPCommon/config"
declare InstanceCfg=
declare SDPInstance=
declare Log=
declare -i ErrorCount=0
declare -i WarningCount=0
declare -i DoCheckpoint=0
declare -i Force=0
declare -i NoOp=0
declare -i Debug=0
declare -i NewServer=0
declare H1="=============================================================================="

declare P4DInitScript=
declare P4DSystemdServiceFile=

function msg () { echo -e "$*"; }
function dbg () { [[ "$Debug" -eq 0 ]] || echo -e "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}"; }

#==============================================================================
# Load SDP Library Functions.

if [[ -d "$SDPCommonLib" ]]; then
   # shellcheck disable=SC1090 disable=SC1091
   source "$SDPCommonLib/logging.lib" ||\
      bail "Failed to load bash lib [$SDPCommonLib/logging.lib]. Aborting."
   # shellcheck disable=SC1090 disable=SC1091
   source "$SDPCommonLib/run.lib" ||\
      bail "Failed to load bash lib [$SDPCommonLib/run.lib]. Aborting."
   # shellcheck disable=SC1090 disable=SC1091
   source "$SDPCommonLib/service_management.lib" ||\
      bail "Failed to load bash lib [$SDPCommonLib/service_management.lib]. Aborting."
   # shellcheck disable=SC1090 disable=SC1091
   source "$SDPCommonLib/utils.lib" ||\
      bail "Failed to load bash lib [$SDPCommonLib/utils.lib]. Aborting."
fi

#------------------------------------------------------------------------------
# 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 a
# 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 -h
# usage -man
# usage -h "Missing required parameter <RequiredParameter>."
#------------------------------------------------------------------------------
function usage
{
   local style=${1:--h}
   local usageErrorMessage=${2:-Unset}

   if [[ "$usageErrorMessage" != Unset ]]; then
      msg "\n\nUsage Error:\n\n$usageErrorMessage\n\n"
   fi

   msg "USAGE for $ThisScript v$Version:

$ThisScript <instance> [-checkpoint] [-f] [-n] [-d|-D]

or

$ThisScript [-h|-man|-V]
"
   if [[ $style == -man ]]; then
      msg "
DESCRIPTION:
	This script configures a new commit server by setting best practices
	configurables, as well as setting SDP-required configurables such as
	server.depot.root and journalPrefix.

	This script is intended to be run on a new, empty P4 data set. If it
	is run on a server with existing configurables, it will abort by
	default to avoid overwriting existing configurables.  Before running
	on a server with existing data, review the configurables it sets to
	ensure they will not cause a problem. (This could be done by
	operating the script on a copy-of-production sandbox or perhaps by
	reviewing the script code).  Use the '-f' (force) option to allow this
	script to be run on a server that already has configuration items set.

REQUIRED PARAMETERS:
	<instance> - Specify the SDP Instance.

OPTIONS:
 -checkpoint

	Specify '-checkpoint' to do a live checkpoint after setting the configurables.

 -f
	Specify '-f' (force) to allow running this script on data set that is not a brand
	new/empty data set.  This script deems a server to be new and empty if the
	change counter is '0'.

 -n
	Enable DRY RUN/Preview mode, displaying commands that would affect data
	rather than executing them.

 -D
	Set extreme debugging verbosity.

LOGGING:
 -L <Log>

	Specify the path to desired log file, or the special value 'off' to disable logging.

	The default log file name is:

	${LOGS:-/tmp}/${ThisScript%.sh}.<timestamp>.log

	This script is self-logging.  That is, output displayed on the screen
	is simultaneously captured in the log file.  Using redirection operators like
	like '> log' or '2>&1' or using 'tee' are unnecessary (but harmless).

HELP OPTIONS:
 -h	Display short help message.
 -man	Display man-style help message.
 -V	Display version info for this script.

FILES:

EXAMPLES:
	Example 1: Do a preview:
	$ThisScript 1 -n

	Example 2: Typical operation to configure new instance 1.
	$ThisScript 1

	Example 3: Same as Example 2, and then do a live checkpoint after.
	$ThisScript 1 -checkpoint

	Example 4: Apply configurables to an existing server using '-f'.
	$ThisScript 1 -f

SEE ALSO:
	See 'ccheck.sh -man' to for info on how to check configurables after
	this script has been run.
"
   fi

   exit 2
}

#==============================================================================
# Command Line Processing

declare -i ShiftArgs=0

set +u
while [[ $# -gt 0 ]]; do
   case $1 in
      (-h) usage -h;;
      (-man|--help) usage -man;;
      (-checkpoint) DoCheckpoint=1;;
      (-f) Force=1;;
      (-V|--version) show_versions; exit 0;;
      (-L) Log="$2"; ShiftArgs=1;;
      (-n) NoOp=1;;
      (-d) Debug=1;;
      (-D) Debug=1; set -x;; # Use bash 'set -x' extreme debug mode.
      (-*) usage -h "Unknown option ($1).";;
      (*)
         if [[ -z "$SDPInstance" ]]; then
            SDPInstance="$1"
         else
            usage -h "SDP Instance parameter already provided as '$SDPInstance'; ignoring parameter '$1'."
         fi
      ;;
   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

if [[ -n "$SDPInstance" ]]; then
   InstanceCfg="$SDPCommonCfg/p4_${SDPInstance}.vars"
   [[ -r "$InstanceCfg" ]] ||\
      bail "Invalid instance parameter '$SDPInstance' specfied; instance config is issing: $InstanceCfg. Aborting."
else
    bail "The <instance> parameter is required. Aborting."
fi

# shellcheck disable=SC1090
source "$SDPEnv" "$SDPInstance" ||\
   bail "Could not do: source \"$SDPEnv\" \"$SDPInstance\""

# These are defined for use in /p4/common/lib/service_management.lib.
# shellcheck disable=SC2034
P4DInitScript="$P4HOME/bin/p4d_${SDPInstance}_init"
# shellcheck disable=SC2034
P4DSystemdServiceFile="/etc/systemd/system/p4d_${SDPInstance}.service"

#==============================================================================
# Command Line Verification

ThisUser=$(id -n -u)
[[ "$ThisUser" != "$OSUSER" ]] &&\
   usage -h "Run $ThisScript as user '$OSUSER', not '$ThisUser'."

[[ -n "$Log" ]] || Log="${LOGS:-/tmp}/${ThisScript%.sh}.$(date +'%Y%m%d-%H%M%S').log"

#==============================================================================
# Main Program

trap terminate EXIT SIGINT SIGTERM

if [[ "$Log" != off ]]; then
   touch "${Log}" || bail "Couldn't touch log file [${Log}]."

   # Redirect stdout and stderr to a log file.
   exec > >(tee "$Log")
   exec 2>&1

   msg "${H1}\nLog is: $Log\n"
fi

msg "Starting $ThisScript v$Version as $ThisUser@$ThisHost on $(date) with \n$CmdLine"

msg "See documentation regarding configurables here:\n
https://help.perforce.com/helix-core/server-apps/cmdref/current/Content/CmdRef/configurables.alphabetical.html\n"

# Capture whether p4d is already running before we (maybe) start it below.
# Used further down to detect a genuinely new server: one whose first-ever
# start at P4D 2026.1 is about to happen as part of this script run.
NewServerBeforeStart=1
svc_is_up p4d && NewServerBeforeStart=0

msg "Starting p4d service (if needed)."
if [[ "$NoOp" -eq 0 ]]; then
   svc_start_p4d
else
   msg "Would have started p4d."
fi

# As of P4D 2026.1, the first-ever start of a data set at 2026.1
# permanently bumps the "security" configurable up to its new default of
# 4 (and similarly hardens dm.user.noautocreate to 2), even if a lower
# value was set beforehand offline via 'p4d -cset'. This is a one-time
# bump tied to that first start (analogous to a version upgrade), not
# something re-enforced on every subsequent start. It blocks the classic
# empty-Protections-table bootstrap this script relies on to create the
# very first super user: even the unauthenticated-friendly 'p4 user -o'
# template read now requires authentication that cannot exist yet. Work
# around this by relaxing both configurables offline (the same
# 'p4d -cset' mechanism already used elsewhere in the SDP -- see
# configure_sample_depot_for_sdp.sh) right after that one-time bump has
# already happened, then starting the server again: a second start does
# not re-trigger the bump, so the relaxed values hold. Only do this for a
# genuinely new server (p4d wasn't already running before the start
# above), so an already-configured/live server is never touched. The live
# 'configure set' calls further below (once $P4USER exists and is logged
# in) restore both configurables to their secure defaults; since the
# server is already past its one-time bump by then, those live changes
# hold across any future restart.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2026.1" ]] && [[ "$NewServerBeforeStart" -eq 1 ]] && [[ "$NoOp" -eq 0 ]]; then
   msg "Temporarily relaxing P4D 2026.1 Secure By Default configurables to bootstrap the first super user."
   svc_stop_p4d
   "$P4DBIN" -r "$P4ROOT" "-cset security=0" ||\
      errmsg "Failed to set configurable security=0 for initial bootstrap."
   "$P4DBIN" -r "$P4ROOT" "-cset dm.user.noautocreate=0" ||\
      errmsg "Failed to set configurable dm.user.noautocreate=0 for initial bootstrap."
   svc_start_p4d
fi

# Ensure trust if SSL (which doubles as a connectivity check), or if not SSL just
# check connectivity.
dbg "Doing trust and/or connectivity check."
if [[ "$P4PORT" =~ ^ssl[46]*: ]]; then
   msg "Trusting P4PORT [$P4PORT]."
   if [[ "$NoOp" -eq 0 ]]; then
      timeout 10s p4 trust -f -y > /dev/null 2>&1 || bail "Could not trust P4PORT [$P4PORT]. Aborting."
   else
      msg "NO_OP: Would have done: timeout 10s p4 trust -f -y"
   fi
else
   msg "Checking connecition to P4PORT [$P4PORT]."
   if [[ "$NoOp" -eq 0 ]]; then
      timeout 10s p4 -s info -s > /dev/null 2>&1 || bail "Could not connect to P4PORT [$P4PORT]. Aborting."
   else
      msg "NO_OP: Would have done: timeout 10s p4 info -s"
   fi
fi

dbg "Checking access level with 'p4 protects -m'."
AccessLevel=$(p4 protects -m 2>&1)

if [[ -n "$AccessLevel" ]]; then
   dbg "AccessLevel=[$AccessLevel]."
   if [[ "$AccessLevel" == super ]]; then
      dbg "Verified: Access Level for P4USER '$P4USER' is 'super'."
   elif [[ "$AccessLevel" = "Protections table is empty." ]]; then
      dbg "Verified: Protections table is not initialized."
   elif [[ -z "$("$P4DBIN" -r "$P4ROOT" -k db.protect -jd - | grep ^@pv@ | head -1)" ]]; then
      # As of P4D 2026.1, an unauthenticated 'p4 protects -m' against a
      # genuinely empty Protections table no longer returns the informative
      # "Protections table is empty." string above -- it returns a generic
      # authentication error instead (e.g. "Perforce password (P4PASSWD)
      # invalid or unset."), which would otherwise incorrectly bail here.
      # Confirm directly against db.protect instead of relying on that
      # message (same technique already used further below in this script).
      dbg "Verified: Protections table is not initialized (confirmed directly via db.protect)."
   else
      bail "Access level of current P4USER '$P4USER' is '$AccessLevel', but it must be 'super'."
   fi
else
   if [[ "$NoOp" -eq 0 ]]; then
      bail "Could not determine access level granted in Protections to user '$P4USER'."
   else
      msg "NO_OP: Assuming protections granted to user '$P4USER' is super."
   fi
fi

# Determine if this is a fresh new server, and thus if the '-f' option is required to run this
# script.
ChangeCounter=$(p4 counter change 2>/dev/null)

# As of P4D 2026.1, 'p4 counter' also requires authentication -- even for a
# fresh/empty server, where an unset counter traditionally just reads back as
# "0" without needing auth. Confirm directly against db.counters instead when
# the live read comes back empty (same technique as the Protections check
# above): no entry for the 'change' counter at all means it's unset, i.e. 0.
if [[ -z "$ChangeCounter" ]]; then
   ChangeCounterLine=$("$P4DBIN" -r "$P4ROOT" -k db.counters -jd - 2>/dev/null | grep '@change@')
   if [[ -z "$ChangeCounterLine" ]]; then
      ChangeCounter=0
   else
      ChangeCounter=$(echo "$ChangeCounterLine" | sed -E 's/.*@change@ @([^@]*)@.*/\1/')
   fi
fi

# Spoof ChangeCounter=0 in NoOp mode.
[[ "$NoOp" -eq 1 && -z "$ChangeCounter" ]] && ChangeCounter=0

dbg "ChangeCounter is: $ChangeCounter"

[[ "$ChangeCounter" == 0 ]] && NewServer=1

if [[ "$NewServer" -eq 1 ]]; then
   msg "Server instance $SDPInstance is a new data set."
else
   if [[ "$Force" -eq 1 ]]; then
      warnmsg "Server instance '$SDPInstance' is not new. Proceeding anyway due to '-f'."
   else
      bail "Aborting because Server instance '$SDPInstance' is not new. Running $ThisScript against an existing data set. The data set is assumed to be new/empty if the 'change' counter is '0'; it is $ChangeCounter. To proceed anyway, use '-f'."
   fi
fi

# Generate the super user account, but only if there is only a single account
# on the server.
UserCount=$(p4 users 2>/dev/null | head -n 2 | wc -l)

# As of P4D 2026.1, 'p4 users' also requires authentication, even on a
# fresh/empty server where it traditionally just returned no output (and
# thus UserCount=0) without needing auth. That would otherwise miss the
# UserCount==1 condition below and incorrectly skip creating $P4USER. Since
# $NewServer (above) already reliably establishes whether this is a
# genuinely fresh server (via a direct db.counters check, not just a live
# read), trust it here too: a fresh server always has 0 real users at this
# point, which is the case UserCount==1 needs to match to proceed.
[[ "$NewServer" -eq 1 && "$UserCount" -eq 0 ]] && UserCount=1

if (( UserCount == 1 )); then
   msg "Creating user '$P4USER'."
   SpecFile="$(mktemp)"
   if p4 --field User="$P4USER" --field FullName="Perforce P4 Admin" --field Email="$P4USER@${MAILFROM##*@}" user -o "$P4USER" > "$SpecFile"; then
      msg "Creating user '$P4USER'."
      if [[ "$NoOp" -eq 0 ]]; then
         if p4 -s user -f -i < "$SpecFile"; then
            msg "Setting password for user '$P4USER'."
            CleartextPasswordFile="$SDP_ADMIN_PASSWORD_FILE"
            EncryptedPasswordFile="${CleartextPasswordFile}.enc"
            if [[ -r "$EncryptedPasswordFile" ]]; then
               TmpFile=$(mktemp)
               touch "$TmpFile"
               chmod 600 "$TmpFile"
               base64 -d - < "$EncryptedPasswordFile" > "$TmpFile" ||\
                  errmsg "Failed to decrypt password in: $EncryptedPasswordFile"
               yes "$(cat "$TmpFile")" | p4 passwd
               rm -f "$TmpFile"
            elif [[ -r "$CleartextPasswordFile" ]]; then
               yes "$(cat "$CleartextPasswordFile")" | p4 passwd
            else
               errmsg "Could not find encrypted or cleartext password files, neither $EncryptedPasswordFile nor $CleartextPasswordFile exist."
            fi

            "$P4CBIN"/p4login

            # Verify the Protections table is not initialized so we don't overwrite an existing table.
            # Check for any entries in the db.protect table.
            if [[ -z "$("$P4DBIN" -r "$P4ROOT" -k db.protect -jd - | grep ^@pv@ | head -1)" ]]; then
               msg "Initializing Protections table."
               ProtectsFile=$(mktemp)
               ProtectsTemplate="${0%/*}/protect.p4t"
               if [[ -r "$ProtectsTemplate" ]]; then
                  if sed -e "s@__P4USER__@$P4USER@g" "$ProtectsTemplate" > "$ProtectsFile"; then
                     if p4 -s protect -i < "$ProtectsFile"; then
                        msg "Protections table initialized to:\n$(p4 protect -o | grep -v '^#')\n"
                    else
                        errmsg "Failed to load generated Protections file:\n$(cat "$ProtectsFile")"
                    fi
                  else
                     errmsg "Failed to generate Protections file from template. Not initializing protections."
                  fi
               else
                  warnmsg "Skipping Protections table initialization due to missing template: $ProtectsTemplate"
               fi
            else
               warnmsg "Skipping Protections table initialization because Protections table is already initialized."
            fi
         else
            errmsg "Failed to create $P4USER user; tried to load this generated spec file:\n$(cat "$SpecFile")"
         fi
      else
         msg "NO_OP: Would have created user $P4USER with password and initialized Protections. User specs is:\n$(cat "$SpecFile")"
      fi
      rm -f "$SpecFile"
   else
      errmsg "Failed to generate spec file for $P4USER user."
   fi
else
   warnmsg "Skipping $P4USER user creation; more than one user account exists."
fi

# Generate the Automation group with P4USER as member and owner.
if [[ "$(p4 group --exists -o Automation 2>&1)" =~ ^Group\ \' ]]; then
   SpecFile="$(mktemp)"
   if p4 --field Timeout=unlimited --field PasswordTimeout=unlimited --field Owners="$P4USER" --field Users="$P4USER" group -o Automation > "$SpecFile"; then
      msg "Creating group 'Automation'."
      if [[ "$NoOp" -eq 0 ]]; then
         p4 -s group -i < "$SpecFile" ||\
            errmsg "Failed to create Automation group; tried to load this generated spec file:\n$(grep -v ^# "$SpecFile")"
      else
         msg "NO_OP: Would have created Automation group with this spec:\n$(grep -v ^# "$SpecFile")"
      fi
      rm -f "$SpecFile"
   else
      errmsg "Failed to generate spec file for Automation group."
   fi
else
   warnmsg "Skipping Automation group creation; group already exists."
fi

# The server.depot.root configurable was introduced in 2014.1.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2014.1" ]]; then
   run "p4 -s configure set server.depot.root=$DEPOTS" 1 1 || errmsg "Failed to set configurable server.depot.root."
fi

# The server.rolechecks configurable was introduced in 2011.1.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2011.1" ]]; then
   run "p4 -s configure set server.rolechecks=1" '' 1 1 || errmsg "Failed to set configurable server.rolechecks."
fi

# SDP-1320: server.startup.autorestart=1 is a new best practice for P4D
# 2026.1+ (the p4d default is 0). Gated to 2026.1+, not just "introduced in",
# since it depends on the P4-7318 fix (gaps in startup.N numbering breaking
# replication on restart) which landed in 2026.1.
# shellcheck disable=SC2072
if [[ ! "$P4D_VERSION" < "2026.1" ]]; then
   run "p4 -s configure set server.startup.autorestart=1" '' 1 1 || errmsg "Failed to set configurable server.startup.autorestart."
fi

run "p4 -s configure set journalPrefix=$CHECKPOINTS/p4_${SDPInstance}" '' 1 1 || errmsg "Failed to set configurable journalPrefix."
run "p4 -s configure set dm.user.noautocreate=2" '' 1 1 || errmsg "Failed to set configurable dm.user.noautocreate."
run "p4 -s configure set dm.info.hide=1" '' 1 1 || errmsg "Failed to set configurable dm.info.hide."
run "p4 -s configure set dm.protects.hide=1" '' 1 1 || errmsg "Failed to set configurable dm.protects.hide."
run "p4 -s configure set dm.user.setinitialpasswd=0" '' 1 1 || errmsg "Failed to set configurable dm.user.setinitialpasswd."

### For now, setting dm.user.resetpassword=1 until P4-27901 is implemented.
### The default for dm.user.resetpassword changes from 1 to 0 in 2026.1; the 0 value is deemed more secure.
### However, that causes breakage with service accounts, per P4-27901. Fix in progress.
run "p4 -s configure set dm.user.resetpassword=1" '' 1 1 || errmsg "Failed to set configurable dm.user.resetpassword."

# For filesys.*.min configurables, use 5G defaults if we have 7G+ of space
# available, otherwise assume this is a demo-scale environment and use 20M.
DiskSpaceAvail=$(df -k "$P4ROOT/" 2>/dev/null | grep / | awk '{print $4}')
if [[ "$DiskSpaceAvail" -ge "$MinKBFor5GLimits" ]]; then
   run "p4 -s configure set filesys.P4ROOT.min=5G" '' 1 1 || errmsg "Failed to set configurable filesys.P4ROOT.min."
else
   run "p4 -s configure set filesys.P4ROOT.min=20M" '' 1 1 || errmsg "Failed to set configurable filesys.P4ROOT.min."
fi

DiskSpaceAvail=$(df -k "$LOGS/" 2>/dev/null | grep / | awk '{print $4}')
if [[ "$DiskSpaceAvail" -ge "$MinKBFor5GLimits" ]]; then
   run "p4 -s configure set filesys.P4JOURNAL.min=5G" '' 1 1 || errmsg "Failed to set configurable filesys.P4JOURNAL.min."
else
   run "p4 -s configure set filesys.P4JOURNAL.min=20M" '' 1 1 || errmsg "Failed to set configurable filesys.P4JOURNAL.min."
fi

if [[ "$DiskSpaceAvail" -ge "$MinKBFor5GLimits" ]]; then
   run "p4 -s configure set filesys.P4LOG.min=5G" '' 1 1 || errmsg "Failed to set configurable filesys.P4LOG.min."
else
   run "p4 -s configure set filesys.P4LOG.min=20M" '' 1 1 || errmsg "Failed to set configurable filesys.P4LOG.min."
fi

DiskSpaceAvail=$(df -k "$DEPOTS/" 2>/dev/null | grep / | awk '{print $4}')
if [[ "$DiskSpaceAvail" -ge "$MinKBFor5GLimits" ]]; then
   run "p4 -s configure set filesys.depot.min=5G" '' 1 1 || errmsg "Failed to set configurable filesys.depot.min."
else
   run "p4 -s configure set filesys.depot.min=20M" '' 1 1 || errmsg "Failed to set configurable filesys.depot.min."
fi

DiskSpaceAvail=$(df -k /tmp/ 2>/dev/null | grep / | awk '{print $4}')
if [[ "$DiskSpaceAvail" -ge "$MinKBFor5GLimits" ]]; then
   run "p4 -s configure set filesys.TEMP.min=5G" '' 1 1 || errmsg "Failed to set configurable filesys.TEMP.min."
else
   run "p4 -s configure set filesys.TEMP.min=20M" '' 1 1 || errmsg "Failed to set configurable filesys.TEMP.min."
fi

run "p4 -s configure set server=4" '' 1 1 || errmsg "Failed to set configurable server."
run "p4 -s configure set monitor=2" '' 1 1 || errmsg "Failed to set configurable monitor."

# For UNIX/Linux servers, set monitor.lsof
run "p4 -s configure set monitor.lsof=\"/usr/bin/lsof -F pln\"" '' 1 1 || errmsg "Failed to set configurable monitor.lsof."

# For P4D 2013.2+, setting db.reorg.disable=1, which turns off
# dynamic database reorg, has been shown to significantly improve
# performance when Perforce databases (db.* files) are stored on
# some solid state storage devices, while not making a difference
# on others.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2013.1" ]]; then
	run "p4 -s configure set db.reorg.disable=1" '' 1 1 || errmsg "Failed to set configurable db.reorg.disable."
fi

# Performance Tracking as required by P4Promtheus.
run "p4 -s configure set track=1" '' 1 1 || errmsg "Failed to set configurable track."

# For P4D 2017.2.1594901 or greater, enable net.autotune.  For net.autotune
# to take effect, it must be enabled on both sides of a connection.  So, to
# get the full benefit, net.autotune must be enabled on all brokers, proxies,
# and clients.  See this KB article for details on fully enabling net.autotune:
# https://portal.perforce.com/s/article/15368
#
# For connections in which net.autotune is not enabled, the p4d default value
# of net.tcpsize takes effect.
#
# When P4D is older than 2014.2 but less than 2017.2.1594901, set net.tcpsize
# to 512k.  In 2014.2, the default value for net.tcpsize became 512k, a
# reasonable default, so it should not be set explicitly. Also, there are
# indications it can reduce performance if set when not needed.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" < "2014.2" ]]; then
   run "p4 -s configure set net.tcpsize=524288" '' 1 1 || errmsg "Failed to set configurable net.tcpsize."
elif [[ "$P4D_VERSION" > "2017.2.1594900" ]]; then
   msg "Unsetting configurable net.tcpsize, deferring to p4d default value."
	# Suppress expected error and ignore exit code when unsetting net.tcpsize.
   run "p4 -s configure unset net.tcpsize 2>/dev/null" ||:
else
   msg "Unsetting configurable net.autotune and net.tcpsize, deferring to p4d default values."
	# Suppress expected errors and ignore exit codes when unsetting net.autotune & net.tcpsize.
   run "p4 -s configure unset net.autotune 2>/dev.null" ||:
   run "p4 -s configure unset net.tcpsize 2>/dev/null" ||:
fi

# For P4D 2016.2.1468155+, set db.monitor.shared = max value.
if [[ "$P4D_VERSION" > "2016.2.1468154" ]]; then
   # This is the number of 8k pages to set aside for monitoring,
   # which requires pre-allocation of sufficient RAM.  The default
   # is 256, or 2MB, enough for about 128 active/concurrent processes.
   # The max as of 2016.2 is 4096.  Setting db.monitor.shared=0
   # causes the db.monitor on disk to be used instead, which can
   # potentially be a bottleneck.
   run "p4 -s configure set db.monitor.shared=4096" '' 1 1 || errmsg "Failed to set configurable db.monitor.shared."
fi

run "p4 -s configure set net.backlog=2048" '' 1 1 || errmsg "Failed to set configurable net.backlog."

run "p4 -s configure set lbr.autocompress=1" '' 1 1 || errmsg "Failed to set configurable lbr.autocompress."

# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2025.2" ]]; then
   run "p4 -s configure set lbr.unloaddepot.compress=1" '' 1 1 || errmsg "Failed to set configurable lbr.unloaddepot.compress."
fi

run "p4 -s configure set lbr.bufsize=1M" '' 1 1 || errmsg "Failed to set configurable lbr.bufsize."
run "p4 -s configure set filesys.bufsize=1M" '' 1 1 || errmsg "Failed to set configurable filesys.bufsize."

run "p4 -s configure set serverlog.file.1=$LOGS/auth.csv" '' 1 1 || errmsg "Failed to set configurable serverlog.file.1."
run "p4 -s configure set serverlog.retain.1=$KEEPLOGS" '' 1 1 || errmsg "Failed to set configurable serverlog.retain.1."

run "p4 -s configure set serverlog.file.3=$LOGS/errors.csv" '' 1 1 || errmsg "Failed to set configurable serverlog.file.3."
run "p4 -s configure set serverlog.retain.3=$KEEPLOGS" '' 1 1 || errmsg "Failed to set configurable serverlog.retain.3."

# The following are useful if using threat detection based on P4AUDIT
# logs or if those logs are otherwise desired. These are not enabled
# by default as they have special considerations for performance,
# storage, retention, and possibly external processing.
### p4 -s configure set serverlog.file.4="$LOGS/audit.csv"

run "p4 -s configure set serverlog.file.7=$LOGS/events.csv" '' 1 1 || errmsg "Failed to set configurable serverlog.file.7."
run "p4 -s configure set serverlog.retain.7=$KEEPLOGS" '' 1 1 || errmsg "Failed to set configurable serverlog.retain.7."

run "p4 -s configure set serverlog.file.8=$LOGS/integrity.csv" '' 1 1 || errmsg "Failed to set configurable serverlog.file.8."
run "p4 -s configure set serverlog.retain.8=$KEEPLOGS" '' 1 1 || errmsg "Failed to set configurable serverlog.retain.8."

# Add a custom trigger for tracking trigger events:
run "p4 -s configure set serverlog.file.11=$LOGS/triggers.csv" '' 1 1 || errmsg "Failed to set configurable serverlog.file.11."
run "p4 -s configure set serverlog.retain.11=$KEEPLOGS" '' 1 1 || errmsg "Failed to set configurable serverlog.retain.11."

# Temporary Change: Disable certain resource pressure features.
run "p4 -s configure set sys.pressure.mem.medium=0" '' 1 1 || errmsg "Failed to set configurable sys.pressure.mem.medium."
run "p4 -s configure set sys.pressure.mem.high=0" '' 1 1 || errmsg "Failed to set configurable sys.pressure.mem.high."

# Net Keepalives
run "p4 -s configure set net.keepalive.count=9" '' 1 1 || errmsg "Failed to set configurable net.keepalive.count."
run "p4 -s configure set net.keepalive.disable=0" '' 1 1 || errmsg "Failed to set configurable net.keepalive.disable."
run "p4 -s configure set net.keepalive.idle=180" '' 1 1 || errmsg "Failed to set configurable net.keepalive.idle."
run "p4 -s configure set net.keepalive.interval=15" '' 1 1 || errmsg "Failed to set configurable net.keepalive.interval."

SpecFile="${0%/*}/spec.depot.p4s"
if [[ -r "$SpecFile" ]]; then
   msg "Creating a depot named 'spec' of type 'spec'."
   if [[ "$NoOp" -eq 0 ]]; then
      p4 -s depot -i < "$SpecFile" ||\
         errmsg "Failed to create spec depot."
   else
      msg "NO_OP: Would have created spec depot with this spec:\n$(cat "$SpecFile")"
   fi
else
   warnmsg "Skipping spec depot creation due to missing depot spec file: $SpecFile"
fi

SpecFile="${0%/*}/unload.depot.p4s"
if [[ -r "$SpecFile" ]]; then
   msg "Creating a depot named 'unload' of unload 'unload'."
   if [[ "$NoOp" -eq 0 ]]; then
      p4 -s depot -i < "$SpecFile" ||\
         errmsg "Failed to create unload depot."
   else
      msg "NO_OP: Would have created unload depot with this spec:\n$(cat "$SpecFile")"
   fi
else
   warnmsg "Skipping unload depot creation due to missing depot spec file: $SpecFile"
fi

# Load shedding and other performance-preserving configurable.
# For p4d 2013.1+
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2013.1" ]]; then
   run "p4 -s configure set server.maxcommands=2500" '' 1 1 || errmsg "Failed to set configurable server.maxcommands."
fi

# For p4d 2013.2+ -Turn off max* command line overrides.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2013.2" ]]; then
   run "p4 -s configure set server.commandlimits=2" '' 1 1 || errmsg "Failed to set configurable server.commandlimits."
fi

msg "See: https://portal.perforce.com/s/article/3867"
run "p4 -s configure set rpl.checksum.auto=1" '' 1 1 || errmsg "Failed to set configurable rpl.checksum.auto."
run "p4 -s configure set rpl.checksum.change=2" '' 1 1 || errmsg "Failed to set configurable rpl.checksum.change."
run "p4 -s configure set rpl.checksum.table=1" '' 1 1 || errmsg "Failed to set configurable rpl.checksum.table."

# Define number of login attempts before there is a delay, to thwart
# automated password crackers.  Default is 3; set to a higher value to
# be more friendly to humans without compromising the protection.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2013.1" ]]; then
   run "p4 -s configure set dm.user.loginattempts=7" '' 1 1 || errmsg "Failed to set configurable dm.user.loginattempts."
fi

# For p4d 2016.1 Patch 5+
# Enable a server with an expired temp license to start, albeit with limited
# functionality, so that license expiry doesn't make it impossible to perform
# license management via the front-door.  This configurable allows the server
# to be started regardless of a bad license, though users will still be blocked
# by license invalid messages.  Perpetual commercial licenses never expire;
# this configurable will not affect those.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2016.1.1408676" ]]; then
   run "p4 -s configure set server.start.unlicensed=1" '' 1 1 || errmsg "Failed to set configurable server.start.unlicensed."
fi

# Starting with p4d 2015.1 Patch 5, disallow P4EXP v2014.2 (a client
# version known to misbehave) from connecting to the server.
# See:  http://portal.perforce.com/articles/KB/15014
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2015.1.1126924" ]]; then
   run "p4 -s configure set rejectList=\"P4EXP,version=2014.2\"" '' 1 1 || errmsg "Failed to set configurable rejectList."
fi

# For p4d 2011.1 thru 2015.1, set rpl.compress=3.  For p4d 2015.2+, set
# rpl.compress=4.  This setting compresses journal data only, which is
# almost always advantageous as it compresses well, while avoiding
# compression of archive data, which is a mixed bag in terms of performance
# benefits, and potentially a net negative.
# server.global.client.views - makes client views global in a commit/edge environment.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2015.2" ]]; then
   run "p4 -s configure set rpl.compress=4" '' 1 1 || errmsg "Failed to set configurable rpl.compress."
   run "p4 -s configure set server.global.client.views=1" '' 1 1 || errmsg "Failed to set configurable server.global.client.views."
elif [[ "$P4D_VERSION" > "2011.1" ]]; then
   run "p4 -s configure set rpl.compress=3" '' 1 1 || errmsg "Failed to set configurable rpl.compress."
fi

# Starting with p4d 2016.2, enable these features.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2016.2" ]]; then
   run "p4 -s configure set server.locks.global=1" '' 1 1 || errmsg "Failed to set configurable server.locks.global."
   run "p4 -s configure set proxy.monitor.level=3" '' 1 1 || errmsg "Failed to set configurable proxy.monitor.level."
fi

# Enable faster resubmit after failed submit.
run "p4 -s configure set submit.noretransfer=1" '' 1 1 || errmsg "Failed to set configurable submit.noretransfer."

# Recommended for Swarm
run "p4 -s configure set dm.shelve.promote=1" '' 1 1 || errmsg "Failed to set configurable dm.shelve.promote."
run "p4 -s configure set dm.keys.hide=2" '' 1 1 || errmsg "Failed to set configurable dm.keys.hide."
run "p4 -s configure set filetype.bypasslock=1" '' 1 1 || errmsg "Failed to set configurable filetype.bypasslock."

# Starting with p4d 2018.2 (as tech-preview, 2019.2 for GA), add best
# practices for Extensions.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2018.2" ]]; then
   run "p4 -s configure set server.extensions.dir=$LOGS/p4-extensions" '' 1 1 || errmsg "Failed to set configurable server.extensions.dir."
fi

# Set configurables to optimize for P4 Authentication Service (P4AS)
# deployment. These will also affect behavior of older `auth-check-sso`
# triggers.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2018.2" ]]; then
   run "p4 -s configure set auth.sso.allow.passwd=1" '' 1 1 || errmsg "Failed to set configurable auth.sso.allow.passwd."
   run "p4 -s configure set auth.sso.nonldap=1" '' 1 1 || errmsg "Failed to set configurable auth.sso.nonldap."
fi

# Enable parallelization.
run "p4 -s configure set net.parallel.max=10" '' 1 1 || errmsg "Failed to set configurable net.parallel.max."
run "p4 -s configure set net.parallel.threads=4" '' 1 1 || errmsg "Failed to set configurable net.parallel.threads."

# Limit max parallel syncs.
run "p4 -s configure set net.parallel.sync.svrthreads=150" '' 1 1 || errmsg "Failed to set configurable net.parallel.sync.svrthreads."

# Enable partitioned clients.
run "p4 -s configure set client.readonly.dir=client.readonly.dir" '' 1 1 || errmsg "Failed to set configurable client.readonly.dir."
run "p4 -s configure set client.sendq.dir=client.readonly.dir" '' 1 1 || errmsg "Failed to set configurable client.sendq.dir."
run "p4 -s configure set db.partition.dropondelete=1" '' 1 1 || errmsg "Failed to set configurable db.partition.dropondelete."

# Starting with p4d 2016.1, use auth.id to simplify ticket handling.
# After setting auth.id, login again.
#
# The default value incorporates ORGNAME (from p4_vars), if set, to make
# auth.id more unique across an enterprise. This is deliberately NOT based
# on $P4SERVER (which is a fixed p4_<SDPInstance> shorthand used elsewhere
# for filenames/log tags) so that P4SERVER's other uses are unaffected. If
# ORGNAME is blank, the resulting value is unchanged from prior releases.
#
# A meaningfully unique auth.id also matters for cross-organization P4
# push/fetch: the auth.id of the server you're pushing to/fetching from
# must differ from your own, or one side has to change its auth.id to
# avoid a collision. The old p4_<SDPInstance>-only default (e.g. "p4_1")
# collided often since most SDP instances are numbered similarly; adding
# ORGNAME makes such collisions far less likely for the increasingly
# common case of cross-organization push/fetch between P4 customers.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2016.1" ]]; then
   run "p4 -s configure set rpl.forward.login=1" '' 1 1 || errmsg "Failed to set configurable rpl.forward.login."
   run "p4 -s configure set auth.id=p4_${ORGNAME:+${ORGNAME}.}${SDP_INSTANCE}" '' 1 1 || errmsg "Failed to set configurable auth.id."
   "$P4CBIN"/p4login
fi

# Set SDP version identifying info.
run "p4 -s counter SDP_DATE \"$(date +'%Y-%m-%d')\"" '' 1 1 || errmsg "Failed to set counter SDP_DATE."
run "p4 -s counter SDP_VERSION \"$SDP_VERSION\"" '' 1 1 || errmsg "Failed to set counter SDP_VERSION."

# Enable real time monitoring with 'p4 monitor rt'.
# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2023.1" ]]; then
   run "p4 -s configure set rt.monitorfile=monfile.mem" '' 1 1 || errmsg "Failed to set configurable rt.monitorfile."
fi

# Basic security features.
run "p4 -s configure set run.users.authorize=1" '' 1 1 || errmsg "Failed to set configurable run.users.authorize."
run "p4 -s configure set dm.user.hideinvalid=1" '' 1 1 || errmsg "Failed to set configurable dm.user.hideinvalid."
run "p4 -s configure set security=4" '' 1 1 || errmsg "Failed to set configurable security."

msg "Restarting server to ensure all configurable changes take effect."
if [[ "$NoOp" -eq 0 ]]; then
   svc_stop_p4d
   svc_start_p4d
else
   msg "NO_OP: Would have stopped and then started p4d."
fi

msg "Logging in."
if [[ "$NoOp" -eq 0 ]]; then
   "$P4CBIN"/p4login -v
else
   msg "NO_OP: Would have run: $P4CBIN/p4login -v"
fi

if [[ "$DoCheckpoint" -eq 1 ]]; then
   if [[ ! -r "$OFFLINE_DB/db.domain" ]]; then
      msg "Creating initial checkpoint with: live_checkpoint.sh $SDPInstance"
      if [[ "$NoOp" -eq 0 ]]; then
         "$P4CBIN/live_checkpoint.sh" "$SDPInstance"
      else
         msg "NO_OP: Would have done: $P4CBIN/live_checkpoint.sh $SDPInstance"
      fi
   else
      msg "Skipping live checkpoint because db.* files exist in $OFFLINE_DB."
   fi
fi

# shellcheck disable=SC2072
if [[ "$P4D_VERSION" > "2017.2.1594900" ]]; then
   msg "\nThe net.autotune value has been set on the server.  To get the full benefit, it must also be\nenabled on proxies, brokers, and clients as well."
fi

msg "\nSummary:"
if [[ "$ErrorCount" -eq 0 && "$WarningCount" -eq 0 ]]; then
   msg "\nAll processing completed successfully."
elif [[ "$ErrorCount" -eq 0 ]]; then
   warnmsg "Processing completed with no errors but $WarningCount warnings. Review the output carefully searching for 'Warning:', for example:\n\tgrep ^Warning: $Log"
else
   errmsg "Processing completed, but with $ErrorCount errors and $WarningCount warnings. Review the output carefully searching for '^Error:' and 'Warning:', for example:\n\tgrep -E '^(Error|Warning):' $Log"
fi

# See the terminate() function in logging.lib.
exit "$ErrorCount"
# Change User Description Committed
#1 33444 Claude (AI Agent by Anthropic) Initial population of r26.1.0.BETA from main.
//p4-sdp/main/Server/setup/configure_new_server.sh
#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/Server/setup/configure_new_server.sh
#10 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.
#9 33099 C. Thomas Tyler It Begins!
 Potentially the final merge of SDP from Classic to Streams!

This aligns with SDP 2025.2 Patch 1.

p4 merge -b SDP_Classic_to_Streams

p4 resovle -n | wc -l
46

p4 resolve -as

p4 resovle -n | wc -l
0

p4 submit
#8 32990 C. Thomas Tyler p4 merge -b SDP_Classic_to_Streams
p4 resolve -as

All files resolved automatically.  The "real" merge work comes in the coming
Merge Down from dev->dev_rebrand.
#7 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.
#6 31913 C. Thomas Tyler p4 merge -b SDP_Classic_to_Streams
  p4 resolve -as
#5 31779 C. Thomas Tyler p4 merge -b SDP_Classic_to_Streams; p4 resolve -as
#4 31722 C. Thomas Tyler Merge to Streams for Classic with:
p4 merge -b SDP_Classic_to_Streams
#3 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
#2 31574 C. Thomas Tyler Merged SDP 2024.2 Patch 4 from Classic to Streams.
p4 merge -b SDP_Classic_to_Streams
#1 31397 C. Thomas Tyler Populate -b SDP_Classic_to_Streams -s //guest/perforce_software/sdp/...@31368.
//guest/perforce_software/sdp/dev/Server/setup/configure_new_server.sh
#65 31358 C. Thomas Tyler Removed obsolete reference to discontinued product.
Brought bat script in alignment with bash script for P4AUDIT settings.
Added info in comments re: P4AUDIT not being enabled by default.
#64 31357 C. Thomas Tyler Refined guidance in configure_new_server.{bat,sh} to align with ccheck.sh.
#63 31136 C. Thomas Tyler Added content to cover scenario where P4JOURNAL is set in db.config.

This addresses SDP-737 (Doc): In SDP Legacy Upgrade Guide, advise p4d -cunset P4JOURNAL if needed.

Also updated URL for list of configurables due to change in Perforce web site layout,
with docs moved from somewhere under www.perforce.com to somewhere under
help.perforce.com.

For example:

Old URL for configurables:
https://www.perforce.com/manuals/cmdref/Content/CmdRef/configurables.alphabetical.html

New URL for configurables:
https://help.perforce.com/helix-core/server-apps/cmdref/current/Content/CmdRef/configurables.alphabetical.html
#62 30847 C. Thomas Tyler The '-init' now creates an initial live checkpoint.
#61 30610 C. Thomas Tyler New best practice configurable: Set rt.monitorfile.

#review-30611
#60 30500 C. Thomas Tyler New best practice configurable: dm.user.hideinvalid=1

#review-30501
#59 30428 C. Thomas Tyler Fixed bug in determining threshhold for setting 5G vs.
20M safety values
for filesys.*.min configurables.
#58 30304 C. Thomas Tyler Tweaked configure_new_server.sh to be easier to work with in lab scale
environments.
#57 30303 C. Thomas Tyler Handle missing required parameter.
#56 30283 C. Thomas Tyler New best practice: Set submit.noretransfer=1.

#review-30284
#55 30019 C. Thomas Tyler Added net.keepalive settings to best practices.

#review @robert_cowham @mwittenberg
#54 29923 C. Thomas Tyler Updated HTML hyperlinks to use 'portal.perforce.com'.

This replaces currently broken links to 'answers.perforce.com' and
currently redirected links to 'community.perforce.com'.

#review-29924
#53 29849 C. Thomas Tyler Updates to configure_new_server.sh:
* Added logic to start service so this script can now be run if the service is down at the start.
* The 'security' configurable is now set to 4 (was unset).
* Enhanced error handling.
* Added logic to more fully initialize a new/empty server:
  - Create perforce P4USER (if there is only a single user on the system).
  - Create Automation group.
  - Initialize basic Protections.

Updates to configure_new_server.bat:
* Added logic to start service so this script can now be run if the service is down at the start.
* The 'security' configurable is now set to 4 (was unset).

In mkdirs.cfg, change the default password to one good enough to be used with `security=4`.

#review-29850
#52 29600 C. Thomas Tyler Added configurables that are good for HAS deployments, and deemed
harmless for non-HAS deployments, auth.sso.allow.passwd and
auth.sso.nonldap.

Removed explicit setting of filesys.checklinks, now deferring to p4d
default.

Set reasonable defaults for net.parallel.max, net.parallel.threads,
net.parallel.sync.svrthreads.

Changed monitor from 1->2.

Removed ref to discontinued KB link.

Fixed shellcheck compliance issues with *.sh script, and added summary
of errors and warnings.

#review @andy_boutte @robert_cowham @mark_zinthefer
#51 28522 C. Thomas Tyler Changed default for server=4 to server=3.
#50 27854 C. Thomas Tyler Correction to comments in configure_new_server.sh.
This is a non-functional
change.
#49 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
#48 27516 C. Thomas Tyler Updated stale core doc link with KB article re: rpl.* params.

Non-functional change.

#review @d_benedict
#47 27511 C. Thomas Tyler Removed submit.allowbgtransfer as a default setting.
It requires
additional configuration when set.

#review @robert_cowham
#46 26920 C. Thomas Tyler Added setting for server.extensions.dir.
#45 26689 C. Thomas Tyler Fixed typo in output.
No functional change.
#44 26688 C. Thomas Tyler Removed 'Operating System' value from rejectList, per advice of
Engineering and Support.
#43 26571 C. Thomas Tyler Fixed bug resulting in failure due to undefined LOGFILE variable.

Addressed shellcheck compliances issues.

#review-26572
#42 26400 C. Thomas Tyler Added refresh_P4ROOT_from_offline_db.sh.

Updated backup_functions.sh to support functionality for db refresh.

Upgrade start_p4d() and stop_p4d() to use systemd if available, else
use the underlying SysV init scripts.

Updated verify_sdp.sh to be called from other scripts (sans
its own logging).  Added many checks to verify_sdp.sh to
support P4ROOT/offline_db swap.

Logic in P4ROOT/offline_db swap is more careful about what gets
swapped.

Added start_p4broker() and stop_p4broker() that behave similarly.

More shellcheck compliance.

#review-26401
#41 26158 C. Thomas Tyler Enable 'p4 submit -b' by setting submit.allowbgtransfer=1 for
P4D 2019.1+.
#40 25802 C. Thomas Tyler Comment clarity improvements.
No functional change.
#39 25004 C. Thomas Tyler Committing Rusy's shelved change after merging with other changes.

#review-28411
#38 24875 C. Thomas Tyler Added setting of dm.info.hide=1, to hide P4ROOT and other
sensitivie info from output of 'p4 info' from a non-authenticated
user.

Removed setting of dm.user.resetpassword, which was already
commented out in the Unix version. This is not really a
general best practice to have set, as most accounts use some
form of LDAP integration.  And even when not, having this
set imposes a certaion workflow on Perforce-managed passwords
that is often better handled in other ways.
#37 24587 C. Thomas Tyler Added net.autotune=1 setting and related comments.

Corrected misinformation in comments related to net.tcpsize configurable, and tweaked logic slightly.

Added more info in README and changed format to Markdown (renaming from .txt to .md).

Enhanced gen_default_broker_cfg.sh to detect whether net.autotune is enabled, and if so, add net.autotune to the broker configuration.

#review-24207 @nick_poole
#36 24222 C. Thomas Tyler Enhanced rejectList value for P4EXP to also reject versions of
P4EXP that impersonate the version string from Windows Explorer.
The 'Operating System' also blocks the versions that impersonate.
#35 24145 C. Thomas Tyler Added comment for why filesys.P4LOG.main and filesys.TEMP.min aren't set.
Comment tweak only, no functional change.
#34 23679 C. Thomas Tyler Added comment indicating that these scripts serve as a guide defining
best practices configurables for a production environment.  Also
added a handy URL to bookmark documenting many configurables:

https://www.perforce.com/perforce/doc.current/manuals/cmdref/Content/CmdRef/configurables.configurables.html

No functional change.
#33 23442 C. Thomas Tyler Fixed issue with super user not being logged in after the restart
that occurs after setting auth.id.
#32 23316 C. Thomas Tyler Added filetype.bypasslock=1 configurable, recommended for Swarm.

This is needed to allow reviews of exclusively locked files.  It
allows Swarm to unshelve such files for review, by doing:
p4 unshelve --bypass-exclusive-lock -s <shelved_changelist>
#31 23000 Russell C. Jackson (Rusty) net.tcpsize=0 should only be set on 2017.1 and later.
#30 22977 C. Thomas Tyler For P4D 2016.2/1468155+ servers, added configurable setting.
p4 configure set db.monitor.shared=4096

Also added notes describing why we set it and other how it works.
#29 22520 C. Thomas Tyler Updated configure_new_server.* scripts, which reflect SDP best
practices for enterprise environments.

Taking out the setting to disable autologinpromt, upon discovery
that it has a safety feature of going interactive only in an
interactive terminal shell.  It will still wreak havoc with
non-interactive commands that do things like 'ssh' with '-t' (to
simulate a interactive terminal shell, as is sometimes
necessary in automation).  But as that is somewhat obscure,
the most widely applicable best practice is to use the default
p4d behavior, i.e. with autologinprompt enabled.

#review @sven_erik_knop @nick_poole
#28 22393 C. Thomas Tyler Enhanced to search for the *.depot.p4s spec files in whatever dir the
configure_new_server.sh script is in when the script is exectued, so
that you don't have to run it from the directory it lives in.

#review-22391
#27 22031 C. Thomas Tyler Bumped up dm.user.loginattempts from 3 to 7, to be more friendly to
humans who mistype passwords.
#26 21883 C. Thomas Tyler Added new configurable setting: 'filesys.bufsize=1M'.
#25 21630 C. Thomas Tyler Configurables for best results with Swarm in particular, but
a generally better overall experience.
p4 configure set dm.shelve.promote=1
p4 configure set dm.keys.hide=2

Note that setting dm.shelve.promote=1 will slow down shelving
operations on an edge server, but will make the shelves globally
available.  On balance, dm.shelve.promote=1 is recommended,
though admins should be aware of the trade off (a simpler global
view and cross-site code reviews, at some cost for performance
of shelving at edge sites).
#24 21454 C. Thomas Tyler For p4d 2016.1 Patch 5+ servers, enable a server with an expired temp license to
start, albeit with limited functionality, so that license expiry doesn't make it
impossible to perform license management via the front-door.  This configurable
allows the server to be started regardless of a bad license, though users will
still be blocked by license invalid messages.  Perpetual commercial licenses never
expire; this configurable will not affect those.

Also added +x file type modifier to the *.bat file.
#23 21369 C. Thomas Tyler Configured to re-login after setting auth.id, and restart p4d at the
end of the script.
#22 21232 C. Thomas Tyler Define auth.id for P4D 2016.1+ servers to "p4_<instance>".

The value doesn't really affect behavior for auth.id, so long as it's defined.
#21 21173 C. Thomas Tyler Taking advantage of new 2016.2 configurables.
#20 20332 C. Thomas Tyler A few configurable tweaks:
* Setting server=4 logging as the default.
* Setting net.backlog=2048, per Support.
* Setting net.tcpsize=0 to engage 'auto-self-tuning' magic.
#19 20305 Russell C. Jackson (Rusty) Commented out the audit log.
#18 20248 Russell C. Jackson (Rusty) Commented the line about passwordreset.
I find myself commenting that out all the time now because people want AD integration.
#17 19837 C. Thomas Tyler Added defense against known-misbehaving client versions
using rejectList configurable, availabe starting with P4D
2015.1 Patch 5.

See: http://answers.perforce.com/articles/KB/15014
#16 19661 C. Thomas Tyler Change to best-practice configurables.

For p4d 2016.1 Patch 2+ (2016.1.1395783+), disable auto
prompting for a password, as this can cause 'p4' commands
to go interactive that wouldn't normally, wreaking havoc
with automation.

Fix with: p4 configure set auth.autologinprompt=0.
#15 19302 C. Thomas Tyler Adjusted setting of db.reorg.disable to go with the block comments
made previously to receive a setting for db.reorg.disable.  In those
comments, setting of the value had been commented out, but now are
not.

This impact has no functional change other than adding the safety
feature of avoiding setting db.reorg.disable for older versions of
p4d that don't support it.
support it.
#14 19112 Russell C. Jackson (Rusty) Turn off database reorg per best practice recommendation from Anton and Michael S.
Stop running weekly_backup.sh automatically since a compact database actually causes
a performance hit. Added note to occasionally run weekly_backup.sh to recapture free space.
#13 18937 C. Thomas Tyler Removed configurables for 'errors' and 'events' structured logs.
Added 'maxmb' setting of 200MB for the structured audit log.

Enhanced Windows version work like Unix version:
* Added a check for the 'instance' paramter.
* Loads SDP environment from p4env.bat (equiv of p4_vars).
* Uses SDP environment to set various things.
* Now creates 'spec' and 'unload' depots.

Changed both Unix and Windows versions to use KEEPLOGS setting
defiend in standard SDP enviornment file to apply to 'retain'
setting of structured server logs.

Removed obsolete comment relationg to the SetDepotSpecMapField
trigger, which was obsoleted with server.depot.root in 2014.1.

Changed mechanism for creating 'spec' and 'unload' depots
to one that works the same for Windows and Linux.

Removed defaultChangeType setting.  The impact on Swarm and
performance may not be worth the security benefit for.  It
is still a good practice for some environments, but I'm not
sure it's a clear best practice to set it.
#12 16805 Russell C. Jackson (Rusty) #review-16795

Added the audit log as a default structured log and set the rotation to keep 31 days.
#11 16460 C. Thomas Tyler Routine Merge Down to dev from main using:
p4 merge -b perforce_software-sdp-dev
#10 16335 C. Thomas Tyler Routine Merge Down to dev from main using:
p4 merge -b perforce_software-sdp-dev
#9 16029 C. Thomas Tyler Routine merge to dev from main using:
p4 merge -b perforce_software-sdp-dev
#8 15554 C. Thomas Tyler Routine merge-down from main.
#7 12116 Russell C. Jackson (Rusty) Update dev from main.
#6 12107 C. Thomas Tyler Routine merge down from 'main' to 'dev', resolved with
'p4 resolve -as'.
#5 12030 C. Thomas Tyler Merged down from main to refresh dev branch for SDP.
#4 12028 C. Thomas Tyler Refreshed SDP dev branch, merging down from main.
#3 11465 Russell C. Jackson (Rusty) Added monitor and lbr.autocompress.
#2 11463 Russell C. Jackson (Rusty) Updated dev to prepare for Summit agreed changes.
#1 10638 C. Thomas Tyler Populate perforce_software-sdp-dev.
//guest/perforce_software/sdp/main/Server/setup/configure_new_server.sh
#1 10148 C. Thomas Tyler Promoted the Perforce Server Deployment Package to The Workshop.