Application Packaging Developer's Guide

Creating Installation Scripts

This section discusses optional package installation scripts. The pkgadd command automatically performs all the actions necessary to install a package using the package information files as input. You do not have to supply any package installation scripts. However, if you want to create customized installation procedures for your package, you can do so with installation scripts. Installation scripts:

There are four types of installation scripts with which you can perform customized actions:

Script Processing During Package Installation

The type of scripts you use depends on when the action of the script is needed during the installation process. As a package is installed, the pkgadd command performs the following steps:

  1. Executes the request script.

    This is the only point at which your package can solicit input from the administrator installing the package.

  2. Executes the checkinstall script.

    The checkinstall script gathers file system data and can create or alter environment variable definitions to control the subsequent installation. For more information on package environment variables, see "Package Environment Variables".

  3. Executes the preinstall script.

  4. Installs package objects, for each class to be installed.

    Installation of these files occurs class by class, and class action scripts are executed accordingly. The list of classes operated on and the order in which they should be installed is initially defined with the CLASSES parameter in your pkginfo file. However, your request script or checkinstall script can change the value of the CLASSES parameter. For more information on how classes are processed during installation, see "How Classes Are Processed During Installation".

    1. Creates symbolic links, devices, named pipes, and required directories.

    2. Installs the regular files (file types e, v, f), based on their class.

      The class action script is passed only regular files to install. All other package objects are created automatically from information in the pkgmap file.

    3. Creates all hard links.

  5. Executes the postinstall script.

Script Processing During Package Removal

When a package is being removed, the pkgrm command performs these steps:

  1. Executes the preremove script.

  2. Removes the package objects, for each class.

    Removal also occurs class by class. Removal scripts are processed in the reverse order of installation, based on the sequence defined in the CLASSES parameter. For more information on how classes are processed during installation, see "How Classes Are Processed During Installation".

    1. Removes hard links.

    2. Removes regular files.

    3. Removes symbolic links, devices, and named pipes.

  3. Executes the postremove script.

The request script is not processed at the time of package removal. However, its output (a list of environment variables) is retained in the installed package and made available to removal scripts.

Package Environment Variables Available to Scripts

The following groups of environment variables are available to all installation scripts. Some of the environment variables can be modified by a request or checkinstall script.

Obtaining Package Information for a Script

Two commands can be used from scripts to solicit information about a package:

Exit Codes for Scripts

Each script must exit with one of the exit codes shown in Table 3-3.

Table 3-3 Installation Script Exit Codes

Code 

Meaning 

Successful completion of script.  

Fatal error. Installation process is terminated at this point.  

2  

Warning or possible error condition. Installation continues. A warning message is displayed at the time of completion.  

3  

The pkgadd command is cleanly halted. Only the checkinstall script returns this code,

10  

System should be rebooted when installation of all selected packages is completed. (This value should be added to one of the single-digit exit codes described above.)  

20  

System should be rebooted immediately upon completing installation of the current package. (This value should be added to one of the single-digit exit codes described above.)  

See Chapter 5, Package Creation Case Studies for examples of exit codes returned by installation scripts.


Note -

All installation scripts delivered with your package should have an entry in the prototype file. The file type should be i (for package installation script).


Writing a request Script

The request script is the only way your package can interact directly with the administrator installing it. It can be used, for example, to ask the administrator if optional pieces of a package should be installed.

The output of a request script must be a list of environment variables and their values. This list can include any of the parameters you created in the pkginfo file and the CLASSES and BASEDIR parameters. The list can also introduce environment variables that have not been defined elsewhere (although the pkginfo file should always provide default values, when practical). For more information on package environment variables, see "Package Environment Variables".

When your request script assigns values to a environment variable, it must then make those values available to the pkgadd command and other package scripts.

request Script Behaviors

Design Rules for request Scripts


Note -

If it is possible that the administrators who will be installing your package will be using the JumpStartTM product, then the installation of your package must not be interactive. This implies that either you should not provide a request script with your package, or you need to communicate to the administrator that they should use the pkgask command, prior to installation, to store their responses to the request script. For more information on the pkgask command, see the pkgask(1M) man page.


How to Write a request Script

  1. Make the directory containing your information files the current working directory.

  2. Create a file named request with your favorite text editor.

  3. Save your changes and quit the editor when you are done.

  4. Complete one of the following tasks.

  5. Build your package.

    See "How to Build a Package", if needed.

Where to Go Next

After you build the package, install it to confirm that it installs correctly and verify its integrity. Chapter 4, Verifying and Transferring a Package explains how to do this and provides step-by-step instructions on how to transfer your verified package to a distribution medium.

Example--Writing a request Script

When a request script assigns values to environment variables, it must make those values available to the pkgadd command. This example shows a request script segment that performs this task for the four environment variables CLASSES, NCMPBIN, EMACS, and NCMPMAN. (These were defined in an interactive session with the administrator earlier in the script.)


# make environment variables available to installation
# service and any other packaging script we might have
 
cat >$1 <<!
CLASSES=$CLASSES
NCMPBIN=$NCMPBI
EMACS=$EMACS
NCMPMAN=$NCMPMAN
!

Gathering Data With the checkinstall Script

The checkinstall script is executed shortly after the optional request script. It runs as the user install, if such a user exists, or the user nobody. The checkinstall script does not have the authority to change file system data; it is strictly a data gatherer. However, based on the information it gathers, it can create or modify environment variables in order to control the course of the resulting installation. It is also capable of cleanly halting the installation process.

The checkinstall script is intended to perform basic checks on a file system that would not be normal for the pkgadd command. For example, it can be used to check ahead to determine if any files from the current package are going to overwrite existing files, or manage general software dependencies (the depend file only manages package-level dependencies).

Unlike the request script, the checkinstall script is executed whether or not a response file is provided; and, its presence does not brand the package as "interactive." This means that the checkinstall script can be used in situations where a request script is forbidden or administrative interaction is not practical.


Note -

The checkinstall script is available starting with the Solaris 2.5 and compatible releases.


checkinstall Script Behaviors

Design Rules for checkinstall Scripts

How to Gather File System Data

  1. Make the directory containing your information files the current working directory.

  2. Create a file named checkinstall with your favorite text editor.

  3. Save your changes and quit the editor when you are done.

  4. Complete one of the following tasks.

  5. Build your package.

    See "How to Build a Package", if needed.

Where to Go Next

After you build the package, install it to confirm that it installs correctly and verify its integrity. Chapter 4, Verifying and Transferring a Package explains how to do this and provides step-by-step instructions on how to transfer your verified package to a distribution medium.

Example--Writing a checkinstall Script

This example checkinstall script checks to see if database software needed by the SUNWcadap package is installed.


# checkinstall script for SUNWcadap
#
# This confirms the existence of the required specU database
 
# First find which database package has been installed.
pkginfo -q SUNWspcdA	# try the older one
 
if [ $? -ne 0 ]; then
   pkginfo -q SUNWspcdB	# now the latest
 
	  if [ $? -ne 0 ]; then	# oops
		    echo "No database package can be found. Please install the"
		    echo "SpecU database package and try this installation again."
		    exit 3		# Suspend
	  else
		    DBBASE="`pkgparam SUNWsbcdB BASEDIR`/db"	# new DB software
	  fi
else
	  DBBASE="`pkgparam SUNWspcdA BASEDIR`/db"	# old DB software
fi
 
# Now look for the database file we will need for this installation
if [ $DBBASE/specUlatte ]; then
	  exit 0		# all OK
else
	  echo "No database file can be found. Please create the database"
	  echo "using your installed specU software and try this"
	  echo "installation again."
	  exit 3		# Suspend
fi
 

Writing Procedure Scripts

The procedure scripts provide a set of instructions to be performed at particular points in package installation or removal. The four procedure scripts must be named one of the predefined names, depending on when the instructions are to be executed, and are executed without arguments.

Procedure Script Behaviors

Procedure scripts are executed as uid=root and gid=other.

Design Rules for Procedure Scripts

How to Write Procedure Scripts

  1. Make the directory containing your information files the current working directory.

  2. Create one or more procedure scripts with your favorite text editor.

    A procedure script must be named one of the predefined names: preinstall, postinstall, preremove, or postremove.

  3. Save your changes and quit the editor.

  4. Complete one of the following tasks.

  5. Build your package.

    See "How to Build a Package", if needed.

Where to Go Next

After you build the package, install it to confirm that it installs correctly and verify its integrity. Chapter 4, Verifying and Transferring a Package explains how to do this and provides step-by-step instructions on how to transfer your verified package to a distribution medium.

Writing Class Action Scripts

Defining Object Classes

Object classes allow a series of actions to be performed on a group of package objects at installation or removal. You assign objects to a class in the prototype file. All package objects must be given a class, although the class of none is used by default for objects that require no special action.

The installation parameter CLASSES, defined in the pkginfo file, is a list of classes to be installed (including the none class).


Note -

Objects defined in the pkgmap file that belong to a class not listed in this parameter in the pkginfo file will not be installed.


The CLASSES list determines the order of installation. Class none is always installed first, if present, and removed last. Since directories are the fundamental support structure for all other file system objects, they should all be assigned to the none class. Exceptions can be made, but as a general rule, the none class is safest. The reason for this is to ensure that the directories are created before the objects they will contain and also to ensure that no attempt is made to delete a directory before it has been emptied.

How Classes Are Processed During Installation

The following list describes the system actions that occur when a class is installed. The actions are repeated once for each volume of a package as that volume is being installed.

  1. The pkgadd command creates a path name list.

    The pkgadd command creates a list of path names upon which the action script will operate. Each line of this list contains source and destination path names, separated by a space. The source path name indicates where the object to be installed resides on the installation volume and the destination path name indicates the location on the target system where the object should be installed. The contents of the list are restricted by the following criteria:

    • The list contains only path names belonging to the associated class.

    • If the attempt to create the package object fails, directories, named pipes, character devices, block devices, and symbolic links are included in the list with the source path name set to /dev/null. Normally they will be automatically created by the pkgadd command (if not already in existence) and given proper attributes (mode, owner, group) as defined in the pkgmap file.

    • Linked files where the file type is l are not included in the list under any circumstances. Hard links in the given class are created in item 4.

  2. If no class action script is provided for installation of a particular class, the path names in the generated list are copied from the volume to the appropriate target location.

  3. If there is a class action script, the script is executed.

    The class action script is invoked with standard input containing the list generated in item 1. If this is the last volume of the package, or there are no more objects in this class, the script is executed with the single argument of ENDOFCLASS.


    Note -

    Even if there are no regular files of this class anywhere in the package, the class action script will be called at least once with an empty list and the ENDOFCLASS argument.


  4. The pkgadd command performs a content and attribute audit and creates hard links.

    After successfully executing items 2 or 3, the pkgadd command audits both content and attribute information for the list of path names. The pkgadd command creates the links associated with the class automatically. Detected attribute inconsistencies are corrected for all path names in the generated list.

How Classes Are Processed During Removal

Objects are removed class by class. Classes that exist for a package but that are not listed in the CLASSES parameter are removed first (for example, an object installed with the installf command). Classes listed in the CLASSES parameter are removed in reverse order. The none class is always removed last. The following list describes the system actions that occur when a class is removed:

  1. The pkgrm command creates a path name list.

    The pkgrm command creates a list of installed path names that belong to the indicated class. Path names referenced by another package are excluded from the list unless their file type is e (meaning the file should be edited upon installation or removal).

    If the package being removed modified any files of type e during installation, it should remove just the lines it added. Do not delete a non-empty editable file; just remove the lines the package added.

  2. If there is no class action script, the path names are deleted.

    If your package has no removal class action script for the class, all the path names in the list generated by the pkgrm command are deleted.


    Note -

    Files with a file type of e (editable), which are not assigned to a class and an associated class action script, will be removed at this point, even if the path name is shared with other packages.


  3. If there is a class action script, the script is executed.

    The pkgrm command invokes the class action script with standard input for the script containing the list generated in item 1.

  4. The pkgrm command performs an audit.

    After successfully executing the class action script, the pkgrm command removes knowledge of the path names from the package database unless a path name is referenced by another package.

The Class Action Script

The class action script defines a set of actions to be executed during installation or removal of a package. The actions are performed on a group of path names based on their class definition. (See Chapter 5, Package Creation Case Studies for examples of class action scripts.)

The name of a class action script is based on the class on which it should operate and whether those operations should occur during package installation or removal. The two name formats are as follows:

Name Format 

Description 

i.class

Operates on path names in the indicated class during package installation. 

r.class

Operates on path names in the indicated class during package removal.  

For example, the name of the installation script for a class named manpage would be i.manpage and the removal script would be named r.manpage.


Note -

This file name format is not used for files belonging to the sed, awk, or build system classes. For more information on these special classes, see "The Special System Classes".


Class Action Script Behaviors

Design Rules for Class Action Scripts

The Special System Classes

The system provides four special classes in the Solaris 7 release. They are:

If there are several files in a package that require special processing that can be fully defined through sed, awk, or sh commands, installation will be faster by using the system classes rather than multiple classes and their corresponding class action scripts.

The sed Class Script

The sed class provides a method to modify an existing object on the target system. The sed class action script executes automatically at installation if a file belonging to class sed exists. The name of the sed class action script should be the same as the name of the file on which the instructions will be executed.

A sed class action script delivers sed instructions in the format shown in Figure 3-1.

Figure 3-1 Format of a sed Class Action Script


# comment, which may appear on any line in the file
 
!install
# sed(1) instructions which will be invoked during
# installation of the object
 
[address [,address]] function [arguments]
 
  . . .
 
!remove
 
# sed(1) instructions to be invoked during the removal process
 
[address [,address]] function [arguments]

Two commands indicate when instructions should be executed. The sed instructions that follow the !install command are executed during package installation and those that follow the !remove command are executed during package removal. It does not matter which order these commands are used in the file.

For more information on sed instructions, see the sed(1) man page. For examples of sed class action scripts, see Chapter 5, Package Creation Case Studies.

The awk Class Script

The awk class provides a method to modify an existing object on the target system. Modifications are delivered as awk instructions in an awk class action script.

The awk class action script is executed automatically at installation if a file belonging to class awk exists. Such a file contains instructions for the awk class script in the format shown in Figure 3-2.

Figure 3-2 Format of an awk Class Action Script


# comment, which may appear on any line in the file
 
!install
 
# awk(1) program to install changes
 
 . . . (awk program)
 
!remove
 
# awk1(1) program to remove changes
 
 . . . (awk program)

Two commands indicate when instructions should be executed. The awk instructions that follow the !install command are executed during package installation, and those that follow the !remove command are executed during package removal. It does not matter in which order these commands are used in the file.

The name of the awk class action script should be the same as the name of the file on which the instructions will be executed.

The file to be modified is used as input to awk and the output of the script ultimately replaces the original object. Environment variables may not be passed to the awk command with this syntax.

For more information on awk instructions, see the awk(1) man page.

The build Class Script

The build class creates or modifies a package object file by executing Bourne shell instructions. These instructions are delivered as the package object, which runs automatically at installation if it belongs to the build class.

The name of the build class action script should be the same as the name of the file on which the instructions will be executed, and must be executable by the sh command. The script's output becomes the new version of the file as it is built or modified.

For example, if a package delivers a default file, /etc/randomtable, and if the file does not already exist on the target system, the prototype file entry might be:


e build /etc/randomtable ? ? ?

and the package object, /etc/randomtable, might look like this:


!install
# randomtable builder
if [ -f $PKG_INSTALL_ROOT/etc/randomtable ]; then
		echo "/etc/randomtable is already in place.";
	    else
		echo "# /etc/randomtable" > $PKG_INSTALL_ROOT/etc/randomtable
		echo "1121554	# first random number" >> $PKG_INSTALL_ROOT/etc/randomtable
fi
 
!remove
# randomtable deconstructor
if [ -f $PKG_INSTALL_ROOT/etc/randomtable ]; then
		# the file can be removed if it's unchanged
		if [ egrep "first random number" $PKG_INSTALL_ROOT/etc/randomtable ]; then
			rm $PKG_INSTALL_ROOT/etc/randomtable;
		fi
fi
 

See Chapter 5, Package Creation Case Studies for another example using the build class.

The preserve Class Script

The preserve class preserves a package object file by determining whether or not an existing file should be overwritten when the package is installed. Two possible scenarios when using a preserve class script are:

Both scenario outcomes are considered successful by the preserve script. A failure occurs only, when in the second scenario, the file is unable to be copied to the target directory.

Starting with the Solaris 7 release, the i.preserve script and a copy of this script, i.CONFIG.prsv, can be found in the /usr/sadm/install/scripts directory with the other class action scripts.

Figure 3-3 Format of a preserve Class Action Script


#ident "$Header: i.CONFIG.prsv,v 12.1 1997/09/19 $"
 
error=no
echo "## checking common configuration files"
while read src dest
do
      [ "$src" = /dev/null ] && continue
 
      if [ -f "$dest" ]
      then
              echo $dest preserved
      else
              echo $dest
              cp $src $dest || error=yes
      fi
 
done
[ "$error" = yes ] &&
        exit 2
exit 0

Modify the script to include the filename or filenames you would like to preserve.

How to Write Class Action Scripts

  1. Make the directory containing your information files the current working directory.

  2. Assign the package objects in the prototype file the desired class names. For example, assigning objects to an application and manpage class would look like:


    f manpage /usr/share/man/manl/myappl.1l
    f application /usr/bin/myappl

  3. Modify the CLASSES parameter in the pkginfo file to contain the class names you want to use in your package. For example, entries for the application and manpage classes would look like:


    CLASSES=manpage application none


    Note -

    The none class is always installed first and removed last, regardless of where it appears in the definition of the CLASSES parameter.


  4. If you are a creating class action script for a file belonging to the sed, awk, or build class, make the directory containing the package object your current working directory.

  5. Create the class action scripts or package objects (for files belonging to the sed, awk, or build class). An installation script for a class named application would be named i.application and a removal script would be named r.application.

    Remember, when a file is part of a class that has a class action script, the script must install the file. The pkgadd command does not install files for which a class action script exists, although it does verify the installation. And, if you define a class but do not deliver a class action script, the only action taken for that class is to copy components from the installation medium to the target system (the default pkgadd behavior).

  6. Complete one of the following tasks.

  7. Build your package.

    See "How to Build a Package", if needed.

Where to Go Next

After you build the package, install it to confirm that it installs correctly and verify its integrity. Chapter 4, Verifying and Transferring a Package explains how to do this and provides step-by-step instructions on how to transfer your verified package to a distribution medium.