OpenSolaris Home Server Scripting 3: Managing Package Repositories

Package Scripting

OpenSolaris OS comes with the Image Packaging System (IPS) for managing installation and additional software. By default, it is configured to pull packages from the /release repository, but of course there are many other interesting repositories with software to install from.

Chris Gerhard recommends adding at least the /extras repository (free, registration required) so you can easily install VirtualBox, Adobe Flash, TrueType Fonts etc.

If you have a support contract or are an Oracle/Sun employee, you may want to switch your preferred repository to the supported one. The more adventurous may want to switch to the development repository.

Then, the Software Porting Community on has a hierarchical system for making open source software available on OpenSolaris through two repositories: /pending and /contrib.

And then there are a couple of more repositories from user groups, private people, companies offering commercial packages and so on.

One way to register package repositories with the IPS on your home server is by using the package management GUI, or by using the pkg(1) command (See also: "How to Add or Update a Publisher").

But of course we want to stick to our "Script Everything" philosophy and write ourselves a small script that takes care of all of our package configuration needs.

Scripting Package Configuration

We'll use a simple configuration file that contains all the parameters necessary for configuring our favorite package repositories, one line per repository.

For each repository, we'll need:

  • Its URL for pkg(1) to pull packages from.
  • A name for the repository.
  • An optional certificate file and a key file for repositories that want them (We'll just store the base name and assume they'll end with key.pem or .certificate.pem).
  • An optional flag that indicates whether we want this repository to be our preferred one.

To keep things nice and simple, we'll separate the fields with spaces and add a few comments for documentation. Here's an example, taken from my current home server configuration:

admin@krengi:/krongi/config/pkg$ more pkg.config 
# Package configuration
# Fields are separated by a space.
# Fields: URL publishername preferred keyfile
# "preferred" is either empty or not.
# Keyfile is the basename of the key/certificate name standardsupport OpenSolaris_standard_support preferred contrib extras OpenSolaris_extras hacluster Open_HA_Cluster_2009.06

Certificate and key files are stored together with our configuration file in the same directory:

admin@krengi:/krongi/config/pkg$ ls -al
total 14
drwxr-xr-x 2 admin staff   9 2010-03-20 14:48 .
drwxr-xr-x 6 admin staff   6 2010-03-05 13:49 ..
-rw-r--r-- 1 admin staff 758 2010-03-20 14:40 Open_HA_Cluster_2009.06.certificate.pem
-rw-r--r-- 1 admin staff 888 2010-03-20 14:41 Open_HA_Cluster_2009.06.key.pem
-rw-r--r-- 1 admin staff 750 2010-03-20 14:41 OpenSolaris_extras.certificate.pem
-rw-r--r-- 1 admin staff 888 2010-03-20 14:41 OpenSolaris_extras.key.pem
-rw-r--r-- 1 admin staff 758 2010-03-20 14:41 OpenSolaris_standard_support.certificate.pem
-rw-r--r-- 1 admin staff 888 2010-03-20 14:41 OpenSolaris_standard_support.key.pem
-rw-r--r-- 1 admin staff 535 2010-03-20 14:48 pkg.config

Resetting to Default State

As always, we'll start with a function that resets everything to a default state: Only the /release repository, configured as the preferred one:

# Hard coded constants
# Pfexec versions of commands
PFPKG="pfexec pkg"
# Clear repositories from pkg and revert to default
function clear_publishers {
        # Set default publisher.
        echo "Setting default publisher $DEFAULT_PUB at $DEFAULT_PUB_URL."
        $PFPKG set-publisher -P -O $DEFAULT_PUB_URL $DEFAULT_PUB
        # List all publishers we know except the default one.
        PUBLISHERS=$( pkg publisher -Ha | sed -e 's/\s\s*/ /g' | \
                cut '-d ' -f1 | grep -v $DEFAULT_PUB )
        # Clear all publishers.
        if [ "$PUBLISHERS" ] ; then
                echo "Clearing all other publishers."
                $PFPKG unset-publisher $PUBLISHERS
        echo "Done."

Going Through the List of Repositories

Now the more interesting part follows: We'll feed the configuration file line by line into a while loop that puts together the parameters for the right pkg(1) call.

We'll also copy key and certificate files into /var/pkg/ssl which is the same location that the package manager GUI uses.

Here's the piece of code for parsing the configuration file and configuring package repositories:

PFMKDIR="pfexec mkdir"
PFCHOWN="pfexec chown"
PFCP="pfexec cp"
# Print an error message and exit.
function emit_error {
	echo "Error: $1"
	exit 1
# Set up repositories for pkg
# The argument is a file containing information about publishers and their URLs
# with possible keyfiles and "preferred" option.
function add_publishers {
	CONFIG_DIR=$(dirname $1)
	# Make sure the directory for storing keys is set up correctly.
	if [ ! -d $KEY_DIR ] ; then
		echo "Creating directory $KEY_DIR."
		$PFMKDIR -m 0755 -p $KEY_DIR
		$PFCHOWN root:root $KEY_DIR
	# File format:
	# One line per package repository.
	# Lines containing "#" are ignored.
	# Fields in a line are separated by space.
        # Fields: "URL publisher keyfile preferred".
	# "preferred" can be any string. If present, this publisher will be
	# marked as preferred.
	# Keyfile will be expanded to "keyfile.key.pem" and
	# "keyfile.certificate.pem".
	# We assume that keyfiles are in the same directory as the config file.
	# "keyfile" and "preferred" can be left out.
	cat $CONFIG_FILE | grep -v '#' | while read url pub key pref; do
		# Handle the keyfile field.
		if [ $key ] ; then
			echo "Storing key and certificate for $key in $KEY_DIR."
			$PFCP $CONFIG_DIR/$key.key.pem $KEY_DIR
			[ $? -eq 0 ] || \
				emit_error \
				"Can't copy $CONFIG_DIR/$key.key.pem."
			key_opt="-k $KEY_DIR/$key.key.pem"
			$PFCP $CONFIG_DIR/$key.certificate.pem $KEY_DIR
			[ $? -eq 0 ] || \
				emit_error \
				"Can't copy $CONFIG_DIR/$key.certificate.pem."
			key_opt="$key_opt -c $KEY_DIR/$key.certificate.pem"
			key_string=" with key $key"
		# Handle the preferred field.
		if [ $pref ] ; then
			pref_string=" preferred"
		# Put everything together into a pkg command.
		echo "Adding$pref_string publisher $pub at $url$key_string."
		$PFPKG set-publisher $pref_opt $key_opt -O $url $pub
		[ $? -eq 0 ] || \
			emit_error "Couldn't add publisher $publisher."

This script is slightly more chatty than previous scripts. You may want to modify it to be more silent or use a log file.


Download the full config_pkg script including a help function and argument parsing and feel free to modify it to your needs. Over time, you'll accumulate quite a few repositories, some with key/certificate files and some not. Then this is a handy tool to configure them all at once whenever needed.

Your Take

What are your favourite repositories? Do you use alternative package management systems, if so which ones? What packages do you install on a regular basis after a fresh install of OpenSolaris?

Related Articles

Stay in Touch!

Did you like this article? Have you found it useful, interesting or entertaining?

Then click here to get free regular updates and help me reach my goal of 1,000 regular blog readers this summer!

Thank you for reading Constant Thinking.