— modern ops stuff —
Using pkg(1)
20 March 2011 // Solaris

pkg is pretty labyrinthine, and very powerful. It makes a lot of complex tasks simple, but at the cost of making some seemingly simple tasks a little more complex than you might expect. On this page I’m going to try to remember to record the things that I found were clever, useful, or more complicated than I expected.

Searching for Things

If for some reason your repo server isn’t searchable (as the early ones weren’t), you might be able to have a rough guess at a package name and do something like:

# pkg list -a "*print*"

And see all the packages with print in their name.

To find out to which package a file belongs, like the old

# pkginfo -l -p $(which lpadmin)

you can now

# pkg search -l $(which lpadmin)

A nice thing about pkg is that it accepts the -H and -o flags in the same way the ZFS commands do, so to just get the package name in the above example you can

$ pkg search -Hl -o pkg.name $(which lpadmin)

Ambiguous Names

I needed a telnet client, but I don’t want the server stuff. No problem, right?

$ pkg list -a "*telnet*"
NAME (PUBLISHER)                              VERSION         STATE UFOXI
network/telnet                                0.5.11- known -----
service/network/telnet                        0.5.11- known -----
# pkg install network/telnet
Creating Plan
pkg: 'network/telnet' matches multiple packages

It took me a good few minutes to work out how to specify only the network/telnet package, trying all kind of regex type stuff. Eventually, this educated guess came up trumps.

# pkg install pkg://solaris/network/telnet

Finding Dependencies

I was going to install Subversion, but I didn’t want a whole load of junk. I just wanted to know what packages the subversion package depended on, and it took me ages to find out how to do it.

$ pkg contents -rHt depend -o fmri versioning/subversion

-r tells pkg to run the query on the remote repository rather than the local database (because we haven’t installed the package yet); -H omits headers (it would just print FMRI on the first line otherwise); -t depend is the type of query I want to perform; and the tricky part is the -o fmri part. If you omit that, pkg gives you a load of crap about the package delivering no filesystem content, which as far as I can tell is wrong and misleading. I’d think the correct action would be just to say something along the lines of “I don’t know what output you want”, but maybe I just don’t quite understand what’s happening.

It’s actually probably easier to pull down the whole package manifest with -m and run it through grep.

$ pkg contents -m versioning/subversion | grep ^depend
depend fmri=pkg:/database/sqlite-3@ type=require
depend fmri=pkg:/library/neon@0.29.5- type=require
depend fmri=pkg:/system/library@0.5.11- type=require
depend fmri=pkg:/library/apr-13@1.3.9- type=require
depend fmri=pkg:/library/expat@2.0.1- type=require
depend fmri=pkg:/library/apr-util-13@1.3.9- type=require
depend fmri=pkg:/library/zlib@1.2.3- type=require

Of course, those dependencies may have dependencies, and the best way to see what pkg will actually do to your system is to do a verbose dry-run.

# pkg install -nv versioning/subversion
           Packages to install:        5
     Estimated space available:  2.12 GB
Estimated space to be consumed: 33.53 MB
       Create boot environment:       No
Create backup boot environment:       No
          Rebuild boot archive:       No

Changed packages:
    None -> 1.6.16,5.11-
    None -> 1.3.9,5.11-
    None -> 1.3.9,5.11-
    None -> 0.3.1,5.11-
    None -> 0.29.5,5.11-

Finding Dependents

If you want to remove a package but you think something else might depend on it:

$ pkg search -l "depend::system/library/gcc-3-runtime"
incorporate depend system/library/gcc-3-runtime@3.4.3- pkg:/consolidation/sfw/sfw-incorporation@0.5.11-
require     depend system/library/gcc-3-runtime@3.4.3- pkg:/driver/graphics/nvidia@0.256.44-

Obsolete Packages

I wanted to set up my Solaris workstation as a XEN host. (Don’t ask.) Adding the packages failed:

# pkg install system/xvm
No updates necessary for this image.

I assumed it was already installed.

# pkg list system/xvm
pkg list: no packages matching 'system/xvm' installed

Wrong. I queried it on the server:

$ pkg info -r system/xvm
          Name: system/xvm
         State: Not installed (Obsolete)
     Publisher: solaris
       Version: 0.5.11
 Build Release: 5.11
        Branch: 0.160
Packaging Date: February 28, 2011 04:50:48 PM
          Size: 0.00 B
          FMRI: pkg://solaris/system/xvm@0.5.11,5.11-0.160:20110228T165048Z

So it exists, but it’s obsolete and you can’t install it. This seems stupid at first, but look at the package size. Zero. This gives you a clue. When a package is obsoleted and you do an upgrade, the existing package is removed from your system. This also gives the publisher a way to split up or renmame existing packages. Obsolete the old one, drop in the new ones. Makes sense.