This content is submitted by a BigAdmin user. It has not been reviewed for technical accuracy by Sun Microsystems, though it may have been lightly edited to improve readability. If you find an error or would like to comment on the article, please contact the submitter or use the comment field at the bottom of the article.
Community submissions may not follow Sun trademark guidelines. For information on Sun trademarks, please see http://www.sun.com/suntrademarks/.
Using the pkgman Utility to Manage Packages on Solaris Hosts
Derek Olsen, January 2008
Introduction
This tech tip describes pkgman, a package
management utility that can be used to maintain packages in a desired state on hosts that run the
Solaris 8, 9, or 10 Operating System for SPARC or x86 platforms. This tech tip
illustrates how to use pkgman by installing GTK+, a multi-platform toolkit for creating graphical
user interfaces, which is available from Sunfreeware.com.
Note: The examples in this document use the Solaris 10 OS.
Adding packages to or removing packages from a Solaris host is trivial. However, if you
have a large number of hosts running different versions of the Solaris OS
with unique package requirements, those tasks can be cumbersome.
What happens after the host has been jumpstarted and a request comes in to
install some additional software package? Do you have an authoritative
source you can check to see if you are already using that software somewhere?
Or does the resolution to the request depend on who responds to it? How will
you make sure the same version of the package instance is installed to
limit drift in your hosts' configuration? What if you need to roll upgrades of,
say, PostgreSQL through development, test, and production? Do you have a
documented procedure for doing that? Maybe you do, and I've been wasting my
time building pkgman.
From my experience as a Solaris administrator, I've
personally struggled with a graceful solution to the previous questions, and I have
met others with similar struggles. The problem with my prior approaches
to managing packages was the complexity involved with the solution. This led
to a situation where I was the only one who could easily roll out new
packages, upgrade packages, or recall packages. Obviously, I wanted to be able
to have a vacation or call in sick sometime, so I went back to the whiteboard.
The goal of this document is to demonstrate how to install and configure
pkgman to manage packages. Installing the GTK+ (2.12.0) package
from Sunfreeware.com is the core of our example. The GTK+
package installation is a nice, real-world example to give you an idea of whether
pkgman is something worth using in your shop.
Requirements for pkgman
We will start with the requirements of pkgman, because every shop has certain
parameters it needs to operate within.
Ruby version 1.8.X is required to run pkgman. (I plan to test against Ruby
1.9.X in January of 2008.)
The Solaris packages to be installed must be in data stream format.
The packages to be installed need to be available locally through HTTP.
Installing pkgman
If you have not been scared off by the requirements, let's move on to installing
pkgman:
Download the tarball marked "latest stable version" from the download list at
http://code.google.com/p/pkgman/downloads/list.
The name for the tarball is pkgman-<release number>.tar.gz.
Unpack the tarball. You end up with a directory called pkgman-<release number>.
Alternatively, you can use subversion to check out the pkgman repository. The
following command checks out the pkgman subversion repository into a
directory called pkgman:
Change directory to the root of the pkgman directory.
The setup script uses /usr/local
as the prefix for deploying pkgman. So
the executable goes into /usr/local/bin, and the configuration file goes into
/usr/local/etc. The setup script also changes the shebang line to match the
path to Ruby on your host.
ruby setup.rb
---> bin
<--- bin
---> conf
<--- conf
---> bin
<--- bin
---> conf
<--- conf
rm -f InstalledFiles
---> bin
mkdir -p /usr/local/bin/
install pkgman.rb /usr/local/bin/
<--- bin
---> conf
mkdir -p /usr/local/etc/
install pkgman.yaml /usr/local/etc/
<--- conf
If you wanted to install pkgman into a different directory you would do
something like the following. Here, I am changing the directory prefix from /usr/local
to my home directory:
ruby setup.rb all --prefix=$HOME
---> bin
<--- bin
---> conf
<--- conf
---> bin
<--- bin
---> conf
<--- conf
rm -f InstalledFiles
---> bin
mkdir -p /users/deet/bin/
install pkgman.rb /users/deet/bin/
<--- bin
---> conf
mkdir -p /users/deet/etc/
install pkgman.yaml /users/deet/etc/
<--- conf
Installing GTK+ Packages
Now that we have pkgman available at /usr/local/bin/pkgman.rb (or wherever
you put it), we can start to focus on the important work, which is installing
packages!
You'll want to determine which sunfreeware.com mirror is the best for you to use for downloading your packages. Check
the list of available mirrors.
To be considerate of bandwidth costs, you should download the packages to your local site and then make them available
locally through HTTP. As of this writing (December 2007), the software packages and versions you'll need to download to get GTKk+ running
are as follows:
Please keep in mind that these packages require the libgcc shared object. In this example,
I assume that the libgcc software is already installed.
If you need to install libgcc, you can add in the libgcc
package record after you see how the config file is set up.
After you have downloaded the required packages, you need to make them available through HTTP. Additionally,
the packages need to be decompressed because pkgman does not currently support compressed
packages. An enhancement request exists to track handling of compressed files.
To decompress the gzipped packages, you can run the following command in the directory where the gzipped packages
reside:
for f in `ls *gz`; do gunzip $f; done
Constructing the pkgman.yaml Configuration File
Now we are going to construct the pkgman.yaml configuration file.
I've stripped out the comments from the pkgman.yaml file that gets installed to
keep this section of the document from getting cluttered. The configuration
file contains the information about what packages should be installed or
removed as well the script settings. The script
settings consist of items such as the location of the packages and how to log
activities.
Here is what the pkgman.yaml file script settings section looks
like for my environment:
For most environments, all you need to change are the http_host,
http_port, and http_uri keys.
For example, if the URL that you use to browse the package repository at your site is
http://10.30.1.22/solaris/support/extras, then
your pkgman.yaml settings section would look like the following:
At this point, I am not going to delve too deep into the details of the
pkgman.yaml file, but you can find further information by reading the "CONFIG
FILE" section of the README file at http://pkgman.googlecode.com/svn/trunk/README.
Now that the settings section is complete, we need to construct the records for
each package we want to install. The information we need in order to construct an
install record is the package name, package version, file name, and which hosts
the record applies to.
Let's start with the atk software package. You can determine the package name by using
the pkginfo command. Here, I am querying the package file atk-1.18.0-sol10-sparc-local
to determine the package name and the package version:
You can also get the package version through the pkgparam command as follows:
[root@jumpstart /jumpstart/pkgs/sfw]$ pkgparam -f \
atk-1.18.0-sol10-sparc-local
VERSION
1.18.0
So now we know that the package name is SMCatk, the package version is
1.18.0, and the file name is atk-1.18.0-sol10-sparc-local. So
we will put this information into a package record in the pkgman.yaml file.
The install record for the SMCatk package would look like this:
We are going to use the value default for the hosts key. The
supported values for the hosts key are detailed in the
README file.
To tie the settings section and the package record together, let's look at
what our current pkgman.yaml file looks like.
In plain English, the following pkgman.yaml file indicates that the software package
SMCatk version 1.18.0 should be installed on all hosts that run pkgman.
The package file name is atk-1.18.0-sol10-sparc-local, and it's available for download from
http://jumpstart:1080/jumpstart/pkgs/sfw/atk-1.18.0-sol10-sparc-local.
Additionally, all output would be logged by syslog using the priority daemon.notice.
If logging is configured to "syslog," logs will go only to syslog, and nothing will be sent to your terminal.
Now we need to add the remaining packages to the pkgman.yaml file.
Why don't you pick a package or two, construct the package records, and then
compare your results to what I have in the following complete pkgman.yaml
file? The order of the packages is unimportant because all the content ends up as an unsorted array.
So now that we have pkgman installed and an initial configuration file set up, let's
see what we can do.
First, let me cover the pkgman command-line options and what they mean.
[root@jtest ~]$ which pkgman
/usr/local/bin/pkgman
[root@jtest ~]$ pkgman
Usage: /usr/local/bin/pkgman [ -n ] -f pkgman.yaml
-f [ /path/to/pkgman.yaml | http://server/path/to/pkgman.yaml ]
-n Just print what would happen without making any changes
-h print usage and exit
The -n argument is optional and indicates that you want to run pkgman in
dry-run mode. In dry-run mode, no changes are made to the system. You can
use dry-run mode to see what packages would be installed or removed from a
host before you run pkgman for real.
The -f argument is required and is followed by the location of the
pkgman.yaml file. The file can be on the local file system or available through HTTP.
Some sites don't use cfengine or a similar tool to push out files to
their hosts, so I thought having the pkgman.yaml file available through HTTP would
be useful.
Now let's actually run pkgman and point it to our configuration
file. Whooo!
In this first example I'm going to run pkgman in dry-run mode. I'm using
the default logging configuration, which ends up sending everything to /var/adm/messages.
We can see that all of our desired packages are flagged as needing to be installed.
So in this example, let's go ahead and do the actual installations by
running pkgman without the dry-run flag. From the logging output,
everything looks like it was done correctly.
[root@jtest /]$ pkgman -f \
http://jumpstart:1080/jumpstart/pkgs/sfw/pkgman.yaml
[root@jtest ~]$ tail -16 /var/adm/messages
Dec 11 17:33:40 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCatk> was successful.
Dec 11 17:33:44 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCcairo> was successful.
Dec 11 17:33:45 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCexpat> was successful.
Dec 11 17:33:51 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCfontc> was successful.
Dec 11 17:33:54 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCftype> was successful.
Dec 11 17:34:08 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCglib> was successful.
Dec 11 17:35:00 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCgtk> was successful.
Dec 11 17:35:02 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCjpeg> was successful.
Dec 11 17:35:04 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCliconv> was successful.
Dec 11 17:35:06 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMClibpng> was successful.
Dec 11 17:35:12 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCpango> was successful.
Dec 11 17:35:13 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCrender> was successful.
Dec 11 17:35:14 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCrenpro> was successful.
Dec 11 17:35:19 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCtiff> was successful.
Dec 11 17:35:21 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCxrend> was successful.
Dec 11 17:35:23 jtest pkgman[10494]: [ID 702911 daemon.notice] \
Installation of <SMCzlib> was successful.
Let's run pkgman one more time in dry-run mode just to see what happens.
This time I'm changing the "logging" entry in the pkgman.yaml file.
The line previously read :logging: syslog. Now it reads :logging: console.
So if any work needs to be done, that will be reported to the terminal.
Nothing was reported because the desired packages are already installed.
However, for the doubters in the crowd, we will double-check the package
database to make sure the packages actually got installed.
Well, everything appears to be in place here. Now we have a host with GTK+
and the required, dependent packages installed.
Now you should be able to repeat the package installations easily on any other hosts that you want to
install GTK+ on.
JumpStart Postinstallation Script
The following portion of my JumpStart (using Flash archives) postinstallation script
demonstrates how I have integrated pkgman into JumpStart.
I said that I just install the desired OS cluster with JumpStart, but that's not totally
true, because I add the Ruby package to the OS before creating my Flash archive.
I run pkgman after the installation reboot is complete, because not all
packages have been created to honor an alternate root installation. Hard-coded paths in preinstallation or
postinstallation scripts might not work.
Additionally, I do some other setup work in the postinstallation script, so it is the logical place for me
to include the pkgman execution. During a Flash installation, any scripts located
in /etc/flash/reboot are executed during the first boot. The process removes
the reboot directory and its contents after script execution, which is nicer than creating temporary init scripts.
Once the initial post-JumpStart pkgman execution is complete, future
executions of pkgman are triggered by cfengine. I have cfengine configured
to execute pkgman if a certain trigger file exists on the host
(/etc/.run_pkgman).
When I have to deploy package modifications, the
destination hosts tend to line up with my cfengine groups. For example, when
I want to push out the GTK+ packages to the Solaris workstations, I use cfengine
to touch the trigger file on all the hosts in my cfengine "workstations" group.
Here is the snippet of my cfengine file that controls the execution of
pkgman:
I use a dedicated cfengine file for one-time jobs, such as touching trigger
files. To trigger pkgman on all the workstations, I would add the following to the
cfengine file used for one-time jobs. Remember to delete the job after you've pushed
out the cfengine changes.
That pretty much wraps up our whirlwind tour of pkgman. Our goal was to
install the GTK+ packages from sunfreeware.com, which we accomplished.
I hope that through this example, I have provided enough information for you to
determine if pkgman is worth further investigation. Please consult the
README file for further
information.
If you have any additional comments or questions please drop me a line at
someword [at] gmail.com!
Thanks for your time...
About the Author
Derek is a long-time UNIX/Linux system administrator. Over the years,
he has developed a special fascination for custom JumpStart installations, package management, and configuration management. He lives and works in Portland, Oregon (USA) and spends his free time mucking about with the Solaris OS, drinking beer, and convincing himself that he is in charge of his dog, not the other way around.
Discuss and comment on this resource in the BigAdmin Wiki
Unless otherwise licensed, code in all technical manuals herein (including articles, FAQs, samples) is provided under this License.