by Glynn Foster
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.
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.
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
| ||This dependency is required. A package cannot be installed if any of its required dependencies cannot be satisfied.|
| ||If this dependency is present on the system already then it must be at a specified version level or greater.|
| ||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.|
| ||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.|
| ||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.|
| ||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.|
| ||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.
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.
# 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:/firstname.lastname@example.org type=require depend fmri=pkg:/email@example.com 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:
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:/firstname.lastname@example.org type=require depend fmri=pkg:/email@example.com 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.
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.
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:/firstname.lastname@example.org require pkg:/email@example.com require pkg:/firstname.lastname@example.org require pkg:/email@example.com require pkg:/firstname.lastname@example.org 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:/email@example.com require pkg:/firstname.lastname@example.org require pkg:/email@example.com require pkg:/firstname.lastname@example.org require pkg:/email@example.com require ....
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.
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,
action_type in this case is
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.
# 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.
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.
# 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.
# 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.
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.
Here are some additional resources:
|Revision 1.0, 11/02/2011|