#!/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 #------------------------------------------------------------------------------ # This broker_wrapper script is called by the Helix p4broker server when users # use the 'p4' command line client targeting the HMS broker and runs 'p4 hms' # commands. # # It's purposes are: # * Enable HMS commands to be called via the Perforce Broker, e.g. as # 'p4 hms status all'. # # * Provide a bridge between broker filter scripts command-line parsing of # stdin, translating that into traditional command line calls. # # * Captures stdin, stderr and the exit code of called scripts so they can # be returned to the user. This script must always exit with a 1, so the # exit code of the user is repoted to the user as EXIT_CODE: <N> as the # last line of output. # # This simplifies development broker-enabled scripts, enabling them to # be written without being concerned too much about the vagaries of # broker filter scripts. There are, however, some restrictions on # the 'hms' script called by this script: # # 1. The output must be devoid of any '"' (double quote) characters. # 2. The script cannot be interactive in any way. # 3. The script cannot give real-time progress info to the user. # All output is captured, and only when the script exits, the # entirety of the output is sent back to the user at once. # 4. The exit code will be translated to text for the user to see, # but cannot be interpreted in anyway. # # This scripts job is to build the command line for the 'hms' script, # call it, and return the output to the user. # # The HMS_CALLED_BY_WRAPPER environment variable is set to 1 in this # script, so that it can be checked by the HMS script. This allows the # know when it is being called via the broker (and thus subject to the # above restrictions) or not. For example, the hms script may want to # offer an interactive mode, which cannot be supported when called by # the broker. # # The broker config file should contain the following snippet (uncommented): #------------------------------------------------------------------------------ # # Implement Helix Management System (hms) commands. # # command: ^hms$ # { # action = filter; # checkauth = true; # execute = /p4/common/hms/scripts/broker_wrapper; # } #------------------------------------------------------------------------------ function log () { declare message="$*" [[ -n "$Log" ]] || return 1 echo -e "$(date +'%Y/%m/%d %H:%M:%S %Z: ') $message" >> $Log 2>&1 } declare InputFile=$(mktemp) declare OutputFile=$(mktemp) declare Log=${LOGS:-/tmp}/${0##*/}.log declare User declare UserHost declare HMSCmdLine declare -i LoggedInSuperUser=0 declare -i ExitCode declare -i ArgCount declare -i i=0 export HMS_CALLED_BY_WRAPPER=1 # Sample broker input: # # message: brokerListenPort: 4737 # brokerTargetPort: 4738 # command: hms # clientProg: p4 # clientVersion: 2015.2/LINUX26X86_64/1387115 # clientProtocol: 79 # apiProtocol: 99999 # workspace: SDP.waukperforce03 # user: ttyler # maxPerm: super # clientIp: 127.0.0.1 # clientHost: # cwd: /p4/common/bin # clientPort: 4737 # argCount: 2 # Arg0: status # Arg1: 1:master # Load HMS environment. source /p4/common/bin/p4_vars hms export HMS_HOME=${HMS_HOME:-/p4/common/hms} declare Version=1.0.10 # Read from STDIN the input stream provided by the broker. log "Started parsing broker input." while read line; do echo $line >> $InputFile [[ $line == "user: "* ]] && User=${line#user: } [[ $line == "maxPerm: super" ]] && LoggedInSuperUser=1 if [[ $line == "argCount: "* ]]; then ArgCount=${line#argCount: } if [[ $ArgCount -eq 0 ]]; then HMSCmdLine="$P4CBIN/hms -h" log "HMSCmdLine=$P4CBIN/hms -h" else i=0 HMSCmdLine="$P4CBIN/hms" while [[ $i -lt $ArgCount ]]; do read line log "ARG $i is ${line#Arg*: }" HMSCmdLine="$HMSCmdLine ${line#Arg*: }" i=$((i+1)) done log "HMSCmdLine=$P4CBIN/hms -h" fi fi done HMSCmdLine=$(echo $HMSCmdLine) echo "action: REJECT" if [[ LoggedInSuperUser -eq 1 ]]; then $HMSCmdLine > $OutputFile 2>&1 ExitCode=$? echo -e "message: \"$(cat $OutputFile)\nEXIT_CODE: $ExitCode\n\"" else echo -e "message: \"\nError: You must be logged in as a super user to run 'hms' commands.\n\"" ExitCode=1 fi rm -f $InputFile $OutputFile # Always exit 1, so the broker won't try to pass commands on to p4d. exit 1;
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 24292 | gmc | "Forking branch Dev of perforce-software-sdp to gmc-sdp." | ||
//guest/perforce_software/sdp/dev/Server/Unix/p4/common/hms/scripts/broker_wrapper | |||||
#3 | 20831 | C. Thomas Tyler | Enhanced log handling in HMS broker wrapper. | ||
#2 | 20801 | C. Thomas Tyler |
Implemented security: 'p4 hms' commands require a super user to be logged in. Added 'p4 sbi' (show broker input) broker debugging utility. |
||
#1 | 20745 | C. Thomas Tyler |
Approving as is since it isn't changing core SDP functionality, and reviewing it all line by line will take some time. We can do that as we move forward with it. First addition of HMS v1.0 files. This change is a soft launch HMS for initial deployment and testing. Updates to HMS-related files are expected and will bypass pre-commit code review until stabilized. |