Tips for Using Triggers in a Mixed Environment

Tips for Using Triggers in a Mixed Environment

Version 1.1
by Doug Fierro
Technical Lead, Rational Software
supplement to presentation #CCM28


Summary of Topics

Appendix A - simple trigger examples

Appendix B - trigger to catch element creation casename conflicts on Windows


Introduction

Triggers are a simple yet powerful extension to the ClearCase product that enable sites to customize a policy and process to be implemented. This can range from a simple action such as email notification for certain events or limiting checkouts of certain files, to more advanced implementations such as integrating with an external software application for sharing data. Triggers are a documented way to implement customized, flexible policy and process control without API programming knowledge.

This paper assumes intermediate knowledge of the ClearCase product, but a beginner reader should be able to follow along as well. Advanced trigger topics or scripting methods are not discussed here.

As with most parts of the ClearCase product, it is best to start off small when first implementing triggers. It is important that sites also understand the implication and scope of how triggers can be deployed in their development environment, as well as things to watch out for. Triggers are an extra overhead, and thus should be used wisely. A poorly written trigger script can result in performance degradation, or worse, potential loss of data- this is especially true for any type of trigger which operates on the body contents of a versioned element being checked in. An advanced trigger should take into account things such as checking for return code values, and knowing the limitations of certain utilities being used- some UNIX flavors of sed() for example are known to truncate lines to 4000 characters.

Heterogeneous or mixed platform environments involving UNIX and Windows can be challenging to implement triggers successfully- this paper hopes to provide some tips in this area as well. ClearCase supports incremental adoption of process via triggers- "evolutionary, not revolutionary." A flexible approach to process is usually the most successful, and ClearCase provides that flexibility to customers.

What is a trigger?

Quite simply, a trigger in ClearCase is an object within the ClearCase Versioned Object Base (VOB) repository that executes a script or program upon a pre-determined event. The execution of the trigger can return a zero or non-zero value, which is interpreted by ClearCase as true or false. If the return value of a trigger is false, this can limit the action being performed within the ClearCase VOB from proceeding.

Triggers are represented as object types, or metadata, within the VOB's database. Triggers have certain properties, such as ownership, firing conditions, and actions to take, which include a path of a program or script to execute if the firing conditions are met. Actions include any operation within a ClearCase VOB repository that creates, modifies, or deletes data.

Triggers have very flexible scope, which can range from the entire VOB repository for a particular event, down to a subset of elements, or even a single file element to monitor. Triggers also allow a user-exclusion list to specify certain privileged users who are allowed to bypass a particular trigger, such as the owner or administrator of a repository.

Triggers can fire before or after an event occurs. Usually pre-event triggers are used as process enforcement to allow or deny a particular command from proceeding, depending on the results of the trigger being executed. Post-event triggers will fire after the particular event being monitored has completed successfully. These post-event triggers are useful for email notification, report generation, or processing data after a command completes, such as initiating a scheduled build if certain project files are updated.

You do not have to be a programmer to implement triggers for simple policy and process control. In fact, as long as you have a way to return a zero or non-zero value from a program or script, and a way to print text output, that is the basis for many triggers that can be used in a variety of ways! ClearCase also provides you an easy-to-use, documented utility that works on both UNIX and Windows for assisting with such tasks.

Trigger Limitations

Since triggers are objects that only live within the context of a VOB, you cannot trigger events that are not related to an existing VOB repository, such as creating a new view or new VOB, or any registry commands. You also cannot trigger read-only events, such as listing data or traversing directory paths within a VOB. Triggers always execute at the client side, not on the server. Triggers are not supported as global metadata types within VOBs, so that means you cannot define a global trigger type within an AdminVob for use by multiple VOBs. Triggers can only be created by the VOB owner or privileged user. If multiple triggers are attached to a certain event, the firing order it indeterminate. From a Windows GUI, the current working directory may not be set. MultiSite does not propagate trigger types in a replicated VOB, and imported MultiSite synch packets are not affected by local triggers. As of release 3.2.1, the MODIFY_TYPE cptype is not implemented, nor is support to trigger directly on the merge command.

Triggers are not bullet-proof for enforcing security- a clever or knowledgable user can circumvent a trigger depending on the environment. A user however would have to go out of their way to bypass a trigger, and have a solid understanding of ClearCase at the administrative level. Even so, ClearCase still keeps a change history of any data under control that is modified, added, or deleted should such an attempt occur. If you have users in your development environment that are actively trying to subvert the development process, then that may be a sign that the established process needs to be re-examined, or that a non-trusted user needs to be dealt with.

Do I need a trigger for this?

A ClearCase administrator should always ask if a trigger is really needed for the task at hand. Creating several global triggers within a repository can adversely affect performance if a site becomes too "trigger happy", especially on commonly-executed commands like checkout, checkin, and mkbranch. Triggers execute within the context of a shell environment, which creates another process that runs in addition to the initial ClearCase command.

An administrator can take several steps to adequately assess a request for a trigger to be implemented. One alternative is the lock() command, which is more efficient than using a trigger, because it does not fire off another process to run. Entire elements, as well as metadata instances such as branch and label names, can be locked with a user exclusion list specified (-nusers). A trigger also can be scoped down so that the entire user community is not affected. Some examples might be attaching a trigger specifically for design or documentation files on that subset of elements, rather than creating a global element trigger type that fires on each file modification in the VOB, or only having the trigger fire on certain element or metadata types. You can define new element types in the ClearCase magic file.

Another option is to see if a trigger action that does post-event processing or subsequent actions within a ClearCase repository can instead be run during off-hours, such as in a crontab() or at() job.

A clever way to suspend a trigger from executing is to obsolete it after it is created, then unlock it when necessary:

 cleartool lock -obsolete trtype:triggername

This solution could be used in conjunction with say a simple trigger that disables checkouts on the release branch for regular users when you want to limit access to that branch.

For simply applying a build or release label, a time-based view that freezes the time to say 'now' should be encouraged over the use of a trigger if there is concern that that there may be concurrent changes on the build/release branch during the labelling process.

Finally, triggers simply enforce policy and process - they should not define it. If a policy or process appears to be broken, try to fix the cause of the problem, not the symptom!

Listing triggers

You can use the cleartool lstype() command to list all available triggers in a particular VOB:

  cleartool lstype -kind trtype [ -invob vob:<vobtag> ]

... or just details of a particular trigger:

  cleartool lstype -long trtype:<trigger name>@<vobtag>

You can also display the same information from a GUI as well. To display triggers on UNIX from the xclearcase() GUI, select the Admin->Trigger pull-down menu. On Windows, you can choose the "type explorer" button on the Administration tab of the ClearCase Homebase, or you can right-mouse-click on the VOB tag folder in Explorer and choose ClearCase->Explore Types .

On UNIX:

On Windows:

To list any triggers specifically attached to a single element, you can use the ClearCase describe command- be sure to specify the element and not a version of the element!

   cleartool describe elementname@@

Which triggers are being applied in a VOB?

Unfortunately, there is no trigger listing command that tells you what individual elements or metadata may be affected by a global trigger, or if a trigger has been specifically applied to one or more elements. Use the cleartool find() command to list triggers applied specifically to an individual element:

  cleartool find -all -element "trtype(<trigname>)" -print

   (quotes not needed in DOS shell)

NOTE: there is a user-contributed trigger script, T0029, which can be used for this purpose as well.

return to summary of topics


UNIX/Windows interoperation challenges for triggers

There are several challenges involved in implementing triggers to run in a mixed UNIX/Windows environment. Most of these are due to the fact that triggers always execute on the local client, not on the server, and because of the basic differences between UNIX and Windows operating systems. Some of these challenges include:

A more detailed discussion on these interoperation topics follows.

Interop: common path

On UNIX systems, the VOB tag path is a way to universally access data under ClearCase within the context of a view. On Windows, the equivalent VOB tag path could be several different possible locations, including the default letter drive (usually, but not always, M:), a mapped local drive, or for a snapshot view, any valid writable path is possible:

M:\myview\project
Z:\project
C:\users\terry\myview_snapshot\project

This can pose a problem for trigger scripts that may be installed within a VOB, or depend on a path inside a VOB.

For dynamic views on Windows NT, the path:

  \\view\<viewname>\<vobtag>

is a guaranteed path to be consistent on any NT client. It is similar to the UNIX view-extended path method of /view/<viewname>/<vobtag> . Snapshot views, however, are not accessible using this method.

NOTE: it is not recommended to have machine named "view" on the network if a site is using ClearCase in a Windows environment.

To make things more complicated, ClearCase operations initiated from the Explorer interface on Windows do not set the current working directory correctly, so such access from a trigger script that assumes the local directory is set may fail in Explorer unless you have constructed a fully qualified path to the element or directory.

Interop: trigger script install paths

For specifying a path location that a trigger will execute, it is desirable that the following characteristics are adhered to:

For simplicity, it is recommended that such paths be referenced outside of a ClearCase VOB. This is recommended not only to help alleviate the common-VOB-path problem, but it is also more secure and less dependent on the user's environment. Trigger scripts/programs themselves should always be checked into a VOB and versioned over time, just as any other important piece of data that affects your project. This includes versioning third-party utilities in use, such as Perl.

NOTE: It is possible to achieve this level of security and global accessibility of versioned trigger scripts directly from a strictly controlled view, either by use of a UNIX-hosted exported view or a UNIX/UNC view-extended path into the VOB. Be sure this special view repository is on the same machine as the VOB server to reduce points of failure, and you have the restricted view rules set correctly to match the versions of trigger scripts to be available. Use of exported views is beyond the scope of this paper.

A trigger path that executes inside of a VOB from a user's view may be subverted, or the wrong version may be selected by the view, or no version of the trigger script/program may be selected at all, which will always return a non-zero value. Someone using a "-time" rule in their view for example may not pick up the latest trigger script installed in a VOB. Another example is using a metadata rule to select files in a view such as a label or attribute value, and the trigger element does not have such data attached to it. Yet another potential trap on Windows clients is that public VOBs are not automatically mounted when the machine starts up.

With the introduction of snapshot views in ClearCase 3.2, it is possible to not have the trigger file itself loaded upon execution, or the snapshot view path may not match the trigger execution path, since a user can place a rooted snapshot view anywhere they have write access.

A non-privileged user who knows ClearCase well can also set their view to ignore a particular file in the VOB, then replace or eclipse that element with a local copy of their own file:

 (UNIX example bypassing trigger checking for empty comments:)


cd /vobs/restricted/src
ct lstype -long trtype:CHECK_COMMENT

.....
action: -exec /vobs/restricted/scripts/check_comment.sh

edcs
(add after checked out rule: "element * check_comment.sh -none" )
vi /tmp/check_comment.sh
	#!/bin/sh
	#bypassing trigger script to use this one instead
	#hard-coded zero return value guarantees success!
	exit 0
chmod a+x /tmp/check_comment.sh
cp /tmp/check_comment.sh ../scripts/check_comment.sh
cat ../scripts/check_comment.sh
	(what do you see now in your view?)
cleartool ls ../scripts

	../scripts/check_comment.sh@@ [eclipsed]


A common directory location that is highly available on the network is the best place to install scripts or programs that are called by triggers. Using the existing ClearCase share that contains the VOB storage is a good place to install trigger scripts, since those locations are already set up on the network, and having the trigger scripts located on the VOB server reduces points of failure. Always use a full path to the target file in a trigger declaration, and use UNC pathnames on Windows over hard-coded letter drives if possible.

Interop: use of -execunix and -execwin

Prior to release 3.2 of ClearCase, a trigger only supported one path to execute. This was very difficult to implement in a mixed UNIX-Windows platform environment, since both operating systems do not use the same path field separators ('/' vs. '\'), and accessing a network machine share is very different as well (Windows UNC '\\machine\share'  path vs. UNIX automount '/net/machine/share'  path).

With the introduction of two new "-exec" options, "-execunix" and "-execwin", these headaches now go away. It is now possible for a ClearCase trigger to access the same shared script or program using different paths that are recognized by the local client platform OS, or you have the option of writing different scripts that are targeted for UNIX or Windows only. For security reasons, triggers that have only -execunix specified always fail if executed from a Windows client; likewise, triggers that have only -execwin actions fail on UNIX.

NOTE: If using these new 3.2 features of mktrtype, client machines running older releases of ClearCase will fail on such triggers, since they will not be able to recognize the new syntax/functionality.

Interop: standard input/output/error

To get around the differences of how UNIX and Windows redirect and process stdin/stdout/stderr messages, use the clearprompt() utility that comes with ClearCase, on both UNIX and Windows. Clearprompt() is a very versatile utility for communicating with users via a trigger script or program. It can prompt for user input of choice list selections, text, or file paths. It can display messages, as well as return zero or non-zero values corresponding to user responses to questions. It can work in both a command line or GUI interface, with the option to always display a pop-up GUI if desired.

Interop: clearprompt details

The four general areas that clearprompt covers are:


clearprompt list - displays list of choices to choose from
clearprompt text - displays text box for user to type in
clearprompt file - displays file browser to choose path argument
clearprompt [ proceed | yes_no ] - displays message to user with options

Both the proceed and yes_no options of clearprompt() are very similar, as they both can pass the return code back to the calling trigger depending what the user chooses. The button choices when using proceed are "proceed" and "abort"; the button choices when using yes_no are "yes", "no", and "abort". Only the "yes" and "proceed" choices return values of zero- the rest return non-zero values (false).

Clearprompt() can be called directly from any shell as a standalone system command. The syntax is identical on both UNIX and Windows platforms. Some examples follow below.

clearprompt list example

The following clearprompt invocation for a list box on UNIX:

  clearprompt list -outfile $TMPFILE -items choice1,choice2,choice3 \
-prompt "pick from the list:" -prefer_gui

... produces the following display:

clearprompt text example

The following clearprompt invocation for a text box on Windows:

  clearprompt text -outfile %TMPFILE% -prompt "enter text here:" -prefer_gui

... produces the following display:

clearprompt file example

The following clearprompt invocation for displaying a file browser in the sibling "headers" directory:

  clearprompt file -outfile $TMPFILE -directory ../headers \
-prompt "choose dependent header file:" -prefer_gui

... produces the following display:

clearprompt proceed example

The following clearprompt invocation for displaying a proceed message:

clearprompt proceed -type warning -mask proceed \
-prompt "this command is restricted" -prefer_gui

... produces the following display:

clearprompt yes_no example

The following clearprompt invocation for displaying a yes or no choice to the user:

clearprompt yes_no -prompt "did you test this change with the BETA2.3 libs?" -prefer_gui

... produces the following display:

We will see some examples of clearprompt() being used with triggers later on.

Interop: common scripting language

For existing ClearCase sites that may be migrating to Windows from UNIX, a big challenge is to try and preserve the work that was done to implement trigger scripts using a native shell language like Bourne or C-shell. The native shell on Windows, which uses DOS *.bat scripts, does not recognize UNIX shell commands or syntax.

One option is to adopt a scripting language that is recognized on both UNIX and NT. Currently, that software package is Perl. ClearCase provides a bundled version of Perl under the install area (Perl on UNIX; ccperl.exe in Windows) that should be sufficient for most generic simple commands. Using some of the more advanced features of Perl may require a download and install of the latest version (which is free). Perl is very similar to traditional UNIX scripting languages, and supports more advanced features than native shell languages. There are also many user-contributed ClearCase trigger scripts that are already written in Perl to reuse.

Another option is to obtain a third party tool shell environment that can support UNIX shell commands on Windows. Such toolkits and packages include MKS, cygWin32 from Cygnus, the Hamilton Cshell for Windows, the GNU project at MIT, and the POSIX package from Microsoft that comes with the NT Resource Kit. Much free software is available to download off the internet at http://www.download.com (formerly freeware.com).

A drawback to using a common scripting language for both UNIX and windows environments is that non-trivial trigger scripts may become more complex due to logic introduced to test for local environment/platform paths and data. Therefore, another option is to just maintain two sets of scripts for each trigger using the "-execunix" and "-execwin" features described earlier. This requires more administrative overhead, but may be desirable if it results in more simple and efficient scripts, or if the task of scripting is shared between people who each each have deep knowledge of one platform or the other, such as a MultiSite environment where two remote sites have different primary VOB platforms. It is advised, however, to use Perl when such mixed platform trigger scripts become more complex in functionality, or start growing in length over time. Since Perl is free, highly available, and generally superior to native shell languages, new sites are encouraged to begin their trigger scripts in Perl.

Interop: sendmail support on Windows

A common post-trigger event action is to send email notification. UNIX supports command-line access to email better than Windows- in fact, most standard Windows installations don't support email at all.

To get around this shortcoming, several email packages for Win32 platforms are available that support execution from within a script or the command line. Most of these are based on the SMTP protocol, which is supported on both UNIX and Windows.

return to summary of topics


Triggers In Action

Events you can trigger on: types

You can trigger on the following types in ClearCase:

The MODIFY_TYPE operations that you can trigger on include mktype,rmtype,rntype,lock,unlock,chevent.

Events you can trigger on: elements

For element triggers, you can execute on a variety of opkind operations that affect elements:

  • checkout
  • reserve
  • uncheckout
  • unreserve
  • checkin
  • chevent
  • chtype
  • lnname
  • lock
  • mkbranch
  • mkelem
  • mkslink
  • rmbranch
  • rmelem
  • rmname
  • rmver
  • unlock
  • chevent
    • mkattr
    • mkhlink
    • mklabel
    • mktrigger
    • rmattr
    • rmhlink
    • rmlabel
    • rmtrigger

    Trigger environment variables

    Triggers also set environment variables specifically for the action program that runs. Not all trigger EVs are set for a particular event. Read up on the mktrtype man page for more details.

    CLEARCASE_ATTACH CLEARCASE_ATTYPE CLEARCASE_BRTYPE CLEARCASE_CI_FPN CLEARCASE_COMMENT CLEARCASE_ELTYPE CLEARCASE_FTEXT CLEARCASE_FVOB_PN CLEARCASE_FXPN CLEARCASE_HLTYPE CLEARCASE_ID_STR CLEARCASE_IS_FROM CLEARCASE_LBTYPE CLEARCASE_MTYPE CLEARCASE_NEW_TYPE CLEARCASE_OP_KIND CLEARCASE_OUT_PN CLEARCASE_PN
    CLEARCASE_PN2 CLEARCASE_POP_KIND CLEARCASE_PPID CLEARCASE_RESERVED
    CLEARCASE_SLINKTXT CLEARCASE_TRTYPE CLEARCASE_TTEXT CLEARCASE_TVOB_PN CLEARCASE_TXPN
    CLEARCASE_USER CLEARCASE_VAL CLEARCASE_VIEW_TAG CLEARCASE_VOB_PN CLEARCASE_VTYPE CLEARCASE_XN_SFX CLEARCASE_XPN

    Undocumented: CLEARCASE_COMMAND_LINE (not guaranteed for future releases!)

    Trigger examples

    Formatting note: command line examples with the last character ' \ ' present are to indicate a line wrap, and should not be typed in the actual command.

    We begin with the trigger that every site should have in their VOBs- the rmelem trigger! This is a very dangerous ClearCase command that should be restricted from regular users. Usually only the VOB owner or CM admins are allowed access to this command.

    The following syntax calls a Perl script from either UNIX or Windows clients. Note that full paths are used to call the Perl executables on each platform, plus referencing the trigger script that is executed. The script is not stored in a VOB:

    cleartool mktrtype -element -all -preop rmelem -nusers <vob owner> \
    -execunix "/path/to/Perl /global/vobstore/triggers/no_rmelem.pl" \
    -execwin "\\UNC_path\to\ccperl \\<vob server>\<vob share>\triggers\no_rmelem.pl" \
    NO_RMELEM

    This simple Perl script can be used on both platforms; note the use of clearprompt to display messages to the user:

    
    ---------------------------------------------------------------
    # trigger script: no_rmelem.pl
    $ERRMSG="Users are restricted from running the rmelem command.\n";
    $ERRMSG = "$ERRMSG Will using rmversion or rmname do?";
    system("clearprompt proceed -prompt \"$ERRMSG\" -mask proceed -prefer_gui");
    #hard-code return value to non-zero (false)
    exit 1;
    ---------------------------------------------------------------
    
    

    There is a little trick you can do using clearprompt if you just want to display a message and return a non-zero value. It works from both UNIX and Windows clients, and can simplify your triggers, again assuming that users do not try to adjust their PATH to bypass the clearprompt() command itself. You simply specify -mask and -default parameters to clearprompt that limit the choice a user can select to a non-zero return value- either "no" or "abort" : (do not type from C-shell on UNIX, or quotes will be interpreted incorrectly):

    cleartool mktrtype -element -all -preop rmelem -nusers cmadmin \
    -exec "clearprompt proceed -prompt \"rmelem restricted. Use rmversion or rmname instead\" \
    -mask abort -default abort -prefer_gui" NO_RMELEM

    Displayed output to user:

    The above trigger utilizing clearprompt does not require any scripting, dual-exec paths, and is available on all ClearCase platforms.

    If you get to install only one trigger at your site, the remove element one should be it!

    Another common trigger that sites request is to enforce checkin comments. By making use of the trigger environment variables that ClearCase provides upon execution of a trigger, we can find out values such as the comment string provided, and act accordingly. Note that this is an all-element trigger the way it is created:

    cleartool mktrtype -element -all -preop checkin -nusers <vob owner> \
    -execunix "/path/to/Perl /global/vobstore/triggers/comment_trigger.pl" \
    -execwin "\\UNC_path\to\ccperl \
     \\<vob server>\<vob share>\triggers\comment_trigger.pl" \
    NO_EMPTY_COMMENTS

    Here is another Perl script that can be used on both platforms with the ClearCase-supplied Perl binary:

    
    ---------------------------------------------------------------
    # trigger script: comment_trigger.pl
    $COMMENT="$ENV{'CLEARCASE_COMMENT'}";
    $ERRMSG="You must supply a comment on checkin; please re-try checkin";
    #test for zero-length comment string provided:
    if (length($COMMENT) < 1) {
        system("clearprompt proceed -prompt \"$ERRMSG\" -mask proceed -prefer_gui");
        exit 1;
    }
    exit 0;
    ---------------------------------------------------------------
    
    

    You may want a trigger to always fire after a certain event, like to send email upon certain modifications, or make sure newly created elements have the right permissions or ownership. Some of these triggers do not necessarily require an external script- you can for example, supply a ClearCase command directly to an -exec argument:

    cleartool mktrtype -element -all -postop mkelem -eltype directory \
    -execunix 'cleartool protect -chmod g+w $CLEARCASE_PN' \
    -execwin "cleartool protect -chmod g+w %CLEARCASE_PN%" CHMOD_DIRECTORY

    A trigger can call anything that returns a zero or non-zero value, including a simple hard-coded exit value, provided it is recognized on the client platform that is executing the trigger. These terse exits however do not allow you to pass meaningful messages to the user who may be encountering the trigger, and tend to look ugly from the GUI.

    cleartool mktrtype -type -preop mktype -lbtype -all -nusers vobadm \
    -execunix "exit 1" -execwin "ccperl -e \"exit 1\" " NO_CREATE_LABELS

    The above trigger will produce the following output for a regular user using the Windows GUI:

    For UNIX-only environments, specifying   -exec "exit 1"   for a preop trigger is the most efficient solution to hard-code a false return value; executing /bin/false is actually another shell invocation. Windows does not have an equivalent "exit" or "false" utility available from the command line, but you can create a simple one-line script on Windows using the supplied ccperl and place it with your other Windows trigger scripts and then call it from a trigger:

    false.bat
    ccperl -e "exit 1"

    Another option to simplify your mixed-platform triggers is to make a symbolic link called 'ccperl' that points to 'Perl' (ln -s ccperl Perl) on the UNIX side, then have just one -exec call (provided you trust your users to not override the default path location for Perl!):

    cleartool mktrtype -type -preop mktype -lbtype -all -nusers vobadm \
    -exec "ccperl -e \"exit 1\" " NO_CREATE_LABELS

     (remember that C-shell doesn't process escaped quotes the same as say Bourne shell when entering commands)

    Technically, you can pass any garbage value you want in an -exec statement to force a non-zero return code for a preop trigger:

    cleartool mktrtype -type -preop mktype -lbtype -all -nusers vobadm -exec "sorry_charlie" NO_CREATE_LABELS
      ... but the error messages leave a lot to be desired, and this is definitely not a best practice :-) It is important to note however that a trigger will always return a non-zero value if the -exec path cannot be found or executed.

    additional examples

    Additional trigger examples can be found in in several resources:

    For those using the ClearDDTS integration, you can see the default integration trigger scripts that are shipped under /usr/atria/bugtrack. Also see Appendix A at the end of this document for more examples you can use.

    Troubleshooting triggers

    There are many ways to go about troubleshooting triggers in your ClearCase environment. One such solution is setting the CLEARCASE_TRACE_TRIGGERS environment variable to a non-zero value before executing the trigger. If a trigger is not successfully executing from a GUI, try the same operation from the command line- usually command line output is easier to capture. Remember that clearprompt is recommended for passing information to and from the user over print functions from a shell. Also remember that the current working directory for a trigger is not usually set if initiated from a GUI on Windows. You can also try executing the ClearCase command as a different user, or as the same user logged in to a different machine, to determine if it is an environment problem or not. Don't forget if you are in a mixed environment, that UNIX references environment variables different from Windows ($VAR vs %VAR%); ClearCase won't complain if you specify the wrong variable syntax in the -exec statement, since it is only fired if the trigger conditions are true. You should always do a sanity check of triggers once you create them- log in as an ordinary user and make sure they work! A separate test VOB is a perfect way to test newly created triggers before going live with them.

    A useful tip is to dump out all the CLEARCASE* environment variables within a trigger script on execution for debugging or learning purposes. The following script examples show how to dump out all the CLEARCASE* EVs when called during a trigger invocation:

    Perl

    @env_keys = keys %ENV;
    @env_values = values %ENV;
    while (@env_keys) {
       print pop(@env_keys), "=", pop(@env_values), "\n";
    }

    Bourne Batch
    #!/bin/sh
    env | grep CLEARCASE
    #un-comment line below to write to temp file:
    #env | grep CLEARCASE > /tmp/env.CLEAR.$$ 2>&1
    @echo off
    set
    rem edit out the 'rem' in last line
    rem to direct output to a file:
    rem set > %TEMP%/env.CLEAR.txt

    Remember that the trigger-defined environment variables only exist when the trigger is actually firing, so you would need to include such code into the trigger script itself that is executed.

    Some other useful hints include naming your triggers appropriately- if a user gets denied an operation attempt from a trigger named TRIG1, that may not be as clear as if the trigger were named say NO_CHECKIN_MAIN_BRANCH. You may also want to include in the comment of your scripts, the actual ClearCase command used to install the trigger in place. This can be highly beneficial to both the original script author, and any new CM staff members later who may inherit the role of maintaining the previously defined triggers!

    For triggers where the -nusers list may change frequently, it may be easier to have one master user exclusion list, and then this common group list is referred to by other trigger scripts at run time when necessary. It is easy however to adjust the specified user list for a trigger from the GUI as well.

    return to summary of topics


    Appendix A

    more simple trigger examples

    #trigger to not allow branches to be re-named by users:
    ct mktrtype -type -preop rntype -nusers vobadm
      -exec <exec path> -brtype -all NO_RENAME_BRANCHES
    

    #trigger to not allow users to move, rename or rmname files; #remember, moving a file only affects the directory, not the file element itself! ct mktrtype -element -all -preop lnname,rmname -eltype directory -nusers vobadm -exec <exec path> NO_RENAME_RMNAME_FILES

    #trigger to only allow the VOB owner to lock an element: ct mktrtype -element -all -preop lock -nusers vobadm -exec <exec path> NO_LOCKING_ELEMENTS

    #update previous trigger example to allow mary and joe to lock elements too: ct mktrtype -element -all -replace -preop lock -nusers vobadm,mary,joe -exec <exec path> NO_LOCKING_ELEMENTS

    #only allow VOB owner to create label types (anyone can apply labels already defined) : ct mktrtype -type -preop mktype -lbtype -all -nusers vobadm -exec <exec path> NO_CREATE_LABELS

    #only allow VOB owner to apply existing labels to the main branch of elements: ct mktrtype -element -all -preop mklabel -brtype main -nusers vobadm -exec <exec path> NO_APPLY_LABELS

    #elements in the document directory of the VOB are not to be branched; #this is a two-step process- first create the trigger type without -all, #then apply it to a subset of data within the VOB: ct mktrtype -element -preop mkbranch -exec <exec path> NO_BRANCHING ct mktrigger -recurse NO_BRANCHING <vobtag>/docs

    #execute a script on all text files after checkin: ct mktrtype -element -all -postop checkin -eltype text_file -exec <path to script> PROCESS_CHECKIN

    #same trigger as above except scoped down to the main branch: ct mktrtype -element -all -postop checkin -eltype text_file -brtype main -exec <path to script> PROCESS_MAIN_CHECKIN

    #script to send email to VOB/CM admin whenever new branch work is created : ct mktrtype -type -postop mktype -brtype -all -exec <path to mail script> MAIL_BRTYPE_NOTIFY

    Appendix B

    trigger to catch element creation casename conflicts on Windows

    # Author: David Robinson; Rational Software
    #
    # This perl script is a ClearCase preop trigger on mkelem to prevent
    # the addition of two elements in a directory with names that differ
    # only in the case of characters. It is appropriate for a case-insensitive 
    # system like Windows NT supports.
    # The trigger checks for name conflicts only in the CHECKEDOUT version of
    # the parent directory element.
    #
    # It should be installed with the following command:
    # cleartool mktrype -element -all -preop mkelem ^
    #   -execwin "ccperl \CheckCaseConflict.pl" CheckCaseConflict
    
    # preserve current working directory
    chop ($homedir=`cd`);
    
    # separate element name from name of parent directory
    @splitpath 	= split(/\\/,$ENV{"CLEARCASE_PN"});
    $file 	= pop(@splitpath);
    $directory 	= join("\\",@splitpath);
    
    # get a list of element in the directory
    # then subset with case-insensitive match on element name
    chdir($directory);
    chop (@ls = `cleartool ls -short -nxname`);
    @filematch = grep(/^$file$/i,@ls);
    
    # if there is an unambiguous match, then try to rename the file to match it
    # before aborting the mkelem
    if (@filematch == 1) {
        if (rename($file.".mkelem",$filematch[0])) {
            system("clearprompt","proceed","-type warning","-mask proceed","-prompt",
                "\"File renamed to $filematch[0], which is already under source control\"");
        }
        else {
            system("clearprompt","proceed","-type error","-mask abort","-prompt",
                "\"Rename failed, but file has name conflicts in the VOB\"");
        }
        chdir($homedir);
        exit (4);
    }
    
    # if there is an ambiguous match, then just abort with notification
    if (@filematch > 1) {
        system("clearprompt","proceed","-type error","-mask abort","-prompt",
    	"\"File has name conflicts in the VOB\"");
        chdir($homedir);
        exit (4);
    }
    
    chdir($homedir);
    exit (0);
    
    

    return to summary of topics


    Recommended reading and references

    ClearCase User's Manual, UNIX, release 3.2.1,
    ClearCase User's Manual, NT, release 3.2.1,

    ClearCase Windows/UNIX Interoperation, release 3.2.1 and later

    cleartool manual pages for mktrtype, mktrigger, rmtrigger, lstype, type_object, clearprompt

    feel free to contact the author at fierro@rational.com