Advanced Administration with the Image Packaging System (IPS) on Oracle Solaris 11

November 2011

by Glynn Foster

Take a deeper look at advanced IPS to learn how to determine package dependencies, explore manifests, perform advanced searches, and analyze the state of your system.


Oracle Solaris 11 takes a new approach to lifecycle and package management to greatly simplify the process of managing system software helping to reduce the risk of operating system maintenance, including reducing unplanned and planned downtime. With Image Packaging System (IPS), administrators can install and update software from locally connected or remote software package repositories using a much-improved and modernized process.

If you'd like to download software, participate in forums, and get access to other technical how-to goodies in addition to content like this, become an OTN member. No spam!

In another article, Introducing the Basics of Image Packaging System (IPS) on Oracle Solaris 11, we covered the basics of administration including how to install and uninstall packages, how to discover basic information about packages installed on the system and in the repository, and how to update a system.

This article covers advanced topics for using IPS, including detailing different package dependencies, exploring package manifests, using advanced search queries, browsing logs, and recovering from unexpected events. To learn more about IPS, check out a variety of content at the IPS Technology Spotlight page on Oracle Technology Network. Also see the Oracle Solaris 11 Cheat Sheet for Image Packaging System.

Understanding Package Dependencies

In many cases, one software package depends on another package. For example, one package might require functionality that is in a second package in order to function or install correctly. These relationships, or dependencies, between packages are important for automating package installation operations and for upgrading system software to known and well-tested states. IPS supports a number of different relationships between packages, some of which are listed in Table 1.

Table 1. Package Relationships
Dependency Description
require This dependency is required. A package cannot be installed if any of its required dependencies cannot be satisfied.
optional If this dependency is present on the system already then it must be at a specified version level or greater.
exclude This dependency enforces a restriction such that a package cannot be installed if the specified package is present at the specified version level or greater.
incorporate This dependency is optional, but the version range has both a lower and an upper bound, allowing only further dot-separated integers to be added to the existing sequences.
conditional This dependency is required only if another predicate package is installed on the system. This is often used to allow packages to provide support for features (such as X11 or language bindings) only if the features are already present on the system.
group This dependency is required unless the package is on the avoid list, in which case, the system will try to avoid installing this package. However, if another package requires this dependency, it will be installed regardless of whether it is on the avoid list.
parent This dependency is used to ensure that global zones and non-global zones are kept in sync for all kernel components and any software that spans the zone boundary.

Let's take a look at how these relationships are expressed by IPS by looking at how packages are described in what's known as a package manifest.

Exploring Package Manifests

A package manifest describes how a package is assembled and provides basic information about the package (such as the name, version, description, categorization, and so on), what files the package includes, and what other packages or services the package relies on to meet its dependencies. While many package commands filter this information into a presentable form, it is sometimes useful to look at the package manifest directly using the pkg contents -m command, as shown in Listing 1.

Listing 1: Looking at the Package Manifest
# pkg contents -m gzip
set name=pkg.summary value="GNU Zip (gzip)"
set name=pkg.description value="The GNU Zip (gzip) compression utility"
set name=variant.arch value=i386 value=sparc
set name=info.classification \
value="org.opensolaris.category.2008:Applications/System Utilities"
set name=info.source_url value=http://alpha.gnu.org/gnu/gzip/gzip-1.3.5.tar.gz
set name=opensolaris.arc_url value=http://arc.opensolaris.org/caselog/PSARC/2008/488
license 91533ecafdca90d38563499351a030e497bc9dae \
chash=33000d74d113ed003308b6b2c6f6565597517ab8 license=SUNWgzip.copyright \
pkg.csize=657 pkg.size=1278
set name=org.opensolaris.consolidation value=userland
set name=info.upstream_url value=http://directory.fsf.org/GNU/gzip.html
depend fmri=pkg:/system/library@0.5.11-0.75.0.0.0.0.0 type=require
depend fmri=pkg:/shell/bash@4.1.9-0.175.0.0.0.525 type=require
dir group=sys mode=0755 owner=root path=usr
dir group=sys mode=0755 owner=root path=usr/bin
dir group=sys mode=0755 owner=root path=usr/share
dir facet.doc.info=true group=bin mode=0755 owner=root path=usr/share/info
dir facet.doc.man=true group=bin mode=0755 owner=root path=usr/share/man
dir facet.doc.man=true group=bin mode=0755 owner=root path=usr/share/man/man1
file c62b206499c0a4d8d001ba11535bca174b560e0d \
chash=3ed74ac7fa132f4ae5a708693d01836a157e3157 group=bin mode=0555 \
owner=root path=usr/bin/gzdiff pkg.csize=843 pkg.size=1983
file 3dd5f1cc40a1f4905f38de0e63c8014d4859bafc \
chash=265d006e043a0e1be102dd657d9d948e35389d24 group=bin mode=0555 \
owner=root path=usr/bin/gzgrep pkg.csize=1286 pkg.size=2953
file 146b8d4d51585df4af0f119e42e9ab6640aa4e97 \
chash=2261abcd4128f9a37757925583db89d2cf86caa8 elfarch=sparc \
elfbits=32 elfhash=da755339ab13a8e0ee46e645360674fac22c821c \
group=bin mode=0555 owner=root path=usr/bin/gzip pkg.csize=40521 \
pkg.size=67840 variant.arch=sparc
file 3040df3097d8301929cc5d784006e06a8403a611 \
chash=d89a6fc5dc477dd3d746da4fd42d332181a57b3e elfarch=i386 \
elfbits=32 elfhash=e104a125d6921a36ad6e8df471c772da28a2fa34 \
group=bin mode=0555 owner=root path=usr/bin/gzip pkg.csize=34020 \
pkg.size=71696 variant.arch=i386
....

Each line within the manifest is called an action. Actions describe a small part of the overall package. The first part of each line describes the action type: set, license, depend, dir, file, and so on. Midway down the manifest, we can see how package dependencies are expressed. In this case, the package has two dependencies: one for pkg:/shell/bash and one for pkg:/system/library, as shown below.

depend fmri=pkg:/shell/bash@4.1.9-0.175.0.0.0.525 type=require
depend fmri=pkg:/system/library@0.5.11-0.75.0.0.0.0.0 type=require

Notice that we include two versions of the /usr/bin/gzip binary executable for different architectures, SPARC and x86, as shown in Listing 2.

Listing 2: Specifying SPARC and x86 Binary Executables in the Package Manifest
file 146b8d4d51585df4af0f119e42e9ab6640aa4e97 \
chash=2261abcd4128f9a37757925583db89d2cf86caa8 elfarch=sparc \
elfbits=32 elfhash=da755339ab13a8e0ee46e645360674fac22c821c \
group=bin mode=0555 owner=root path=usr/bin/gzip pkg.csize=40521 \
pkg.size=67840 variant.arch=sparc
file 3040df3097d8301929cc5d784006e06a8403a611 \
chash=d89a6fc5dc477dd3d746da4fd42d332181a57b3e elfarch=i386 \
elfbits=32 elfhash=e104a125d6921a36ad6e8df471c772da28a2fa34 \
group=bin mode=0555 owner=root path=usr/bin/gzip pkg.csize=34020 \
pkg.size=71696 variant.arch=i386

The ability to include support for different architectures in a single package is a key IPS feature called variants. Depending on your system architecture, IPS will know which version to install on your system. From a development and administration point of view, this feature drastically reduces the work needed to maintain separate software packages and keep them in sync, and it lowers the cost of storage since you need only one version of the architecture-independent portion of the package. More details about package manifests and how they are created are covered in another article, How to Create and Publish Packages to an IPS Repository on Oracle Solaris 11.

Now that we've had a quick look at package manifests, let's look at some complicated search examples.

Advanced Searching

The pkg contents and pkg search commands are used to view and search for package content. These two commands are related and can be used to provide similar information, especially when piped to other commands for filtering.

Quite often, before you install a package, it's useful to see what packages will be installed due to dependency relationships specified in the package you plan to install. Let's look at a concrete example using the pkg contents command. We will use the -r option to give us results from the remote repository, since we want to query uninstalled packages rather than installed packages.

# pkg contents -r -o fmri,type -t depend php-52
FMRI                                                     TYPE
pkg:/compress/bzip2@1.0.6-0.175.0.0.0.525                require
pkg:/image/library/libjpeg@6.0.2-0.175.0.0.0.0.0         require
pkg:/image/library/libpng@1.4.8-0.175.0.0.0.0.0          require
pkg:/library/libxml2@2.7.6-0.175.0.0.0.0.525             require
pkg:/library/libxslt@1.1.26-0.175-0.0.0.0.525            require
....

The output shows a list of packages that PHP depends on (installed or not installed) in the first column, represented by the value of the fmri attribute from the package manifest, and a list of the dependency types in the second column, represented by the value of the type attribute from the package manifest.

In this case, we get a list of all dependencies that are required in order to successfully install this package. Also note that we used the -r flag to enable a query on the repository rather than to query locally, since we do not yet have the PHP package installed on the system. A similar output can be displayed using pkg search, as follows:

# pkg search -o search.match,search.match_type 'web/php-52@:depend::'
SEARCH.MATCH                                             SEARCH.MATCH_TYPE
pkg:/compress/bzip2@1.0.6-0.175.0.0.0.525                require
pkg:/image/library/libjpeg@6.0.2-0.175.0.0.0.0.0         require
pkg:/image/library/libpng@1.4.8-0.175.0.0.0.0.0          require
pkg:/library/libxml2@2.7.6-0.175.0.0.0.0.525             require
pkg:/library/libxslt@1.1.26-0.175-0.0.0.0.525            require
....

The pkg contents and pkg search commands are related; both are used to query the system for the contents of packages. The contents command displays actions in one or more packages, filtering the output based on the options you chose. The search command approaches the query from the other direction, looking for packages that contain a user-supplied token.

In the first column of this example (represented by the search package name match), we have a list of packages, and in the second column (represented by the match type), we have a list of dependency types.

The search command uses a field or structured query that takes the form of pkg_name:action_type:key:token. In this case, we use web/php-52@ as the package name since we want to search for pkg:/web/php-52 and not other matches, for example, pkg:/web/php-52/extensions/php-pear. The action_type in this case is depend.

We leave the other two fields blank, because we want to search for all dependencies. If we wanted to be more specific, we could specify require as our key and set *zlib as our token, for example, to determine whether pkg:/web/php-52 has a required dependency on pkg:/library/zlib (which it does).

As another example, let's do the reverse and see what installed packages depend on pkg:/library/libxml2 with a required dependency. Let's continue to use the pkg search command, as shown in Listing 3.

Listing 3: Using Search to Determine Dependencies for Installed Packages
# pkg search -l -o pkg.name 'depend:require:library/libxml2'
PKG.NAME
system/library/libdbus-glib
system/zones
desktop/calculator/gcalctool
system/library
library/gnome/gnome-libs
desktop/system-monitor/gnome-system-monitor
SUNWcs
desktop/xscreensaver
desktop/compiz/library/libcompizconfig
....

In this example, we use the -l flag to search for installed packages. Many more searches are possible with IPS, and they can be referenced in the man pages or formal documentation.

Analyzing the State of your System

If something unexpected happens, it might be necessary to analyze the state of your system a little further. There are three additional IPS commands that allow you to check a history log of all package operations performed on a given system, check the validity of a package or set of packages installed on a system and, if there are problems, fix them.

To check the history log of all package operations, use the pkg history command, as shown in Listing 4.

Listing 4: Checking the History Log of All Package Operations
# pkg history
START               OPERATION              CLIENT          OUTCOME
2011-05-23T00:48:32 set-property           transfer module Succeeded
2011-05-23T00:48:32 add-publisher          transfer module Succeeded
2011-05-23T00:48:32 refresh-publishers     transfer module Succeeded
2011-05-23T00:48:32 image-create           transfer module Succeeded
2011-05-23T00:48:45 rebuild-image-catalogs transfer module Succeeded
2011-05-23T00:48:55 set-property           transfer module Succeeded
2011-05-23T00:48:55 install                transfer module Succeeded
2011-05-23T00:02:39 uninstall              transfer module Succeeded
2011-05-23T01:02:39 update-publisher       transfer module Succeeded
2011-05-30T23:11:36 install                pkg             Succeeded
2011-05-31T00:11:01 refresh-publishers     pkg             Succeeded
2011-05-31T00:11:01 install                pkg             Failed
....

In the output, the order is by date, and the output lists the operation that was done and who called the operation (in this case, transfer module is during the installation of this system and pkg is the command line client). Additionally, we can easily search through the history using a set of date stamps (in this case, all package commands between October 1, 2011 and October 18, 2011), as follows:

# pkg history -t 2011-10-01T00:00:00-2011-10-18T00:00:00
START               OPERATION              CLIENT          OUTCOME
2011-10-04T02:24:53 update                 pkg             Succeeded
2011-10-04T02:24:54 refresh-publisher      pkg             Succeeded
2011-10-04T02:25:55 rebuild-image-catalogs pkg             Succeeded
2011-10-04T05:13:47 add-publisher          pkg             Succeeded
....
2011-10-16T20:45:23 update                 pkg             Succeeded
2011-10-16T20:45:53 rebuild-image-catalogs pkg             Succeeded

It is also possible to output some different column headers using pkg history - o including, among other options, the time it took for the packaging operation to complete, what boot environment it was applied to, and the user who started the operation.

# pkg history -o user,be,time,command -t 2011-10-01T00:00:00-2011-10-18T00:00:00
USER   BE        TIME      COMMAND
root   solaris   1:04:51   /usr/bin/pkg update
root   solaris   0:01:13   /usr/bin/pkg update
root   solaris   0:00:12   /usr/bin/pkg update
root   solaris-1 0:00:16   /usr/bin/pkg unset-publisher myrepo
root   solaris-1 0:03:47   /usr/bin/pkg install wireshark
root   solaris-1 0:00:02   /usr/bin/pkg refresh
....

While ZFS snapshots and clones are a great way to recover from errors in the system, IPS also provides the facility to validate the installation of packages on a system. Using the pkg verify command, you can check a specific package or groups of packages:

# pkg verify -v gzip
Verifying: PACKAGE                STATUS
pkg://solaris/compress/gzip       OK

In this case, we use the -v flag to get more information on the command line. If the -v flag is not used, there is no output if the packages are validated successfully.

As an example, let's deliberately make some modifications to /usr/bin/gzip by writing 1024 bytes on top of it and try the verification process again:

# mkfile 1024 /usr/bin/gzip
# pkg verify -v gzip
Verifying: PACKAGE                STATUS
pkg://solaris/compress/gzip       ERROR
	file: usr/bin/gzip
		Mode: 01600 should be 0555
		Unexpected Exception: Request error: class file/memory mismatch

IPS detected an incorrect permission on the file /usr/bin/gzip and raised an exception due to not being able to validly check the ELF headers for the binary executable. Fortunately for us, we can quickly fix the problem using the pkg fix command, as shown in Listing 5.

Listing 5: Fixing a Package Problem
# pkg fix gzip
Verifying: PACKAGE				ERROR
	file: usr/bin/gzip
		Mode: 01600 should be 0555
		Unexpected Exception: Request error: class file/memory mismatch
Created ZFS snapshot: 2011-06-30-05:24:15
Repairing: pkg//solaris/compress/gzip

DOWNLOAD				PKGS	FILES	XFER (MB)
Completed				 1/1  324/314   0.0/0.0

PHASE							ACTIONS
Update Phase						    3/3

PHASE							  ITEMS
Image State Update Phase				    2/2

As shown in the output, IPS quickly downloads the appropriate content and repairs the package. In this case, since the content was cached on the system, IPS did not have to download anything.

Summary

The Oracle Solaris 11 Image Packaging System is a major advancement in software management providing an integrated user experience and improved safety for system updates. IPS takes much of the complexity out of managing Oracle Solaris by providing improved automation and auditing, allowing administrators to flexibly manage multiple application environments across virtualized and non-virtualized instances of the operating system.

For More Information

Here are some additional resources:

Revision 1.0, 11/02/2011