#!/bin/bash #============================================================================== # Copyright and license info is available in the LICENSE file included with # the Server Deployment Package (SDP), and also available online: # https://swarm.workshop.perforce.com/projects/perforce-software-sdp/view/main/LICENSE #------------------------------------------------------------------------------ set -u #============================================================================== # Declarations and Environment declare ThisScript="${0##*/}" declare RunDir="${0%%/*}" declare Version=7.0.0 declare CmdLine="$ThisScript $*" declare ThisUser= declare ThisHost=${HOSTNAME%%.*} declare SDPInstance=UnsetSDPInstance declare SDPInstallRoot="/p4" declare PerforcePackageBase="/opt/perforce" declare SDPPackageBase="$PerforcePackageBase/helix-sdp" declare SDPPackageBins="$SDPPackageBase/helix_binaries" declare ImmutableSDPDir="$SDPPackageBase/sdp" declare WritableP4Dir="$SDPPackageBase/p4" declare WritableSDPDir="$WritableP4Dir/sdp" declare SDPMountPointBase="" declare SymlinkTarget= declare ConfigFile= declare SetcapCmd= declare TmpFile= declare Cmd= declare GenSudoersScript= declare FirewallType= declare FirewallDir= declare -i LoadActiveCrontab=1 declare -i CrontabFileGenerated=0 declare -i DoFirewall=1 declare -i FirewallOnline=0 declare -i NoOp=0 declare -i Debug=0 declare -i PreflightOnly=0 declare -i TestMode=0 declare -i TestCleanup=0 declare -i DoChownCommands=1 declare -i DoNFSChownCommands=1 declare -i UpdateSudoers=0 declare -i LimitedSudoers=1 declare -i EnableSystemdServices=1 declare -i RunningAsRoot=0 declare -i InstallP4D=1 declare -i InstallP4Broker=1 declare -i InstallP4Proxy=0 declare -i InstallP4DTG=0 declare -i ErrorCount=0 declare -i WarningCount=0 declare -i UsePackageDirs=0 declare -i LimitedSudoers=2 declare BinList= declare InitMechanism= declare InitScripts= declare SDPVersionString= declare SDPVersionFile= declare SDPVersion= declare OverrideCD= declare OverrideDD= declare OverrideLG= declare OverrideDB1= declare OverrideDB2= declare SystemdTemplatesDir= declare TarRoot= declare TarRootCommon= declare TarRootConfig= declare TarRootCron= declare TarRootBinDir= declare TarRootInit= declare TarRootSSL= declare TarRootUnsupported= declare ServerID= declare TargetServerID= declare TargetPort= declare ListenPort= declare ServerType= declare -i ServerIDSet=0 declare -i TargetPortSet=0 declare -i ListenPortSet=0 declare -i FastMode=0 declare -i UseSystemd=1 declare -i DoServiceInit=1 declare Log= declare ExtendPermsTo= declare ExecPerms= declare ReadPerms= declare CrontabFile= declare CrontabFileInP4= declare SDPCrontabDir= #============================================================================== # Local Functions function msg () { echo -e "$*"; } function dbg () { [[ "$Debug" -eq 0 ]] || msg "DEBUG: $*"; } function errmsg () { msg "\\nError: (line: ${BASH_LINENO[0]}) $*" >&2; ErrorCount+=1; } function warnmsg () { msg "\\nWarning: (line: ${BASH_LINENO[0]}) $*"; WarningCount+=1; } function bail() { errmsg "(line: ${BASH_LINENO[0]}) ${1:-Unknown Error}\\n" >&2; exit "${2:-1}"; } #------------------------------------------------------------------------------ # This function takes as input an SDP version string, and returns a version # id of the form YYYY.N.CL, where YYYY is the year, N is an incrementing # release ID with a given year, and CL is a changelist identifier. The # YYYY.N together comprise the major version, often shortened to YY.N, e.g. # r20.1 for the 2020.1 release. # # The full SDP Version string looks something like this: # Rev. SDP/MultiArch/2019.3/26494 (2020/04/23). # # This function parses that full string and returns a value like: 2019.3.26494 function get_sdp_version_from_string () { local versionString="${1:-}" local version= version="20${versionString##*/20}" version="${version%% *}" version="${version/\//.}" echo "$version" } #------------------------------------------------------------------------------ # Function: run ($cmd, $desc, $honorNoOp) # # Input: # # $cmd - Command to execute, including arguments.? # # $desc - Description of command to run. Optional; default is no description. # # $honorNoOp - If set to 1, command is always executed; NoOp setting is ignored. # Optional, default is 0. #------------------------------------------------------------------------------ function run () { declare cmd="${1:-echo}" declare desc="${2:-}" declare honorNoOp="${3:-1}" [[ -n "$desc" ]] && msg "$desc" msg "Running: $cmd" if [[ "$NoOp" -eq 1 && "$honorNoOp" -eq 1 ]]; then msg "NO_OP: Would run $cmd" return 0 else # shellcheck disable=SC2086 if eval $cmd; then return 0 else return 1 fi 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 # 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 "Incorrect command line usage." #------------------------------------------------------------------------------ function usage { declare style=${1:--h} declare usageErrorMessage=${2:-Unset} if [[ "$usageErrorMessage" != Unset ]]; then msg "\\n\\nUsage Error:\\n\\n$usageErrorMessage\\n\\n" fi # tag::includeManual[] msg "USAGE for $ThisScript v$Version: $ThisScript <instance> [-s <ServerID>] [-t <ServerType>] [-tp <TargetPort>] [-lp <ListenPort>] [-I <svc>[,<svc2>]] [-MDD /bigdisk] [-MCD /ckps] [-MLG /jnl] [-MDB1 /db1] [-MDB2 /db2] [-f] [-p] [-no_init|-no_systemd|-no_enable] [-fs|-ls] [-no_cron] [-no_firewall] [-test [-clean]] [-n] [-L <log>] [-d|-D] OR $ThisScript <instance> [-c <CfgFile>] [-f] [-p] [-no_init|-no_systemd] [-test [-clean]] [-n] [-L <log>] [-d|-D] or $ThisScript [-h|-man] " if [[ $style == -man ]]; then msg " DESCRIPTION: == Overview == This script initializes an SDP instance on a single machine. This script is intended to support two scenarios: * First time SDP installation on a given machine. In this case, the user calls the install_sdp.sh script, which in turn calls this script. See 'install_sdp.sh -man' for more information. * Adding new SDP instances (separate Helix Core data sets) to an existing SDP installation on a given machine. For this scenario, this mkdirs.sh script is called directly. An SDP instance is a single Helix Core data set, with its own unique set of one set of users, changelist numbers, jobs, labels, versioned files, etc. An organization may run a single instance or multiple instances. This is intended to be run either as root or as the operating system user account (OSUSER) that p4d is configured to run as, typically 'perforce'. It should be run as root for the initial install. Subsequent additions of new instances do not require root. == Directory Structure == If an initial install as done by a user other than root, various directories must exist and be writable and owned by 'perforce' before starting: * /p4 * /hxcheckpoints * /hxdepots * /hxlogs * /hxmetadata * /hxmetadata2 * /opt/perforce/helix-sdp (optional; used for package installations) The directories starting with '/hx' are configurable, and can be changed by settings in the mkdirs.cfg file (or mkdirs.N.cfg), or with command line options as illustrated here: -MDD /bigdisk -MCD /ckps -MLG /jnl -MDB1 /db1 -MDB2 /db2 This script creates an init script in the /p4/N/bin directory. == Crontab == Crontabs are generated for all server types. After running this script, set up the crontab based on templates generated as /p4/common/etc/cron.d. For convenience, a sample crontab is generated for the current machine as /p4/p4.crontab.<SDPInstance> (or /p4/p4.crontab.<SDPInstance>.new if the former name exists). These files should be copied or merged into any existing files named with this convention: /p4/common/etc/cron.d/crontab.<osuser>.<host> where <osuser> is the user that services run as (typically 'perforce'), and <host> is the short hostname (as returned by a 'hostname -s' command). == Init Mechanism == If this script is run as root, the init mechanism (Systemd or SysV) is configured for installed services. The Systemd mechanim is used if the the /etc/systemd/system folder exists and systemctl is in the PATH of the root user. Otherwise, the SysV init mechanism is used. == Firewall Configuration == This script checks to see if a known firewall type is available. The firewalld is checked using the command 'firewall-cmd --state' command, and the ufw firewall is checked using the 'ufw status'. If either firewall is detected, the ports required for Helix Core applications installed are opened in the firewall. For more information, see the templates in these folders: /p4/common/etc/firewalld /p4/common/etc/ufw If the firewall service is not online, no firewall coniguration is performed. == SELinux Configuration == If Systemd is used and the semanage and restorecon utilities are available in the PATH of the root user, then SELinux configuration for the installed services is done. REQUIRED PARAMETERS: <instance> Specify the SDP instance name to add. This is a reference to the Perforce Helix Core data set. OPTIONS: -s <ServerID> Specify the ServerID, overriding the REPLICA_ID setting in the configuration file. -S <TargetServerID> Specify the ServerID of the P4TARGET of the server being installed. Use this only when setting up an HA replica of an edge server. -t <ServerType> Specify the server type, overriding the SERVER_TYPE setting in the config file. Valid values are: * p4d_master - A master/commit server. * p4d_replica - A replica with all metadata from the master (not filtered in any way). * p4d_filtered_replica - A filtered replica or filtered forwarding replica. * p4d_edge - An edge server. * p4d_edge_replica - Replica of an edge server. If used, '-S <TargetServerID>' is required. * p4broker - An SDP host running only a standalone p4broker, with no p4d. * p4proxy - An SDP host running only a standalone p4p with no p4d. -tp <TargetPort> Specify the target port. Use only if ServerType is p4proxy and p4broker. -lp <ListenPort> Specify the listen port. Use only if ServerType is p4proxy and p4broker. -I [<svc>[,<svc2>]] Specify additional init scripts to be added to /p4/<instance>/bin for the instance. By default, the p4p service is installed only if '-t p4proxy' is specified, and p4dtg is never installed by default. Valid values to specify are 'p4p' and 'dtg' (for the P4DTG init script). If services are not installed by default, they can be added later using templates in /p4/common/etc/init.d. Also, templates for systemd service files are supplied in /p4/common/etc/systemd/system. -MDD /bigdisk -MCD /ckps -MLG /jnl -MDB1 /db1 -MDB2 /db2 Specify the '-M*' optons to specify mount points, overriding DD/CD/LG/DB1/DB2 settings in the config file. Sample: -MDD /bigdisk -MLG /jnl -MDB1 /fast If -MDB2 is not specified, it is set the the same value as -MDB1 if that is set, or else it defaults to the same default value as DB1. -c <CfgFile> Specify the path to the configuration file to use, overriding the default logic of finding the file based on naming convention. -f Specify -f 'fast mode' to skip chown/chmod commands on depot files. This should only be used when you are certain the ownership and permissions are correct, and if you have large amounts of existing data for which the chown/chmod of the directory tree would be slow. -p Specify '-p' to halt processing after preflight checks are complete, and before actual processing starts. By default, processing starts immediately upon successful completion of preflight checks. -no_init Specify '-no_init' to avoid any service configuration, which is done by default if running as root (using systemd if available, otherwise SysV). If '-no_init' is used, then neither systemd nor SysV init mechanism is configured for installed services. This option is implied if not running as root. This option is implied if '-test' is used. -no_systemd Specify '-no_systemd' to avoid using systemd, even if it appears to be available. By default, systemd is used if it appears to be available. This is helpful in operating in containerized test environments where systemd does not work even if it appears to be available. This option is implied if the systemctl command is not available in the PATH of the root user. This option is implied if '-no_init' is used. -no_enable Specify '-no_enable' to avoid enabling systemd services to start automatically after a reboot. If this option is used, systemd services will still be created, allowing services to be manually started and stopped. Specifically, this options means the 'systemctl enable' command is not run for generated services. -no_cron Specify '-no_cron' to avoid loading the crontab. A crontab file is generated in the $SDPInstallRoot directory, but but with '-no_cron, this file is not loaded as the active crontab. -no_firewall Specify '-no_firewall' to avoid attempting firewall configuration. By default, if the firewalld service is found to be running, it is configured so that the ports for p4d and p4broker are open. -fs Specify '-full' when calling gen_sudoers.sh to install a new, full sudoers file. This option is only available if running as root. This option is mutually exclusive with '-ls'. See 'gen_sudoers.sh -man' for more info. -ls Specify '-limited' when calling gen_sudoers.sh to install a new, limited sudoers file. This option is only available if running as root. This option is mutually exclusive with '-fs'. See 'gen_sudoers.sh -man' for more info. -L <log> Specify the path to a log file, or the special value 'off' to disable logging. By default, all output (stdout and stderr) goes to this file in the current directory: mkdirs.<instance>.<datestamp>.log NOTE: This script is self-logging. That is, output displayed on the screen is simultaneously captured in the log file. Do not run this script with redirection operators like '> log' or '2>&1', and do not use 'tee'. DEBUGGING OPTIONS: -test Specify '-test' to execute a simulated install to /tmp/p4 as the install root (rather than /p4), and with the mount point directories specified in the configuration file prefixed with /tmp/hxmounts, defaulting to: * /tmp/hxmounts/hxdepots * /tmp/hxmounts/hxlogs * /tmp/hxmounts/hxmetadata This option implies '-no_init'. -clean Specify '-clean' with '-test' to clean up from prior test installs, which will result in removal of files/folders installed under /tmp/hxmounts and /tmp/p4. Do not specify '-clean' if you want to test a series of installs. -n No-Op. In No-Op mode, no actions that affect data or structures are taken. Instead, commands that would be run are displayed. This is an alternative to -test. Unlike '-p' which stops after the preflight checks, with '-n' more processing logic can be exercised, with greater detail about what commands that would be executed without '-n'. -d Increase verbosity for debugging. -D Set extreme debugging verbosity, using bash '-x' mode. Also implies -d. HELP OPTIONS: -h Display short help message -man Display man-style help message FILES: The mkdirs.sh script uses a configuration file for many settings. A sample file, mkdirs.cfg, is included with the SDP. After determining your SDP instance name (e.g. '1' or 'abc'), create a configuration file for it named mkdirs.<N>.cfg, replacing 'N' with your instance. Running 'mkdirs.sh N' will load configuration settings from mkdirs.N.cfg. UPGRADING SDP: This script can be useful in testing and upgrading to new versions of the SDP, when the '-test' flag is used. EXAMPLES: Example 1: Setup of first instance Setup of the first instance on a machine using the default instance name, '1', executed after using sudo to become root: $ sudo su - $ cd /hxdepots/sdp/Server/Unix/setup $ vi mkdirs.cfg Adjust settings as desired, e.g P4PORT, P4BROKERPORT, etc. $ ./mkdirs.sh 1 A log will be generated, mkdirs.1.<timestamp>.log Example 2: Setup of additional instance named 'abc'. Setup a second instance on the machine, which will be a separate Helix Core instance with its own P4ROOT, its own set of users and changelists, and its own license file (copied from the master instance). Note that while the first run of mkdirs.sh on a given machine should be done as root, but subsequent instance additions can be done as the 'perforce' user (or whatever operating system user accounts Perforce Helix services run as). $ sudo su - perforce $ cd /hxdepots/sdp/Server/Unix/setup $ cp mkdirs.cfg mkdirs.abc.cfg $ chmod +w mkdirs.abc.cfg $ vi mkdirs.abc.cfg Adjust settings in mkdirs.abc.cfg as desired, e.g P4PORT, P4BROKERPORT, etc. $ ./mkdirs.sh abc A log will be generated, mkdirs.abc.<timestamp>.log Example 3: Setup of additional instance named 'alpha' to run a standalone p4p targeting commit.example.com:1666 and listening locally on port 1666. $ sudo su - $ cd /hxdepots/sdp/Server/Unix/setup $ ./mkdirs.sh alpha -t p4proxy -tp commit.example.com:1666 -lp 1666 Example 4: Setup of instance named '1' to run a standalone p4broker targeting commit.example.com:1666 and listening locally on port 1666. $ sudo su - $ cd /hxdepots/sdp/Server/Unix/setup $ ./mkdirs.sh 1 -t p4broker -tp commit.example.com:1666 -lp 1666 Example 5: Setup 2 instances A and B with limited sudoers on a fresh new machine: $ sudo su - $ cd /hxdepots/sdp/Server/Unix/setup $ cp mkdirs.cfg mkdirs.A.cfg Adjust settings in mkdirs.A.cfg as desired, e.g P4PORT, P4BROKERPORT, etc. $ cp mkdirs.A.cfg mkdirs.B.cfg Adjust settings in mkdirs.B.cfg as desired, e.g P4PORT, P4BROKERPORT, etc. Ensure port numbers do not conflict. Then generate Instance A: $ ./mkdirs.sh A -ls A log will be generated, mkdirs.A.<timestamp>.log Next generate instnace B, updating the limited sudoers to reference both instances. $ ./mkdirs.sh B -ls SEE ALSO: See 'install_sdp.sh -man' for more info on installing on a new machine. See 'gen_sudoers.sh -man' for more info on generating/replacing sudoers. See template: * systemd service file templates: /p4/common/etc/systemd/system * firewalld templates: /p4/common/etc/firewalld * ufw firewall templates: /p4/common/etc/ufw * Init script templates: /p4/common/etc/init.d " fi exit 1 } #------------------------------------------------------------------------------ # Function: terminate function terminate { # Disable signal trapping. trap - EXIT SIGINT SIGTERM msg "\\n$ThisScript: EXITCODE: $ErrorCount\\n" [[ "$Log" != "off" ]] && msg "Log is: $Log" # With the trap removed, exit. exit "$ErrorCount" } #============================================================================== # Command Line Processing [[ $(id -u) -eq 0 ]] && RunningAsRoot=1 declare -i shiftArgs=0 set +u while [[ $# -gt 0 ]]; do case $1 in (-c) ConfigFile="$2"; shiftArgs=1;; (-s) ServerID="$2"; ServerIDSet=1; shiftArgs=1;; (-S) TargetServerID="$2"; shiftArgs=1;; (-t) case "$2" in (p4d_master|p4d_replica|p4d_filtered_replica|p4d_edge|p4d_edge_replica) ServerType="$2" InstallP4D=1 InstallP4Broker=1 InstallP4Proxy=0 ;; (p4broker) ServerType="$2"; InstallP4D=0; InstallP4Broker=1; InstallP4Proxy=0;; (p4proxy) ServerType="$2"; InstallP4D=0; InstallP4Broker=0; InstallP4Proxy=1;; # Support aliases (p4b) ServerType="p4broker"; InstallP4D=0; InstallP4Broker=1; InstallP4Proxy=0;; (p4p) ServerType="p4proxy"; InstallP4D=0; InstallP4Broker=0; InstallP4Proxy=1;; (p4d) ServerType="p4d_master"; InstallP4D=1; InstallP4Broker=1; InstallP4Proxy=0;; (edge) ServerType="p4d_edge"; InstallP4D=1; InstallP4Broker=1; InstallP4Proxy=0;; (*) usage -h "Invalid server type specified: $2\\nValid values are: * p4d_master (or p4d) * p4d_replica * p4d_filtered_replica * p4d_edge (or edge) * p4d_edge_replica * p4proxy (or p4p) * p4broker (or p4b)\\n";; esac shiftArgs=1 ;; (-tp) TargetPort="$2"; TargetPortSet=1; shiftArgs=1;; (-lp) ListenPort="$2"; ListenPortSet=1; shiftArgs=1;; (-I) InitScripts="$2" shiftArgs=1 [[ "$InitScripts" == *"p4p"* ]] && InstallP4Proxy=1 [[ "$InitScripts" == *"dtg"* ]] && InstallP4DTG=1 ;; (-MDD) OverrideDD="$2"; shiftArgs=1;; (-MCD) OverrideCD="$2"; shiftArgs=1;; (-MLG) OverrideLG="$2"; shiftArgs=1;; (-MDB1) OverrideDB1="$2"; shiftArgs=1;; (-MDB2) OverrideDB2="$2"; shiftArgs=1;; (-f) FastMode=1;; (-p) PreflightOnly=1;; (-no_init) DoServiceInit=0; UseSystemd=0;; (-no_systemd) UseSystemd=0;; (-no_enable) EnableSystemdServices=0;; (-fs) UpdateSudoers=1; LimitedSudoers=0;; (-ls) UpdateSudoers=1; LimitedSudoers=1;; (-no_cron) LoadActiveCrontab=0;; (-no_firewall) DoFirewall=0;; (-test) TestMode=1; SDPInstallRoot="/tmp/p4"; SDPMountPointBase="/tmp/hxmounts"; DoServiceInit=0;; (-clean) TestCleanup=1;; (-R) # Syntax: -R <alt_root>[:<alt_mount_base>] TestMode=1 if [[ "$2" == *":"* ]]; then # alt_root is to the left of the colon, alt mount base is to the right. SDPInstallRoot="${2%%:*}" SDPMountPointBase="${2:##*:}" else SDPInstallRoot="$2" SDPMountPointBase= fi DoServiceInit=0 shiftArgs=1 ;; (-h) usage -h;; (-man) usage -man;; (-n) NoOp=1;; (-L) Log="$2"; shiftArgs=1;; (-d) Debug=1;; (-D) Debug=1; set -x;; # Debug; use bash 'set -x' high verbosity debugging mode. (*) if [[ "$SDPInstance" == "UnsetSDPInstance" ]]; then SDPInstance="$1" else usage -h "Instance $1 specified after already being specified as $SDPInstance. Only one instance can be specified." 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 [[ "$SDPInstance" == "UnsetSDPInstance" ]]; then usage -h "No instance specified." fi if [[ "$TargetPortSet" -eq 1 || "$ListenPortSet" -eq 1 ]]; then [[ "$ServerType" == "p4d"* ]] && usage "The '-tp <TargetPort>' and '-lp <ListenPort>' can only be used when ServerType is p4proxy or p4broker." fi if [[ "$UpdateSudoers" -eq 1 && "$RunningAsRoot" -eq 0 ]]; then if [[ "$LimitedSudoers" -eq 1 ]]; then usage -h "The '-ls' (limited sudoers) option was specified, but can only be used when running as root." else usage -h "The '-fs' (full sudoers) option was specified, but can only be used when running as root." fi fi #============================================================================== # Main Program # Pre-Preflight checks occur before logging starts, to ensure essential utils # (including those needed for logging) are available in the PATH. for util in awk date id rsync sed tee touch; do if ! command -v $util > /dev/null; then errmsg "Cannot find this essential util in PATH: $util" fi done if [[ "$ErrorCount" -ne 0 ]]; then bail "Aborting due to essential tools not available in directories listed in the PATH." fi [[ -n "$Log" ]] ||\ Log="mkdirs.${SDPInstance}.$(date +'%Y%m%d-%H%M%S').log" if [[ "$Log" != off ]]; then touch "$Log" || bail "Couldn't touch log file [$Log]." fi trap terminate EXIT SIGINT SIGTERM # Redirect stdout and stderr to the log file. if [[ "$Log" != off ]]; then exec > >(tee "$Log") exec 2>&1 msg "Log is: $Log" fi ThisUser=$(whoami) msg "Started $ThisScript v$Version as $ThisUser@$ThisHost on $(date) with this command line:\\n$CmdLine" dbg "InstallP4D=$InstallP4D" dbg "InstallP4Broker=$InstallP4Broker" dbg "InstallP4Proxy=$InstallP4Proxy" # If /opt/perforce/helix-sdp exists, us it. if [[ -d "$SDPPackageBase" ]]; then msg "Using SDP Package structure because $SDPPackageBase exists." UsePackageDirs=1 fi TmpFile=$(mktemp) # Standard Preflight checks after logging has started. export SDP_INSTANCE="${SDPInstance}" # If the config file wasn't specified, find it. if [[ -z "$ConfigFile" ]]; then # Check for config file in same dir as this script, looking first for an # instance-specific variant. if [[ -n "$RunDir" ]]; then if [[ "$RunDir" == \. ]]; then GenSudoersScript="$PWD/gen_sudoers.sh" else GenSudoersScript="$RunDir/gen_sudoers.sh" fi else RunDir=. GenSudoersScript="$PWD/gen_sudoers.sh" fi if [[ -r "$RunDir/mkdirs.${SDPInstance}.cfg" ]]; then ConfigFile="$RunDir/mkdirs.${SDPInstance}.cfg" elif [[ -r "$SDPInstallRoot/common/site/config/mkdirs.${SDPInstance}.cfg" ]]; then ConfigFile="$SDPInstallRoot/common/site/config/mkdirs.${SDPInstance}.cfg" elif [[ -r "$SDPInstallRoot/common/config/mkdirs.${SDPInstance}.cfg" ]]; then ConfigFile="$SDPInstallRoot/common/config/mkdirs.${SDPInstance}.cfg" else ConfigFile="$RunDir/mkdirs.cfg" fi fi #------------------------------------------------------------------------------ # Load settings from the mkdirs config file. if [[ -r "$ConfigFile" ]]; then msg "Loading mkdirs config file: $ConfigFile" # Note that CD must come after DD in this list below, because CD uses the value of DD as a default of CD is not defined. for c in DB1 DB2 DD CD LG SHAREDDATA MASTERINSTANCE OSUSER OSGROUP CASE_SENSITIVE ADMINUSER P4ADMINPASS DEFAULT_DOMAIN MAILFROM MAILTO MAILHOST SSL_PREFIX P4_PORT P4BROKER_PORT P4WEB_PORT P4FTP_PORT P4P_TARGET_PORT P4MASTERHOST P4SERVICEPASS PERMS MASTER_ID SERVER_TYPE REPLICA_ID COMPLAINFROM_DOMAIN COMPLAINFROM; do value=$(grep ^$c= "$ConfigFile") if [[ -n "$value" ]]; then value="${value#*=}" eval export $c="$value" # Perform value sanity check verifications. For SERVER_TYPE, also do implicit conversion from types # specified in mkrep.sh. case "$c" in (SERVER_TYPE) # Convert all unfiltered replica types to p4d_replica. [[ "$value" =~ ^(p4d_ha|p4d_ham|p4d_ro|p4d_rom|p4d_fr|p4d_frm|p4d_fs|p4d_fsm)$ ]] && \ value="p4d_replica" # Convert all filtered replica types to p4d_filtered_replica. [[ "$value" =~ ^(p4d_ffr)$ ]] && \ value="p4d_filtered_replica" [[ "$value" =~ ^(p4d_master|p4d_replica|p4d_filtered_replica|p4d_edge|p4d_edge_replica|p4broker|p4proxy)$ ]] || \ errmsg "SERVER_TYPE value of [$value] is invalid. Set to one of: p4d_master,p4d_replica,p4d_filtered_replica,p4d_edge,p4d_edge_replica,p4broker,p4proxy." ;; (PERMS) [[ "$value" =~ ^(Owner|Group|Other)$ ]] || \ errmsg "PERMS value of [$value] is invalid. Set to one of: Owner, Group, or Other." ;; esac else # Silently ignore if optional settings aren't set; give an error if required settings are missing. [[ "$c" =~ (COMPLAINFROM|COMPLAINFROM_DOMAIN|MAILHOST|P4FTP_PORT|P4P_TARGET_PORT|P4WEB_PORT|PERMS) ]] && \ continue if [[ "$c" == "REPLICA_ID" && "$SERVER_TYPE" =~ ^(p4d_replica|p4d_filtered_replica|p4d_edge|p4d_edge_replica)$ ]]; then errmsg "Missing REPLICA_ID (required as SERVER_TYPE is $SERVER_TYPE) in mkdirs config file: $ConfigFile" # The 'CD' setting is optional. If it is not defined, set it to the same value as DD which is already defined at this point. elif [[ "$c" == "CD" ]]; then dbg "CD was not defined, so it was set to the default value of DD [$DD]." export CD="$DD" else errmsg "Missing required setting [$c] in mkdirs config file: $ConfigFile" fi fi done else errmsg "Missing mkdirs config file: $ConfigFile" fi #------------------------------------------------------------------------------ # Handle command line overrides of certain settings in the config file. # If '-s <ServerID>' was specified on the command line, override REPLICA_ID. if [[ -n "$ServerID" ]]; then msg "\\nUsing ServerID [$ServerID] due to '-s $ServerID'. Ignoring REPLICA_ID value from config file [$REPLICA_ID]." else ServerID="$REPLICA_ID" msg "Using ServerID value from REPLICA_ID setting in config file [$ServerID]." fi # If '-t <ServerType>' was specified on the command line, override SERVER_TYPE. if [[ -n "$ServerType" ]]; then msg "\\nUsing Server Type [$ServerType] due to '-t $ServerType'. Ignoring SERVER_TYPE value from config file [$SERVER_TYPE]." else ServerType="$SERVER_TYPE" msg "Using ServerType value from SERVER_TYPE setting in config file [$ServerType]." fi [[ "$ServerType" == "p4d_edge_replica" && -z "$TargetServerID" ]] && \ errmsg "ServerType is p4d_edge_replica but '-S <TargetServerID>' is not set." [[ ("$ServerType" =~ ^(p4d_replica|p4d_filtered_replica|p4d_edge|p4d_edge_replica)$) && ("$REPLICA_ID" == "$MASTER_ID") ]] && \ errmsg "ServerType is $ServerType but the REPLICA_ID value is the same as the MASTER_ID." #------------------------------------------------------------------------------ # Determine SDP "TarRoot". For greenfield installations, this is where the # SDP tarball was extracted (usually /hxdepots/sdp) or for package installs, # the /opt/perforce/helix-sdp/sdp directory -- in either case the clean, # unmodified SDP structure, without generated files or symlinks. For # reliability in non-package installs, this directory is calculated as # 3 levels above the current directory where mkdirs.sh is run from. # # This mkdirs.sh script is run from <Base>/Server/Unix/setup, where <Base> is # usually /hxdepots/sdp or /opt/perforce/helix-sdp/sdp for package # installations. Set TarRoot and several values derived from it. if [[ "$UsePackageDirs" -eq 1 ]]; then TarRoot="$ImmutableSDPDir" else TarRoot="$(pwd -P)" TarRoot="${TarRoot%/*}" TarRoot="${TarRoot%/*}" TarRoot="${TarRoot%/*}" fi TarRootCommon="$TarRoot/Server/Unix/p4/common" TarRootConfig="$TarRoot/Server/Unix/p4/common/config" TarRootCron="$TarRoot/Server/Unix/p4/common/etc/cron.d" TarRootInit="$TarRoot/Server/Unix/p4/common/etc/init.d" TarRootSSL="$TarRoot/Server/Unix/p4/ssl" TarRootUnsupported="$TarRoot/Unsupported" # The helix_binaries dir is parallel to, not under, the # package root dir. TarRootBinDir="${TarRoot%/*}/helix_binaries" ExtendPermsTo="${PERMS:-Owner}" case "${ExtendPermsTo}" in (Owner) ExecPerms=700; ReadPerms=600;; (Group) ExecPerms=750; ReadPerms=640;; (Other) ExecPerms=755; ReadPerms=644;; esac #------------------------------------------------------------------------------ # Do preflight checks, starting with the SDP version check. SDPVersionFile="$TarRoot/Version" if [[ -r "$SDPVersionFile" ]]; then SDPVersionString="$(cat "$SDPVersionFile")" SDPVersion="$(get_sdp_version_from_string "$SDPVersionString")" msg "SDP Version from $SDPVersionFile is: $SDPVersion" else errmsg "Preflight check failed: Missing SDP Version file: $SDPVersionFile" fi [[ -n "$OverrideDD" ]] && DD="$OverrideDD" [[ -n "$OverrideCD" ]] && CD="$OverrideCD" [[ -n "$OverrideLG" ]] && LG="$OverrideLG" [[ -n "$OverrideDB1" ]] && DB1="$OverrideDB1" [[ -n "$OverrideDB2" ]] && DB2="$OverrideDB2" # If -MDB1 is specified, and -MDB2 is not, use the value DB1 value for DB2. [[ -n "$OverrideDB1" && -z "$OverrideDB2" ]] && DB2="$OverrideDB1" #------------------------------------------------------------------------------ # Normalizations: Trim the leading '/' from DB1, DB2, LG, DD and CD values. These # normalizations allow the values as specified in the configuration file to be # more flexible. That is, absolute paths with the leading '/' can be # specified, which tend to be more readable and familiar to humans reading the # config file, since the values match the actual mount point names. The older # format, with the leading slash removed, is still accepted for backward # compatibility. DD="${DD#/}" CD="${CD#/}" LG="${LG#/}" DB1="${DB1#/}" DB2="${DB2#/}" P4SERVER="p4_$SDPInstance" export MAIL=mail if [[ "$RunningAsRoot" -eq 1 ]]; then msg "Verified: Running as root." elif [[ $(id -u -n) == "$OSUSER" ]]; then warnmsg "Not running as root. The chown commands will be skipped and basic directories must exist.\\n" DoChownCommands=0 DoNFSChownCommands=0 else errmsg "$0 must be run as root or $OSUSER.\\n" fi #------------------------------------------------------------------------------ # Handle -test mode. if [[ "$TestMode" -eq 1 ]]; then DB1="${SDPMountPointBase#/}/$DB1" DB2="${SDPMountPointBase#/}/$DB2" DD="${SDPMountPointBase#/}/$DD" CD="${SDPMountPointBase#/}/$CD" LG="${SDPMountPointBase#/}/$LG" msg "\\n********* -test specified *********\\n" msg "SDP Dir: $TarRoot" msg "Override for SDP Root: $SDPInstallRoot" msg "Override for SDP Mount Point Base: $SDPMountPointBase\\n" msg "DD=$DD\\nCD=$CD\\nLG=$LG\\nDB1=$DB1\\nDB2=$DB2\\n" if [[ "$TestCleanup" -eq 1 ]]; then msg "Test Cleanup specified with -clean." DirList="$SDPInstallRoot $SDPMountPointBase" for d in $DirList; do if [[ -d "$d" ]]; then run "rm -rf $d" "Cleanup: Removing test dir from prior test: $d" ||\ errmsg "Failed to remove test dir from prior test: $d" fi done fi fi # If we aren't running as root, extend the preflight checks to verify basic dirs # exist. if [[ $(id -u) -ne 0 ]]; then DirList="$SDPInstallRoot" DirList+=" /$DD /$LG" if [[ "$ServerType" == "p4d"* ]]; then DirList+=" /$DB1" [[ "$DB1" == "$DB2" ]] || DirList+=" /$DB2" [[ "$DD" == "$CD" ]] || DirList+=" /$CD" fi for d in $DirList; do if [[ -d "$d" ]]; then dirOwner=$(stat -c "%U" "$d") dirGroup=$(stat -c "%G" "$d") [[ "$dirOwner" == "$OSUSER" ]] ||\ errmsg "Dir [$d] exists but with wrong owner, $dirOwner instead of $OSUSER." [[ "$dirGroup" == "$OSGROUP" ]] ||\ warnmsg "Dir [$d] exists but with wrong group, $dirGroup instead of $OSGROUP." else errmsg "Dir must exist if not running as root: $d" fi done fi if [[ "$UsePackageDirs" -eq 1 ]]; then dirOwner=$(stat -c "%U" "$ImmutableSDPDir") dirGroup=$(stat -c "%G" "$ImmutableSDPDir") dirPerms=$(stat -c "%a" "$ImmutableSDPDir") if [[ "$dirOwner" == root && "$dirGroup" == root && "$dirPerms" == 755 ]]; then msg "Verified: ownership and perms for dir $ImmutableSDPDir are correct, root:root, 755." else errmsg "Ownership and perms for dir $ImmutableSDPDir should be root:root, 755 but are $dirOwner:$dirGroup, $dirPerms." fi dirOwner=$(stat -c "%U" "$SDPPackageBase") dirGroup=$(stat -c "%G" "$SDPPackageBase") dirPerms=$(stat -c "%a" "$SDPPackageBase") if [[ "$dirOwner" == root && "$dirGroup" == "$OSGROUP" && "$dirPerms" == 775 ]]; then msg "Verified: ownership and perms for dir $SDPPackageBase are correct, root:$OSGROUP, 775." else errmsg "Ownership and perms for dir $SDPPackageBase should be root:$OSGROUP, 775 but are $dirOwner:$dirGroup, $dirPerms." fi fi if [[ "$ErrorCount" -eq 0 ]]; then msg "Verified: Preflight checks passed ($WarningCount warnings)." else bail "Aborting due to failed preflight checks." fi if [[ "$UsePackageDirs" -eq 0 ]]; then # Check for required and optional binaries. [[ -f "$TarRootBinDir/p4" ]] || errmsg "No p4 in $TarRootBinDir/" if [[ "$ServerType" == "p4d"* ]]; then [[ -f "$TarRootBinDir/p4d" ]] || errmsg "No p4d in $TarRootBinDir/" else [[ -f "$TarRootBinDir/p4d" ]] || warnmsg "No p4d in $TarRootBinDir/" fi if [[ "$ServerType" == "p4proxy" ]]; then [[ -f "$TarRootBinDir/p4p" ]] || errmsg "No p4p in $TarRootBinDir/" else [[ -f "$TarRootBinDir/p4p" ]] || warnmsg "No p4p in $TarRootBinDir/" fi if [[ "$ServerType" == "p4broker" ]]; then [[ -f "$TarRootBinDir/p4broker" ]] || errmsg "No p4broker in $TarRootBinDir/" else [[ -f "$TarRootBinDir/p4broker" ]] || warnmsg "No p4broker in $TarRootBinDir/" fi fi if [[ "$PreflightOnly" -eq 1 ]]; then msg "Exiting early after successful preflight checks due to '-p'." exit 0 fi #------------------------------------------------------------------------------ # Preflight checks completed. Continue on! #------------------------------------------------------------------------------ # Acquire helix_binaries as needed. msg "\\nAcquiring Helix Binaries from FTP server if needed." if [[ "$UsePackageDirs" -eq 1 ]]; then if [[ ! -d "$SDPPackageBins" ]]; then run "rsync -a $ImmutableSDPDir/helix_binaries/ $SDPPackageBins" \ "Copying to $SDPPackageBins" ||\ errmsg "Failed to copy to $SDPPackageBins." else dbg "Using existing directory: $SDPPackageBins" fi for binary in p4 p4d p4broker p4p; do if [[ -r "$SDPPackageBins/$binary" ]]; then msg "Using existing binary: $SDPPackageBins/$binary" else run "$SDPPackageBins/get_helix_binaries.sh -sbd $SDPPackageBins -b $binary" \ "Acquiring binary $SDPPackageBins/$binary" ||\ errmsg "Failed to acquire binary $SDPPackageBins/$binary" fi done fi run "chmod 755 $TarRootBinDir/p4" || errmsg "Failed to chmod p4 binary." # shellcheck disable=SC2015 [[ -f "$TarRootBinDir/p4d" ]] && run "chmod $ExecPerms $TarRootBinDir/p4d" ||\ errmsg "Failed to chmod p4d binary." # shellcheck disable=SC2015 [[ -f "$TarRootBinDir/p4broker" ]] && run "chmod $ExecPerms $TarRootBinDir/p4broker" ||\ errmsg "Failed to chmod p4broker binary." # shellcheck disable=SC2015 [[ -f "$TarRootBinDir/p4p" ]] && run "chmod $ExecPerms $TarRootBinDir/p4p" ||\ errmsg "Failed to chmod p4p binary." #------------------------------------------------------------------------------ # Calculate binary versions. P4RELNUM=$("$TarRootBinDir/p4" -V | grep -i Rev. | awk -F / '{print $3}') P4BLDNUM=$("$TarRootBinDir/p4" -V | grep -i Rev. | awk -F / '{print $4}' | awk '{print $1}') if [[ "$ServerType" == "p4d"* ]]; then P4DRELNUM=$("$TarRootBinDir/p4d" -V | grep -i Rev. | awk -F / '{print $3}') P4DBLDNUM=$("$TarRootBinDir/p4d" -V | grep -i Rev. | awk -F / '{print $4}' | awk '{print $1}') fi #------------------------------------------------------------------------------ # Start installation. msg "\\nCreating/verifying SDP directories." if [[ "$UsePackageDirs" -eq 1 ]]; then DirList="$SDPInstallRoot /$DD/p4 /$LG/p4 $WritableP4Dir/common/bin $WritableP4Dir/common/config" else DirList="$SDPInstallRoot /$DD/p4 /$LG/p4 /$DD/p4/common/bin /$DD/p4/common/config" fi if [[ "$ServerType" == "p4d"* ]]; then DirList+=" /$DB1/p4" [[ "$DB1" == "$DB2" ]] || DirList+=" /$DB2/p4" [[ "$DD" == "$CD" ]] || DirList+=" /$CD/p4" fi for d in $DirList; do if [[ ! -d "$d" ]]; then run "mkdir -p $d" "Creating initial install dir: $d" ||\ errmsg "Failed to create initial install dir: $d" fi done DirList="$SDPInstallRoot/ssl /$LG/p4/$SDPInstance/tmp" if [[ "$ServerType" == "p4d"* ]]; then DirList+=" /$DD/p4/$SDPInstance/depots /$CD/p4/$SDPInstance/checkpoints" if [[ "$ServerType" == "p4d_edge" || "$ServerType" == "p4d_filtered_replica" || "$SHAREDDATA" == "TRUE" ]]; then DirList="$DirList /$CD/p4/$SDPInstance/checkpoints.${ServerID#p4d_}" elif [[ "$ServerType" == "p4d_edge_replica" ]]; then DirList="$DirList /$CD/p4/$SDPInstance/checkpoints.${TargetServerID#p4d_}" fi elif [[ "$ServerType" == "p4proxy" ]]; then DirList+=" /$DD/p4/$SDPInstance/cache" fi for d in $DirList; do if [[ ! -d "$d" ]]; then run "mkdir -p $d" "Creating install subdir: $d" ||\ errmsg "Failed to create install subdir: $d" fi done if [[ ! -d "$SDPInstallRoot/$SDPInstance" ]]; then run "mkdir $SDPInstallRoot/$SDPInstance" "Creating dir for instance: $SDPInstallRoot/$SDPInstance" ||\ errmsg "Failed to create dir for instance $SDPInstallRoot/$SDPInstance." fi #------------------------------------------------------------------------------ # ServerID handling. if [[ "$ServerType" == "p4d_edge" || "$ServerType" == "p4d_filtered_replica" ]]; then if [[ "$DoChownCommands" -eq 1 ]]; then run "chown $OSUSER:$OSGROUP /$CD/p4/$SDPInstance/checkpoints.${ServerID#p4d_}" \ "Adjusting ownership of checkpoints.${ServerID#p4d_}." fi run "ln -f -s /$CD/p4/$SDPInstance/checkpoints.${ServerID#p4d_} $SDPInstallRoot/$SDPInstance/checkpoints.${ServerID#p4d_}" \ "Creating symlink for $SDPInstallRoot/$SDPInstance/checkpoints.${ServerID#p4d_}" ||\ errmsg "Failed to create symlink." if [[ "$DoChownCommands" -eq 1 ]]; then run "chown -h $OSUSER:$OSGROUP $SDPInstallRoot/$SDPInstance/checkpoints.${ServerID#p4d_}" \ "Adjusting ownership of symlink to checkpoints.${ServerID#p4d_}." fi elif [[ "$ServerType" == "p4d_edge_replica" ]]; then if [[ "$DoChownCommands" -eq 1 ]]; then run "chown $OSUSER:$OSGROUP /$CD/p4/$SDPInstance/checkpoints.${TargetServerID#p4d_}" \ "Adjusting ownership of checkpoints.${TargetServerID#p4d_}." fi run "ln -f -s /$CD/p4/$SDPInstance/checkpoints.${TargetServerID#p4d_} $SDPInstallRoot/$SDPInstance/checkpoints.${TargetServerID#p4d_}" \ "Creating symlink for $SDPInstallRoot/$SDPInstance/checkpoints.${TargetServerID#p4d_}" ||\ errmsg "Failed to create symlink." if [[ "$DoChownCommands" -eq 1 ]]; then run "chown -h $OSUSER:$OSGROUP $SDPInstallRoot/$SDPInstance/checkpoints.${TargetServerID#p4d_}" \ "Adjusting ownership of symlink to checkpoints.${TargetServerID#p4d_}." fi fi if [[ -f "$TarRootSSL/config.txt" && ! -f "$SDPInstallRoot/ssl/config.txt" ]]; then if [[ "$UsePackageDirs" -eq 1 ]]; then run "cp $ImmutableSDPDir/Server/Unix/p4/ssl/config.txt $SDPInstallRoot/ssl/." \ "Copying SSL cert generation file config.txt to $SDPInstallRoot/ssl." ||\ errmsg "Failed to copy $TarRootSSL/config.txt to $SDPInstallRoot/ssl/config.txt." else run "cp $TarRootSSL/config.txt $SDPInstallRoot/ssl/." \ "Copying SSL cert generation file config.txt to $SDPInstallRoot/ssl." ||\ errmsg "Failed to copy $TarRootSSL/config.txt to $SDPInstallRoot/ssl/config.txt." fi else msg "Using existing $SDPInstallRoot/ssl directory." fi #------------------------------------------------------------------------------ # Add/verify /p4/sdp symlink. msg "\\nAdding/Verifying SDP symlink: $SDPInstallRoot/sdp" if [[ -L "$SDPInstallRoot/sdp" ]]; then SymlinkTarget=$(readlink "$SDPInstallRoot/sdp") if [[ "$UsePackageDirs" -eq 1 ]]; then if [[ "$SymlinkTarget" == "$WritableSDPDir" ]]; then msg "Verified: $SDPInstallRoot/sdp is a symlink to $WritableSDPDir." else warnmsg "Symlink $SDPInstallRoot/sdp should be to $WritableSDPDir, but instead points to [$SymlinkTarget]." fi else if [[ "$SymlinkTarget" == "$TarRoot" ]]; then msg "Verified: $SDPInstallRoot/sdp is a symlink to $TarRoot." else warnmsg "Symlink $SDPInstallRoot/sdp should be to $TarRoot, but instead points to [$SymlinkTarget]." fi fi elif [[ -e "$SDPInstallRoot/sdp" ]]; then errmsg "This path is expected to be a symlink but is not: $SDPInstallRoot/sdp" else if [[ "$UsePackageDirs" -eq 1 ]]; then run "ln -s $WritableSDPDir $SDPInstallRoot/sdp" "Creating symlink to SDP package install area." ||\ errmsg "Failed to make symlink for sdp." else run "ln -s $TarRoot $SDPInstallRoot/sdp" "Creating symlink to SDP package install area." ||\ errmsg "Failed to make symlink for sdp." fi fi #------------------------------------------------------------------------------ # Add/verify /p4/common symlink. if [[ -L "$SDPInstallRoot/common" ]]; then SymlinkTarget=$(readlink "$SDPInstallRoot/common") if [[ "$UsePackageDirs" -eq 1 ]]; then if [[ "$SymlinkTarget" == "$WritableSDPDir/Server/Unix/p4/common" ]]; then msg "Verified: The $SDPInstallRoot/common symlink references $WritableSDPDir/Server/Unix/p4/common, as expected (because $ImmutableSDPDir exists)." elif [[ "$SymlinkTarget" == "/$DD/p4/common" ]]; then warnmsg "The $SDPInstallRoot/common symlink references the non-package path /$DD/p4/common; it is expected to reference $WritableSDPDir/Server/Unix/p4/common (because $ImmutableSDPDir exists)." elif [[ "$SymlinkTarget" == "/$DD/p4/common" ]]; then warnmsg "The $SDPInstallRoot/common symlink references an unexpected target path [$SymlinkTarget]." fi else if [[ "$SymlinkTarget" == "/$DD/p4/common" ]]; then msg "Verified: The $SDPInstallRoot/common symlink references /$DD/p4/common, as expected (because $ImmutableSDPDir does not exist)." elif [[ "$SymlinkTarget" == "ImmutableSDPDir/common" ]]; then warnmsg "The $SDPInstallRoot/common symlink references $ImmutableSDPDir/common; it is expected to reference /$DD/p4/common (because $ImmutableSDPDir does not exist)." elif [[ "$SymlinkTarget" == "/$DD/p4/common" ]]; then warnmsg "The $SDPInstallRoot/common symlink references an unexpected target path [$SymlinkTarget]." fi fi elif [[ -e "$SDPInstallRoot/common" ]]; then errmsg "This path is expected to be a symlink but is not: $SDPInstallRoot/common" else if [[ "$UsePackageDirs" -eq 1 ]]; then run "ln -s $WritableSDPDir/Server/Unix/p4/common $SDPInstallRoot/common" \ "Creating symlink for common dir." ||\ errmsg "Failed to create symlink for common dir." else run "ln -s /$DD/p4/common $SDPInstallRoot/common" \ "Creating symlink for common dir." ||\ errmsg "Failed to create symlink for common dir." fi if [[ "$DoChownCommands" -eq 1 ]]; then run "chown -h $OSUSER:$OSGROUP $SDPInstallRoot/common" \ "Adjusting ownership of symlink to $SDPInstallRoot/common" ||\ errmsg "Failed to adjust ownership of symlink to $SDPInstallRoot/common" fi fi #------------------------------------------------------------------------------ # Add /hxlogs directories. DirList="/$LG/p4/$SDPInstance/logs /$LG/p4/$SDPInstance/tmp" if [[ "$ServerType" == "p4d"* ]]; then DirList+=" /$DB1/p4/$SDPInstance/db1/save /$DB2/p4/$SDPInstance/db2/save" fi for d in $DirList; do if [[ ! -d "$d" ]]; then run "mkdir -p $d" "Creating dir: $d" ||\ errmsg "Failed to create dir: $d" fi done #------------------------------------------------------------------------------ # Working in /p4/N, add bin dir and symlinks as needed. # Test a cd to /$DD/p4/<instance>, unless on a broker only host. if [[ "$NoOp" -eq 0 && "$ServerType" != "p4broker" ]]; then cd "/$DD/p4/$SDPInstance" || errmsg "Could not do: cd /$DD/p4/$SDPInstance" fi # Test cd to /p4 if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot" || errmsg "Could not do: cd $SDPInstallRoot" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot" fi if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstance" || bail "Could not do: cd $SDPInstance (from directory: $SDPInstallRoot)" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot/$SDPInstance" fi if [[ ! -d bin ]]; then run "mkdir bin" || errmsg "Failed to do: mkdir bin" fi if [[ "$InstallP4D" -eq 1 ]]; then if [[ ! -L root ]]; then run "ln -s /$DB1/p4/$SDPInstance/db1 root" ||\ errmsg "Failed to make symlink for P4ROOT." fi if [[ ! -L offline_db ]]; then run "ln -s /$DB2/p4/$SDPInstance/db2 offline_db" ||\ errmsg "Failed to make symlink for offline_db." fi if [[ ! -L depots ]]; then run "ln -s /$DD/p4/$SDPInstance/depots" ||\ errmsg "Failed to make symlink for depots." fi if [[ ! -L checkpoints ]]; then run "ln -s /$CD/p4/$SDPInstance/checkpoints" ||\ errmsg "Failed to make symlink for checkpoints." fi if [[ "$ServerType" == "p4d_edge" || "$ServerType" == "p4d_filtered_replica" ]]; then if [[ ! -L "checkpoints.${ServerID#p4d_}" ]]; then run "ln -s /$CD/p4/$SDPInstance/checkpoints.${ServerID#p4d_}" ||\ errmsg "Failed to make symlink for checkpoints.${ServerID#p4d_}." fi elif [[ "$ServerType" == "p4d_edge_replica" ]]; then if [[ ! -L "checkpoints.${TargetServerID#p4d_}" ]]; then run "ln -s /$CD/p4/$SDPInstance/checkpoints.${TargetServerID#p4d_}" ||\ errmsg "Failed to make symlink for checkpoints.${TargetServerID#p4d_}." fi fi fi #------------------------------------------------------------------------------ # Add /p4/N/logs and /p4/N/tmp symlinks on /hxlogs for all server types. for d in logs tmp; do if [[ ! -d "$d" ]]; then if [[ ! -L "$d" ]]; then run "ln -s /$LG/p4/$SDPInstance/$d" ||\ errmsg "Failed to make symlink for /p4/$SDPInstance/$d." fi fi done #------------------------------------------------------------------------------ # Set ServerID for all server types. # For all p4d* type servers, add $P4ROOT/server.id, with commit server using # COMMIT_ID or SERVER_ID. case "$ServerType" in (p4d_master) # If the ServerID was not set by the user with '-s', then set a # default value for a master. if [[ "$ServerIDSet" -eq 0 ]]; then ServerID="${COMMIT_ID:-${MASTER_ID:-UNSET_SERVERID}}" fi if [[ "$NoOp" -eq 0 ]]; then echo "$ServerID" > "$SDPInstallRoot/$SDPInstance/root/server.id" else msg "NO_OP: Would write $ServerID into $SDPInstallRoot/$SDPInstance/root/server.id" fi ;; (p4d_*) if [[ "$NoOp" -eq 0 ]]; then echo "$ServerID" > "$SDPInstallRoot/$SDPInstance/root/server.id" else msg "NO_OP: Would write $ServerID into $SDPInstallRoot/$SDPInstance/root/server.id" fi ;; (*) # If the ServerID was not set by the user with '-s', then use ServerType # as default value for the ServerID of a broker/proxy. if [[ "$ServerIDSet" -eq 0 ]]; then ServerID="$ServerType" fi ;; esac #------------------------------------------------------------------------------ # Initialize directories. # # For package installations, the /opt/perforce/helix-sdp/sdp structure is # root-owned and immutable except by package upgrades. # This block creates locally modifiable subdirs common, downloads, # helix_binaries, and p4/sdp folders under /opt/perforce/helix-sdp, copying # from the immutable area. # # When used with the install_sdp.sh script, some of this work will already # be done. This mkdirs.sh script only creates/populates directories that do # not already exist. if [[ "$UsePackageDirs" -eq 1 ]]; then DirList="downloads helix_binaries p4/sdp/Server/Unix/p4/common" for d in $DirList; do if [[ ! -d "$d" ]]; then run "mkdir -p $SDPPackageBase/$d" \ "Creating locally modifiable dir $SDPPackageBase/$d" ||\ errmsg "Failed to create dir $SDPPackageBase/$d" else dbg "No need to create existing directory: $SDPPackageBase/$d" fi done if [[ ! -d "$WritableSDPDir/Server/Unix/p4/common" ]]; then run "rsync -a $ImmutableSDPDir/Server/Unix/p4/common/ $WritableSDPDir/Server/Unix/p4/common" \ "Copying to $WritableSDPDir/Server/Unix/p4/common" ||\ errmsg "Failed to copy to $WritableSDPDir/Server/Unix/p4/common" else dbg "Using existing directory: $WritableSDPDir/Server/Unix/p4/common" fi if [[ ! -f "$WritableP4Dir/Version" ]]; then run "rsync $ImmutableSDPDir/Version $WritableP4Dir/Version" \ "Copying to $WritableP4Dir/Version" ||\ errmsg "Failed to copy to $WritableP4Dir/Version" else dbg "Using existing file: $WritableP4Dir/Version" fi else # The legacy, non-package logic is preserved for non-package installations. # It does not use rsync, and only executes if # /p4/common/bin/p4_vars does # not yet exist. if [[ ! -f "$SDPInstallRoot/common/bin/p4_vars" ]]; then run "cp -R $TarRootCommon/bin/* $SDPInstallRoot/common/bin" "Copying $SDPInstallRoot/common/bin" ||\ errmsg "Failed to copy to $SDPInstallRoot/common/bin" # Copy certain subdirs of /p4/common if don't already exist. for d in cloud etc lib site; do if [[ ! -d "$SDPInstallRoot/common/$d" ]]; then run "cp -pr $TarRootCommon/$d $SDPInstallRoot/common/." "Copying $SDPInstallRoot/common/$d." ||\ errmsg "Failed to copy $d to $SDPInstallRoot/common/" fi done fi fi #------------------------------------------------------------------------------ # Operate in /p4/common/bin if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot/common/bin" ||\ bail "Could not do: cd $SDPInstallRoot/common/bin" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot/common/bin" fi #------------------------------------------------------------------------------ # Processing for new installations that don't yet have /p4/common/bin/p4_vars. if [[ ! -f "$SDPInstallRoot/common/bin/p4_vars" ]]; then if [[ ! -L "p4_${P4RELNUM}_bin" ]]; then run "ln -s p4_$P4RELNUM.$P4BLDNUM p4_${P4RELNUM}_bin" "Linking p4_${P4RELNUM}_bin." ||\ errmsg "Failed to symlink p4_${P4RELNUM}_bin" fi if [[ "$ServerType" == "p4d"* ]]; then if [[ ! -L "p4d_${P4DRELNUM}_bin" ]]; then run "ln -s p4d_$P4DRELNUM.$P4DBLDNUM p4d_${P4DRELNUM}_bin" "Linking p4d_${P4DRELNUM}_bin." ||\ errmsg "Failed to symlink p4_${P4DRELNUM}_bin" fi fi if [[ ! -L "p4_bin" ]]; then run "ln -s p4_${P4RELNUM}_bin p4_bin" "Linking p4_bin." ||\ errmsg "Failed to symlink p4_bin" fi if [[ ! -f p4_vars ]]; then msg "Generating Common Environment File: $PWD/p4_vars" if [[ "$NoOp" -eq 0 ]]; then sed -e "s|REPL_SDPVERSION|${SDPVersionString}|g" \ -e "s|REPL_OSUSER|${OSUSER}|g" \ "$TarRootConfig/p4_vars.template" > p4_vars fi fi fi #------------------------------------------------------------------------------ # Copy version-tagged binaries to /p4/common/bin. if [[ ! -f "$SDPInstallRoot/common/bin/p4_$P4RELNUM.$P4BLDNUM" ]]; then if [[ "$UsePackageDirs" -eq 1 ]]; then run "cp $SDPPackageBins/p4 $SDPInstallRoot/common/bin/p4_$P4RELNUM.$P4BLDNUM" ||\ bail "Failed to copy p4 binary." else run "cp $TarRootBinDir/p4 $SDPInstallRoot/common/bin/p4_$P4RELNUM.$P4BLDNUM" ||\ bail "Failed to copy p4 binary." fi fi if [[ "$ServerType" == "p4d"* ]]; then if [[ ! -f "$SDPInstallRoot/common/bin/p4d_$P4DRELNUM.$P4DBLDNUM" ]]; then if [[ "$UsePackageDirs" -eq 1 ]]; then run "cp $SDPPackageBins/p4d $SDPInstallRoot/common/bin/p4d_$P4DRELNUM.$P4DBLDNUM" ||\ bail "Failed to copy p4d binary" else run "cp $TarRootBinDir/p4d $SDPInstallRoot/common/bin/p4d_$P4DRELNUM.$P4DBLDNUM" ||\ bail "Failed to copy p4d binary" fi # shellcheck disable=SC2072 if [[ "$P4DRELNUM" > "2023.0" ]]; then [[ -f /.dockerenv ]] ||\ SetcapCmd="setcap CAP_SYS_RESOURCE=+ep $SDPInstallRoot/common/bin/p4d_$P4DRELNUM.$P4DBLDNUM" fi fi fi #------------------------------------------------------------------------------ # Working in /p4/common/bin, create p4d sylinks if needed. if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot/common/bin" || bail "Could not do: cd $SDPInstallRoot/common/bin" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot/common/bin" fi if [[ "$ServerType" == "p4d"* ]]; then if [[ ! -L "p4d_${SDPInstance}_bin" ]]; then run "ln -s p4d_${P4DRELNUM}_bin p4d_${SDPInstance}_bin" ||\ errmsg "Failed to symlink p4d_${SDPInstance}_bin" fi fi #------------------------------------------------------------------------------ # Copy p4broker binary to version-tagged file and create p4broker links if # p4broker binary exists. if [[ -f "$TarRootBinDir/p4broker" ]]; then # shellcheck disable=SC2016 P4BRELNUM=$("$TarRootBinDir/p4broker" -V | grep -i Rev. | awk -F / '{print $3}') # shellcheck disable=SC2016 P4BBLDNUM=$("$TarRootBinDir/p4broker" -V | grep -i Rev. | awk -F / '{print $4}' | awk '{print $1}') if [[ ! -f "$SDPInstallRoot/common/bin/p4broker_$P4BRELNUM.$P4BBLDNUM" ]]; then if [[ "$UsePackageDirs" -eq 1 ]]; then run "cp $SDPPackageBins/p4broker $SDPInstallRoot/common/bin/p4broker_$P4BRELNUM.$P4BBLDNUM" ||\ errmsg "Could not copy p4broker binary." else run "cp $TarRootBinDir/p4broker $SDPInstallRoot/common/bin/p4broker_$P4BRELNUM.$P4BBLDNUM" ||\ errmsg "Could not copy p4broker binary." fi fi #------------------------------------------------------------------------------ # Working in /p4/common/bin, create p4broker* sylinks if needed. if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot/common/bin" || bail "Could not do: cd $SDPInstallRoot/common/bin" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot/common/bin" fi if [[ -L "p4broker_${P4BRELNUM}_bin" ]]; then run "unlink p4broker_${P4BRELNUM}_bin" ||\ errmsg "Could not unlink: p4broker_${P4BRELNUM}_bin" fi run "ln -s p4broker_$P4BRELNUM.$P4BBLDNUM p4broker_${P4BRELNUM}_bin" "Creating broker symlink." ||\ errmsg "Could not create broker symlink." if [[ -L "p4broker_${SDPInstance}_bin" ]]; then run "unlink p4broker_${SDPInstance}_bin" ||\ errmsg "Could not unlink: p4broker_${SDPInstance}_bin" fi run "ln -s p4broker_${P4BRELNUM}_bin p4broker_${SDPInstance}_bin" "Creating broker instance symlink." ||\ errmsg "Could not create broker instance symlink." fi if [[ "$ServerType" == "p4broker" || "$InstallP4Broker" -eq 1 ]]; then if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot/$SDPInstance/bin" || \ bail "Could not do: cd $SDPInstallRoot/$SDPInstance/bin" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot/$SDPInstance/bin" fi if [[ ! -L "p4broker_${SDPInstance}" ]]; then run "ln -s $SDPInstallRoot/common/bin/p4broker_${SDPInstance}_bin p4broker_${SDPInstance}" ||\ errmsg "Could not create symlink." fi msg "Generating Helix Broker init script: p4broker_${SDPInstance}_init" if [[ "$NoOp" -eq 0 ]]; then sed "s|REPL_SDP_INSTANCE|${SDPInstance}|g" "$TarRootInit/p4broker_instance_init.template" > "p4broker_${SDPInstance}_init" else msg "NO_OP: Would have generated p4broker_${SDPInstance}_init" fi run "chmod +x p4broker_${SDPInstance}_init" fi #------------------------------------------------------------------------------ # Copy p4p binary to version-tagged binary and create p4p symlinks if p4p # binary exists. if [[ -f "$TarRootBinDir/p4p" ]]; then # shellcheck disable=SC2016 P4PRELNUM=$("$TarRootBinDir/p4p" -V | grep -i Rev. | awk -F / '{print $3}') # shellcheck disable=SC2016 P4PBLDNUM=$("$TarRootBinDir/p4p" -V | grep -i Rev. | awk -F / '{print $4}' | awk '{print $1}') if [[ ! -f "$SDPInstallRoot/common/bin/p4p_$P4PRELNUM.$P4PBLDNUM" ]]; then if [[ "$UsePackageDirs" -eq 1 ]]; then run "cp $SDPPackageBins/p4p $SDPInstallRoot/common/bin/p4p_$P4PRELNUM.$P4PBLDNUM" ||\ errmsg "Could not copy p4p binary." else run "cp $TarRootBinDir/p4p $SDPInstallRoot/common/bin/p4p_$P4PRELNUM.$P4PBLDNUM" ||\ errmsg "Could not copy p4p binary." fi fi #------------------------------------------------------------------------------ # Working in /p4/common/bin, create p4p* sylinks if needed. if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot/common/bin" || bail "Could not do: cd $SDPInstallRoot/common/bin" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot/common/bin" fi if [[ -L "p4p_${P4PRELNUM}_bin" ]]; then run "unlink p4p_${P4PRELNUM}_bin" || errmsg "Could not unlink: p4p_${P4PRELNUM}_bin" fi run "ln -s p4p_$P4PRELNUM.$P4PBLDNUM p4p_${P4PRELNUM}_bin" ||\ errmsg "Could not symlink to p4p." if [[ -L "p4p_${SDPInstance}_bin" ]]; then run "unlink p4p_${SDPInstance}_bin" || errmsg "Could not unlink: p4p_${SDPInstance}_bin" fi run "ln -s p4p_${P4PRELNUM}_bin p4p_${SDPInstance}_bin" fi if [[ "$ServerType" == "p4proxy" || "$InstallP4Proxy" -eq 1 ]]; then if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot/$SDPInstance/bin" || \ bail "Could not do: cd $SDPInstallRoot/$SDPInstance/bin" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot/$SDPInstance/bin" fi if [[ ! -L "p4p_${SDPInstance}" ]]; then run "ln -s $SDPInstallRoot/common/bin/p4p_${SDPInstance}_bin p4p_${SDPInstance}" ||\ errmsg "Could not symlink for p4p_${SDPInstance}." fi msg "Generating Helix Proxy init script: p4p_${SDPInstance}_init" if [[ "$NoOp" -eq 0 ]]; then sed -e "s|REPL_SDP_INSTANCE|${SDPInstance}|g" \ "$TarRootInit/p4p_instance_init.template" > "p4p_${SDPInstance}_init" else msg "NO_OP: Would have generated p4p_${SDPInstance}_init" fi run "chmod +x p4p_${SDPInstance}_init" if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot/$SDPInstance" || \ bail "Could not do: cd $SDPInstallRoot/$SDPInstance" else msg "NO_OP: Would be operating in: $SDPInstallRoot/$SDPInstance" fi run "ln -s /$DD/p4/$SDPInstance/cache" fi #------------------------------------------------------------------------------ # Generate SDP_ADMIN_PASSWORD_FILE file. if [[ ! -e "$SDPInstallRoot/common/config/.p4passwd.${P4SERVER}.admin" ]]; then if [[ "$NoOp" -eq 0 ]]; then echo "$P4ADMINPASS" > "$SDPInstallRoot/common/config/.p4passwd.${P4SERVER}.admin" else msg "NO_OP: Would write admin password into $SDPInstallRoot/common/config/.p4passwd.${P4SERVER}.admin" fi else warnmsg "Skipping update of existing admin password file $SDPInstallRoot/common/config/.p4passwd.${P4SERVER}.admin" fi #------------------------------------------------------------------------------ # Generate service user password file (to be deprecated later). if [[ ! -e "$SDPInstallRoot/common/config/.p4passwd.${P4SERVER}.service" ]]; then if [[ "$NoOp" -eq 0 ]]; then echo "$P4SERVICEPASS" > "$SDPInstallRoot/common/config/.p4passwd.${P4SERVER}.service" else msg "NO_OP: Would write service password into $SDPInstallRoot/common/config/.p4passwd.${P4SERVER}.service" fi else warnmsg "Skipping update of existing service password file $SDPInstallRoot/common/config/.p4passwd.${P4SERVER}.service" fi #------------------------------------------------------------------------------ # Operating in the Instance Bin dir, /p4/N/bin if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot/$SDPInstance/bin" ||\ bail "Could not do: cd $SDPInstallRoot/$SDPInstance/bin" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot/$SDPInstance/bin" fi if [[ ! -L "p4_${SDPInstance}" ]]; then run "ln -s $SDPInstallRoot/common/bin/p4_bin p4_${SDPInstance}" ||\ errmsg "Could not create symlink for: p4_${SDPInstance}" fi if [[ "$InstallP4D" -eq 1 ]]; then msg "Generating Helix Core Server init script: p4d_${SDPInstance}_init" if [[ "$NoOp" -eq 0 ]]; then sed "s|REPL_SDP_INSTANCE|${SDPInstance}|g" \ "$TarRootInit/p4d_instance_init.template" > "p4d_${SDPInstance}_init" ||\ errmsg "Failed to generate init script." run "chmod +x p4d_${SDPInstance}_init" ||\ errmsg "Failed to chmod init script." fi fi if [[ "$InstallP4DTG" -eq 1 ]]; then msg "Generating P4DTG init script: p4dtg_${SDPInstance}_init" if [[ "$NoOp" -eq 0 ]]; then sed "s|REPL_SDP_INSTANCE|${SDPInstance}|g" \ "$TarRootInit/p4dtg_instance_init.template" > "p4dtg_${SDPInstance}_init" ||\ errmsg "Failed to generate init script." run "chmod +x p4dtg_${SDPInstance}_init" ||\ errmsg "Failed to chmod init script." fi warnmsg "The p4dtg_${SDPInstance}_init script has been generated. Additional steps are\\nrequired to complete installation." fi if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot/$SDPInstance/bin" || bail "Could not do: cd $SDPInstallRoot/$SDPInstance/bin" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot/$SDPInstance/bin" fi if [[ "$InstallP4D" -eq 1 ]]; then if [[ $CASE_SENSITIVE -eq 1 ]]; then if [[ ! -L "p4d_$SDPInstance" ]]; then msg "Generating P4D symlink for case-sensitive instance: p4d_${SDPInstance}." run "ln -s $SDPInstallRoot/common/bin/p4d_${SDPInstance}_bin p4d_$SDPInstance" ||\ errmsg "Failed to symlink p4d_$SDPInstance" fi else msg "Generating P4D wrapper for case-insensitive instance: p4d_${SDPInstance}." if [[ "$NoOp" -eq 0 && ! -e "p4d_${SDPInstance}" ]]; then echo '#!/bin/bash' > "p4d_${SDPInstance}" || errmsg "Failed to generate script." echo "P4D=/p4/common/bin/p4d_${SDPInstance}_bin" >> "p4d_$SDPInstance" ||\ errmsg "Failed to generate script." # shellcheck disable=SC2016 echo 'exec $P4D -C1 "$@"' >> "p4d_$SDPInstance" ||\ errmsg "Failed to generate script." run "chmod +x p4d_$SDPInstance" || errmsg "Failed to chmod wrapper script." fi fi fi if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot/common/config" ||\ bail "Could not do: cd $SDPInstallRoot/common/config" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot/common/config" fi if [[ "$ServerType" == "p4proxy" ]]; then P4P_TARGET_PORT="${SSL_PREFIX}${P4MASTERHOST}:${P4_PORT}" [[ "$TargetPortSet" -eq 1 ]] && P4P_TARGET_PORT="$TargetPort" [[ "$ListenPortSet" -eq 1 ]] && P4_PORT="$ListenPort" fi if [[ "$ServerType" == "p4broker" ]]; then P4_PORT="${SSL_PREFIX}${P4MASTERHOST}:${P4_PORT}" [[ "$TargetPortSet" -eq 1 ]] && P4_PORT="$TargetPort" [[ "$ListenPortSet" -eq 1 ]] && P4BROKER_PORT="$ListenPort" fi msg "Generating Instance Vars file: p4_${SDPInstance}.vars" if [[ "$NoOp" -eq 0 ]]; then sed -e "s|REPL_MAILTO|${MAILTO}|g" \ -e "s|REPL_MAILFROM|${MAILFROM}|g" \ -e "s|REPL_ADMINUSER|${ADMINUSER}|g" \ -e "s|REPL_MASTER_ID|${MASTER_ID}|g" \ -e "s|REPL_SSLPREFIX|${SSL_PREFIX}|g" \ -e "s|REPL_P4PORT|${P4_PORT}|g" \ -e "s|REPL_P4BROKERPORT|${P4BROKER_PORT}|g" \ -e "s|REPL_P4WEBPORT|${P4WEB_PORT}|g" \ -e "s|REPL_P4FTPPORT|${P4FTP_PORT}|g" \ -e "s|REPL_P4MASTERHOST|${P4MASTERHOST}|g" \ -e "s|REPL_P4P_TARGET_PORT|${P4P_TARGET_PORT}|g" \ "$TarRootCommon/config/instance_vars.template" > "p4_${SDPInstance}.vars" ||\ errmsg "Failed to generate p4_${SDPInstance}.vars" fi if [[ "$ServerType" == p4_master ]]; then msg "Generating config file for P4Review: p4_${SDPInstance}.p4review.cfg" if [[ "$NoOp" -eq 0 ]]; then sed -e "s|REPL_ADMINISTRATOR|${MAILTO}|g" \ -e "s|REPL_COMPLAINFROM|${COMPLAINFROM}|g" \ -e "s|REPL_MAILHOST|${MAILHOST}|g" \ -e "s|REPL_P4MASTERHOST|${P4MASTERHOST}|g" \ "$TarRootCommon/config/p4review.cfg.template" > "p4_${SDPInstance}.p4review.cfg" ||\ errmsg "Failed to generate p4_${SDPInstance}.p4review.cfg" fi fi # If the site has neither an actual or sample SiteTags.cfg file, install the sample. if [[ -e "$SDPInstallRoot/common/config/SiteTags.cfg" ]]; then msg "Verified: SiteTags.cfg exists as $SDPInstallRoot/common/config/SiteTags.cfg." elif [[ -e "$SDPInstallRoot/common/config/SiteTags.cfg.sample" ]]; then msg "Verified: SiteTags.cfg.sample exists as $SDPInstallRoot/common/config/SiteTags.cfg.sample" else msg "Copying SiteTags.cfg.sample to $SDPInstallRoot/common/config/SiteTags.cfg.sample." if [[ "$NoOp" -eq 0 ]]; then cp -p "$TarRootConfig/SiteTags.cfg.sample" "$SDPInstallRoot/common/config/SiteTags.cfg.sample" ||\ errmsg "Could not do: cp -p \"$TarRootConfig/SiteTags.cfg.sample\" \"$SDPInstallRoot/common/config/SiteTags.cfg.sample\"" else msg "NO_OP: Would have done: cp -p \"$TarRootConfig/SiteTags.cfg.sample\" \"$SDPInstallRoot/common/config/SiteTags.cfg.sample\"" fi fi if [[ -e "$SDPInstallRoot/common/config/configurables.cfg" ]]; then msg "Verified: configurables.cfg exists as $SDPInstallRoot/common/config/configurables.cfg." else msg "Copying configurables.cfg to $SDPInstallRoot/common/config/configurables.cfg" if [[ "$NoOp" -eq 0 ]]; then cp -p "$TarRootConfig/configurables.cfg" "$SDPInstallRoot/common/config/configurables.cfg" ||\ errmsg "Could not do: cp -p \"$TarRootConfig/configurables.cfg\" \"$SDPInstallRoot/common/config/configurables.cfg\"" else msg "NO_OP: Would have done: cp -p \"$TarRootConfig/configurables.cfg\" \"$SDPInstallRoot/common/config/configurables.cfg\"" fi fi if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot" || bail "Could not do: cd $SDPInstallRoot" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot" fi # Generate crontab for p4d servers, standalone proxies, and standalone brokers. SDPCrontabDir="$SDPInstallRoot/common/etc/cron.d" if [[ "$ServerType" == "p4d"* || "$ServerType" == "p4proxy" || "$ServerType" == "p4broker" ]]; then if [[ ! -f "${SDPInstallRoot}/p4.crontab.${SDPInstance}" ]]; then CrontabFileInP4="p4.crontab.${SDPInstance}" else CrontabFileInP4="p4.crontab.$SDPInstance.new" run "rm -f ${SDPInstallRoot}/$CrontabFileInP4" msg "Existing crontab file found; writing new crontab to ${SDPInstallRoot}/${CrontabFileInP4}" fi CrontabFile="$SDPCrontabDir/crontab.$OSUSER.$ThisHost.${SDPInstance}" if [[ "$ServerType" == "p4d"* ]]; then msg "Generating p4d server crontab: $CrontabFileInP4" if sed -e "s|REPL_MAILTO|${MAILTO}|g" \ -e "s|REPL_MAILFROM|${MAILFROM}|g" \ -e "s|REPL_INSTANCE|${SDPInstance}|g" \ "$TarRootCron/template.crontab.combined" > "$TmpFile"; then CrontabFileGenerated=1 else errmsg "Failed to generate crontab file from: $TarRootCron/template.crontab.combined" fi elif [[ "$ServerType" == "p4proxy" ]]; then msg "Generating p4p server crontab: $CrontabFileInP4" if sed -e "s|REPL_MAILTO|${MAILTO}|g" \ -e "s|REPL_MAILFROM|${MAILFROM}|g" \ -e "s|REPL_INSTANCE|${SDPInstance}|g" \ "$TarRootCron/template.crontab.proxy" > "$TmpFile"; then CrontabFileGenerated=1 else errmsg "Failed to generate crontab file from $TarRootCron/template.crontab.proxy" fi elif [[ "$ServerType" == "p4broker" ]]; then msg "Generating p4broker server crontab: $CrontabFileInP4" if sed -e "s|REPL_MAILTO|${MAILTO}|g" \ -e "s|REPL_MAILFROM|${MAILFROM}|g" \ -e "s|REPL_INSTANCE|${SDPInstance}|g" \ "$TarRootCron/template.crontab.broker" > "$TmpFile"; then CrontabFileGenerated=1 else errmsg "Failed to generate crontab file from $TarRootCron/template.crontab.broker" fi fi if [[ "$NoOp" -eq 0 ]]; then msg "Deploying generated crontab file: $CrontabFileInP4" mv -f "$TmpFile" "$CrontabFileInP4" ||\ errmsg "Failed to do: mv -f $TmpFile $CrontabFileInP4" cp -f "$CrontabFileInP4" "$CrontabFile" ||\ errmsg "Failed to do: cp -f $CrontabFileInP4 $CrontabFile" else msg "NO_OP: Would have generated crontab $CrontabFileInP4 with contents:" cat "$TmpFile" rm -f "$TmpFile" fi #------------------------------------------------------------------------------ # Load crontab (unless '-no_cron' was specified). if [[ "$LoadActiveCrontab" -eq 1 ]]; then if [[ "$CrontabFileGenerated" -eq 1 ]]; then if [[ -r "$CrontabFile" ]]; then if [[ "$RunningAsRoot" -eq 1 ]]; then run "crontab -u $OSUSER $CrontabFile" "As root, loading crontab for $OSUSER." ||\ errmsg "As root, failed to load crontab for user $OSUSER." else run "crontab $CrontabFile" "As $OSUSER, loading crontab." ||\ errmsg "As $OSUSER, failed to load crontab." fi else errmsg "Not loading crontab for user $OSUSER; did not find expected crontab file: $CrontabFile" fi else warnmsg "Not loading crontab for user $OSUSER because crontab was not generated." fi else msg "Not loading crontab due to '-no_cron'." fi if [[ "$DoChownCommands" -eq 1 && -e "$CrontabFileInP4" ]]; then run "chown $OSUSER:$OSGROUP $CrontabFileInP4 $CrontabFile" || \ errmsg "Failed to chown $CrontabFileInP4 $CrontabFile" fi fi if [[ -r "$TarRootUnsupported/Maintenance/template.maintenance.cfg" && "$ServerType" == "p4d"* ]]; then msg "Appending configuration section [$SDPInstance] to $TarRootUnsupported/Maintenance/maintenance.cfg" if [[ -r "$TarRootUnsupported/Maintenance/maintenance.cfg" ]]; then run "chmod +w $TarRootUnsupported/Maintenance/maintenance.cfg" fi if [[ "$NoOp" -eq 0 ]]; then echo -e "[$SDPInstance]" >> "$TarRootUnsupported/Maintenance/maintenance.cfg" msg "Appending to: $TarRootUnsupported/Maintenance/maintenance.cfg" sed -e "s|REPL_INSTANCE|$SDPInstance|g" \ -e "s|REPL_ADMINISTRATOR|${MAILTO}|g" \ -e "s|REPL_COMPLAINFROM|${COMPLAINFROM}|g" \ -e "s|REPL_MAILHOST|${MAILHOST}|g" \ -e "s|REPL_DOMAIN|${COMPLAINFROM_DOMAIN}|g" \ "$TarRootUnsupported/Maintenance/template.maintenance.cfg" >> "$TarRootUnsupported/Maintenance/maintenance.cfg" ||\ errmsg "Could not append to: $TarRootUnsupported/Maintenance/maintenance.cfg" fi fi if [[ "$NoOp" -eq 0 ]]; then cd "$SDPInstallRoot/${SDPInstance}/bin" || \ bail "Could not do: cd $SDPInstallRoot/${SDPInstance}/bin" msg "Operating in: $PWD" else msg "NO_OP: Would be operating in: $SDPInstallRoot/${SDPInstance}/bin" fi if [[ "$SHAREDDATA" == "TRUE" ]]; then if [[ "$ServerType" == p4d_replica || "$ServerType" == p4d_standby ]]; then msg "Configuring Replica sharing depot data with master. Skipping chown of /$DD and /$DD/p4" DoNFSChownCommands=0 fi fi if [[ "$DoChownCommands" -eq 1 ]]; then if [[ "$TestMode" -eq 0 ]]; then if [[ "$DoNFSChownCommands" -eq 1 ]]; then run "chown $OSUSER:$OSGROUP /$DD" || errmsg "Failed to chown /$DD" fi run "chown $OSUSER:$OSGROUP /$LG" || errmsg "Failed to chown /$LG" if [[ "$ServerType" == "p4d"* ]]; then run "chown $OSUSER:$OSGROUP /$DB1" || errmsg "Failed to chown /$DB1" if [[ "$DB1" != "$DB2" ]]; then run "chown $OSUSER:$OSGROUP /$DB2" || errmsg "Failed to chown /$DB2" fi fi fi if [[ "$DoNFSChownCommands" -eq 1 ]]; then run "chown $OSUSER:$OSGROUP /$DD/p4" || errmsg "Failed to chown /$DD/p4" if [[ "$CD" != "$DD" ]]; then run "chown $OSUSER:$OSGROUP /$CD/p4" || errmsg "Failed to chown /$CD/p4" fi fi run "chown $OSUSER:$OSGROUP /$LG/p4" || errmsg "Failed to chown /$LG/p4" if [[ "$ServerType" == "p4d"* ]]; then run "chown $OSUSER:$OSGROUP /$DB1/p4" || errmsg "Failed to chown /$DB1/p4" if [[ "$DB1" != "$DB2" ]]; then run "chown $OSUSER:$OSGROUP /$DB2/p4" || errmsg "Failed to chown /$DB2/p4" fi fi run "chown -h $OSUSER:$OSGROUP $SDPInstallRoot" || errmsg "Failed to chown $SDPInstallRoot" run "chown -h $OSUSER:$OSGROUP $SDPInstallRoot/$SDPInstance" ||\ errmsg "Failed to chown $SDPInstance" run "chown -h $OSUSER:$OSGROUP $SDPInstallRoot/common" ||\ errmsg "Failed to chown $SDPInstallRoot/common" for path in "$SDPInstallRoot/sdp" "$SDPInstallRoot"/* "$SDPInstallRoot/$SDPInstance"/*; do run "chown -h $OSUSER:$OSGROUP $path" || errmsg "Failed to chown -h $OSUSER:$OSGROUP $path" done run "chown -Rh $OSUSER:$OSGROUP $SDPInstallRoot/common/" || errmsg "Failed to chown $SDPInstallRoot/common/" if [[ $TestMode -eq 0 ]]; then run "chown -Rh $OSUSER:$OSGROUP $SDPInstallRoot/sdp/" || errmsg "Failed to chown $SDPInstallRoot/sdp/" fi run "chown -Rh $OSUSER:$OSGROUP $SDPInstallRoot/common" || errmsg "Failed to chown $SDPInstallRoot/common" if [[ "$ServerType" == "p4d"* ]]; then run "chown -Rh $OSUSER:$OSGROUP /$DB1/p4/$SDPInstance" || errmsg "Failed to chown /$DB1/p4/$SDPInstance" if [[ "$DB1" != "$DB2" ]]; then run "chown -Rh $OSUSER:$OSGROUP /$DB2/p4/$SDPInstance" || errmsg "Failed to chown /$DB2/p4/$SDPInstance" fi fi run "chown -Rh $OSUSER:$OSGROUP /$LG/p4/$SDPInstance" || errmsg "Failed to chown /$LG/p4/$SDPInstance" run "chown -Rh $OSUSER:$OSGROUP $SDPInstallRoot/$SDPInstance/bin" || errmsg "Failed to chown $SDPInstallRoot/$SDPInstance/bin" else msg "Skipped chown/chmod commands for large directory trees." fi if [[ "$ServerType" == "p4d"* ]]; then run "chmod $ExecPerms /$DB1/p4" || errmsg "Failed to chmod /$DB1/p4" if [[ "$DB1" != "$DB2" ]]; then run "chmod $ExecPerms /$DB2/p4" || errmsg "Failed to chmod /$DB2/p4" fi fi run "chmod $ExecPerms /$DD/p4" || errmsg "Failed to chmod /$DD/p4" if [[ "$CD" != "$DD" ]]; then run "chmod $ExecPerms /$CD/p4" || errmsg "Failed to chmod /$CD/p4" fi run "chmod $ExecPerms /$LG/p4" || errmsg "Failed to chmod /$LG/p4" if [[ "$ServerType" == "p4d"* ]]; then run "chmod -R $ExecPerms /$DB1/p4/$SDPInstance" || errmsg "Failed to chmod /$DB1/p4/$SDPInstance" if [[ "$DB1" != "$DB2" ]]; then run "chmod -R $ExecPerms /$DB2/p4/$SDPInstance" || errmsg "Failed to chmod /$DB2/p4/$SDPInstance" fi fi run "chmod -R $ExecPerms $SDPInstallRoot/common" || errmsg "Failed to chmod $SDPInstallRoot/common" run "chmod -R $ExecPerms /$LG/p4/$SDPInstance" || errmsg "Failed to chmod /$LG/p4/$SDPInstance" if [[ "$InstallP4D" -eq 1 ]]; then if [[ "$SDPInstance" != "$MASTERINSTANCE" ]]; then if [[ -f "$SDPInstallRoot/$MASTERINSTANCE/root/license" && ! -f "$SDPInstallRoot/$SDPInstance/root/license" ]]; then run "ln -s $SDPInstallRoot/$MASTERINSTANCE/root/license $SDPInstallRoot/$SDPInstance/root/license" ||\ errmsg "Failed to copy license from master instance $MASTERINSTANCE to $SDPInstance." run "chown $OSUSER:$OSGROUP $SDPInstallRoot/$SDPInstance/root/license" ||\ errmsg "Failed to chown $SDPInstallRoot/$SDPInstance/root/license" fi fi fi for f in "$SDPInstallRoot/${SDPInstance}"/bin/*_init; do run "chmod 755 $f" || errmsg "Failed to chmod $f to 755." done run "chmod $ExecPerms $SDPInstallRoot/ssl" || errmsg "Failed to chmod $ExecPerms $SDPInstallRoot/ssl" for f in "$SDPInstallRoot/common/config/.p4passwd.${P4SERVER}."* "$SDPInstallRoot"/ssl/*; do run "chmod $ReadPerms $f" || errmsg "Failed to chmod $f to $ReadPerms." done if [[ "$DoChownCommands" -eq 1 ]]; then run "chown -R $OSUSER:$OSGROUP $SDPInstallRoot/ssl" ||\ errmsg "Failed to do chown for ssl dir." if [[ "$UsePackageDirs" -eq 1 ]]; then DirList="downloads helix_binaries p4" for d in $DirList; do if [[ ! -d "$d" ]]; then run "chown -R $OSUSER:$OSGROUP $SDPPackageBase/$d" ||\ errmsg "Failed to chown dir $SDPPackageBase/$d" fi done fi fi if [[ "$TestMode" -eq 1 ]]; then msg "\\nThis was done in test mode. Production install directories were not affected, and systemd/SELinux config were not attempted.\\n" if [[ -d "/p4/common" ]]; then msg "If you are upgrading an existing SDP installation, compare these current folders and files: diff -qr /p4/$SDPInstance/bin $SDPInstallRoot/$SDPInstance/bin diff -qr /p4/common $SDPInstallRoot/common Be careful to ensure generated files are correct, including files in /p4/common/config and /p4/common/bin/p4_vars are appropriate.\\n" fi fi #------------------------------------------------------------------------------ # Enable the OOM Killder defense feature. if [[ -n "$SetcapCmd" ]]; then if [[ "$RunningAsRoot" -eq 1 ]]; then msg "Enabling OOM killer protection for p4d.\\nRunning: $SetcapCmd" # shellcheck disable=SC2086 if eval $SetcapCmd; then run "getcap $SDPInstallRoot/common/bin/p4d_$P4DRELNUM.$P4DBLDNUM" else errmsg "Failed to do: $SetcapCmd" fi else warnmsg "Additional Processing is advised to activate OOM killer protection for p4d:\\n" msg "As root, execute this command:\\n\\t$SetcapCmd\\n" msg "And then restart the p4d_${SDPInstance} service." fi fi #------------------------------------------------------------------------------ # Determine Init Mechanism if [[ "$UseSystemd" -eq 1 && -d "/etc/systemd/system" ]]; then InitMechanism="Systemd" if [[ -z "$(command -v systemctl)" ]]; then warnmsg "systemctl isn't in PATH, but /etc/systemd/system exists. Acting as if '-no_systemd' was specified." UseSystemd=0 fi elif [[ -x "/sbin/launchd" ]]; then InitMechanism="Launchd" UseSystemd=0 elif [[ -d "/etc/init.d" ]]; then InitMechanism="SysV" UseSystemd=0 else bail "Could not determine init mechanism. Systemd, SysV, and Launchd aren't available. Aborting." fi SystemdTemplatesDir="$SDPInstallRoot/common/etc/systemd/system" if [[ "$RunningAsRoot" -eq 1 && "$DoServiceInit" -eq 1 ]]; then # Determine list of binaries to install. [[ "$InstallP4D" -eq 1 ]] && BinList+=" p4d" [[ "$InstallP4Broker" -eq 1 ]] && BinList+=" p4broker" [[ "$InstallP4Proxy" -eq 1 ]] && BinList+=" p4p" if [[ "$InitMechanism" == "SysV" ]]; then if [[ -n "$(command -v chkconfig)" ]]; then msg "\\nConfiguring $InitMechanism services.\\n" cd /etc/init.d || bail "Could not cd to [/etc/init.d]." for svc in $BinList; do initScript=${svc}_${SDPInstance}_init if [[ -x /p4/${SDPInstance}/bin/$initScript ]]; then run "ln -s /p4/${SDPInstance}/bin/$initScript" run "chkconfig --add $initScript" run "chkconfig $initScript on" fi done else msg "Skipping SysV service initiailzation; no 'chkconfig' in PATH." fi elif [[ "$InitMechanism" == "Systemd" && "$UseSystemd" -eq 1 ]]; then msg "\\nConfiguring $InitMechanism services.\\n" cd /etc/systemd/system || bail "Could not cd to /etc/systemd/system." for binary in $BinList; do svcName="${binary}_${SDPInstance}" svcFile="${svcName}.service" # If the version of SDP deployed is 2020.1+, it will have templates # for systemd unit files. Use those if found, otherwise use the # baseline templates that come with the Helix Installer. svcTemplate="$SystemdTemplatesDir/${binary}_N.service.t" sed -e "s|__INSTANCE__|${SDPInstance}|g" \ -e "s|__OSUSER__|$OSUSER|g" \ "$svcTemplate" > "$svcFile" ||\ bail "Failed to generate $PWD/$svcFile from template $svcTemplate." if [[ "$EnableSystemdServices" -eq 1 ]]; then run "systemctl enable $svcName" "Enabling $svcName to start on boot." ||\ warnmsg "Failed to enable $svcName with $InitMechanism." else msg "Not enabling service $svcName due to '-no_enable'." fi if [[ -n "$(command -v semanage)" ]]; then if run "semanage fcontext -a -t bin_t /p4/${SDPInstance}/bin/${binary}_${SDPInstance}_init" \ "Configuring SELinux for init script /p4/${SDPInstance}/bin/${binary}_${SDPInstance}_init." > "$TmpFile" 2>&1; then cat "$TmpFile" # The temp file should have no output because semanage is silent on success, but display it anyway. msg "SELinux configured OK." else # If we get an error indicating semanage is already defined, suppress that. if grep -q -E "ValueError: File context for .* already defined" "$TmpFile"; then msg "SELinux configured OK (it was already defined)." else cat "$TmpFile" errmsg "Failed SELinux addition of init script for /p4/${SDPInstance}/bin/${binary}_${SDPInstance}_init." fi fi rm -f "$TmpFile" else warnmsg "SELinux is available but semanage not in PATH. Skipping semanage setup" fi if [[ -n "$(command -v restorecon)" ]]; then run "restorecon -vF /p4/${SDPInstance}/bin/${binary}_${SDPInstance}_init" ||\ errmsg "Failed SELinux restorecon of init script for ${binary}_${SDPInstance}." else warnmsg "SELinux is available but restorecon not in PATH. Skipping restorecon setup." fi done run "systemctl daemon-reload" "Reloading systemd after generating Systemd unit files." ||\ warnmsg "Failed to reload systemd daemon." fi else if [[ "$DoServiceInit" -eq 0 ]]; then msg "Skipping $InitMechanism and SELinux configuration due to '-no_init'." else msg "Skipping $InitMechanism and SELinux configuration; not running as root." fi fi #------------------------------------------------------------------------------ # Configure Firewall. if [[ "$RunningAsRoot" -eq 1 ]]; then if [[ "$DoFirewall" -eq 1 ]]; then if [[ -r "/etc/firewalld/services" ]]; then FirewallType="Firewalld" FirewallDir="/etc/firewalld/services" elif [[ -r "/etc/ufw/applications.d" ]]; then FirewallType="ufw" FirewallDir="/etc/ufw/applications.d" elif [[ -r "/etc/sysconfig/iptables" ]]; then FirewallType="IPTables" FirewallDir="/etc/sysconfig" else FirewallType="uknown firewall type or no firewall detected" fi # Verify firewall is available. if [[ "$FirewallType" == "Firewalld" ]]; then # FirewallOnline indicates that the firewall-cmd utility is available and the firewalld is online. if firewall-cmd --state > /dev/null 2>&1; then msg "Verified: firewalld is available and running." FirewallOnline=1 else warnmsg "Skipping firewalld configuration because firwalld is not running." fi elif [[ "$FirewallType" == "ufw" ]]; then # FirewallOnline indicates that the ufw utility is available and the ufw firewall is online. if [[ "$(ufw status 2>/dev/null)" =~ ' active' ]]; then msg "Verified: ufw is available and running." FirewallOnline=1 else warnmsg "Skipping firewalld configuration because ufw is not running." fi else warnmsg "Skipping firewall configuration because firewall type is not handled: $FirewallType." fi else msg "Skipping firewall configuration due to '-no_firewall'." fi else dbg "Skipping firewall configuration (not running as root)." fi #------------------------------------------------------------------------------ # Add Firewall rules. if [[ "$FirewallOnline" -eq 1 ]]; then # Add Firewall rules for Firewalld, popular on the RHEL/Rocky Linux family. if [[ "$FirewallType" == "Firewalld" ]]; then msg "\\nConfiguring $FirewallType services.\\n" TmpFile=$(mktemp) for binary in $BinList; do svcName="${binary}_${SDPInstance}" svcFile="${svcName}.xml" if [[ "$NoOp" -eq 0 ]]; then sed -e "s|__INSTANCE__|$SDPInstance|g" \ -e "s|__P4PORT__|${P4_PORT##*:}|g" \ -e "s|__P4BROKER_PORT__|${P4BROKER_PORT##*:}|g" \ "$WritableSDPDir/Server/Unix/p4/common/etc/firewalld/${binary}_N.xml.t" > "$TmpFile" ||\ bail "Failed to generate firewalld service file." else msg "NO_OP: Would have generated firewalld entry using template: $WritableSDPDir/Server/Unix/p4/common/etc/firewalld/${binary}_N.xml.t" fi run "cp -f $TmpFile $FirewallDir/$svcFile" \ "Installing generated firewalld service file to $FirewallDir/$svcFile." ||\ bail "Failed to install $FirewallDir/$svcFile." run "firewall-cmd --add-service=$svcName" \ "Adding firewall entry for $svcName." ||\ warnmsg "Adding firewall entry for $svcName failed." done rm -f "$TmpFile" run "firewall-cmd --runtime-to-permanent" \ "Permanently adding firewall entries" ||\ warnmsg "Adding permanent firewall entries failed." run "firewall-cmd --reload" "Reloading firewalld." ||\ warnmsg "Firewalld reload failed." if [[ -n "$(command -v iptables-save)" ]]; then run "iptables-save" "Showing firewall rules." ||\ warnmsg "Showing firewall failed." fi # Add Firewall rules for ufw, popular on the Ubuntu family. elif [[ "$FirewallType" == "ufw" ]]; then msg "\\nConfiguring $FirewallType services.\\n" TmpFile=$(mktemp) for binary in $BinList; do svcName="${binary}_${SDPInstance}" if [[ "$NoOp" -eq 0 ]]; then sed -e "s|__INSTANCE__|$SDPInstance|g" \ -e "s|__P4PORT__|${P4_PORT##*:}|g" \ -e "s|__P4BROKER_PORT__|${P4BROKER_PORT##*:}|g" \ "$WritableSDPDir/Server/Unix/p4/common/etc/ufw/${binary}_N.t" > "$TmpFile" ||\ bail "Failed to generate ufw firewall application file." else msg "NO_OP: Would have generated ufw firewall rule using template: $WritableSDPDir/Server/Unix/p4/common/etc/ufw/${binary}_N.t" fi run "cp -f $TmpFile $FirewallDir/$svcName" \ "Installing generated ufw firewall application file to $FirewallDir/$svcName." ||\ bail "Failed to install $FirewallDir/$svcName." run "ufw app update $svcName" \ "Updating ufw firewall application $svcName." ||\ bail "Failed to update ufw firewall application $svcName." run "ufw allow $svcName" \ "Adding ufw firewall rules for application $svcName." ||\ bail "Failed to allow ufw firewall rules for application $svcName." done rm -f "$TmpFile" run "ufw reload " "Reloading ufw firewall." ||\ warnmsg "ufw firewall reload failed." if [[ -n "$(command -v iptables-save)" ]]; then run "iptables-save" "Showing firewall rules." ||\ warnmsg "Showing firewall failed." fi fi fi #------------------------------------------------------------------------------ # Do the big, long-running things at the end. msg "\\nAll structural processing is complete. Wrapping up with potentially long-running chown/chmod tasks." if [[ "$SHAREDDATA" == "FALSE" && -d "/$DD/p4/$SDPInstance" ]]; then if [[ "$FastMode" -eq 0 ]]; then msg "Setting permissions on depot files - this may take some time ..." run "chmod -R $ExecPerms /$DD/p4/$SDPInstance" || errmsg "Failed to chmod: /$DD/p4/$SDPInstance" else msg "Skipped chmod -R of /$DD/p4/$SDPInstance due to '-f'." fi fi if [[ "$CD" != "$DD" ]]; then if [[ "$SHAREDDATA" == "FALSE" && -d "/$CD/p4/$SDPInstance" ]]; then if [[ "$FastMode" -eq 0 ]]; then msg "Setting permissions on depot files - this may take some time ..." run "chmod -R $ExecPerms /$CD/p4/$SDPInstance" || errmsg "Failed to chmod: /$CD/p4/$SDPInstance" else msg "Skipped chmod -R of /$CD/p4/$SDPInstance due to '-f'." fi fi fi if [[ "$SHAREDDATA" == "FALSE" && -d "/$DD/p4/$SDPInstance" ]]; then if [[ "$FastMode" -eq 0 ]]; then msg "Setting ownership on depot files - this may take some time ..." run "chown -Rh $OSUSER:$OSGROUP /$DD/p4/$SDPInstance" || errmsg "Failed to chown: /$DD/p4/$SDPInstance" else msg "Due to '-f' (fast), skipped chown -Rh of /$DD/p4/$SDPInstance; doing targeted chowns instead." Cmd="chown -h $OSUSER:$OSGROUP /$DD/p4/$SDPInstance" [[ -d "/$DD/p4/$SDPInstance/depots" ]] && Cmd+=" /$DD/p4/$SDPInstance/depots" [[ -d "/$DD/p4/$SDPInstance/cache" ]] && Cmd+=" /$DD/p4/$SDPInstance/cache" run "$Cmd" "Doing targeted chown commands in /$DD:" || \ errmsg "Failed to do: $Cmd" fi fi if [[ "$CD" != "$DD" ]]; then if [[ "$SHAREDDATA" == "FALSE" && -d "/$CD/p4/$SDPInstance" ]]; then if [[ "$FastMode" -eq 0 ]]; then Cmd="chown -Rh $OSUSER:$OSGROUP /$CD/p4/$SDPInstance" run "$Cmd" "Setting ownership on checkpoint files - this may take some time ..." ||\ errmsg "Failed to do: $Cmd" else msg "Due to '-f' (fast), skipped chown -Rh of /$CD/p4/$SDPInstance; doing targeted chowns instead." if [[ -d "/$CD/p4/$SDPInstance/checkpoints" ]]; then Cmd="chown -h $OSUSER:$OSGROUP /$CD/p4/$SDPInstance/checkpoints*" run "$Cmd" "Doing targeted chown commands in /$CD:" || \ errmsg "Failed to do: $Cmd" fi fi fi else if [[ "$FastMode" -eq 1 ]]; then if [[ -d "/$DD/p4/$SDPInstance/checkpoints" ]]; then msg "Due to '-f' (fast), doing targeted chowns for checkpoint dirs." Cmd="chown -h $OSUSER:$OSGROUP /$DD/p4/$SDPInstance/checkpoints*" run "$Cmd" "Doing targeted chown commands for checkpoints in /$DD/p4/$SDPInstance/checkpoints:" || \ errmsg "Failed to do: $Cmd" fi fi fi if [[ "$UpdateSudoers" -eq 1 ]]; then Cmd="$GenSudoersScript" if [[ "$LimitedSudoers" -eq 1 ]]; then Cmd+=" -limited" else Cmd+=" -full" fi if [[ "$TestMode" -eq 0 ]]; then Cmd+=" -y -f" fi if [[ -x "$GenSudoersScript" ]]; then if [[ "$NoOp" -eq 0 ]]; then msg "Running: $Cmd" $Cmd || errmsg "Error from script to update sudoers, $GenSudoersScript." else msg "NO_OP: Would run: $Cmd" fi else errmsg "Skipping sudoers update because this is not executable: $GenSudoersScript" fi fi exit "$ErrorCount"
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#135 | 30991 | C. Thomas Tyler | Fixed sestatus call (typo). | ||
#134 | 30936 | C. Thomas Tyler |
Enhanced SELinux detection logic to so semanage and restorecon are called only if it is beneficial to do so. |
||
#133 | 30892 | C. Thomas Tyler | Added usage error for unkown option/flag. | ||
#132 | 30883 | C. Thomas Tyler | Corrected text in message confusing ufw with firewalld firewalls. | ||
#131 | 30839 | C. Thomas Tyler |
Adjusted mkdirs.sh to be backward compatible with old structure installs (not using package dirs). |
||
#130 | 30782 | C. Thomas Tyler |
Added new install_sdp.sh script and supporting documentation. The new install_sdp.sh makes SDP independent of the separate Helix Installer software (the reset_sdp.sh script). The new script greatly improves the installation experience for new server machines. It is ground up rewrite of the reset_sdp.sh script. The new script preserves the desired behaviors of the original Helix Installer script, but is focused on the use case of a fresh install on a new server machine. With this focus, the scripts does not have any "reset" logic, making it completely safe. Added various files and functionalityfrom Helix Installer into SDP. * Added firewalld templates to SDP, and added ufw support. * Improved sudoers generation. * Added bash shell templates. This script also installs in the coming SDP Package structure. New installs use a modified SDP structure that makes it so the /p4/sdp and /p4/common now point to folders on the local OS volume rather than the /hxepots volume. The /hxdepots volume, which is often NFS mounted, is still used for depots and checkpoints, and for backups. The new structure uses a new /opt/perforce/helix-sdp structure under which /p4/sdp and /p4/common point. This structure also contains the expaneded SDP tarball, downloads, helix_binaries, etc. This change represents the first of 3-phase rollout of the new package structure. In this first phase, the "silent beta" phase, the new structure is used for new installations only. This phase requires no changes to released SDP scripts except for mkdirs.sh, and even that script remains backward-compatible with the old structure if used independently of install_sdp.sh. If used with install_sdp.sh, the new structure is used. In the second phase (targeted for SPD 2024.2 release), the sdp_upgrade.sh script will convert existing installations to the new structure. In the third phase (targeted for SDP 2025.x), this script will be incorporated into OS pacakge installations for the helix-sdp package. Perforce internal wikis have more detail on this change. #review-30783 |
||
#129 | 30681 | C. Thomas Tyler |
Added gen_sudoers.sh script to generate a sudoers file for perforce OSUSER. This generates a more secure limited sudoers file. Previously, adding a sudoers entry for the OSUSER (usually 'perforce') was done only by the Helix Installer. In the Helix Installer variant, a single "one-size-filts-all" sudoers file was used, with the following characteristics: * The instances for Helix Core services were referenced with a '*' wildcard to match all SDP instances, which has since been determined to introduce a vulnerability. In this new script, the wildcard is replaced with separate entries for each SDP instance. * There were entries for all known paths of utilities like lslocks, setcap, and getcap. This new script generates the correct path valid for the current machine. With this change, the functionality will be available in the SDP directly. This new gen_sudoers.sh script can be called by mkdirs.sh directly to update the sudoers file each time a new SDP instance is added, if the new '-fs' (full sudo) or '-ls' (limited sudoers) entries are used. There is no change to the default behavior of mkdirs.sh; only a change if new options are utilized. This script comes with docs and examples for the new script as well as doc changes for mkdirs.sh. (Also added missing documentation for the '-no_enable' option). Further changes needed: * Add doc reference in SDP_Guide.Unix.adoc |
||
#128 | 30527 | C. Thomas Tyler |
Corrected issue where systemd service is configured with P4USER rather than OSUSER. #review-30528 |
||
#127 | 30503 | C. Thomas Tyler | Completed earlier work to use TarRootUnsupported variable to reduce hard-coding. | ||
#126 | 30502 | C. Thomas Tyler | Added SDP Version file to set of files copied to local, non-package area. | ||
#125 | 30474 | C. Thomas Tyler | Fixed typo/bug. | ||
#124 | 30473 | C. Thomas Tyler | Made it easier to call mkdirs.sh without explicit './' from setup dir. | ||
#123 | 30471 | C. Thomas Tyler | Added '-no_enable' option to avoid enabling systemd services. | ||
#122 | 30469 | C. Thomas Tyler |
Refined '-f' (fast) mode in mkdirs.sh. As before, we skip the big 'chown -R' commands in fast mode. But with this change, we do targeted 'chown' commands to ensure key directories like /hxdepots/p4/N and /hxdepots/p4/N/depots and /hxcheckpionts/p4/N/checkpoints have correct ownership. |
||
#121 | 30454 | C. Thomas Tyler |
mkdirs.sh v6.2.0: Added in-code docs for TarRoot, and corrected TarRoot to work seamlessly with both package and non-package installations. Fixed issue with SDPVersion file in non-package installs. Added logic to avoid generating calling 'semanage' unnecessarily to do SELInux configuration if it was allready done. This removes a source of most harmless non-zero exit codes. |
||
#120 | 30452 | C. Thomas Tyler | Refined symlink chown logic for /p4/common. | ||
#119 | 30449 | C. Thomas Tyler | Fixed bug with ownership chown targeting wrong path. | ||
#118 | 30448 | C. Thomas Tyler | Fixed doc typo. | ||
#117 | 30447 | C. Thomas Tyler | Added '-c <cfg_file>'. | ||
#116 | 30446 | C. Thomas Tyler |
Change to be backward-compatible with mkdirs.cfg files that do not define a value for CD. Default for CD is same was DD. |
||
#115 | 30445 | C. Thomas Tyler |
Added undocumented support for /opt/perforce/helix-sdp package directory. #review With this change, mkdirs.sh behavior is changed depending on the pre-existence of the directory /opt/perforce/helix-sdp, the future package install location. The /opt/perforce/helix-sdp folder is not created by design, effectively making support for the package structure a Tech Preview (i.e. Beta) feature. This change provides behaviors needed to support package installation that also dovetail with goals of decoupling the /p4/common and /p4/sdp folders from NFS in NFS environments. If the /opt/perforce/helix-sdp is created with proper permissions and user/group ownersihp before mkdirs.sh is run, new behaviors apply. The proper ownership and permissions are: /opt/perforce/helix-sdp - root:perforce, 775 perms. Allows perforce user to manage subdirs, e.g. common, downloads, helix_binaries, p4/sdp. /opt/perforce/helix-sdp/sdp - root:root, 755 perms. This is the immutable area, an extract of the SDP tarball and no additional files. This root-managed area is intended to be updated only by OS package upgrades, and cannot be affected by the perforce user. These folders in the structure are modifiable by the perforce user (owned by perforce:perforce), and will contain generated files, symlinks, and possibly even local custom files. * /opt/perforce/helix-sdp/downloads, for unpacking SDP tarballs for upgrades. * /opt/perforce/helix-sdp/helix_binaries, contains get_helix_binaries.sh, p4*. * /opt/perforce/helix-sdp/p4/sdp - A copy of /opt/perforce/helix-sdp/sdp, owned by perforce:perforce rather than root:root. In this version, the following behaviour changes occur if /opt/perforce/helix-sdp exists when this script is run: * The /p4/sdp symlink points to /opt/perforce/helix-sdp/p4/sdp rather than /hxdepots/sdp. * The /p4/common symlink points to /opt/perforce/helix-sdp/p4/sdp/Server/Unix/p4/common rather than /hxdepots/p4/common. In this beta version, if run in an environment where those /p4/common and /p4/sdp symlinks already exist, the symlinks are NOT changed even if /opt/perforce/helix-sdp exists. This is Phase 1 if a multi-phased release of this feature. Phase 1 will support only greenfield installations where /opt/perforce/helix-sdp is created externally to this script. (Targeted for SDP 2024.1 Patch 1, July 2024) In Phase 2, the /opt/perforce/helix-sdp will be created by this script in greenfield installations with a documented '-pkg' option (if run as root), and sdp_upgrade.sh will migrate to this structure if and only if /opt/perforce/helix-sdp exists. Targeted for SDP 2024.1 Patch 2 (Summer 2024). In Phase 3, this will be integrated into the OS package installation mechanism for Rocky9+ and Ubuntu 22.04+, possibly others. (Targeted for SDP 2025.1+.) SDP-1069: Decouple /p4/common and /p4/sdp from NFS. The above captures the initial plan. See this wiki page with more updated information as it evolves: https://perforce.atlassian.net/wiki/spaces/PROS/pages/936542265/SDP-1069+Decouple+SDP+from+NFS |
||
#114 | 30433 | C. Thomas Tyler | Corrected chown command for a symlink. | ||
#113 | 30431 | C. Thomas Tyler |
Fixed issue with some dbg() calls not displaying output. Fixed issue with command line did not display correctly. |
||
#112 | 30430 | C. Thomas Tyler |
Enhanced logic determining owner/group to use 'stat' rather than 'ls' with sed/awk. This is more portable, clearer, and likely faster. |
||
#111 | 30362 | C. Thomas Tyler | Removed a line of dead code. | ||
#110 | 30333 | C. Thomas Tyler |
Added HxCheckpoints, optional setting to store checkpoints on a separate volume from depots. Default is same value as HxDepots. This changes makes the SPD more adaptable to customers, especially using NFS, that prefer to have separate mounts for checkpoints vs. those for archive files. The original SDP design was to have everything that needed to be backed up (i.e. metadata checkpoints and the versioned file tree) on a single volume. This is still the preferred mode, but allowing checkpoints and archives to be separate is useful for some. #review-30334 |
||
#109 | 30036 | C. Thomas Tyler |
mkdirs.sh tweaks: * The configurables.cfg file is deployed if it doesn't already exist. * The SiteTags.cfg.sample file is deployed if neither SiteTags.cfg.sample nor SiteTags.cfg exists. |
||
#108 | 30020 | C. Thomas Tyler | Changed mkdirs.sh to not require p4d on a non-p4d server. | ||
#107 | 29802 | C. Thomas Tyler |
Fixed typo/bug. #review-29803 @robert_cowham |
||
#106 | 29691 | C. Thomas Tyler |
Added logic to avoid applying the 'setcap' (the OOM Killer defense) in Docker environments (e.g. for testing). Similar to @296666, but that changeg was for upgrade.sh, and this is for mkdirs.sh. Info: Using the 'setcap' command on a binary in a Docker container renders the binary inoperable. Attempts to execute the binary result in an 'Operation not permitted' error. The workaround: Don't use 'setcap' on binaries in a Docker container. #review-29692 |
||
#105 | 29620 | C. Thomas Tyler | Added setcap capability to mkdirs.sh. | ||
#104 | 29388 | C. Thomas Tyler | Added crontab for broker-only installs. | ||
#103 | 29305 | C. Thomas Tyler |
Fixed typo. #review-29300 |
||
#102 | 29299 | C. Thomas Tyler |
Fixed bug that caused crontab not to be generated for proxy-only installs. Also: Cosmetic change: Normalized NO_OP message prefix. #review-29300 |
||
#101 | 29156 | C. Thomas Tyler |
Fixed minor bugs resulting in harmless errors when mkdirs.sh is used for proxy-only or broker-only hosts. Enhanced clarity of error messages related to 'cd' failures. #review-29157 |
||
#100 | 28397 | C. Thomas Tyler |
Enhanced support for proxy-only and broker-only hosts. #review-28398 |
||
#99 | 28192 | C. Thomas Tyler |
Added new optional PERMS setting in mkdirs.cfg, to allow opening of SDP perms when mkdirs.sh is used. This is useful for customer environments (mainly test environments). Documentation for the feature is included in the mkdirs.cfg file. Default behavior is unchanged. |
||
#98 | 27992 | C. Thomas Tyler |
Added DEFAULT_DOMAIN to list of required values that must be defined in mkdirs.cfg in the checks executed in mkdirs.sh. |
||
#97 | 27886 | Domenic | Add closing brace for TargetServerID variable in the error message. | ||
#96 | 27802 | C. Thomas Tyler |
Doc correction to mkdirs.sh. No functional change. |
||
#95 | 27782 | Domenic |
Add a check for REPLICA_ID matching MASTER_ID to ensure that replica/edge servers don't use the same setting as the master server. Anchor the checks for SERVER_TYPE so that leading/trailing characters aren't included. This also meant adding an explicit entry for p4d_edge_replica as it was previously implicit from p4d_edge. Update version to v4.6.0. |
||
#94 | 27729 | C. Thomas Tyler | Fixed issue causing some chown commands not to run reliably. | ||
#93 | 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 |
||
#92 | 27385 | ashaikh |
Fix mkdirs.sh install errors on replica servers When you run the mkdirs.sh script on an edge server, you get a symlink error for the checkpoints directory: Running: ln -s /tmp/hxmounts/hxdepots/p4/1/checkpoints.edge.1 /tmp/p4/1/checkpoints.edge.1 ln: failed to create symbolic link ‘/tmp/p4/1/checkpoints.edge.1’: No such file or directory Error: (line: 735) Failed to create symlink. You also get an error for the chown commands on the checkpoints directory because there is an extra / slash in the path. SDP Job - https://swarm.workshop.perforce.com/jobs/SDP-596 |
||
#91 | 27369 | C. Thomas Tyler |
mkdirs.sh v4.5.0: * p4p no longer installed by default unless ServerType is p4proxy. * p4dtg_init no longer installed by default. * If p4dtg installed, warning message indicates more setup needed. * Added '-I <svc>' to install p4dtg and/or p4p. * p4d no longer installed if ServerType is p4proxy or p4broker. * Fixed issue where '-n' (NoOp mode) missed displaying some commands that would execute during proxy initialization. * Fixed harmless error if run from /p4/sdp/Server/Unix/setup rather than /hxdepots/p4/sdp/Server/Unix/setup after the initial install. * Allowed for several aliases to the server type flag, e.g. 'p4p', 'p4d', 'p4b', 'edge', etc, with corresponding doc chnages. * Fixed an issue where a 'chmod' command would attempt to execute in NoOp mode. * Enhanced some 2nd-pass workflows, removing harmless but unnecessary errors. * Enhanced docs to indicate where init script and systemd templates can be found. #review-27370 |
||
#90 | 27307 | C. Thomas Tyler |
mkdirs.sh v4.4.1: * Fixed issue with generated root-owned files after initial install. * Fixed dependency on USER environment variable, which is not guaranteed to be defined on all platforms. Now 'whoami' is used. |
||
#89 | 27250 | C. Thomas Tyler |
Adjusted JournalPrefix standard to account for shared /hxdepots. The JournalPrefix standard now allows for unfiltered replicas (such as HA/DR replicas) to use same journalPrefix value as filtered replicas and edge servers, using per-ServerID checkpoints folder, if they share the same /hxdepots (e.g. NFS-mounted) with the master (e.g. when lbr.replication=shared). Related code change made to mkdirs.sh and mkrep.sh to support the tweaks to the standard. #review-27251 |
||
#88 | 27099 | C. Thomas Tyler |
Eliminated extra /p4/Version file. The standard for determining the SDP version for 2020.1 and forward will be the file /p4/sdp/Version. This is more clear. Job SDP-564 evolved slightly (per DevNotes in the job). The goal remains the same, to standardize the method of determining the SDP version for SDP 2020.1+. It was deemed that having an extra copy in /p4/Version will not help with that, and instead would introduce more failure modes and possibilities for out-of-sync files. This does mean the 'tarball extraction' sdp folder that is symlinked to from /p4/sdp is now a critical part of the SDP installation. This is normal and as documented, though there have been cases where SDP is copied from one machine to another in some incomplete way, e.g. rysnc of /p4/common but not /hxdepots/sdp and the symlink to it from /p4/sdp. However, the verify_sdp.sh will catch that form of misconfiguration. #review-27100 |
||
#87 | 27061 | Robert Cowham | mkdirs.sh now respects the MASTER_ID value from mkdirs.cfg (or mkdirs.N.cfg). | ||
#86 | 27022 | C. Thomas Tyler | Changed 'exes' to 'helix_binaries' in folder and script name, per review. | ||
#85 | 26986 | C. Thomas Tyler |
Refinements to mkdirs.sh and mkdirs.cfg, per code review: https://swarm.workshop.perforce.com/reviews/26962 In mkdirs.cfg: * Added comments about proper use of DB1/DB2. * Added comment about coming removal of P4FTP/P4WEB settings. In mkdirs.sh v4.1.1: * Replaced -M with set of -M* flags to specify mount points. * Completed implementation of -M* flags. * Enhanced examples in usage function. * Added clarification of difference between '-n' and '-p'. * Fixed some typos. #review @rcowham |
||
#84 | 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. |
||
#83 | 26718 | Robert Cowham |
Rename P4MASTER to P4MASTERHOST for clarity with comments in: - mkdirs.cfg/mkdirs.sh - p4_<instance>.vars - other files which reference Remove unnecessary sed for p4p.template |
||
#82 | 26185 | C. Thomas Tyler |
Standby replicas no longer need to use an idiosyncratic journals.rep folder, and now use the same checkpoints dir naming convention as edge servers and other replica types. Back story: Prior to P4D 2018.1, standby replicas follow a different convention for placement of journal files. With the introduction of the rpl.journalcopy.location configurable in P4D 2018.1, standby replicas now set that configurable and use the same convention as other replica types. |
||
#81 | 26080 | Robert Cowham | Fix typo and failing test | ||
#80 | 26079 | C. Thomas Tyler |
Fixed typo. Thanks, Robert! |
||
#79 | 26060 | C. Thomas Tyler |
This supercedes review-24715. Bringing over recent bug fixes and code clean up from Rusty Jackson's local branch. Adds an edge maintenance script to unload clients on edge servers. Automated setting up maintenance.cfg from mkdirs.cfg settings. Cleaned up sdputils.py - It had a logic bug, and fixed all scripts based on changes. == Merge Details == Merge strategy: All the fixes to Maintenance scripts were brought in, but not the changes to active them in crontab that would enable them. Rusty's original change had crontab changes to call maintenance scripts, and also calls to 'p4 unlock -x' as a workround to p4d bugs related to orphanged locks on edge servers. Those bugs are already fixed. Also, adding anything new to cron requires a test suite addition and doc updates. So changes to the template.crontab.combined were ignored. However, a new file was added to the Maintenace folder, sample_cron_entries.txt, to make it easy for folks to see those changes. Rusty's original change had mkdirs.sh changes to generate maintenance.cfg. This change was enhanced during the merge. Rather than overwriting maintenance.cfg (potentially blowing away configuration for other instances), a new section for the new instance is appended to maintenance.cfg when 'mkdirs.sh <instance>' is run. Future considerations: Before adding anything from Maintenance to cron, we need to do the following: * Have mkdirs.sh install the Maintenance folder to the as-deployed structure under /p4/common, i.e. to /p4/common/maintenance, for HMS management compliance. * Add tests and docs for each script called (directly or indirectly). |
||
#78 | 25922 | C. Thomas Tyler |
Fixed root-owned symlinks in /p4/N after running mkdirs.sh. This harmless-but-ugly issue caused no functional issues, but is not as intended. |
||
#77 | 25575 | Robert Cowham |
Updates to SDP and tests for 19.1 upgrades #review @tom_tyler |
||
#76 | 25568 | Robert Cowham | Wasn't processing server type p4d_ham | ||
#75 | 25551 | Robert Cowham | Fix test broken by 25550 when hms removed. | ||
#74 | 25546 | Robert Cowham | Fix failing test - check properly for link existence before creating. | ||
#73 | 25450 | Robert Cowham | Fix failing test - over enthusiastic string quoting (with wildcard)... | ||
#72 | 25427 | C. Thomas Tyler | Fixed root ownership of generated crontab file. | ||
#71 | 25386 | C. Thomas Tyler |
Fixed mkdirs.sh issue with SSL-enabled installs due to missing a 'chown'. Bypassing pre-commit to patch. #review-25387 |
||
#70 | 25363 | C. Thomas Tyler |
Fixed bug where /p4/N/bin ownership is not set correctly (owned by root). Fixed issue with missing symlink creation for replicas. Made compliant with shellcheck.sh v0.6.0, driving many changes and fixing potential glob-expansion issues. Fixed an issue with '-test' not setting DB1/DB2. Removed unused/obsolete MD def'n. Added 'p4d_ha' server type to distinguish from existing 'p4d_standby' type, and added comments to mkdirs.cfg to note that p4d_standby is for pre-2018.1 servers, and p4d_ha is for 2018.1+. The distinction is that P4D 2018.1 introduced rpl.journalcopy.location, which changes P4D behaviors and corresponding best practice for placement of the actively pulled journal file for 'journalcopy' replicas. For pre-2018.1, we use /hxlogs/p4/N/journals.rep, and for 2018.1+ with rpl.journalcopy.location=1 set, we us /hxdepots/p4/N/checkpoints.<tag>. Normalized inconsistent indentation. |
||
#69 | 25316 | Robert Cowham | Fix breaking test - logic around $CN was misunderstood. | ||
#68 | 25306 | ashaikh |
Fix syntax error in mkdirs.sh script Currently the mkdirs.sh script will not create the /p4/common/bin or the /p4/common/config folders due to a syntax error and failure in the conditional check. This leads to a cascading failure in other parts of the script. From my limited testing, the CN value is never an empty string because if mkdirs.sh is not run in test mode, the value is imported from the mkdirs.cfg file. |
||
#67 | 25231 | Robert Cowham |
Output line numbers on mkdirs errors Tweak tests to cope when parsing output |
||
#66 | 25190 | Robert Cowham |
Change to make instance dir a directory under /p4 (so on root volume). This avoids potential problems where /hxdepots is shared on multiple instances. It also improves performance often. Left the option to put /p4/common on a shared volume if required. |
||
#65 | 25147 | Robert Cowham |
Made -test parameter work again and included tests to detect future breakage! |
||
#64 | 25005 | C. Thomas Tyler | Removed hms reference. | ||
#63 | 23580 | C. Thomas Tyler |
Fixed a typo that would cause a chown to fail. Thanks to @rmarin for spotting that the first attempt to fix this was wrong! #review @rmarin |
||
#62 | 23456 | C. Thomas Tyler |
Fixed mkdirs.sh bug where 'chown' was trying to change ownership of the wrong dir. Bypassing pre-commit review as this is an obvious typo fix. #review-23457 |
||
#61 | 23354 | C. Thomas Tyler |
Fixed bug where checkpoints.* dir for replicas was created on /hxlogs rather than /hxdepots volume. Removed unnecessary logic to create a symlink for checkpoints.* dir for replicas. Fixed ownership of new checkpoints.* dir on creation. PATCH: Bypassing pre-commit review. #review-23355 |
||
#60 | 23266 | C. Thomas Tyler |
Fixes and Enhancements: * Enabled daily_checkpoint.sh operate on edge servers, to keep /p4/N/offline_db current on those hosts for site-local recovery w/o requiring a site-local replica (though having a site-local replica can still be useful). * Disabled live_checkpoint.sh for edge servers. * More fully support topologies using edge severs, in both geographically distributed and horizaontal scaling "wokspace server" solutions. * Fix broken EDGESERVER value definition. * Modified name of SDP counter that gets set when a checkpoint is taken to incorporate ServerID, so now the counter name will look like lastSDPCheckpoint.master.1, or lastSDPCheckpoint.p4d_edge_sfo, rather than just lastSDPCheckpoint. There will be multiple such counters in a topology that uses edge servers, and/or which takes checkpoints on replicas. * Added comments for all functions. For the master server, journalPrefix remains: /p4/N/checkpoints/p4_N The /p4/N/checkpoints is reserved for writing by the master/commit server only. For non-standby (possibly filtered) replicas and edge serves, journalPrefix is: /p4/N/checkpoints.<ShortServerID>/p4_N.<ShortServerID> Here, ShortServerID is just the ServerID with the 'p4d_' prefix trimmed, since it is redundant in this context. See mkrep.sh, which enshines a ServerID (server spec) naming standard, with values like 'p4d_fr_bos' (forwarding replica in Boston) and p4d_edge_blr (Edge server in Bangalore). So the journalPrefix for the p4d_edge_bos replica would be: /p4/N/checkpoints.edge_bos/p4_N.edge_bos For "standby" (aka journalcopy) replicas, journalPrefix is set to /p4/N/journals.rep. which is written to the $LOGS volume, due to the nature of standby replicas using journalPrefix to write active server logs to pre-rotated journals. Some take-away to be updated in docs: * The /p4/N/checkpoints folder must be reserved for checkpoints that originate on the master. It should be safe to rsync this folder (with --delete if desired) to any replica or edge server. This is consistent with the current SDP. * I want to change 'journals.rep' to 'checkpoints.<ShortServerID>' for non-standby replicas, to ensure that checkpoints and journals taken on those hosts are written to a volume where they are backed up. * In sites with multiple edge serves, some sharing achive files ('workspace servers'), multiple edge servers will share the same SAN. So we one checkpoints dir per ServerID, and we want that dir to be on the /hxdepots volume. Note that the journalPrefix for replicas was a fixed /p4/N/journals.rep. This was on the /hxlogs volume - a presumably fast-for-writes volume, but typically NOT backed up and not very large. This change puts it under /p4/N/checkpoints.* for edge servers and non-standby replicas, but ensures other replica types and edge servers can generate checkpoints to a location that is backed up and has plenty of storage capacity. For standby replicas only (which cannot be filtered), the journalPrefix remains /p4/N/journals.rep on the /hxlogs volume. |
||
#59 | 23202 | C. Thomas Tyler | Fixed an obvious typo in mkdirs.sh. | ||
#58 | 22957 | C. Thomas Tyler |
Merged two changes initiated on main down to: Change @22826 by robert_cowham: Ignore some files on Mac. Change @22950 by awkan/ttyler: Provide an override for difference between proxy listening port and target port |
||
#57 | 22788 | C. Thomas Tyler | Backed out the backout; moving forward with this change. | ||
#56 | 22694 | Russell C. Jackson (Rusty) | Backout accidental submit of shelved change. | ||
#55 | 22693 | Russell C. Jackson (Rusty) |
Branched a Unix only version of the SDP. Removed extra items to create a cleaner tree. Moved a few items around to make more sense without Windows in the mix. |
||
#54 | 22625 | Russell C. Jackson (Rusty) | Approved in Review 22364 | ||
#53 | 22623 | Russell C. Jackson (Rusty) | Update to account for Tom's name change. | ||
#52 | 22201 | C. Thomas Tyler | Fixed typo. | ||
#51 | 22200 | C. Thomas Tyler |
More elegant and portable implementation of logic to find config file in same dir as mkdirs.sh script. Works on Mac, too. This works for various means of calling mkdirs.sh, e.g. ./mkdirs.sh /full/path/to/mkdirs.sh /path/with/symlink/to/mkdirs.sh mkdirs.sh (found in PATH) Approving my own review here for this minor change so I can deploy, as others are on holiday or traveling. |
||
#50 | 22145 | Robert Cowham | Update mkdirs to help testing. | ||
#49 | 22070 | Russell C. Jackson (Rusty) |
Pull the configuration items out into mkdirs.cfg and source that file in mkdirs.sh. Makes it a little cleaner, and less likely for someone to mess up the mkdirs.sh script. Also preps for potential future configure_sdp.sh script to ask questions and create the mkdirs.cfg file. |
||
#48 | 21418 | C. Thomas Tyler |
Changed CASEINSENSITIVE to CASE_SENSITIVE, to make it harder to pick the wrong value by miscalculating the double-negative. Changed the default to be case-sensitive, for several reasons: * Case-sensitive is better for git interoperability. Most git repos in the wild, especially those used in corporate environments, are case sensitive. * Case-sensitive is better for importing from most legacy SCM systems, as it can handle a wider array of data sets. * Case-sensitive is required for some data sets that have case-only variants. * The SDP now includes a case check trigger to help avoid the worst perils of a case-sensitive server. * While confusion is always possible if the client OS doesn't match the case sensitivty setting of the server, the least harmful permuatations of problems occur with the widest array of client platforms when you have a case-senstive server. * Case-insensitive is really only best suited to pure-Windows sites. Also added a comment indicating you don't need the Review daemon if you intend to handle review-style email notifications with Swarm. |
||
#47 | 21327 | Russell C. Jackson (Rusty) | Update to have mkdirs put the correct instance name into the crontab files. | ||
#46 | 21267 | Robert Cowham |
Fix failing tests. Changed default filesystem names to: DB1=hxmetadata1 DB2=hxmetadata2 DD=hxdepots LG=hxlogs hx=Helix. Updated docs to reflect this |
||
#45 | 21192 | Russell C. Jackson (Rusty) | Fixed issue with root and offline_db links. | ||
#44 | 21178 | Russell C. Jackson (Rusty) |
Change the SDP so that root and offline_db can be on different volumes and still accomplish a fast database recovery using recreate_db_checkpoint.sh and recreate_db_sync_replica.sh. This is done by switching the links now rather than moving the db files. |
||
#43 | 21123 | Russell C. Jackson (Rusty) | Corrected cp path for ssl directory. | ||
#42 | 21049 | Russell C. Jackson (Rusty) |
Added config.txt to /p4/ssl so we and customers don't have to go find it in the admin guide. Added comments and cp command for config.txt and setting up ssl certs. Uncommented the journalcopy echo commands at the bottom of mkdirs.sh per discussion with Tom. |
||
#41 | 20982 | Russell C. Jackson (Rusty) | Added the new CN setting for /p4/common to the test folder path resets. | ||
#40 | 20905 | Russell C. Jackson (Rusty) |
Defaulted the SDP to be on the same volume as $CN since that is where it is usually located. Changed MAILTO to default to $MAILFROM since that is what it is most of the time and I am lazy and don't like typing the email address twice. |
||
#39 | 20904 | Russell C. Jackson (Rusty) |
Added CN=$DD and changed all $DD/p4/common entries to $CN/p4/common in order to allow you to install an instance on a different depotdata volume than the 1st instance. Before this change, doing that would incorrectly create a common folder on the 2nd depotdata volume. Also removed the lines that copy the binaries from an existing /p4/common/bin folder back to the SDP. It is perfectly acceptable to install another instance that is using a newer version than the existing instance. |
||
#38 | 20790 | C. Thomas Tyler | Added '/p4/common/hms' to list of dirs to install.' | ||
#37 | 20708 | C. Thomas Tyler |
Per discussion: s/checkpoints.rep/journals.rep/g This directory name changed, used in the journalPrefix configurable, is intended to clarify that the should be targeted to for a FAST volume for use with journalcopy, rather than the LARGE volume as would be implied when using a directory with "checkpoints" in the name. |
||
#36 | 20432 | C. Thomas Tyler |
Improved edge & daisy chained replica support in instance_vars.template. Changed so P4MASTER is set dynamically, based on how/whether the P4TARGET of the current ServerID is set. This also eliminates a possible discrepancey beteween P4MASTER as defined in the p4_N.vars/mkdirs.sh and the master hostname as defined in P4TARGET configurables. The value defined with P4TARGET must also work with SSH keys. (As a best practice P4TARGET should be a host alias so that it doesn't need to be changed in case of failvoer of your P4TARGET server). Changed so SHAREDDATA is set dynamically, based on how/whether the lbr.replication of the current ServerID is set. If it is unset, set to none, ondemand, or cache, then SHAREDDATA is set to TRUE, otherwise FALSE. Dynamic queries use 'p4d -cset' so they work regardless of whether the p4d process is up or not. Some internal refactoring was necessary to ensure all variables are set before they are used. This involved a minor tweak to mkdirs.sh to remove the now-unnecessary 'sed' for SHAREDDATA when generating p4_N.vars from the template. SHAREDDATA must still be configured in mkdirs.sh because it can be run before a replica is fully configured. Goals: * Simplfy SDP configuration for complex topologies by eliminating configuration external to p4d where possible/practical. * Reduce chances for discrepancies and errors as topologies evolve over time. * Allow the p4_1.vars file to identical on all hosts in the topology, an HMS requirement. |
||
#35 | 20395 | C. Thomas Tyler | Fixed typo. | ||
#34 | 20376 | C. Thomas Tyler |
Incorporated HMS service user naming standard into the SDP, i.e. "svc_<serverid>." Removed SVCUSER setting from mkdirs.sh accordingly. Fixed mkdirs.sh so /p4/common/etc is created if it doesn't already exist, just as the 'lib' dir is handled. Also a minor structural enhacement in instance_vars.template. Added SDP_ALWAYS_LOGIN setting to instance_vars.template, setting the default to 0 to prevent unnecessary logins. |
||
#33 | 20363 | C. Thomas Tyler |
Removed references to legacy names for checkpoint scripts. No functional changes. Bypassing pre-commit code review. #review-20364 |
||
#32 | 20217 | Russell C. Jackson (Rusty) | Needed move password creation outside of common area since it is instance specific now. | ||
#31 | 20170 | Russell C. Jackson (Rusty) |
Moved password and users into the config directory to allow for instance specific users and passwords. Ran into a case where two different teams were sharing the same server hardware and needed this type of differentiation. Surprised that we haven't hit this sooner. Also defaulted mkdirs to use the numeric ports since this is the most common installation. |
||
#30 | 19983 | Russell C. Jackson (Rusty) | Commented out the echo around using journalcopy until we are ready to support that. | ||
#29 | 19410 | Russell C. Jackson (Rusty) |
Made out on setting permissions consistent in mkdirs. Added the new output as valid in test_SDP. |
||
#28 | 19314 | Russell C. Jackson (Rusty) |
Change p4verify.sh to use -S to verify shelves on a replica instead of printing the files on the shelf. Removed the HOST_IP settings from mkdirs and instance_vars since it causes problems in a shared depotdata environment, and it was a temporary fix to work around a bug with auth.id that is being fixed. |
||
#27 | 19311 | adrian_waters | If creating a replica that shares depot files with master, don't do chown/chmod on the depot files as this can take a significant time when migrating existing Helix servers into the SDP; In addition, issue 'warning' message that chown/chmod could take some time to complete so user is aware of processing being carried out | ||
#26 | 18952 | C. Thomas Tyler |
Tweaks to mkdirs.sh: * Replaced ADMINEMAIL with MAILTO and MAILFROM settings. This allows MAILTO to be a distribution list or a comma-delimited list of email addresses, while MAILFROM must always be exactly one email address. * Added quotes to allow handling of adresses like '#P4AdminTeam," where the '#' character designates a distribution list. |
||
#25 | 18930 | C. Thomas Tyler |
Fixed typo; caught by test suite. Bypassing pre-commit review 'cuz this is an obivious fix. #review-18931 |
||
#24 | 18925 | C. Thomas Tyler |
Enhanced p4_vars.template to support operating on an SDP-managed host where no p4d process runs, such as a p4p (proxy) host, where no /p4/n/root/server.id file exists. The $SERVERID value will be empty (but defined) in this case. Enhanced to better support operating with replicas that share /depotdata with their master servers, by making P4TRUST and P4TICKETS values contain $SERVERID. Moved SHAREDDATA from p4_vars to instance_vars, since it is not inherently a global setting. In sophisticated enterprise environments, it can vary on a per-replica basis. Adjusted mkdirs.sh accordingly. |
||
#23 | 18618 | Russell C. Jackson (Rusty) | Added a crontab for the edge servers. | ||
#22 | 18203 | richard_baum |
Removed hard-coded /p4 path for server.id file location. This fixes "-test" mode so server.id file is written to the correct location. Without this it is written to /p4 where there could be an installation with the same instance ID. In that case the server.id file could get overwritten with different data. If there is not an existing instance an error message would be displayed. Now neither of these should occur :-) Also fixed some typos. |
||
#21 | 16563 | C. Thomas Tyler |
Routine Merge Down to dev from main using: p4 merge -b perforce_software-sdp-dev p4 resolve -as |
||
#20 | 16373 | C. Thomas Tyler |
Routine Merge Down to dev from main using: p4 merge -b perforce_software-sdp-dev |
||
#19 | 16335 | C. Thomas Tyler |
Routine Merge Down to dev from main using: p4 merge -b perforce_software-sdp-dev |
||
#18 | 16029 | C. Thomas Tyler |
Routine merge to dev from main using: p4 merge -b perforce_software-sdp-dev |
||
#17 | 15701 | C. Thomas Tyler | Routine merge down using 'p4 merge -b perforce_software-sdp-dev'. | ||
#16 | 14136 | C. Thomas Tyler |
Routine merge down to dev from main for SDP using perforce_software-sdp-dev. |
||
#15 | 14038 | C. Thomas Tyler | Routine merge-down to SDP dev from main. | ||
#14 | 13906 | C. Thomas Tyler |
Normalized P4INSTANCE to SDP_INSTANCE to get Unix/Windows implementations in sync. Reasons: 1. Things that interact with SDP in both Unix and Windows environments shoudn't have to account for this obscure SDP difference between Unix and Windows. (I came across this doing CBD work). 2. The Windows and Unix scripts have different variable names for defining the same concept, the SDP instance. Unix uses P4INSTANCE, while Windows uses SDP_INSTANCE. 3. This instance tag, a data set identifier, is an SDP concept. I prefer the SDP_INSTANCE name over P4INSTANCE, so I prpose to normalize to SDP_INSTANCE. 4. The P4INSTANCE name makes it look like a setting that might be recognized by the p4d itself, which it is not. (There are other such things such as P4SERVER that could perhaps be renamed as a separate task; but I'm not sure we want to totally disallow the P4 prefix for variable names. It looks too right to be wrong in same cases, like P4BIN and P4DBIN. That's a discussion for another day, outside the scope of this task). Meanwhile: * Fixed a bug in the Windows 2013.3 upgrade script that was referencing undefined P4INSTANCE, as the Windows environment defined only SDP_INSTANCE. * Had P4INSTANCE been removed completely, this change would likely cause trouble for users doing updates for existing SDP installations. So, though it involves slight technical debt, I opted to keep a redundant definition of P4INSTANCE in p4_vars.template, with comments indicating SDP_INSTANCE should be used in favor of P4INSTANCE, with a warning that P4INSTANCE may go away in a future release. This should avoid unnecessary upgrade pain. * In mkdirs.sh, the varialbe name was INSTANCE rather than SDP_INSTANCE. I changed that as well. That required manual change rather than sub/replace to avoid corrupting other similar varialbe names (e.g. MASTERINSTANCE). This is a trivial change technically (a substitute/replace, plus tweaks in p4_vars.template), but impacts many files. |
||
#13 | 13586 | C. Thomas Tyler |
Routine merge down from main -> dev. Trivial merges, all resolved with 'p4 resolve -as.' |
||
#12 | 12923 | C. Thomas Tyler |
Routine merge down from main to dev. Resolved with 'p4 resolve -as', no merges or conflicts. |
||
#11 | 12170 | Russell C. Jackson (Rusty) | Merged in changes in Main | ||
#10 | 12116 | Russell C. Jackson (Rusty) | Update dev from main. | ||
#9 | 12107 | C. Thomas Tyler |
Routine merge down from 'main' to 'dev', resolved with 'p4 resolve -as'. |
||
#8 | 12028 | C. Thomas Tyler | Refreshed SDP dev branch, merging down from main. | ||
#7 | 11523 | Russell C. Jackson (Rusty) |
Modified P4BROKERPORTNUM to just be the port number and added P4BROKERPORT to instance_vars to be consistent with P4PORT. Also makes it easier to modify p4review.py to use P4BROKERPORT rather than P4PORT for the subject line when needed. |
||
#6 | 11490 | Russell C. Jackson (Rusty) |
Added SSL_PREFIX back and P4MASTERPORTNUM in order to support the sync_replica.sh and weekly_sync_replica.sh scripts. |
||
#5 | 11477 | Russell C. Jackson (Rusty) |
Updated to use /usr/bin/env python Added workshop header. Changed cfg to config. |
||
#4 | 11474 | Russell C. Jackson (Rusty) |
Had to move the cfg directory to the metadata volume and link it under the instance directory to provide the proper separation in a shared volume environment. The instance specific vars cannot be in a shared directory since they need to be different on each node using the shared volume. Since the files moved back to the instance directory, I changed the names back to: instance_vars p4review.cfg to keep things simple. Also moved p4_vars.template to SDP/Server/Unix/p4/common/cfg so that it doesn't get copied to the /p4/common/bin folder. Plus, it makes more sense for it to be in that directory in the SDP structure. |
||
#3 | 11468 | Russell C. Jackson (Rusty) | Added comments regarding configuring Edge and Edge replicas. | ||
#2 | 11466 | Russell C. Jackson (Rusty) |
Initial work to simplify p4_vars and remove cluster stuff. Testing of named instances surfaced some bugs that are in prod sdp, now fixed in dev. Added three triggers from RCJ SDP Moved p4review.cfg into the new /p4/common/cfg to go along with the instance_vars files. mkdirs.sh now generates an instance_p4review.cfg as well. Removed incremental p4verify to clean up a bit. It didn't support replicas and was really never used. All port settings now live in <instance>_vars file. You set what you want the ports to be in mkdirs.sh. There is no more fancy logic to try to guess what the port should be. You set it, and that is what it is. Remaining to do is to updated scripts to not need p4master_run. Saved that work for later since this is tested and works. |
||
#1 | 10638 | C. Thomas Tyler | Populate perforce_software-sdp-dev. | ||
//guest/perforce_software/sdp/main/Server/Unix/setup/mkdirs.sh | |||||
#1 | 10148 | C. Thomas Tyler | Promoted the Perforce Server Deployment Package to The Workshop. |