System Admins and Developers
Hands-On Labs
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://solaris/system/library@0.5.11,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.
| Name | Values |
|---|---|
| facet.locale.* | true, false |
| facet.doc.man | true, false |
| facet.doc | true, false |
| facet.devel.* | true, false |
| variant.arch | sparc, i386, zos |
| variant.debug.* | true, false |
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
oracle@solaris:~$ pkg publisher
PUBLISHER TYPE STATUS URI
solaris (preferred) origin online http://pkg.oracle.com/solaris/release/
Adding an Additional Package publisher
oracle@solaris:~$ sudo pkg set-publisher -g http://pkg.sunfreeware.com:9001 sunfreeware.com Password: oracle@solaris:~$ pkg publisher PUBLISHER TYPE STATUS URI solaris (preferred) origin online http://pkg.oracle.com/solaris/release/ sunfreeware.com origin online http://pkg.sunfreeware.com:9001/
And lets remove it, as we don't need it right now.
oracle@solaris:~$ sudo pkg unset-publisher sunfreeware.com
Password:
oracle@solaris:~$ pkg publisher
PUBLISHER TYPE STATUS URI
solaris (preferred) origin online http://pkg.oracle.com/solaris/release/
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.
oracle@solaris:~/Work/srm-1.2.10$ pkg search gperf
INDEX ACTION VALUE PACKAGE
basename file usr/bin gperf pkg:/developer/gperf@3.0.3-0.175.0.0.0.2.537
pkg.description set GNU gperf is a perfect hash function generator. For a given list of strings,
it produces a hash function and hash table, in form of C or C++ code,
for looking up a value depending on the
input string.
pkg:/developer/gperf@3.0.3-0.175.0.0.0.2.537
pkg.fmri set solaris/developer/gperf pkg:/developer/gperf@3.0.3-0.175.0.0.0.2.537
pkg.summary set GNU gperf pkg:/developer/gperf@3.0.3-0.175.0.0.0.2.537
basename dir usr/share/doc/gperf pkg:/developer/gperf@3.0.3-0.175.0.0.0.2.537
Search For a Package in a Remote Repository. To search for the bash package in the remote (-r) repository associated with the current image.
oracle@solaris:~/Work/srm-1.2.10$ pkg search -r bash INDEX ACTION VALUE PACKAGE basename file usr/bin/bash pkg:/shell/bash@4.1.9-0.175.0.0.0.2.537 pkg.fmri set solaris/shell/bash pkg:/shell/bash@4.1.9-0.175.0.0.0.2.537 basename dir etc/bash pkg:/shell/bash@4.1.9-0.175.0.0.0.2.537 basename dir usr/share/bash pkg:/shell/bash@4.1.9-0.175.0.0.0.2.537
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.
oracle@solaris:~/Work/srm-1.2.10$ sudo pkg install gperf
Packages to install: 1
Create boot environment: No
Create backup boot environment: No
Services to change: 1
DOWNLOAD PKGS FILES XFER (MB)
Completed 1/1 8/8 0.1/0.1
PHASE ACTIONS
Install Phase 27/27
PHASE ITEMS
Package State Update Phase 1/1
Image State Update Phase 2/2
oracle@solaris:~/Work/srm-1.2.10$ pkg list gperf
NAME (PUBLISHER) VERSION IFO
developer/gperf 3.0.3-0.175.0.0.0.2.537 i--
This example uninstalls the gperf package.
oracle@solaris:~/Work/srm-1.2.10$ sudo pkg uninstall gperf Packages to remove: 1 Create boot environment: No PHASE ACTIONS Removal Phase 21/21 PHASE ITEMS Package State Update Phase 1/1 Package Cache Update Phase 1/1 Image State Update Phase 2/2 PHASE ITEMS Reading Existing Index 8/8 Indexing Packages 1/1 oracle@solaris:~/Work/srm-1.2.10$ pkg list gperf pkg list: no packages matching 'gperf' installed
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:
oracle@solaris:~$ pkgrepo create ~/myrepo oracle@solaris:~$ pkgrepo info -s ~/myrepo PUBLISHER PACKAGES STATUS UPDATED oracle@solaris:~$ pkgrepo set -s ~/myrepo publisher/prefix=example.com oracle@solaris:~$ pkgrepo info -s ~/myrepo PUBLISHER PACKAGES STATUS UPDATED example.com 0 online 2011-05-19T11:31:28.549665Z
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:
oracle@solaris:~$ sudo zfs create rpool/export/ips
oracle@solaris:~$ sudo zfs create rpool/export/ips/example
eoracle@solaris:~$ zfs list
NAME USED AVAIL REFER MOUNTPOINT
rpool 8.42G 7.20G 92.5K /rpool
rpool/ROOT 6.14G 7.20G 31K legacy
rpool/ROOT/solaris 6.14G 7.20G 6.00G /
rpool/dump 1023M 7.20G 1023M -
rpool/export 225M 7.20G 36K /export
rpool/export/home 225M 7.20G 32K /export/home
rpool/export/home/oracle 225M 7.20G 225M /export/home/oracle
rpool/export/ips 31K 7.20G 31K /export/ips
rpool/export/ips/example 31K 7.20G 31K /export/ips/example <--- Our new zfs file system
rpool/swap 1.06G 8.10G 172M -
The next thing we need to do is to create our repository and set the publisher using pkgrepo(1):
oracle@solaris:~$ sudo pkgrepo create /export/ips/example oracle@solaris:~$ pkgrepo info -s /export/ips/example PUBLISHER PACKAGES STATUS UPDATED oracle@solaris:~$ sudo pkgrepo set -s /export/ips/example publisher/prefix=example.com oracle@solaris:~$ pkgrepo info -s /export/ips/example PUBLISHER PACKAGES STATUS UPDATED example.com 0 online 2011-05-19T16:55:14.278173Z
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)
oracle@solaris:~$ svcs application/pkg/server STATE STIME FMRI disabled 11:05:09 svc:/application/pkg/server:default oracle@solaris:~$ sudo svccfg -s application/pkg/server setprop pkg/port=10001 <---- Set the port to 10001 oracle@solaris:~$ sudo svccfg -s application/pkg/server setprop pkg/inst_root=/export/ips/example <---- rep. location oracle@solaris:~$ sudo svcadm refresh application/pkg/server oracle@solaris:~$ sudo svcadm enable application/pkg/server oracle@solaris:~$ svcs application/pkg/server STATE STIME FMRI online 10:51:10 svc:/application/pkg/server:default
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):
oracle@solaris:~$ svcs application/pkg/server
STATE STIME FMRI
online 13:03:52 svc:/application/pkg/server:defaul
oracle@solaris:~$ sudo svcadm disable application/pkg/server
oracle@solaris:~$ svcs application/pkg/server
STATE STIME FMRI
disabled 13:04:20 svc:/application/pkg/server:default
oracle@solaris:~$ sudo svcadm enable application/pkg/server
oracle@solaris:~$ svcs application/pkg/server
STATE STIME FMRI
online 13:04:34 svc:/application/pkg/server:defaul
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.
oracle@solaris:~$ sudo zfs create rpool/export/ips/devtest oracle@solaris:~$ sudo pkgrepo create /export/ips/devtest oracle@solaris:~$ sudo pkgrepo set -s /export/ips/devtest publisher/prefix=devtest.example.com oracle@solaris:~$ sudo svccfg -s pkg/server add devtest oracle@solaris:~$ sudo svccfg -s pkg/server:devtest addpg pkg application oracle@solaris:~$ sudo svccfg -s pkg/server:devtest addpg general framework oracle@solaris:~$ sudo svccfg -s pkg/server:devtest setprop general/complete=astring:\"\" oracle@solaris:~$ sudo svccfg -s pkg/server:devtest setprop general/enabled=boolean: true oracle@solaris:~$ sudo svccfg -s pkg/server:devtest setprop pkg/port=10002 oracle@solaris:~$ sudo svccfg -s pkg/server:devtest setprop pkg/inst_root=/export/ips/devtest oracle@solaris:~$ sudo svcadm refresh pkg/server:devtest oracle@solaris:~$ sudo svcadm enable pkg/server:devtest oracle@solaris:~$ svcs pkg/server STATE STIME FMRI online 23:24:11 svc:/application/pkg/server:default online 0:14:46 svc:/application/pkg/server:devtest
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
oracle@solaris:~$ pkg contents -m wget > wget_manifest oracle@solaris:~$ cat wget_manifest set name=pkg.fmri value=pkg://solaris/web/wget@1.12,5.11-0.175.0.0.0.2.537:20111019T122502Z set name=variant.arch value=i386 value=sparc set name=info.upstream-url value=http://www.gnu.org/software/wget/ set name=pkg.description value="GNU wget - a utility to retrieve files from the World Wide Web" set name=info.classification value=org.opensolaris.category.2008:Applications/Internet set name=info.source-url value=http://ftp.gnu.org/gnu/wget/wget-1.12.tar.bz2 set name=pkg.summary value="wget - GNU wget" set name=org.opensolaris.consolidation value=userland set name=org.opensolaris.arc-caseid value=PSARC/2000/488 license 97a51b7c9fd624f1d16cda23f472e1fbe24d0efc chash=626a60459b65a1cac3a1ce0303c40f3e69403b4c license=GPLv3 pkg.csize=12330 pkg.size=35702 depend fmri=pkg:/library/security/openssl@1.0.0.5-0.175.0.0.0.0.525 type=require depend fmri=pkg:/system/library@0.5.11-0.175.0.0.0.0.0 type=require depend fmri=pkg:/library/libidn@1.19-0.175.0.0.0.0.525 type=require dir group=sys mode=0755 owner=root path=etc dir group=sys mode=0755 owner=root path=usr dir group=bin mode=0755 owner=root path=usr/bin dir group=bin mode=0755 owner=root path=usr/sfw dir group=bin mode=0755 owner=root path=usr/sfw/bin dir group=sys mode=0755 owner=root path=usr/share . file 6be18eb59d8f6906ee4ee18104f3318ae817ee80 chash=17183aaa04fcae20401cec26df325bf66b5d135d elfarch=sparc elfbits=32 elfhash=df980eca224f1e3627dee713590403b359b3084a group=bin mode=0555 owner=root path=usr/bin/wget pkg.csize=211661 pkg.size=506548 variant.arch=sparc . . file 68bc81098633a627d03da5c92ac7e048556460df chash=19c439fc21948815d089487a775b0f72323ca227 elfarch=i386 elfbits=32 elfhash=116c3f5c151fabe88e1274a817ad7557ea6bbbb5 group=bin mode=0555 owner=root path=usr/bin/wget pkg.csize=191555 pkg.size=528028 variant.arch=i386 file 291bbb69aa064bb0affa458acb0a1007a178ec13 chash=222ef630db851d7ce5dceae8941dc1c349399ecc facet.doc.info=true group=bin mode=0444 owner=root path=usr/share/info/wget.info pkg.csize=62581 pkg.size=199596 restart_fmri=svc:/application/texinfo-update:default variant.arch=i386 .
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:
oracle@solaris:~$ cd ~/Work oracle@solaris:~/Work$ tar -zxf ../Download/srm-1.2.10.tar.gz oracle@solaris:~/Work$ cd srm-1.2.10 oracle@solaris:~/Work/srm-1.2.10$ mkdir proto_inst oracle@solaris:~/Work/srm-1.2.10$ ./configure exec_prefix=`pwd`/proto_inst/usr prefix=`pwd`/proto_inst/usr checking for a BSD-compatible install... /usr/bin/ginstall -c checking whether build environment is sane... yes checking for a thread-safe mkdir -p... /usr/gnu/bin/mkdir -p checking for gawk... gawk checking whether make sets $(MAKE)... yes checking for gcc... gcc . . config.status: executing depfiles commands
oracle@solaris:~/Work/srm-1.2.10$ make make all-recursive make[1]: Entering directory `/home/oracle/Work/srm-1.2.10' Making all in lib make[2]: Entering directory `/home/oracle/Work/srm-1.2.10/lib' gcc -DHAVE_CONFIG_H -I. -I.. -O2 -DNDEBUG -MT snprintf.o -MD -MP -MF .deps/snprintf.Tpo -c -o snprintf.o snprintf.c . . make[1]: Leaving directory `/home/oracle/Work/srm-1.2.10'
oracle@solaris:~/Work/srm-1.2.10$ make install . . Making install in src make[1]: Entering directory `/home/oracle/Work/srm-1.2.10/src' make[2]: Entering directory `/home/oracle/Work/srm-1.2.10/src' test -z "/home/oracle/Work/srm-1.2.10/proto_inst/usr/bin" || /usr/gnu/bin/mkdir -p "/home/oracle/Work/srm-1.2.10/proto_inst/usr/bin" /usr/bin/ginstall -c srm '/home/oracle/Work/srm-1.2.10/proto_inst/usr/bin' . . make[1]: Leaving directory `/home/oracle/Work/srm-1.2.10'
oracle@solaris:~/Work/srm-1.2.10$ ls -R proto_inst/ proto_inst/: usr proto_inst/usr: bin share proto_inst/usr/bin: srm proto_inst/usr/share: man proto_inst/usr/share/man: man1 proto_inst/usr/share/man/man1: srm.1
oracle@solaris:~/Work/srm-1.2.10$ ./proto_inst/usr/bin/srm --version srm (srm) 1.2.10
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....
oracle@solaris:~/Work/srm-1.2.10$ pkgsend generate proto_inst > srm_1_2_1_manifest
oracle@solaris:~/Work/srm-1.2.10$ cat srm_1_2_1_manifest dir group=bin mode=0755 owner=root path=usr timestamp=20110705T162628Z dir group=bin mode=0755 owner=root path=usr/share timestamp=20110705T162628Z dir group=bin mode=0755 owner=root path=usr/bin timestamp=20110705T162628Z dir group=bin mode=0755 owner=root path=usr/share/man timestamp=20110705T162628Z dir group=bin mode=0755 owner=root path=usr/share/man/man1 timestamp=20110705T162628Z file usr/share/man/man1/srm.1 group=bin mode=0644 owner=root path=usr/share/man/man1/srm.1 pkg.size=2488 file usr/bin/srm group=bin mode=0755 owner=root path=usr/bin/srm pkg.size=24560
Lets add some meta data to our manifest. Using a text editor, add the following 5 lines to our manifest
set name=pkg.fmri value=srm@1.2.10,5.11 set name=pkg.description value="Secure rm 1.2.10" set name=description value="Secure rm" set name=summary value="Secure rm" set name=info.classification value="org.opensolaris.category.2008:Applications/System Utilities"
And we need to find any dependencies we might have, we can use 'pkgdepend generate' to do that:
oracle@solaris:~/Work/srm-1.2.10$ pkgdepend generate -d ./proto_inst srm_1_2_1_manifest > srm_1_2_1_depend
oracle@solaris:~/Work/srm-1.2.10$ cat srm_1_2_1_depend depend fmri=__TBD pkg.debug.depend.file=libc.so.1 pkg.debug.depend.path=lib pkg.debug.depend.path=usr/ccs/lib pkg.debug.depend.path=usr/lib pkg.debug.depend.path=usr/sfw/lib pkg.debug.depend.reason=usr/bin/srm pkg.debug.depend.type=elf type=require
OK, so now we know what our dependencies are, now lets resolve them to packages.
oracle@solaris:~/Work/srm-1.2.10$ pkgdepend resolve srm_1_2_1_depend
oracle@solaris:~/Work/srm-1.2.10$ ls *.res srm_1_2_1_depend.res
oracle@solaris:~/Work/srm-1.2.10$ more srm_1_2_1_depend.res depend fmri=pkg:/system/library@0.5.11-0.151.0.1 type=require
As you can see here we only depend on one package, so let's add that to our manifest file and format it.
oracle@solaris:~/Work/srm-1.2.10$ cat srm_1_2_1_depend.res >> srm_1_2_1_manifest
oracle@solaris:~/Work/srm-1.2.10$ pkgfmt srm_1_2_1_manifest
oracle@solaris:~/Work/srm-1.2.10$ more srm_1_2_1_manifest set name=pkg.fmri value=srm@1.2.10,5.11set name=pkg.description value="Secure rm 1.2.10" set name=description value="Secure rm" set name=info.classification \ value="org.opensolaris.category.2008:Applications/System Utilities" set name=summary value="Secure rm" dir path=usr group=bin mode=0755 owner=root timestamp=20110705T162628Z dir path=usr/bin group=bin mode=0755 owner=root timestamp=20110705T162628Z dir path=usr/share group=bin mode=0755 owner=root timestamp=20110705T162628Z dir path=usr/share/man group=bin mode=0755 owner=root \ timestamp=20110705T162628Z dir path=usr/share/man/man1 group=bin mode=0755 owner=root \ timestamp=20110705T162628Z file usr/bin/srm path=usr/bin/srm group=bin mode=0755 owner=root \ pkg.size=24560 file usr/share/man/man1/srm.1 path=usr/share/man/man1/srm.1 group=bin \ mode=0644 owner=root pkg.size=2488 depend fmri=pkg:/system/library@0.5.11-0.151.0.1 type=require
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
oracle@solaris:~/Work/srm-1.2.10$ sudo svccfg -s pkg/server setprop pkg/readonly=false oracle@solaris:~/Work/srm-1.2.10$ sudo svcadm refresh pkg/server:default oracle@solaris:~/Work/srm-1.2.10$ sudo svcadm restart pkg/server:default oracle@solaris:~/Work/srm-1.2.10$ svcprop -p pkg/readonly pkg/server:default false oracle@solaris:~/Work/srm-1.2.10$
To publish our package we use 'pkgsend publish':
oracle@solaris:~/Work/srm-1.2.10$ sudo pkgsend publish -d ./proto_inst -s /export/ips/example \
srm_1_2_1_manifest.p5m
pkg://example.com/srm@1.2.10,5.11:20111117T63324Z
PUBLISHED
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:
oracle@solaris:~/Work/srm-1.2.10$ sudo svcadm disable pkg/server:default oracle@solaris:~/Work/srm-1.2.10$ sudo svcadm enable pkg/server:default oracle@solaris:~/Work/srm-1.2.10$ pkgrepo info -s http://localhost:10001 PUBLISHER PACKAGES STATUS UPDATED example.com 1 online 2011-11-17T17:43:48.638470Z
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.
oracle@solaris:~$ pkg publisher
PUBLISHER TYPE STATUS URI
solaris (preferred) origin online http://pkg.oracle.com/solaris/release/ example.com
origin online file:/export/home/oracle/myrepo/
oracle@solaris:~$ sudo pkg unset-publisher example.com
oracle@solaris:~$ sudo pkg set-publisher -p http://localhost:10001 pkg set-publisher:
Added publisher(s): example.com
oracle@solaris:~$ pkg publisher PUBLISHER TYPE STATUS URI solaris (preferred) origin online http://pkg.oracle.com/solaris/release/ example.com origin online http://localhost:10001/
oracle@solaris:~$ pkg info -r srm
Name: utilities/srm
Summary: Secure rm
Description: Secure rm 1.2.10
Category: Applications/System Utilities
State: Not installed
Publisher: example.com
Version: 1.2.10
Build Release: 5.11
Branch: 0.1
Packaging Date: July 5, 2011 05:43:48 PM
Size: 26.41 kB
FMRI: pkg://example.com/utilities/srm@1.2.10,5.11-0.1:20110705T174348Z
oracle@solaris:~$ sudo pkg install srm
Packages to install: 1
Create boot environment: No
DOWNLOAD PKGS FILES XFER (MB)
Completed 1/1 2/2 0.0/0.0
PHASE ACTIONS
Install Phase 13/13
PHASE ITEMS
Package State Update Phase 1/1
Image State Update Phase 2/2
PHASE ITEMS
Reading Existing Index 8/8
Indexing Packages 1/1
oracle@solaris:~$ srm --version srm (srm) 1.2.10
Now you should have a basic understanding of how to create your own IPS repository and how to publish a package to it.
