|
•
|
Perforce triggers are user-written scripts that are called by a Perforce server whenever certain operations (such as changelist submissions, changes to forms, attempts by users to log in or change passwords) are performed. If the script returns a value of 0, the operation continues; if the script returns any other value, the operation fails. Upon failure, the script's standard output (not error output) is sent to the Perforce application as an error message.
|
|
•
|
Daemons run at predetermined times, looking for changes to the Perforce metadata. When a daemon determines that the state of the depot has changed in some specified way, it runs other commands. For example, a daemon might look for newly submitted changelists and send email to users interested in tracking changes to those files. Perforce provides a number of tools that make writing daemons easier.
|
|
|
Client workspace forms whose Name: field begins with p4sandbox- must not be altered in any way (either the name or contents), or P4Sandbox will be unable to work properly with the shared repository. For more information, see the Perforce Command Reference: p4 triggers.
|
Triggers: rnotes change-submit //depot/....exe "/usr/bin/test.pl %change%"
|
Triggers: relnotecheck change-submit //depot/bld/... "/usr/bin/rcheck.pl %user%" verify_jobs change-submit //depot/... "/usr/bin/job.py %change%"
|
As with all Perforce commands that use forms, field names (such as Triggers:) must be flush left (not indented) and must end with a colon, and field values (that is, the set of lines you add, one for each trigger) must be indented with spaces or tabs on the lines beneath the field name.
When testing and debugging triggers, remember that any p4 commands invoked from within the script will run within a different environment (
P4USER,
P4CLIENT, and so on) than that of the calling user.
You must specify the name of the trigger script or executable in ASCII, even when the server is running in Unicode mode and passes arguments to the trigger script in UTF8.
|
|
|
|
|
A run of the same trigger name on contiguous lines is treated as a single trigger, so that multiple paths may be specified. In this case, only the command of the first such trigger line is used.
|
|
|
Trigger types are divided into six subtypes: changelist submission triggers, shelve triggers, fix triggers, form triggers, authentication triggers, and archive triggers.
|
•
|
change-submit: Execute a changelist trigger after changelist creation, but before file transfer. Trigger may not access file contents.
|
|
•
|
change-content: Execute a changelist trigger after changelist creation and file transfer, but before file commit.
|
|
•
|
change-commit: Execute a changelist trigger after changelist creation, file transfer, and changelist commit.
|
|
|
|
|
•
|
shelve-submit: Execute a pre-shelve trigger after changelist has been created and files locked, but prior to file transfer.
|
|
•
|
shelve-commit: Execute a post-shelve trigger after files are shelved.
|
|
•
|
shelve-delete: Execute a shelve trigger prior to discarding shelved files.
|
|
|
|
The special variable %jobs% is available for expansion; it expands to one argument for every job listed on the p4 fix command line (or in the Jobs: field of a p4 change or p4 submit form), and must therefore be the last argument supplied to the trigger script.
|
•
|
fix-add: Execute fix trigger prior to adding a fix.
|
|
•
|
fix-delete: Execute fix trigger prior to deleting a fix.
|
|
|
|
|
•
|
form-save: Execute a form trigger after the form contents are parsed, but before the contents are stored in the Perforce database. The trigger cannot modify the form specified in %formfile% variable.
|
|
•
|
form-out: Execute form trigger upon generation of form to end user. The trigger can modify the form.
|
|
•
|
form-in: Execute form trigger on edited form before contents are parsed and validated by the Perforce server. The trigger can modify the form.
|
|
•
|
form-delete: Execute form trigger after the form contents are parsed, but before the form is deleted from the Perforce database. The trigger cannot modify the form.
|
|
•
|
form-commit: Execute form trigger after the form has been committed for access to automatically-generated fields such as jobname, dates, etc.
|
For job forms, this trigger is run by p4 job as well as p4 fix (after the status is updated). The form-commit trigger has access to the new job name created by p4 job; any form-in and form-save triggers are run before the job name is created.
For job forms, this trigger is also run by p4 change (if a job is added or deleted by editing the Jobs: field of the changelist), and p4 submit (for any jobs present in the Jobs: field of the changelist). In these cases, the special variable %action% is available for expansion on the job form-commit trigger command line. The trigger cannot modify the form.
For change forms, the form-commit trigger only runs when a changelist is saved, submitted or updated with at least one job attached to the changelist; it does not run if zero jobs are attached to the changelist.
|
|
|
|
•
|
archive: Execute the script when a user accesses any file with a filetype containing the +X filetype modifier.
|
For read operations, scripts should deliver the file to the user on standard output. For write operations, scripts receive the file on standard input.
|
|
|
|
•
|
auth-check: Execute an authentication check trigger to verify a user's password against an external password manager during login, or when setting a new password If an auth-check trigger is present, the Perforce security configurable (and any associated password strength requirement) is ignored, as authentication is now controlled by the trigger script.
|
|
•
|
auth-set: Execute an authentication set trigger to send a new password to an external password manager.
|
|
•
|
service-check: Execute a trigger to verify the password of a service user (or operator user), rather than a standard user. Service check triggers work in the same way that auth-check triggers do.
|
|
|
|
For changelist and shelve triggers (change-submit, change-content, change-commit, shelve-submit, shelve-commit, and shelve-delete), a file pattern in depot syntax. When a user submits a changelist that contains any files that match this file pattern, the script linked to this trigger is run. Use exclusionary mappings to prevent triggers from running on specified files.
For fix triggers (fix-add or fix-delete), use fix as the path value.
For form triggers (form-save, form-out, form-in, form-commit, or form-delete), the name of the type of form, (one of branch, change, client, depot, group, job, label, protect, server, spec, stream, triggers, typemap, or user).
For authentication triggers (auth-check, auth-check-sso, auth-set, or service-check), use auth as the path value.
|
|
|
The command for the Perforce server to run when a matching path applies for the trigger type. Specify the command in a way that allows the Perforce server account to locate and run the command. The command (typically a call to a script) must be quoted, and can take as arguments any argument that your command is capable of parsing, including any applicable Perforce trigger %variables%.
For change-submit and change-content triggers, changelist submission continues if the trigger script exits with 0, or fails if the script exits with a nonzero value. For change-commit triggers, changelist submission succeeds regardless of the trigger script's exit code, but subsequent change-commit triggers do not fire if the script exits with a nonzero value.
For form-in, form-out, form-save, and form-delete triggers, the data in the specification becomes part of the Perforce database if the script exits with 0. Otherwise, the database is not updated.
The form-commit trigger type never rejects a change; it exists primarily so that scripts can access a job number (from the %formname% variable) during the process of job creation.
For fix-add and fix-delete triggers, fix addition or deletion continues if the trigger script exits with 0, or fails if the script exits with a nonzero value.
For auth-check and service-check triggers (fired by p4 login from standard users and service/operator users respectively), the user's typed password is supplied to the trigger command as standard input. If the trigger executes successfully, the Perforce ticket is issued. The user name is available as %user% to be passed on the command line.
For auth-check-sso triggers, (fired by p4 login for all users) the output of the client-side script (specified by P4LOGINSSO) is sent to the server-side script in cleartext.
For auth-set triggers, (fired by p4 passwd, but only after also passing an auth-check trigger check) the user's old password and new password are passed to the trigger as standard input. The user name is available as %user% to be passed on the command line.
|
Use the following variables in the command field to pass data to a trigger script:
|
|
|
|
|
|
For example, "pending change 123 added" or " submitted change 124 deleted" are possible %action% values on change forms, and " job000123 created" or " job000123 edited" are possible %action% values for job forms.
|
|
|
|
The number of the changelist being submitted. The abbreviated form %change% is equivalent to %changelist%.
A change-submit trigger is passed the pending changelist number; a change-commit trigger receives the committed changelist number.
A shelve-commit or shelve-delete trigger receives the changelist number of the shelf.
|
change-submit, change-content, change-commit, fix-add, fix-delete, form-commit, shelve-commit, shelve-delete
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The IP address of the user's workstation (even if connected through proxy/broker/replica)
|
|
|
|
|
|
|
|
|
|
|
|
A string of job numbers, expanded to one argument for each job number specified on a p4 fix command or for each job number added to (or removed from) the Jobs: field in a p4 submit, or p4 change form.
|
|
|
|
If a changelist is renumbered on submit, this variable contains the old changelist number.
|
|
|
|
If the command was sent through a proxy, broker or replica, the hostname of the proxy, broker, or replica. (If the command was sent directly, %peerhost% matches %clienthost%)
|
|
|
|
If the command was sent through a proxy, broker or replica, the IP address of the proxy, broker, or replica. (If the command was sent directly, %peerip% matches %clientip%)
|
|
|
|
The IP address and port of the Perforce server, passable only in the context of a client-side script specified by P4LOGINSSO. This is the only variable passable to client-side auth scripts.
|
auth-check-sso
(client side script only)
|
|
|
|
|
|
|
The IP address of the server.
|
|
|
|
The IP address and port of the Perforce server, in the format ip_address:port.
|
|
|
|
The P4ROOT directory of the Perforce server.
|
|
|
|
|
|
|
|
|
|
|
|
Path to temporary form specification file. To modify the form from an in or out trigger, overwrite this file. The file is read-only for triggers of type save and delete.
|
form-commit, form-save, form-in form-out, form-delete
|
|
|
|
form-commit, form-save, form-in, form-out, form-delete
|
|
|
Type of form (for instance, branch, change, and so on).
|
form-commit, form-save, form-in form-out, form-delete
|
|
|
Operation: read, write, or delete
|
|
|
|
Path of archive file based on depot's Map: field. If the Map: field is relative to P4ROOT, the %file% is a server-side path relative to P4ROOT. If the Map: field is an absolute path, the %file% is an absolute server-side path.
|
|
|
|
|
|
To configure Perforce to run trigger scripts when users submit changelists, use changelist submission triggers: these are triggers of type
change-submit,
change-content, and
change-commit.
For changelist submission triggers, the path column of each trigger line is a file pattern in depot syntax. If a changelist being submitted contains any files in this path, the trigger fires. To prevent changes to a file from firing a trigger, use an exclusionary mapping in the path.
Use the change-submit trigger type to create triggers that fire after changelist creation, but before files are transferred to the server. Because change-submit triggers fire before files are transferred to the server, these triggers cannot access file contents. Change-submit triggers are useful for integration with reporting tools or systems that do not require access to file contents.
Example: The following change-submit trigger is an
MS-DOS batch file that rejects a changelist if the submitter has not assigned a job to the changelist. This trigger fires only on changelist submission attempts that affect at least one file in the
//depot/qa branch.
rem REMINDERSrem - If necessary, set Perforce environment vars or use config file rem - Set PATH or use full paths (C:\PROGRA~1\Perforce\p4.exe) rem - Use short pathnames for paths with spaces, or quotes rem - For troubleshooting, log output to file, for instance: rem - C:\PROGRA~1\Perforce\p4 info >> trigger.log
:doitp4 describe -s %1|findstr "Jobs fixed...\n\n\t" > nul if errorlevel 1 echo No jobs found for changelist %1 p4 describe -s %1|findstr "Jobs fixed...\n\n\t" > nul
|
sample1 change-submit //depot/qa/... "jobcheck.bat %changelist%"
|
Every time a changelist is submitted that affects any files under //depot/qa, the
jobcheck.bat file is called. If the string "
Jobs fixed..." (followed by two newlines and a tab character) is detected, the script assumes that a job has been attached to the changelist and permits changelist submission to continue. Otherwise, the submit is rejected.
The second findstr command ensures that the final error level of the trigger script is the same as the error level that determines whether to output the error message.
Use the change-content trigger type to create triggers that fire after changelist creation and file transfer, but prior to committing the submit to the database. Change-content triggers can access file contents by using the
p4 diff2,
p4 files,
p4 fstat, and
p4 print commands with the
@=change revision specifier, where
change is the number of the pending changelist as passed to the trigger script in the
%changelist% variable.
Example: The following change-content trigger is a Bourne shell script that ensures that every file in every changelist contains a copyright notice for the current year.
#!/bin/sh# Set target string, files to search, location of p4 executable... TARGET="Copyright ‘date +%Y‘ Example Company" DEPOT_PATH="//depot/src/..." CHANGE=$1 P4CMD="/usr/local/bin/p4 -p 1666 -c copychecker" XIT=0 echo "" # For each file, strip off #version and other non-filename info # Use sed to swap spaces w/"%" to obtain single arguments for "for" for FILE in ‘$P4CMD files $DEPOT_PATH@=$CHANGE | \ sed -e 's/\(.*\)\#[0-9]* - .*$/\1/' -e 's/ /%/g'‘ do # Undo the replacement to obtain filename... FILE="‘echo $FILE | sed -e 's/%/ /g'‘" # ...and use @= specifier to access file contents: # p4 print -q //depot/src/file.c@=12345 if $P4CMD print -q "$FILE@=$CHANGE" | grep "$TARGET" > /dev/null then echo "" else echo "Submit fails: '$TARGET' not found in $FILE" XIT=1 fi done exit $XIT
|
sample2 change-content //depot/src/... "copydate.sh %change%"
|
Use the change-commit trigger type to create triggers that fire after changelist creation, file transfer, and changelist commission to the database. Use change-commit triggers for processes that assume (or require) the successful submission of a changelist.
Example: A change-commit trigger that sends emails to other users who have files open in the submitted changelist.
#!/bin/sh# mailopens.sh - Notify users when open files are updated changelist=$1 workspace=$2 user=$3 p4 fstat @$changelist,@$changelist | while read line do # Parse out the name/value pair. name=‘echo $line | sed 's/[\. ]\+\([^ ]\+\) .\+/\1/'‘ value=‘echo $line | sed 's/[\. ]\+[^ ]\+ \(.\+\)/\1/'‘ if [ "$name" = "depotFile" ] then # Line is "... depotFile <depotFile>". Parse to get depotFile. depotfile=$value elif [ "‘echo $name | cut -b-9‘" = "otherOpen" -a \ "$name" != "otherOpen" ] then # Line is "... ... otherOpen[0-9]+ <otherUser@otherWorkspace>". # Parse to get otherUser and otherWorkspace. otheruser=‘echo $value | sed 's/\(.\+\)@.\+/\1/'‘ otherworkspace=‘echo $value | sed 's/.\+@\(.\+\)/\1/'‘ # Get email address of the other user from p4 user -o. othermail=‘p4 user -o $otheruser | grep Email: \ | grep -v \# | cut -b8-‘
# Mail other user that a file they have open has been updated mail -s "$depotfile was just submitted" $othermail <<EOM The Perforce file: $depotfile was just submitted in changelist $changelist by Perforce user $user from the $workspace workspace. You have been sent this message because you have this file open in the $otherworkspace workspace. EOM fi done exit 0
|
sample3 change-commit //... "mailopens.sh %change% %client% %user%"
|
To configure Perforce to run trigger scripts when users work with shelved files, use shelve triggers: these are triggers of type
shelve-submit,
shelve-commit, and
shelve-delete.
For shelve triggers, the path column of each trigger line is a file pattern in depot syntax. If a shelve contains any files in this path, the trigger fires. To prevent shelving operations from firing these triggers, use an exclusionary mapping in the path.
The shelve-submit trigger works like the change-submit trigger; it fires after the shelved changelist is created, but before before files are transferred to the server. Shelve-submit triggers are useful for integration with reporting tools or systems that do not require access to file contents.
Use the shelve-commit trigger to create triggers that fire after shelving and file transfer. Use shelve-commit triggers for processes that assume (or require) the successful submission of a shelving operations.
Example: A shelve-commit trigger that notifies a user (in this case,
reviewers) about a shelved changelist.
#!/bin/sh# shelve2.sh - Send email to reviewers when open files are shelved changelist=$1 workspace=$2 user=$3
|
shelving2 shelve-commit //... "shelve2.sh %change% %client% %user%"
|
Use the shelve-delete trigger to create triggers that fire after users discard shelved files.
Example: A shelve-delete trigger that notifies reviewers that shelved files have been abandoned.
#!/bin/sh# shelve3.sh - Send email to reviewers when files deleted from shelf changelist=$1 workspace=$2 user=$3
|
shelving3 shelve-delete //... "shelve3.sh %change% %client% %user%"
|
To configure Perforce to run trigger scripts when users add or delete fixes from changelists, use
fix triggers: these are triggers of type
fix-add and
fix-delete.
Example: The following script, when copied to fixadd.sh and
fixdel.sh, fires when users attempt to add or remove fix records, whether by using the
p4 fix command, or by modifying the
Jobs: field of the forms presented by the
p4 change and
p4 submit commands.
#!/bin/bash# fixadd.sh, fixdel.sh - illustrate fix-add and fix-delete triggers
|
These fix-add and
fix-delete triggers fire whenever users attempt to add (or delete) fix records from changelists. To use the trigger, add the following lines to the trigger table:
sample4 fix-add fix "fixadd.sh %change% %jobs%" sample5 fix-delete fix "fixdel.sh %change% %jobs%"
|
Using both copies of the script, observe that fixadd.sh is triggered by
p4 fix, the
fixdel.sh script is triggered by
p4 fix -d, and either script may be triggered by manually adding (or deleting) job numbers from within the
Jobs: field in a changelist form - either by means of
p4 change or as part of the
p4 submit process.
Because the %jobs% variable is expanded to one argument for every job listed on the
p4 fix command line (or in the
Jobs: field of a
p4 change or
p4 submit form), it must be the last argument supplied to any
fix-add or
fix-delete trigger script.
To configure Perforce to run trigger scripts when users edit forms, use form triggers: these are triggers of type
form-save,
form-in,
form-out,
form-delete, and
form-commit.
Use form triggers to generate customized field values for users, to validate forms, to notify other users of attempted changes to form data, and to otherwise interact with process control and management tools.
|
|
Client workspace forms whose Name: field begins with p4sandbox- must not be altered in any way (either the name or contents), or P4Sandbox will be unable to work properly with the shared repository. For more information, see the Perforce Command Reference: p4 triggers.
|
Use the form-save trigger type to create triggers that fire when users send changed forms to the server. Form-save triggers are called after the form has been parsed by the server but before the changed form is stored in the Perforce metadata.
#!/bin/bashNOAUTH=lockedws USERNAME=$1 WSNAME=$2 IPADDR=$3
|
This form-save trigger fires on
client forms only. To use the trigger, add the following line to the trigger table:
sample6 form-save client "ws_lock.sh %user% %client% %clientip%"
|
Users whose names appear in the output of p4 groups lockedws have changes to their client workspaces parsed by the server, and even if those changes are syntactically correct, the attempted change to the workspace is denied, and an administrator is notified of the attempt.
Use the form-out trigger type to create triggers that fire whenever the Perforce server generates a form for display to the user.
|
|
Never use a Perforce command in a form-out trigger that fires the same form-out trigger, or infinite recursion will result. For example, never run p4 job -o from within a form-out trigger script that fires on job forms.
|
Example: The default Perforce client workspace view maps the entire depot //depot/... to the user's client workspace. To prevent novice users from attempting to sync the entire depot, this Perl script changes a default workspace view of
//depot/... in the
p4 client form to map only the current release codeline of
//depot/releases/main/...
#!/usr/bin/perl# default_ws.pl - Customize the default client workspace view. $p4 = "p4 -p localhost:1666"; $formname = $ARGV[0]; # from %formname% in trigger table $formfile = $ARGV[1]; # from %formfile% in trigger table # Default server-generated workspace view and modified view # (Note: this script assumes that //depot is the only depot defined) $defaultin = "\t//depot/... //$formname/...\n"; $defaultout = "\t//depot/releases/main/... //$formname/...\n"; # Check "p4 clients": if workspace exists, exit w/o changing view. # (This example is inefficient if there are millions of workspaces) open CLIENTS, "$p4 clients |" or die "Couldn't get workspace list"; while ( <CLIENTS> ) { if ( /^Client $formname .*/ ) { exit 0; } } # Build a modified workspace spec based on contents of %formfile% $modifiedform = ""; open FORM, $formfile or die "Trigger couldn't read form tempfile"; while ( <FORM> ) { ## Do the substitution as appropriate. if ( m:$defaultin: ) { $_ = "$defaultout"; } $modifiedform .= $_; } # Write the modified spec back to the %formfile%, open MODFORM, ">$formfile" or die "Couldn't write form tempfile"; print MODFORM $modifiedform; exit 0;
|
This form-out trigger fires on
client workspace forms only. To use the trigger, add the following line to the trigger table:
sample7 form-out client "default_ws.pl %formname% %formfile%"
|
Use the form-in trigger type to create triggers that fire when a user attempts to send a form to the server, but before the form is parsed by the Perforce server.
# Get user list# Use global -G flag to get output as marshaled Python dictionary CMD = "p4 -G -u %s -p 1666 group -o %s" % \ (tuser, job_group) result = {} result = marshal.load(os.popen(CMD, 'r'))
job_users = []for k in result.keys(): if k[:4] == 'User': # user key format: User0, User1, ... u = result[k] job_users.append(u)
# Compare current user to job-editing users.if not user in job_users: print "\n\t>>> You don't have permission to edit jobs." print "\n\t>>> You must be a member of '%s'.\n" % job_group sys.exit(1) else: # user is in job_group -- OK to create/edit jobs sys.exit(0)
|
This form-in trigger fires on
job forms only. To use the trigger, add the following line to the trigger table:
sample8 form-in job "python jobgroup.py %user%"
|
If the user is in the jobbers group, the
form-in trigger succeeds, and the changed job is passed to the Perforce server for parsing. Otherwise, an error message is displayed, and changes to the job are rejected.
Use the form-delete trigger type to create triggers that fire when users attempt to delete a form, after the form is parsed by the Perforce server, but before the form is deleted from the Perforce database.
This form-delete trigger fires on
job forms only. To use the trigger, add the following line to the trigger table:
sample9 form-delete job "nodeljob.sh"
|
Unlike the other form triggers, the form-commit trigger fires after a form is committed to the database. Use these triggers for processes that assume (or require) the successful submission of a form. In the case of job forms, the job's name is not set until after the job has been committed to the database; the
form-commit trigger is the only way to obtain the name of a new job as part of the process of job creation.
Example: The following script, when copied to newjob.sh, shows how to get a job name during the process of job creation, and also reports the status of changelists associated with job fixes.
#!/bin/sh# newjob.sh - illustrate form-commit trigger
|
sample10 form-commit job "newjob.sh %user% %formname% %action%"
|
Use the %action% variable to distinguish whether or not a change to a job was prompted by a user directly working with a job by means of
p4 job, or indirectly by means of fixing the job within the context of
p4 fix or the
Jobs: field of a changelist.
Because the %action% variable is not always set, it must be the last argument supplied to any
form-commit trigger script.
To configure Perforce to work with an external authentication manager (such as LDAP or Active Directory), use
authentication triggers (
auth-check,
auth-check-sso,
service-check, and
auth-set). These triggers fire on the
p4 login and
p4 passwd commands, respectively.
Authentication triggers differ from changelist and form triggers in that passwords typed by the user as part of the authentication process are supplied to authentication scripts as standard input; never on the command line. (The only arguments passed on the command line are those common to all trigger types, such as
%user%,
%clientip%, and so on.)
The examples in this book are for illustrative purposes only. For a more detailed discussion, including links to sample code for an LDAP environment, see "Setting Up External Authentication Triggers" in the Perforce knowledge base:
You must restart the Perforce server after adding an auth-check (or
service-check) trigger in order for it to take effect. You can, however, change an existing
auth-check trigger table entry (or trigger script) without restarting the server.
After an auth-check trigger is in place and the server restarted, the Perforce
security configurable is ignored; because authentication is now under the control of the trigger script, the server's default mechanism for password strength requirements is redundant.
Triggers of type auth-check fire when standard users run the
p4 login command. Similarly,
service-check triggers fire when service users or operator users run the
p4 login command. If the script returns
0, login is successful, and a ticket file is created for the user.
|
|
If you are using auth-check triggers, the Perforce superuser must also be able to authenticate against the remote authentication database. (If you, as the Perforce superuser, cannot use the trigger, you may find yourself locked out of your own server, and will have to (temporarily) overwrite your auth-check trigger with a script that always passes in order to resolve the situation.)
|
#!/bin/bash# checkpass.sh - a trivial authentication-checking script
# Failureecho checkpass.sh: password $USERPASS for $USERNAME is incorrect exit 1
|
This auth-check trigger fires whenever users run
p4 login. To use the trigger, add the following line to the trigger table:
sample11 auth-check auth "checkpass.sh %user%"
|
Triggers of type auth-check-sso fire when standard users run the
p4 login command. Two scripts are run: a client-side script is run on the user's workstation, and its output is passed (in plaintext) to the Perforce Server, where the server-side script runs.
You specify the client side script with P4LOGINSSO. This variable contains the full path to the script, and, optionally, the string
%serverAddress%. By default, the output of the
P4LOGINSSO script is directed to the Perforce Server to which the user was connected when logging in, but you can override this with the
%serverAddress% variable.
An auth-check-sso trigger fires whenever users run
p4 login. The system administrator adds following line to the trigger table:
sample13 auth-check-sso auth "serverside.sh %user%"
|
##!/bin/bash# clientside.sh - a client-side authentication script # # if we use %serverAddress% in the command-line like this: # p4 -E P4LOGINSSO=clientside.sh %serverAddress% # then this script receives the serverAddress as $1, and the user # can use it for multiple connections to different Perforce servers. # # In this example, we simulate a client-side authentication process # based on whether the user is connecting to the same Perforce Server # as is already configured in his or her environment. # (We also output debugging information to a local file.)
if test "$input_saddr" == "$env_saddr" then # User is connected to the server specified by P4PORT - pass echo "sso pass"; echo pass "$input_saddr" >> debug.txt; exit 0 else # User is attempting to connect to another server - fail echo "no pass"; echo fail "$input_saddr" >> debug.txt; exit 1 fi
|
If the user is connected to the same Perforce Server as specified by P4PORT (that is, if the server address passed from the Server to this script matches the server that appears in the output of a plain "
p4 info" command), client-side authentication succeeds. If the user is connected to another Perforce Server (for example, by running
p4 -p host:port login against a different Perforce Server), client-side authentication fails.
#!/bin/bash# # serverside.sh - a server-side authentication script #
|
In a more realistic example, the end user's P4LOGINSSO script points to a
clientside.sh script that contacts an authentication service to obtain a token of some sort. The client-side script then passes this token to Perforce Server's trigger script, and
serverside.sh uses the single-signon service to validate the token.
In this example, clientside.sh merely checks whether the user is using the same connection as specified by
P4PORT, and the output of
clientside.sh is trivially checked for the string "
sso pass"; if the string is present, the user is permitted to log on.
Triggers of type auth-set fire when users (standard users or service users) run the
p4 passwd command and successfully validate their old password with an
auth-check (or
service-check) trigger. The process is as follows:
|
4.
|
The script associated with the auth-check trigger runs. If the auth-check trigger fails, the process ends immediately: the user is not prompted for a new password, and the auth-set trigger never fires.
|
|
5.
|
If the auth-check trigger succeeds, the server prompts the user for a new password.
|
|
6.
|
The Perforce server fires an auth-set trigger and supplies the trigger script with both the old password and the new password on the standard input, separated by a newline.
|
Because the Perforce server must validate the user's current password, you must have a properly functioning
auth-check trigger before attempting to write an
auth-set trigger.
#!/bin/bash# setpass.sh - a trivial authentication-setting script
|
This auth-set trigger fires after users run
p4 passwd and successfully pass the external authentication required by the
auth-check trigger. To use the trigger, add the following two lines to the trigger table:
sample11 auth-check auth "checkpass.sh %user%" sample12 auth-set auth "setpass.sh %user%"
|
The archive trigger type is used in conjunction with the
+X filetype modifier in order to replace the mechanism by which the Perforce Server archives files within the repository. See
Triggers and Windows for platform-specific considerations.
This archive trigger fires when users access files that have the
+X (archive) modifier set.
#!/bin/sh# archive.sh - illustrate archive trigger
if [ "$OP" = write ]then # Create new file from user's submission via stdin while read LINE; do echo ${LINE} >> ${FILE}${REV} done ls -t ${FILE}* | { read first; read second; cmp -s $first $second if [ $? -eq 0 ] then # Files identical, remove file, replace with symlink. rm ${FILE}${REV} ln -s $second $first fi } fi
|
arch archive path "archive.sh %op% %file% %rev%"
|
Changelist and form triggers are run in the order in which they appear in the triggers table. If you have multiple triggers of the same type that fire on the same path, each is run in the order in which it appears in the triggers table. If one of these triggers fails, no further triggers are executed.
All *.c files must pass through the scripts
check1.sh,
check2.sh, and
check3.sh:
Triggers: check1 change-submit //depot/src/*.c "/usr/bin/check1.sh %change%" check2 change-submit //depot/src/*.c "/usr/bin/check2.sh %change%" check3 change-submit //depot/src/*.c "/usr/bin/check3.sh %change%"
|
If any trigger fails (for instance, check1.sh), the submit fails immediately, and none of the subsequent triggers (that is,
check2.sh and
check3.sh) are called. Each time a trigger succeeds, the next matching trigger is run.
Triggers: bugcheck change-submit //depot/*.c "/usr/bin/check4.sh %change%" bugcheck change-submit //depot/*.h "/usr/bin/check4.sh %change%" bugcheck change-submit //depot/*.cpp "/usr/bin/check4.sh %change%"
|
In this case, the bugcheck trigger runs on the
*.c files, the
*.h files, and the
*.cpp files.
|
1.
|
change-submit (fired on changelist submission, before file transmission)
|
|
2.
|
change-content triggers (after changelist submission and file transmission)
|
|
3.
|
change-commit triggers (on any automatic changelist renumbering by the server)
|
|
2.
|
form-in (changed form is transmitted to the server)
|
|
3.
|
form-save (validated form is ready for storage in the Perforce database)
|
|
4.
|
form-delete (validated form is already stored in the Perforce database)
|
To call the same trigger script from more than one Perforce server, use the %serverhost%,
%serverip%, and
%serverport% variables to make your trigger script more portable.
#!/bin/sh# Usage: jobcheck.sh changelist CHANGE=$1 P4CMD="/usr/local/bin/p4 -p 192.168.0.12:1666" $P4CMD describe -s $1 | grep "Jobs fixed...\n\n\t" > /dev/null
|
#!/bin/sh# Usage: jobcheck.sh changelist server:port CHANGE=$1 P4PORT=$2 P4CMD="/usr/local/bin/p4 -p $P4PORT" $P4CMD describe -s $1 | grep "Jobs fixed...\n\n\t" > /dev/null
|
By default, the Perforce service runs under the Windows local System account. The
System account may have different environmental configurations (including not just Perforce-related variables, but
PATH settings and file permissions) than the one in which you are using to test or write your trigger.
For example, C:\Program Files\Perforce\p4.exe is most likely located in
C:\PROGRA~1\Perforce\p4.exe.
If the trigger.log isn't updated at all, the trigger was not fired. If the first
p4 info fails, and the second
p4 info runs, you'll know whether there were differences in environmental settings.
Daemons are processes that are called periodically or run continuously in the background. Daemons that use Perforce usually work by examining the server metadata as often as needed and taking action as often as necessary.
Daemons can be used for almost any task that needs to occur when Perforce metadata has changed. Unlike triggers, which are used primarily for submission validation, daemons can also be used to write information (that is, submit files) to a depot.
The Perforce change review daemon (p4review.py) is available from the Perforce Public Depot:
The review daemon runs under Python, available at http://www.python.org/. Before you run the review daemon, be sure to read and follow the configuration instructions included in the daemon itself.
Users subscribe to files by calling p4 user, entering their email addresses in the
Email: field, and entering any number of file patterns corresponding to files in which they're interested in to the
Reviews: field.
User: sarahm Email: sarahm@elmco.com Update: 1997/04/29 11:52:08 Access: 1997/04/29 11:52:08 FullName: Sarah MacLonnogan Reviews: //depot/doc/... //depot.../README
|
The change review daemon monitors the files that were included in each newly submitted changelist and emails all users who have subscribed to any files included in a changelist, letting those users know that the files in question have changed.
By including the special path //depot/jobs in the
Reviews: field, users can also receive mail from the Perforce change review daemon whenever job data is updated.
|
1.
|
p4 counter is used to read and change a variable, called a counter, in the Perforce metadata. The counter used by this daemon, review, stores the number of the latest changelist that's been reviewed.
|
|
3.
|
p4 reviews generates a list of reviewers for each of these changelists.
|
The command used in the fourth step (p4 describe) is a straightforward reporting command. The other commands (
p4 review,
p4 reviews, and
p4 counter) are used almost exclusively by review daemons.
You can use p4review.py (see
Perforce's change review daemon) as a starting point to create your own daemons, changing it as needed. As an example, another daemon might upload Perforce job information into an external bug tracking system after changelist submission. It would use the
p4 review command with a new review counter to list new changelists, and use
p4 fixes to get the list of jobs fixed by the newly submitted changelists. This information might then be fed to the external system, notifying it that certain jobs have been completed.
|
|
|
|
|
For all changelists between change# and the latest submitted changelist, this command lists the changelists' numbers, creators, and creators' email addresses.
Requires at least review access to run.
|
p4 reviews -c change# filespec
|
Lists all users who have subscribed to review the named files or any files in the specified changelist.
|
|
|
To create a new counter or set the value of an existing counter, you must have review access or greater. To display a counter's value, you must have list access or greater.
If a value argument is not included, p4 counter returns the value of name, or 0 if the counter does not exist.
If a value argument is included, p4 counter sets the value of the name to value. If the counter name does not exist, it is created.
WARNING: The review counters journal, job, and change are used internally by Perforce; use of any of these three names as review numbers could corrupt the Perforce database.
Counters are represented internally as strings. (Prior to release 2008.1, they were stored as signed ints)
|
|
|
|
|
|
Outputs a single line showing the changelist number of the last submitted changelist, as opposed to the highest changelist number known to the Perforce server.
|
If you're writing a change review daemon or other daemon that deals with submitted changelists, you might also want to keep track of the changelist number of the last
submitted changelist, which is the second field in the output of a
p4 changes -m 1 -s submitted command.
This is not the same as the output of
p4 counter change. The last changelist number known to the Perforce server (the output of
p4 counter change) includes pending changelists created by users, but not yet submitted to the depot.
Depending on your platform, the output of individual p4 commands can be fully-buffered (output flushed only after a given number of bytes generated), line-buffered (as on a tty, one line sent per linefeed), or unbuffered.
In general, stdout to a file or pipe is fully buffered, and stdout to a tty is line-buffered. If your trigger or daemon requires line-buffering (or no buffering), you can disable buffering by supplying the
-v0 debug flag to the
p4 command in question.
If you're using pipes to transfer standard output from a Perforce command (with or without the
-v0 flag), you might also experience buffering issues introduced by the kernel, because the
-v0 flag can only unbuffer the output of the command itself.
Copyright 1997-2013 Perforce Software.