Control Scripts
- Overview
- Scripts
- Guidelines
- Format
- Environment Variables
- Execution
- Control file generation
- Control actions
- Custom scripts
- PATH file components
- Configuration file installation
- New users and groups
- System file modification
- Crontab entries
- Removing obsolete files
- Adding a kernel driver or parameter
- Starting a daemon process
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:
- Checking to see if someone is actively using the product and, if
so, preventing reinstallation, update or removal.
- 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).
- Removing obsolete files or previously installed versions of the
product.
- Creating links to, or additional copies of, files after they have
been installed.
- Copying configurable files into place on first-time installation.
- Conditionally copying configurable files into place on later
updates.
- Modifying existing configuration files for new features.
- Rebuilding custom versions of configuration files.
- Creating device files or custom programs.
- 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.
- 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.
Some basic guidelines to writing control scripts:
- 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.
- 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.
- Disk space analysis does not account for files created, copied or
removed by control scripts.
- 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.
- 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.
- Control script stdout and stderr are both logged, so output should
be restricted to only that information the user requires.
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
#
########
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.
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.
- 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.
- 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).
- 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.
- 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.
- 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.
- Only minimal, essential information should be emitted by control
scripts. Ideally, no output is emitted if the script successfully
performs all of its actions.
- 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.
- The messages written by a control script must conform to the
following format conventions whenever possible.
- Never emit blank lines.
- 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).
- 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.
- 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
- Do not use tab characters in any messages.
- 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
- 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).
- Use full sentences wherever possible. Avoid terseness.
- Start sentences and phrases with a capital letter and end
with a period.
- Put two blanks after a period; one after colons,
semicolons, and commas.
- Uppercase first letters of phrases after colons. (This
helps break up the message into digestible "bites" of
information.)
- Surround product, fileset, directory, and file names, and
other variable-valued strings with quotes. For example
echo "ERROR: Cannot open file \"$file\"." &>2
- Speak in present tense. Avoid "would", "will", and so
forth. Also avoid past tense except where necessary.
- Use "cannot" rather than "can't", "could not", "couldn't",
"unable to", "failed to", and similar phrases.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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