initCommon(); $template->displayHeader(); ?>

10.2. Setting Triggers

Triggers provide a way for one package to take action when the installed status of another package changes. A trigger is a script you define in your package’s spec file that gets run by the RPM system when the status of another named package changes. If your package depends in some way on another package, a trigger can allow your package to deal with changes to the other package.

Triggers are not a replacement for package dependencies. Instead, triggers are useful when you need to change a package’s installation based on other packages installed on the system. For example, if your package is a mail client program, your package will need to have a mail transfer agent, or MTA. Linux supports a number of different mail transfer agents, such as sendmail, vmail, exim, qmail, and postfix.

Typically a system will have one mail transfer agent installed. In most cases, a mail client won’t care which MTA is installed, as long as one is installed. (In fact, most of these packages should be marked that they conflict with one another, ensuring that a given system can only have one.)

The %triggerin script is run when a given target package is installed or upgraded. The %triggerin script is also run when your package is installed or upgraded, should the target package be already installed. Similarly, the %triggerun script is run if the target package is removed. It is also run if your package is removed and the target package is installed. The %triggerpostun script is run after the target package has been removed. It is not run if your package is removed.

To define one of these scripts, you need to list the name of the target package; for example:

%triggerin -- tcsh

script commands...

This example sets up a trigger for the tcsh package. If the tcsh package is installed or upgraded, RPM will run the script. If your package is installed or upgraded and the tcsh package is presently installed, RPM will also run the script.

Define the %triggerun script similarly:

%triggerun -- tcsh

script commands...

You can also use version numbers in the trigger script definition to only run the script in the case of a particular version. For example:

%triggerpostun -- vixie-cron < 3.0.1-56

/sbin/chkconfig --del crond

/sbin/chkconfig --add crond

This example, from the vixie-cron scheduling package, runs a post-uninstall trigger for the same package, but for older versions. To define trigger scripts for particular versions, use the same syntax as for requires dependencies for naming the version number and comparisons.

Triggers are run through /bin/sh, the most commonly used shell script engine. With the -p option, though, you can specify a different script interpreter. For example, to write a Perl script, define your trigger like the following:

%triggerpostun -p /usr/bin/perl -- vixie-cron < 3.0.1-56

system("/sbin/chkconfig --del crond");

system("/sbin/chkconfig --add crond");

With subpackages, defined following, you can use a -n option to tie the trigger script to a subpackage. For example:

%triggerpostun -n subpackage_name -- vixie-cron < 3.0.1-56

/sbin/chkconfig --del crond

/sbin/chkconfig --add crond

Inside your trigger scripts, $1, the first command-line argument, holds the number of instances of your package that will remain after the operation has completed. The second argument, $2, holds the number of instances of the target package that will remain after the operation. Thus, if $2 is 0, the target package will be removed.

The anonftp package, mentioned in Chapter 6, has a lot of triggers. Many of these set up a number of commands to be locally available to the anonftp package. This networking package is also closely tied to the version of the C library, glibc, as shown in Listing 11-1

Listing 11-1: Anonftp package trigger scripts.

%triggerin -- glibc

copy() { file="`ls --sort=time $1 |head -n 1`"; ln -f "$file" "$2" 2>/dev/null |

| cp -df "$file" "$2"; }

# Kill off old versions

rm -f /var/ftp/lib/ld-* /var/ftp/lib/libc* /var/ftp/lib/libnsl* /var/ftp/lib/lib

nss_files* &>/dev/null || :

# Copy parts of glibc, needed by various programs in bin.

LIBCVER=`basename $(ls --sort=time /lib/libc-*.so |head -n 1) .so |cut -f2- -d-`

copy /lib/ld-${LIBCVER}.so /var/ftp/lib

copy /lib/libc-${LIBCVER}.so /var/ftp/lib

copy /lib/libnsl-${LIBCVER}.so /var/ftp/lib

copy /lib/libnss_files-${LIBCVER}.so /var/ftp/lib

md5sum /var/ftp/lib/lib*-*.so /var/ftp/lib/libtermcap.so.*.*.* 2>/dev/null >/var

/ftp/lib/libs.md5

chmod 0400 /var/ftp/lib/libs.md5

# Use ldconfig to build symlinks and whatnot.

[ ! -e /var/ftp/etc/ld.so.conf ] && touch /var/ftp/etc/ld.so.conf

/sbin/ldconfig -r /var/ftp

%triggerin -- fileutils

copy() { file="`ls --sort=time $1 |head -n 1`"; ln -f "$file" "$2" 2>/dev/null |

| cp -df "$file" "$2"; }

copy /bin/ls /var/ftp/bin

md5sum `ls /var/ftp/bin/* |grep -v bin.md5` >/var/ftp/bin/bin.md5

chmod 0400 /var/ftp/bin/bin.md5

%triggerin -- cpio

copy() { file="`ls --sort=time $1 |head -n 1`"; ln -f "$file" "$2" 2>/dev/null |

| cp -df "$file" "$2"; }

copy /bin/cpio /var/ftp/bin

md5sum `ls /var/ftp/bin/* |grep -v bin.md5` >/var/ftp/bin/bin.md5

chmod 0400 /var/ftp/bin/bin.md5

%triggerin -- tar

copy() { file="`ls --sort=time $1 |head -n 1`"; ln -f "$file" "$2" 2>/dev/null |

| cp -df "$file" "$2"; }

copy /bin/tar /var/ftp/bin

md5sum `ls /var/ftp/bin/* |grep -v bin.md5` >/var/ftp/bin/bin.md5

chmod 0400 /var/ftp/bin/bin.md5

%triggerin -- gzip

copy() { file="`ls --sort=time $1 |head -n 1`"; ln -f "$file" "$2" 2>/dev/null |

| cp -df "$file" "$2"; }

copy /bin/gzip /var/ftp/bin

ln -sf gzip /var/ftp/bin/zcat

md5sum `ls /var/ftp/bin/* |grep -v bin.md5` >/var/ftp/bin/bin.md5

chmod 0400 /var/ftp/bin/bin.md5

%triggerin -- libtermcap

copy() { file="`ls --sort=time $1 |head -n 1`"; ln -f "$file" "$2" 2>/dev/null |

| cp -df "$file" "$2"; }

rm -f /var/ftp/lib/libtermcap.so.*.*.* &>/dev/null || :

copy '/lib/libtermcap.so.*.*.*' /var/ftp/lib

md5sum /var/ftp/lib/lib*-*.so /var/ftp/lib/libtermcap.so.*.*.* 2>/dev/null >/var

/ftp/lib/libs.md5

chmod 0400 /var/ftp/lib/libs.md5

# Use ldconfig to build symlinks and whatnot.

[ ! -e /var/ftp/etc/ld.so.conf ] && touch /var/ftp/etc/ld.so.conf

/sbin/ldconfig -r /var/ftp

%triggerin -- ncompress

copy() { file="`ls --sort=time $1 |head -n 1`"; ln -f "$file" "$2" 2>/dev/null |

| cp -df "$file" "$2"; }

copy /usr/bin/compress /var/ftp/bin

md5sum `ls /var/ftp/bin/* |grep -v bin.md5` >/var/ftp/bin/bin.md5

chmod 0400 /var/ftp/bin/bin.md5

%triggerpostun -- anonftp 4.0

if [ "$2" != 1 ] ; then

# The user has multiple glibc packages installed. We can't read the

# user's mind, so don't do anything.

exit 0

fi

copy() { file="`ls --sort=time $1 |head -n 1`"; ln -f "$file" "$2" 2>/dev/null |

| cp -df "$file" "$2"; }

# Kill off old versions

rm -f /var/ftp/lib/ld-* /var/ftp/lib/libc* /var/ftp/lib/libnsl* /var/ftp/lib/lib

nss_files* &>/dev/null || :

# Copy parts of glibc, needed by various programs in bin.

LIBCVER=`basename /lib/libc-*.so .so | cut -f2- -d-`

copy /lib/ld-${LIBCVER}.so /var/ftp/lib

copy /lib/libc-${LIBCVER}.so /var/ftp/lib

copy /lib/libnsl-${LIBCVER}.so /var/ftp/lib

copy /lib/libnss_files-${LIBCVER}.so /var/ftp/lib

copy /bin/ls /var/ftp/bin

copy /bin/cpio /var/ftp/bin

copy /bin/tar /var/ftp/bin

copy /bin/gzip /var/ftp/bin

ln -sf gzip /var/ftp/bin/zcat

copy /usr/bin/compress /var/ftp/bin

rm -f /var/ftp/lib/libtermcap.so.*.*.* &>/dev/null || :

copy '/lib/libtermcap.so.*.*.*' /var/ftp/lib

# Use ldconfig to build symlinks and whatnot.

[ ! -e /var/ftp/etc/ld.so.conf ] && touch /var/ftp/etc/ld.so.conf

/sbin/ldconfig -r /var/ftp

# Generate md5sums for verifyscript

md5sum /var/ftp/lib/lib*-*.so /var/ftp/lib/libtermcap.so.*.*.* 2>/dev/null >/var

/ftp/lib/libs.md5

chmod 0400 /var/ftp/lib/libs.md5

md5sum `ls /var/ftp/bin/* |grep -v bin.md5` >/var/ftp/bin/bin.md5

chmod 0400 /var/ftp/bin/bin.md5

displayFooter('$Date: 2005/11/02 19:30:06 $'); ?>