Matplotlib 1.1.0 for Solaris on SPARC and x86, Part 2: Setting up Solaris IPS servers for multiple architecture (fat) packages

on

This is part 2 of a three-part series on building and packaging matplotlib as a multi-architecture, Solaris IPS package.

  1. Compiling matplotlib 1.1.0 for Solaris on SPARC and x86
  2. Setting up Solaris IPS servers to host packages for SPARC and x86
  3. Packaging matplotlib 1.1.0 for Solaris on SPARC and x86
pkg logo

IPS made is a huge step forward compared to SysV packaging. One can still create and use SysV packages in Solaris 11, but why would you? IPS provides easy package distribution, upgrades, dependency resolution, and it's still open source!

Conceptually, IPS is a bit different from System V packages. An IPS package is not just a collection of scripts and files. Instead, IPS works by specifying "actions" (e.g. create directory, copy file, etc.). Similar to other packaging systems, it also includes metadata in a manifest file (e.g. pkg dependencies, descriptions).

Overview

These instructions will go through the steps necessary to setup IPS servers needed to create and host multiple architecture (fat) IPS packages. Basically, we will create three repositories and three IPS servers to host them. To keep things as simple as possible, I'll assume they will all be hosted from the same physical machine (and the same zone).

For projects that need to be compiled for SPARC and x86 (IPS calls them the sparc and i386 variants, respectively), ideally one would create a "universal" package that can be installed to sparc or x86 machines. The way this is done in Solaris is to create a separate package for each "variant" and then to "merge" them into one package. This means three IPS servers are required, one for each architecture, and one for the merged package.

Concepts

The last paragraph had quite a few terms in it that have special meaning in IPS-speak. Learning the following terms will help quite a bit in understanding what needs to be done to create and host IPS packages.
package
This is the "what" in IPS. What is it you would like to install?
publisher
This is the "who" in IPS. Who is it that is providing this package?
variant
This is more specifically, what kind of package are you installing? Examples include sparc/i386 and debug/non-debug.
repository
This is a collection of packages. It can include packages from multiple publishers, for example, if one wanted to mirror Oracle packages in addition to internally-created packages.
server
This is the software responsible for hosting a repository.
merge
This means combining two IPS package variants into one package.

Note that the publisher name is associated with a package, not the particular server. A server does have a default publisher, though. When you query for packages and send new packages to the server, the default publisher is used unless otherwise specified.

Create repositories

In order to create a package which supports multiple architectures, we need three repositories. One for sparc variants, one for i386 variants, and one for the merged packages. This does not mean we need three machines, or even three zones. We will simply run multiple IPS servers, each on a different port.

To keep the instructions simple, we are going to use the same default publisher name for all three servers we create. Remember, the publisher is supposed to identify "who" publishes a package, not "where" they are published. It makes sense that each repository should have the same default publisher name. For this example we will use "mycompany" as the publisher.

Setup local ZFS filesystems

The first thing we will do is create ZFS filesystems for each repository.
  zfs create rpool/export/ips
  zfs create rpool/export/ips/default
  zfs create rpool/export/ips/sparc
  zfs create rpool/export/ips/x86
  zfs set mountpoint=/export/ips rpool/export/ips
Next, we create a skeleton for each IPS repository.
  pkgrepo create /export/ips/default
  pkgrepo create /export/ips/sparc
  pkgrepo create /export/ips/x86
Finally, we set the publisher name. As I said before, this is the "who" publishes the package, not "where" it is published. I use "mycompany" in this example, since I'm creating a package for my company's internal use.
  pkgrepo set -s /export/ips/default publisher/prefix=mycompany
  pkgrepo set -s /export/ips/sparc publisher/prefix=mycompany
  pkgrepo set -s /export/ips/x86 publisher/prefix=mycompany

Setup SMF-based IPS servers

For this example, we create multiple instances of the SMF-based pkg server. There are other options, file-system based sharing for example, but it seems that creating multiple server instances is the best-supported method of hosting.

Setup IPS default (multi-architecture) server

The first thing we will do is setup the default server on the standard http port (80).
  svccfg -s application/pkg/server setprop pkg/port=80
Next, tell it which repository to use.
  svccfg -s application/pkg/server setprop pkg/inst_root=/export/ips/default
Since we want to be able to publish to this repository, change the readonly property to false.
  svccfg -s pkg/server setprop pkg/readonly=false
Refresh the pkg/server SMF service, to make sure the configuration changes get loaded.
  svcadm refresh application/pkg/server
Start the repository service.
  svcadm enable application/pkg/server
The IPS server can now be reached at http://myipsserver Check that it is running with the svcs command.
  % svcs pkg/server
  STATE          STIME    FMRI
  online         May_08   svc:/application/pkg/server:default

Setup IPS sparc server

We need to add a new instance to SMF. Since we're already using the default instance, we give it the name "sparc". We then need to do some basic configuration.
  svccfg -s pkg/server add sparc
  svccfg -s pkg/server:sparc addpg pkg application
  svccfg -s pkg/server:sparc addpg general framework
  svccfg -s pkg/server:sparc setprop general/complete=astring:\"\"
  svccfg -s pkg/server:sparc setprop general/enabled=boolean: true
Next, we set the port number. Since 80 is used already, we can use 8000.
  svccfg -s pkg/server:sparc setprop pkg/port=8000
Set the root repository directory.
  svccfg -s pkg/server:sparc setprop pkg/inst_root=/export/ips/sparc
Change the readonly property to false.
  svccfg -s pkg/server:sparc setprop pkg/readonly=false
Refresh to get configuration changes.
  svcadm disable pkg/server:sparc
  svcadm refresh pkg/server:sparc
Start the server.
  svcadm enable pkg/server:sparc
The IPS server can now be reached at http://myipsserver:8000

Setup IPS x86 server

Now we'll add the final server instance to SMF. As before, we're already using the default instance, so we give this one a name. Finally, we add basic configuration.
  svccfg -s pkg/server add x86
  svccfg -s pkg/server:x86 addpg pkg application
  svccfg -s pkg/server:x86 addpg general framework
  svccfg -s pkg/server:x86 setprop general/complete=astring:\"\"
  svccfg -s pkg/server:x86 setprop general/enabled=boolean: true
Next, we set the port number. Since 80 and 8000 are already use, we can use 8001.
  svccfg -s pkg/server:x86 setprop pkg/port=8001
Set the root repository directory.
  svccfg -s pkg/server:x86 setprop pkg/inst_root=/export/ips/x86
Change the readonly property to false.
  svccfg -s pkg/server:x86 setprop pkg/readonly=false
Refresh to get configuration changes.
  svcadm disable pkg/server:x86
  svcadm refresh pkg/server:x86
Start the server.
  svcadm enable pkg/server:x86
The IPS server can now be reached at http://myipsserver:8001

Build and publish the package

Now that we have all the IPS servers setup, we can build and publish our package. In part 3, we will create a multi-architecture (fat) IPS package for matplotlib, which we compiled in part 1.

Resources