Cover V12, I06

Article
Figure 1
Listing 1
Listing 2
Listing 3
Listing 4

jun2003.tar

Lppbuild -- AIX Package Creation

Charles Ritter

Systems administrators are familiar with configure; make; make install. This is the final step in the software installation process for most open source and in-house projects. But when you are managing software on more than a few servers, a better solution is in order. Binary installation packages provide that solution. Unlike other UNIX variants, AIX defines a package format and includes an installation tool but does not include a package creation tool with the base operating system. Fortunately, some options are available on the Internet, and one of which is lppbuild.

Lppbuild, written by Jim Abbey, is a series of Korn shell scripts and awk programs. The current version is 2.1, and it can be downloaded for free at:

http://www.bullfreeware.com
Using the lppbuild tool itself is very simple. Once you create a properly structured destination directory, just cd /package/directory; lppbuild. A new package will appear like magic. The trick, of course, is to create the proper directories with valid, usable scripts and control data.

We'll use gnut, a command-line oriented Gnutella network program, as an example throughout this article. Gnut discovers other nodes in the network, then shares and retrieves files based on search criteria specified by network users. Gnut has command-line options to run as a daemon unassociated with a terminal and to read configuration data from a start-up script (which is useful for operating a full-time gnutella filesharing node). To demonstrate advanced AIX package features, we will add gnut to the System Resource Controller (SRC) and into the System Management Interface Tool (SMIT) top-level menu.

LPP Format

Before looking at lppbuild in more detail, let's review the Licensed Product Package (LPP) format as defined by IBM. (LPP is the format of the package file; installp is the tool used to install LPP packages. This sometimes causes confusion.) Packages are dump-formatted archives that include: 1) all of the files capable of being installed by the package, 2) a file named lpp_name, and 3) at least one liblpp.a archive.

Packages are divided into filesets, the smallest installable unit in a package. The name of the package and its filesets are defined in lpp_name. (The name of the file containing the package archive is irrelevant.) Common fileset divisions include rte (run-time environment), adt (application development tools), and doc (documentation). Formalities such as these are common with IBM-based operating system packages. They are less common with free software packages or applications distributed by other vendors.

The lpp_name file also defines the fileset version and whether it is an "install" or "update". Note that "update" filesets apply changes but automatically keep earlier versions, which allows for quick rollback to a known application state. Space is allocated in the filesystem based on other information in lpp_name; it defines a fileset as "root", "usr", or "share" depending on where in the filesystem its files are installed.

There is one liblpp.a per fileset. The liblpp.a file contains all other control files used by a fileset. Here is a description of the important ones:

aix adm.gnut.rte.al -- The apply list controls which files in the package archive are associated with the fileset.

aix adm.gnut.rte.copyright -- The fileset copywrite information (required).

aix adm.gnut.rte.inventory -- Contains vital product data about files in the fileset (required).

aixadm.gnut.rte.odmadd -- Data for the ODM database. Commonly used for SMIT menu data.

aixadm.gnut.rte.unodmadd -- Undoes the work of odmadd. It is called at fileset de-installation.

aixadm.gnut.rte.post_i -- A post-installation script. It is called at fileset de-installation.

aixadm.gnut.rte.unpost_i -- Undoes the work of post_i. It is called at fileset de-installation.

My example is a package named aixadm.gnut with one "usr" fileset named aixadm.gnut.rte. Listing 1 shows the contents of the aixadm.gnut package. In the next section, we will build this same package.

Restoring the contents of existing packages and reviewing their contents is useful in identifying bugs. It is also a good source of code that will help familiarize you with common package idioms. Read the IBM documentation included with your operating system for information about all of the optional control files. The lppbuild README is another well-written guide to package options.

Package Resources Examples

Building a package begins by creating the data files that lppbuild will use to create the end product and then putting them in an install destination directory hierarchy (sometimes referred to as a "fakeroot"). The destination directory structure is shown here:

aixadm.gnut/
aixadm.gnut/copyright
aixadm.gnut/rte/
aixadm.gnut/rte/root/
aixadm.gnut/rte/control
aixadm.gnut/rte/post_i
aixadm.gnut/rte/unpost_i
aixadm.gnut/rte/odmadd
aixadm.gnut/rte/unodmadd
aixadm.gnut/rte/requisites
The top-level directory is the name of the package (aixadm.gnut), the second-level directories are the short name of the filesets (rte), and the third-level directory is the "fakeroot". The copyright file goes in the top-level directory (which implies that the same license file applies to all filesets), and all other control files are located in the second-level. The application files are installed in the ./root destination directory.

The "control" file here shows the mandatory version number and description fields, and an optional value for INSTWORK:

VERSION=0.4.0.0
DESCRIPTION="Gnut, Gnutella Network Node v0.4.28"
INSTWORK="10 10"
The version number must be of the form version.release.maintenance.fix (vrmf), as defined by IBM. Install packages (as opposed to updates) must have zeros for maintenance and fix, or lppbuild will fail. The base-level fileset is automatically required. INSTWORK tells installp how much space to allocate in the package directory for the liblpp.a archive.

The "post_i" file shown in Listing 2 will run after the fileset has been installed. It first adds the user and group "gnut", and then adds gnut to the SRC with mkssys, carefully reporting the exit status. The exit status is checked by installp and determines whether to continue or rollback. It is not uncommon for packages to perform more host customization here based on system environment details.

The "odmadd" file in Listing 3 contains the stanzas necessary to add gnut start and stop menus to SMIT. In this example, the top-level gnut menu will appear in the top-level SMIT menu. Sub-menus under "Gnut - Gnutella Server" will display "Stop Gnut Server" and "Start Gnut Server". This is just an example, but you can imagine it might be nice to add options like "Show Server Status", "Add/Remove a Share", or "Display Server Statistics". It is also possible to add menu aliases, so the detail items appear in multiple menu hierarchies, and "fast paths" to speed menu navigation. In a production environment, menu-based configuration aids in training inexperienced operations staff.

The unpost_i and unodmadd files are used to reverse these actions upon de-installation or installation failure.

Generated Files

Missing from the destination directory are the lpp_name, al, and inventory files. These are built automatically by lppbuild. Lppbuild also converts control files from their short names into the long names. This is a big time saver, but there are a two points to note. First, if a package file is installed with write permission enabled, lppbuild will treat it as a configuration file, and no checksum will be generated in the inventory file. This defeats a nice security feature of AIX (lppchk -c will check for file modifications if the inventory file designate is NONVOLITILE). Second, in the case of an update package, lppbuild has no way to estimate the space required to save files from the base package or previous updates. This information is used to automatically resize the filesystems if necessary. If a package requires more space than is available the installation could fail.

Building the Package

Once the destination directory is ready, we can install the application there and build the package. Listing 4 shows the steps to follow. To begin, let's define the target package directory. We refer to this location frequently. Since we intend to run a gnut share, it is necessary to include the files and directories to manage it. When the SRC starts gnut, it expects these to exist.

After following the standard compile routine, install to the special destination directory. How this is accomplished depends on the Makefile. Sometimes DESTDIR is defined; sometimes it is not. If an application doesn't provide a clean method to change the installation directory, you may need to write your own. In this case, Gnut does not provide a method to install man pages or the HTML documentation. So before building the package, simply copy the files into the destination doc directory.

A Caution

Be careful when creating the destination directory. Once installed, all files and directories in the fileset inventory will overwrite existing files and directories of the same name. The root directory is always overwritten, and /usr, /usr/lib, /etc are often overwritten. The permissions on these are important to the security and usability of the system. Make sure the destination directory ownership and permissions are correct before building the package.

Installation

The package is installed by creating a .toc file and running installp. The .toc is created with inutoc ., assuming the package file is in the current directory. Then installp -qaX -d . aixadm.gnut.rte will install it. Figure 1 shows the modified SMIT top-level menu after package installation, with Gnut added.

Conclusion

As computer environments become more complex, package management tools are becoming increasingly useful in systems administration. Packages are useful for managing installation uniformity in a distributed environment. In a production environment, with separate development and operations staff, they reduce the cost of training and operation and help reduce the number of errors made while configuring the software. In the case of AIX, packages also have built-in security features that can identify tampering of system binaries. llpbuild is a useful tool for creating binary installation packages in AIX's LPP package format.

Resources

lppbuild README

General Programming Concepts: Writing and Debugging Programs -- Chapter 20: "Packaging software for installation".

General Programming Concepts: Writing and Debugging Programs -- Chapter 25: "System Management Interface Tool".

http://www.bullfreeware.com -- A freeware package site

http://gnutelliums.com -- A Gnutella portal

Charles Ritter is a UNIX systems administrator who specializes in AIX. He has eight years of enterprise experience, and has consulted for Fortune 500 companies and several major systems vendors. Charles may be reached at: critter@aixadm.org.