This lab will introduce you to the Image Packaging System (IPS) concepts, the process of managing system software, and the process of publishing your own software packages in IPS format. (More information about IPS and Oracle Solaris 11 here.)
This hands-on lab assumes you have some basic knowledge or programming experience of the following technologies.
Additional software needed for the lab:
sudo pkg install gcc-3"
Expected duration: 20 minutes
Oracle Solaris 11 takes a new approach to package management, that greatly simplifies the process of managing patches and updates to reduce the risk of operating system maintenance. With Solaris 11 we introduce Image Packaging System (IPS) that replaces the old SVR4 packages used in earlier Oracle Solaris releases. IPS greatly simplifies software life cycle management, IPS was designed to cope with the complete life cycle of software, addressing software packaging, deployment and installation, updates, system upgrades, and removal of software packages. IPS is also tightly integrated with ZFS, and uses ZFS features (such as as snapshots and clones) to minimize risk and downtime associated with maintenance.
Fist we need to understand the terminology and concepts used in IPS.
IPS manages software in units of packages. An IPS package is a collection of directories, files, links, drivers, dependencies, groups, users, and license information in a defined format. This collection represents the installable objects of a package. Packages have attributes such as package name and description.
You can use commands to view information about a package, or you can view the manifest of a package.
Oracle Solaris 11 supports both, IPS packages and SVR4 packages.
While most administrators can install software from the package repositories, it is also possible to install software from an on-disk IPS package format, .p5p. This is equivalent to .rpm, SVR4 packages, or .nbm files.
From a developer's view, an IPS package is made up of a series of actions; actions are described in the manifest of a package. Actions are used for defining the files and directories of the package, setting package attributes, declaring dependencies on other packages, creating users and groups, and installing device drivers. Actions represent the installable objects on a system. Every action consists primarily of its name and a key attribute. Together, these refer to a unique object as it follows a version history.
Each IPS package is represented by a Fault Management Resource Identifier (FMRI). The pkg(1) command uses valid FMRI package information to perform its command actions. The FMRI includes descriptive information about the package, such as the publisher of the package, package name, version information, and date.
For example, the FMRI, pkg://firstname.lastname@example.org,5.11-0.175.0.0.0.2.1:20111019T082311Z, consists of the following sequence of information
An image is a location on your system where packages and their associated files, directories, links, and dependencies can be installed.
An image can be one of three types:
After you have completed the installation of Oracle Solaris 11 on your system, an image is automatically made available to you. You can install packages without explicitly creating an image. However, creating images is necessary in order to provide a logical separation for different software applications, and especially required if you are working with zones.
The following figure shows the concept of an image.
Engineered with close integration with ZFS and boot management on Solaris, pkg(1) is using ZFS snapshots to facilitate rollback functionality if the package installation either fails or otherwise results in an undesired environment. IPS performs an analysis on the software being updated, and if deemed necessary (during 'pkg update' sequence) automatically creates a new boot environment (BE) where the updated package versions will be installed. The new BE will be activated on reboot, the old BE will be available as a rollback alternative in case the upgrade resulted in a non-working system or broke functionality. (A beadm command is available to list out and control behavior of boot environments on Solaris 11)
For more information about BEs, see the Managing Boot Environments With Oracle Solaris 11 guide.
Software can have components that are optional and components that are mutually exclusive. Examples of optional components include locales and documentation. Examples of mutually exclusive components include SPARC or x86 and debug or non-debug binaries. In IPS, optional components are called facets and mutually exclusive components are called variants. Both variants and facets appear as tags on IPS actions.
Variants and facets affect whether a particular action is selected or deselected for installation.
The following list shows some examples of facet and variant tags and their possible values.
|variant.arch||sparc, i386, zos|
By default an action that's not tagged with facet or variant will be included.
An action that is tagged with a variant that is not selected is excluded.
An action that is tagged with one or more facets is excluded if none of the facets are selected.
A single action can have multiple facet and variant tags. An example of a component with multiple facet and variant tags is an architecture-specific header file that is used by developers.
Variants and facets are set at the image level. An image with a variant set to a particular property can only have actions that match that variant installed on it. For example, you cannot install an x86 package into a SPARC image.
On the client-side, IPS has a graphical front-end called "Package Manager", The "Package Manager" allows you to search, install, update and remove packages; manage repositories; manage boot environments.
With IPS you also have an Update Manager. The Update Manager is a desktop application that enables users to update all installed packages in an image, the Update Manager notifies the user when updates to the installed packages are available.
To get used to working with IPS, lets begin to familiarize ourselves with the IPS commands
List our current Package Authorities
Adding an Additional Package publisher
And lets remove it, as we don't need it right now.
Search for a Package in the Installed Image. The following example searches and locates the bash command gperf and lets us know what package it came from.
Search For a Package in a Remote Repository. To search for the bash package in the remote (-r) repository associated with the current image.
This example installs gperf. The output displays the status of the download, number of packages that were installed, number of files that were installed and the size (in megabytes) of the download.
This example uninstalls the gperf package.
You should now have a basic understanding of the IPS package management system
Expected duration: 20 minutes
We will look at two methods to enable a local repository. First we will look at how you can create a file-based repository that can be accessed directly from the IPS client commands. Second, after that, we will instantiate it as a network service via a pkg server to the repository, allowing it to be accessed over the net. Both of theses two methods are OK to use for development and testing. However if you want to run a repository server on your system permanently it's recommended that (a) you have sufficient disk space to host the files on your local disk, and (b) use SMF to manage the repository server, the default SMF FMRI for the repository server service is svc:/application/pkg/server.
This can be done in two ways, the easiest way is just to modify the properties of the default instance of the repository service to reflect your configuration, that is what we will do in the second part of this lab. The other alternative is to create a second instance of the svc:/application/pkg/server service, this is useful in case you need to run multiple IPS depo servers on the same system, say that you want to have a local copy of the Solaris repository, you can find the instructions on how to make a copy here, and a development/test repository for your own code. I've added instructions on how to do this as an extra exercise if you have time to spare.
It would look something like this:
This the preferred way of setting up a more permanent IPS repository server on your local system. The most common way is to modify the default instance of the application/pkg/server service, we can do that using the svccfg(1M) command. But first we need somewhere to put the repository, so for that we can create a zfs filesystem. By using a zfs filesystem rather than just a directory, we get more options on how to manage the storage as the repository grows when we put more packages in it.
First we need to create a ZFS file system where we can locate the repository, for this example I'm using /export/ips:
The next thing we need to do is to create our repository and set the publisher using pkgrepo(1):
That looks OK, now we need to change the default port and location to 10001 and /export/ips/local on the default instance of the application/pkg/server service in SMF. To do that we use svccfg(1M) and svcadm(1M)
OK lets try to see if it works by pointing our browser to http://localhost:10001
That looks good, let's keep this repository so we can use it in exercise 4 below. But before that lets just have a look at how you stop your IPS repository service using SMF commands. To change the state of a service we use svcadm(1M), just as we did when we started our service. To verify state of our service we use svcs(1M):
More info on SMF can be found here Managing Services (Overview).
From time to time we might need to run multiple IPS servers on our system, say that you have your development and testing IPS repository running in one server but you also need to have a local copy of the Solaris repository. And as both of these are permanent, it's preferable that we use Solaris SMF to manage the pkg.depotd processes as services. We can do that by adding a new instance to the pkg/server service. To do that we need to do the following steps:
1. Create a ZFS filesystem to hold the repository data.
$ sudo zfs create <filesystem>
2. Use pkgrepo(1) command to create a first skeleton repository, and set the publisher. We've previously done this so you can skip this step if you have followed the previous example.
$ sudo pkgrepo create repository <path to repository>
$ sudo pkgrepo set -s <path repository> publisher/prefix=<publisher name>
3. Add a new instance of the pkg/server service
$ sudo svccfg -s pkg/server add <instance_name>
$ sudo scvcfg -s pkg/server:<instance_name> addpg pkg application
$ sudo svccfg -s pkg/server:<instance_name> addpg general framework
$ sudo svccfg -s pkg/server:<instance_name> setprop general/complete=astring:\"\"
$ sudo svccfg -s pkg/server:<instance_name> setprop general/enabled=boolean: true
4. Set the value of the port and path to repository data.
$ sudo svccfg -s pkg/server:<instance_name> setprop pkg/port=<port_value>
$ sudo svccfg -s pkg/server:<instance_name> setprop pkg/inst_root=<repository_directory>
5. Refresh the repository service instance.
$ sudo svcadm refresh application/pkg/server:<instance_name>
6. Start the repository instance.
$ sudo svcadm enable application/pkg/server:<instance_name>
7. Verify that our new service instance runs OK
$ svcs -x application/pkg/server:<instance_name>
8. Open your browser and type http://localhost:<port_value> to confirm that the repository has been created.
As you can see in the end we now have two IPS repositories up and running on our system, the default server at port 10001 and our devtest server at port 10002
Now you know how to set up an IPS repository, as a simple filesystem based repository, an un-manged network repository, modify the default instance of the pkg/server SMF service and finally if you had some spare time over, add a second instance to our pkg/server SMF service
Expected duration: 20 minutes
Lets have a look at the manifest for wget
We can use pkg contents -m <pkg_name> to get
At the top we can see the name of the package or the FMRI, which includes, the publisher, category, name and version. We can take this manifest as a starting point for our own package. We could set a number of properties for our package which is followed by a number of directory actions, where we set the correct permissions on directories that we will touch. This is then followed by the main payload of the packages, all of the files that will be delivered with the package.
As you can see we have two variants available for the wget package, a sparc and a i386, so if you want to deliver both a SPARC and a x86 version of your application you do this in the same package, just add a second "variant". You can also see that wget delivers a 32-bit binary for both SPARC and x86 platforms.
See exercise 3.2 for details on how to set up and start a local repository server.
In our case we need to get a GNU base toolchain installed, we can easily do that by installing the developer/gnu package, it includes all the needed tools for a GNU developer toolchain. It's an empty package that just defines dependencies on all the needed GNU developer tools. Because IPS automatically resolves dependencies, we simply need to install this package and all the other packages it depends on shall be installed automatically. This is actually a very useful feature of IPS, and can be used to create different "bundles" of your software package.
Download the source code from sourceforge here. We use srm 1.2.10 in following example, due to a bug in the new signal handling code in more recent version, 1.2.11, and it will not compile cleanly on Solaris.
Create a workspace and a prototype area where you can create an "install" prototype. Something like this:
OK, so now we have a working srm in our proto_inst area, the next step is now to create our manifest, and coming up next is how to do that:
The first thing we do is use 'pkgsend generate' to create an initial crude manifest....
Lets add some meta data to our manifest. Using a text editor, add the following 5 lines to our manifest
And we need to find any dependencies we might have, we can use 'pkgdepend generate' to do that:
OK, so now we know what our dependencies are, now lets resolve them to packages.
As you can see here we only depend on one package, so let's add that to our manifest file and format it.
OK, now we have a nice looking manifest file that we can use to publish our package.
Make the following edits in the manifest:
1) Adjust permissions for "dir path=usr/share" to be "group=sys".
2) Adjust permissions for "dir path=usr" to be "group=sys".
If you do not do the above 2 steps, installation of this package will break because during installation of this package, IPS will validate the listed permissions and will determine that the listing in this manifest prompts a rejection from those package supplied by Solaris 11.
3) Finally, rename the manifest file to give it a ".p5m" extension
We need to tell SMF that our repository should be read/write and not (as the default) readonly
To publish our package we use 'pkgsend publish':
We publish it directly into the file system where the repo resides. Now that its published, restart the service to validate the presence of this package:
OK, now we have our srm package published in our local repository, lets try and see if we can install it.
The first thing we need to do is to add our local repository to our image, after that we can try to install srm from our local repository.
Now you should have a basic understanding of how to create your own IPS repository and how to publish a package to it.false ,,,,,,,,,,,,,,,,