Index SD-UX Mkpkg Mkbdl Glossary
SD-UX elements: bundle product subproduct fileset vendor

Control Scripts

  1. Overview
  2. Scripts
  3. Guidelines
    1. Format
    2. Environment Variables
    3. Execution
  4. Control file generation
  5. Control actions
    1. Custom scripts
    2. PATH file components
    3. Configuration file installation
    4. New users and groups
    5. System file modification
    6. Crontab entries
    7. Removing obsolete files
    8. Adding a kernel driver or parameter
    9. Starting a daemon process

Overview

SD-UX supports execution of both product and fileset control scripts. These shell scripts allow you to perform additional, customized checks and operations as part your regular software management tasks. The swinstall, swconfig, swverify and swremove commands can execute one or more of these scripts. Control scripts are usually supplied by the software vendor, but you can also write your own. All these scripts are optional.

Product level control scripts are run when any fileset within that product is selected for installation or removal so the activities in product control scripts must pertain to all filesets in that product, but not to any fileset in particular. Actions you want to apply to every fileset in a product should be in the appropriate product level control script.

Fileset scripts must pertain only to the installation, configuration, or removal of that fileset, and not to any other fileset or to the parent product.

Control scripts can perform a wide variety of customization and configuration tasks, such as:

  1. Checking to see if someone is actively using the product and, if so, preventing reinstallation, update or removal.
  2. Checking the local host system to ensure it is compatible with the software (scripts can check beyond the compatibility enforced by the product's uname attributes).
  3. Removing obsolete files or previously installed versions of the product.
  4. Creating links to, or additional copies of, files after they have been installed.
  5. Copying configurable files into place on first-time installation.
  6. Conditionally copying configurable files into place on later updates.
  7. Modifying existing configuration files for new features.
  8. Rebuilding custom versions of configuration files.
  9. Creating device files or custom programs.
  10. Killing and/or starting daemons.

Since writing correct control scripts is very difficult, mkpkg has the ability to automatically generate control scripts for a wide variety of common customization and configuration tasks.

This documentation is a subset of the description of control files found in the HP manual Managing HP-UX Software with SD-UX.

Scripts

checkinstall
This script is run by swinstall during its Analysis phase to insure that the installation (and configuration) can be attempted. For example, the OS run state, running processes, or other prerequisite conditions beyond dependencies could be checked. It should not change the state of the system.

A checkinstall script's chief merit is its ability to detect if the system contains a hardware configuration that might lead to catastrophe - an unbootable system or file system corruption - if the installation of the selected software was allowed to proceed. It also acts as the test for conflicts with other software selections or with software already installed.

Limit 1023 characters. Type path_string

preinstall
This script is run by swinstall before loading the software files. For example, this script could remove obsolete files, or move an existing file aside during an update.

This script and the postinstall script are part of swinstall's Load phase. In the Load phase, a product's preinstall script (if any) runs first. Then, for each selected fileset in that product, the fileset's preinstall script runs. The files are then loaded, and the fileset's postinstall script runs. Finally, the product's postinstall script (if any) runs. Then SD loads the next product that has selected filesets and the process repeats for that product.

Limit 1023 characters. Type path_string

postinstall
This script is run by swinstall after loading the software files. For example, this script could move a default file into place.

Limit 1023 characters. Type path_string

configure
This script is run by swinstall or by swconfig to configure the host for the software, or configure the software for host-specific information. For example, this script could change a host's specific configuration file such as /etc/services, add the host name or other host resources such as available printers to its own configuration file, or perform compilations.

Configure scripts are run by swinstall for all products (in prerequisite order) after the products have completed the Load phase. However, they are only run when installing to a system that will actually be using the software. They are deferred when installing to an alternate root (for example, for diskless or building test file systems) and run instead by the swconfig command when the alternate root is now the root of the system using the software.

The swconfig command can also be used to rerun configure scripts that failed during a normal install. A successful execution of the configure step (whether there is a script or not) moves the software from the INSTALLED state to the CONFIGURED or ready-to-use state. Configure scripts (and all others) must be able to be run many times (that is, they must be re-executable).

Configure scripts are not run for installations to alternate roots.

Limit 1023 characters. Type path_string

verify
Verify scripts are run by the swverify command any time after the software has been installed and configured. Like other scripts, they are intended to verify anything that the SD-UX software management tools do not verify by default. For example, this script could check to see that the software is configured properly and that you have a proper license to use it.

Limit 1023 characters. Type path_string

unconfigure
This script is run by swconfig or by swremove to undo the configuration of the host or the software that was done by the configure script. For example, it could remove its configuration from the /etc/services file. (The unconfigure task moves the software from the CONFIGURED state back to the INSTALLED state.)

Only the swremove command actually removes software. You should be able to unconfigure and reconfigure using swconfig. Unconfigure scripts are not run for removals from alternate roots.

Limit 1023 characters. Type path_string

checkremove
The checkremove script is run by swremove during the remove Analysis phase to allow any vendor-defined checks before the software is permanently removed. For example, the script could check whether anyone was currently using the software.

Limit 1023 characters. Type path_string

preremove
This script is executed just before removing files. It can be destructive to the application because files will be removed next. It could remove files that the postinstall script created.

This script and the postremove script are part of the Remove phase of swremove. Within each product, preremove scripts are run (in the reverse order dictated by any prerequisites), files are removed, then all postremove scripts are run.

Limit 1023 characters. Type path_string

postremove
This script is executed just after removing files. It is the companion script to the postinstall script. For example, if this was a patch fileset, then the preinstall script could move the original file aside, and this postremove script could move the original file back if the patch was removed.

Limit 1023 characters. Type path_string

control_file
The software vendor can include other control scripts, such as a subscript that is sourced by the above scripts. The location of the control scripts is passed to all scripts via the {SW_CONTROL_DIRECTORY} environment variable.

Script Guidelines

Some basic guidelines to writing control scripts:
  1. All scripts are executed serially and directly impact the total time required to complete an installation, configuration, or removal task. Consider the impact control scripts will have on performance.
  2. The current working directory in which the agent executes a control script is not defined. Use the environment variables provided by the agent for all pathname references.
  3. Disk space analysis does not account for files created, copied or removed by control scripts.
  4. The control scripts you write may be executed several times (for example, configure, then unconfigure, then configure...) so they must be able to support multiple executions.
  5. You may have to re-execute or debug control scripts, especially when they generate error or warning conditions, so your scripts should be well-written and commented.
  6. Control script stdout and stderr are both logged, so output should be restricted to only that information the user requires.

Control Script Format

The script should have a simple header similar to the example below. Included in the header should also be comment lines which state the product and fileset to which the script belongs, the name of the script, the revision string as required by the what(1) command, and a simple copyright statement.
     #! /sbin/sh
     ########
     # Product: 
     # Fileset: 
     # configure
     # @(#) $Revision: 10.0 $
     ########
     #
     # (c) Copyright MyCompany, 1996
     #
     ########

Script Environment

There are several environment variables that are available to the scripts during execution:
LANG
Determines the language in which messages are displayed. If LANG is not specified or is set to the empty string, a default value of "C" is used.

This variable applies to all SD commands except swcluster, swgettools, swpackage, and update.

Note that the language in which the SD agent and daemon log messages are displayed is set by the system configuration variable script, /etc/rc.config.d/LANG. For example, /etc/rc.config.d/LANG must be set to LANG=ja_JP.SJIS or LANG=ja_JP.eucJP to make the agent and daemon log messages display in Japanese.

SW_PATH
The search path for commands. A PATH variable defines the minimum set of commands available for use in a control script (for example, /sbin:/usr/bin:/usr/ccs/sbin).

A control script should always set its own PATH variable, and the PATH variable must begin with ${SW_PATH}. The PATH should be set as follows:

            PATH=${SW_PATH}
            export PATH
       
Additional directories, like /usr/local/bin, can be appended to PATH, but you must make sure that the commands in those directories exist.
SW_ROOT_DIRECTORY
Defines the root directory in which the session is operating, either "/" or an alternate root directory. This variable tells control scripts the root directory in which the products are installed. A script must use this directory as a prefix to SW_LOCATION to locate the product's installed files.

All control scripts (except for the configure and unconfigure scripts) can be executed during an install or remove task on an alternate root. If the scripts reference any product files, each reference must include the SW_ROOT_DIRECTORY in the file pathname.

The scripts may only need to perform actions when installing to (removing from) the primary root directory ("/"). If so, then the SW_ROOT_DIRECTORY can be used to cause a simple exit 0 when the task is operating in an alternate root directory:

            if test "${SW_ROOT_DIRECTORY}" != "/"
            then
                 exit 0
            fi
       
SW_LOCATION
Defines the location of the product, which may have been changed from the default product directory (if the product is locatable).

When installing to (or removing from) the primary root directory ("/"), this variable is the absolute path to the product directory. For operations on an alternate root directory, the variable must be prefixed by SW_ROOT_DIRECTORY to correctly reference product files.

If a product is not locatable, then the value of SW_LOCATION will always be the default product directory defined when the product is packaged.

SW_CONTROL_DIRECTORY
Defines the full pathname to the directory containing the script, either a temporary catalog directory, or a directory within in the Installed Products Database (IPD). This variable tells scripts where other control scripts for the software are located (for example, subscripts).

To source a subscript or reference a data file packaged along with a control script:

            . ${SW_CONTROL_DIRECTORY}subscript
            grep something ${SW_CONTROL_DIRECTORY}datafile
       
SW_INITIAL_INSTALL
This variable is normally unset. If it is set, the swinstall session is being run as the back end of an initial system software installation (that is, "cold" install).
SW_DEFERRED_KERNBLD
This variable is normally unset. If it is set, the actions necessary for preparing the system file /stand/system cannot be accomplished from within the postinstall scripts, but instead must be accomplished by the configure scripts. This occurs whenever software is installed to a directory other than /, such as for a cluster client system. This variable should be read only by the configure and postinstall scripts of a kernel fileset.
SW_KERNEL_PATH
The path to the kernel. The default value is /stand/vmunix.
SW_SYSTEM_FILE_PATH
The path to the kernel's system file. The default value is /stand/system.

Script Execution

Every command executed by a control script is a potential source of failure because the command may not exist on the target system. Your script can use any command conditionally, if it checks first for its existence and executability, and if it does not fail when the command is unavailable.
  1. If the target system(s) conform with the POSIX 1003.2 Shells and Utilities standard, then the Execution Environment Utilities of this standard will also be available.
  2. If a fileset has a prerequisite dependency on another product/fileset, then most of the control scripts for the dependent fileset can use the commands of the required product/fileset, if the ${ROOT_DIRECTORY} is /. (All commands perform their tasks in prerequisite order).
  3. Commands should be referenced relative to the path components specified in the PATH variable. (See the discussion of PATH and the SW_PATH environment variable above.)
In addition, input to and output from control scripts must be done carefully so as to minimize problems.
  1. Control scripts must not be interactive. This includes messages such as, Press return to continue. All control scripts are executed by the agent on the target systems. No method of input to control scripts is supported.
  2. Control scripts must write messages for error and warning conditions to stderr (echo &>2), and write all other messages to stdout. Control scripts must not write directly to /dev/console or attempt any other method of writing directly to the display.

    The stdout and stderr from a control script is redirected by the agent to the log file (var/adm/sw/swagent.log) within the primary or alternate root directory in which the task is being performed.

    For interactive swinstall and swremove sessions, you can display and browse this logfile.

  3. Only minimal, essential information should be emitted by control scripts. Ideally, no output is emitted if the script successfully performs all of its actions.
  4. In the agent logfile, the execution of each control script is prefaced by a "begin execution" message:
                   * Running "checkinstall" script for product "PRODUCT".
                   * Running "checkinstall" script for fileset "PRODUCT.FILESET".
           
    Any messages generated by the script will follow. If the script returns a value other than 0 (SUCCESS), then a concluding message is written:
                ERROR:   The "unconfigure" script for "PRODUCT.FILESET" failed (exit
                         code "1"). The script location was
                         "/var/adm/sw/products/PRODUCT/FILESET/unconfigure".
                       * This script had errors but the execution of this product
                         will still proceed.  Check the above output from the script
                         for further details.
                WARNING: The "unconfigure" script for "PRODUCT.FILESET" failed (exit
                         code "2"). The script location was
                                "/var/adm/sw/products/PRODUCT/FILESET/unconfigure".
                       * This script had warnings but the execution of this product
                         will still proceed.  Check the above output from the script
                         for further details.
           
  5. The messages written by a control script must conform to the following format conventions whenever possible.
    1. Never emit blank lines.
    2. All output lines must have one of these forms:
      	                      ERROR:     text 
                                    WARNING:   text 
                                    NOTE:      text 
                                               text
      	      
      In each case, the keyword must begin in column 1, and the text must begin in column 10 (indented nine blanks).
    3. Choose the keyword (ERROR, WARNING, NOTE, or blank) as follows:
      ERROR
      Something happened that must grab your attention. Cannot proceed, or need corrective action (to be taken later).
      WARNING
      Can continue, but it's important that you know something went wrong or requires attention.
      NOTE
      Something out of the ordinary or worth special attention; not just a status message.
      Generic progress and status messages (keep them to a necessary minimum).
      Do not start a line with an asterisk (*) character. This is reserved for operational messages printed by the agent so they can be easily distinguished from other messages.
    4. If the message text requires more than one, 72-character line, break it into several 72-character lines. Indent all lines after the first. For example:
      	      NOTE:    To install your new graphics package, it was necessary to turn
      	               on the lights in the next room. Please turn the
      	      
    5. Do not use tab characters in any messages.
  6. Scripts execute other commands which may unexpectedly fail and emit output not in the above format. Wherever you suspect a failure is possible or likely (and it is reasonable to do so) redirect the standard output or error of the executed command to </dev/null or to a temporary file. Then emit a proper-format message based on the return code or on output from the command. For example:
           if /bin/grep bletch /etc/bagel 2 &>/dev/null
           then echo "ERROR: Cannot find bletch in /etc/bagel." &>2
           fi
           
  7. The following conventions will help a control script's messages have a similar look and feel to the messages generated by the agent (and the commands themselves).
    1. Use full sentences wherever possible. Avoid terseness.
    2. Start sentences and phrases with a capital letter and end with a period.
    3. Put two blanks after a period; one after colons, semicolons, and commas.
    4. Uppercase first letters of phrases after colons. (This helps break up the message into digestible "bites" of information.)
    5. Surround product, fileset, directory, and file names, and other variable-valued strings with quotes. For example
      	      echo "ERROR:  Cannot open file \"$file\"." &>2
      	      
    6. Speak in present tense. Avoid "would", "will", and so forth. Also avoid past tense except where necessary.
    7. Use "cannot" rather than "can't", "could not", "couldn't", "unable to", "failed to", and similar phrases.

Control file generation

During package creation, when mkpkg is creating a product or fileset, it creates the sequence of control fragments for each control script by iterating through the work tickets. If a work ticket needs a control action in that script, then it will generate the fragment and return it. Otherwise it returns an empty string.

Control actions

I have built over three hundred software installation packages for a wide variety of public domain applications, such as database systems, editors, compilers, and games. These software packages vary widely in many ways, but they have only needed a few types of customization. I think the entire body of software that I have managed would need only those customizations that have already been automated by mkpkg.

I also was able to get a copy of all the control scripts written for all software shipped by Hewlett-Packard for HP-UX in Software Distributor. I examined nearly all of the control scripts, and I think that most of the customization actions needed by Hewlett-Packard are also included in this list.

The basic customization actions include: adding directories to the PATH files, adding new users or groups to the system, installing configuration files, inserting fragments to system files, removing obsolete files, adding a kernel driver or parameter, starting a daemon process, and adding cron actions.

Custom scripts

Since mkpkg only contains builtin customization detection and handling for a few common actions, mkpkg provides a mechanism for publishers to execute their own customization scripts. "Custom" scripts allows the user to specify that a given script will be executed as part of a given control script phase. The given script will be included in the package as a control script. Mkpkg will create a control script fragment which will execute the given script and retain the exit code.

PATH file components

In HP-UX 10.x, there are three files /etc/PATH, /etc/MANPATH, /etc/SHLIB_PATH which provide each user with default values for login shell environment variables. Any package that has its own tree would probably need to modify these files. For example, the new standard for independent software packages recommends that packages be installed under /opt/package/{bin,lib,etc,man,...}, so each package would require adding elements to each of the files. Fortunately, it is possible to automatically recognize that a fileset requires control script actions using filename pattern matching and file type checks.

Configuration file installation

In HP-UX 10.x configuration files should not be installed directly into place because end-user's may modify these files. In addition, in a network filesystem environment, a package may be installed on one machine into a shared directory, and then run by each of the other machines after "configuration". Consequently, the configure scripts need to copy configuration files into an unshared, per-machine location. By convention, configuration files are contained under the /etc/ tree, but they may be located in other locations. The system may only automatically detect configuration files in some cases, but packagers may specify additional files.

Since configuration files must be installed into a staging location, mkpkg will search for configuration files that are slated for installation directly into the configuration area, modify their installation location to the staging area, and create a customization work item. For files that have been slated for intsallation in the configuration staging area, mkpkg will create the customization work item to move the configuration file into place.

New users and groups

Some packages require that the software be installed with ownership by a package-specific user. For example, many database systems need to run as a specific user-id, and all of the database's files is owned by that user-id.

Mkpkg can generate the control script fragments that create and remove user-ids and group-ids.

In many cases, mkpkg can automatically detect that software requires a new user-id or group-id by examining the ownership of all files in the product or fileset. If the software has user or group ownership by any user-id or group-id that is not in the basic set of users and groups shipped with every system, then the software needs to create a new user-id or group-id.

System file modification

Some packages need to modify existing system files. There is a class of system files which contain system configuration information and which are relatively insensitive to the ordering or location of entries. For example, /etc/inetd.conf, contains a list of processes that should be started or stopped on entry and exit from various run-levels. Each entry is a single line, and the lines are position-insensitive.

Mkpkg can generate the control scripts that can add or remove a line (or lines) to such files. Mkpkg needs to know the file and the file fragment. During customization, the generated control scripts will check the file for the specified lines. If they are not present, then they are appended to the system file. Decustomization may need to remove those lines from the file.

Crontab entries

The cron system is used to execute scheduled and repetitive actions. Each user may have their own cron schedule. Cron uses a structured configuration file, called a crontab, to control its actions. The standard system file modification action would be sufficient for cron, except for the fact that the crontab should not be modified directly. One gets a copy of the current crontab file by executing "crontab -l" and then you can update the crontab by executing "crontab <crontab>" as the user whose cron schedule is being updated.

Removing obsolete files

Often machines are used for years before they are obsoleted, so customers install upgraded versions of software on top of old versions. In some cases, files that were present in an old version of the software are no longer needed, so the control scripts must remove these files.

Adding a kernel driver or parameter

Some packages need to add a kernel driver or parameter to the kernel configuration. This is rare, but very difficult to get right and very costly if something goes wrong.

Starting a daemon process

Some software contains daemon processes. In many cases, the packages modify one or more system files so the daemons will be restarted automatically after a reboot. However, it is often useful to start these daemon processes immediately, without requiring a reboot.
(C) Copyright 1994, 1995, 1996 Hewlett-Packard Company