Using pkgutil on Solaris with Puppet for easy package management

I’ve been using Puppet on Linux systems for some time now, but I’ve only just started using it in a Solaris environment.

I think one of the killer functions of Puppet is being able to easily install packages and manage services on a system. Most Linux distros these days have tools for working with repositories of packages, like Yum on Fedora/RedHat/CentOS and Apt on Debian and Ubuntu. These work really well with Puppet, because you can easily script a class which requires a specific package, and Puppet will just call the package tool and it’ll install the right package and all of the required dependencies.

Using Solaris feels like a step back from Linux, not having an official repository tool like Yum and Apt. Its package system seems quite primitive which can suffer from the dependency hell that we used to have with RPM before it was wrapped up with Yum. Enter: pkgutil.

Pkgutil is like Yum for Solaris, written in Perl by Peter Bonivart. It was designed for OpenCSW, which is a repository for Open Source packages on Solaris – and also the best place to install Puppet from. With a few simple steps, you can actually build an OpenCSW compatible repository of Solaris packages and tell pkgutil to use it, rather than the standard OpenCSW one.

Puppet has almost gained a proper package provider for Pkgutil (See Puppet issue #4258: Add pkgutil provider), which should be available in Puppet 2.6.4 maybe. In the mean time, we can just install it into our Ruby path to make use of it right now.

Steps involved are:

  • Install pkgutil
  • Install Puppet on Solaris
  • Install the pkgutil provider
  • Build an OpenCSW-compatible repository of your own packages
  • Define pkgutil as a provder in your Puppet configuration
  • Install some packages!

Install pkgutil

Before we do anything, we should install pkgutil. This handy one-liner will install it for Solaris 10 and OpenSolaris.

# pkgadd -d`uname -p`.pkg

For Solaris 8 and 9, take a look at the pkgutil installation page for more details.

Install Puppet

Now that pkgutil is installed, installing Puppet is a breeze!

# /opt/csw/bin/pkgutil --install puppet

This will resolve all the dependencies and install everything just like the Linux package management tools do.

Install the pkgutil provider

I’m using a version of pkgutil from Dominic Cleal’s git repository.

# wget --no-check-certificate -O /opt/csw/lib/ruby/site_ruby/1.8/puppet/provider/package/pkgutil.rb

This wget will download it, and copy into the right place in the filesystem for Puppet to pick it up.

Build an OpenCSW-compatible repository

As part of OpenCSW, Peter Bonivart has released a tool for creating OpenCSW repositories, called bldcat. You can find it as part of the pkgutilplus package from OpenCSW.

Create yourself a new directory for your packages on your webserver. For me, I needed OpenSolaris 2009.06 and Solaris 10 support, so:

`# mkdir -p repo/solaris/i386/5.11/

mkdir -p repo/solaris/i386/5.10/`

Then just put all your packages into that directory, and run bldcat:

# bldcat .

This will generate the catalog, and descriptions file needed for pkgutil. Once you make this directory available by HTTP, you can add the URL into the pkgutil.conf file.

One thing to remember is that you’ll need to do this on a Solaris machine. Although bldcat will work on Linux, it requires some of the Solaris package tools, which won’t be available. For me, I just did it NFS mounted from a Linux server.

Now, set the mirror and noncsw entries like this:

mirror=http://repo.mydomain/repo/solaris<br /> noncsw=true

For my situation, I had to include a few packages that we provided as our standard environment, and the package names weren’t prefixed with CSW, to the ‘noncsw’ option needs to be set.

Because I wanted a mix of OpenCSW packages and our corporate standard packages, I copied in the OpenCSW packages (and dependencies) along with the corporate ones into the one repository. You can put Puppet in there also.

NOTE: All your packages need to be *.pkg.gz format, so make sure you compress any packages that aren’t already gzipped!

Define pkgutil as a provider in your Puppet configuration

In the site.pp file on my Puppet Master, I include this definition:

Package {
    provider => $operatingsystem ? {
        redhat => yum,
        centos => yum,
        sles => zypper,
        solaris => pkgutil,

To see this in action, I’ve used Nagios’s NRPE as an example.

package { nrpe_package:
  name => $operatingsystem ? {
    Solaris => 'CSWnrpe'
    CentOS  => 'nrpe',
    SLES    => 'nagios-nrpe',
    Debian  => 'nagios-nrpe-server',
  ensure => installed,

So with pkgutil, installing packages on Solaris can be as easy as Linux with Puppet.