How to Create and Publish Packages to an IPS Repository on Oracle Solaris 11

by Glynn Foster
Published November 2011 (updated June 2013)

How to create new software packages for Oracle Solaris 11 and publish them to a network package repository.

Oracle Solaris 11 takes a new approach to lifecycle and package management to greatly simplify the process of managing system software helping reduce the risk of operating system maintenance, including reducing unplanned and planned downtime. With Image Packaging System (IPS), administrators can install and update software from locally connected or remote software package repositories using a much-improved and modernized process.

In this article, we look at what is involved in creating and publishing packages to an IPS repository that can then be installed on Oracle Solaris 11 systems. We will use the popular open source version control system, Bazaar, as an example.

To learn more about IPS, check out a variety of content at the IPS Technology Spotlight page on Oracle Technology Network. Also see the Oracle Solaris 11 Cheat Sheet for Image Packaging System.

An Overview of the Package Creation Process

Before we dive into the specific details of creating and publishing a package to an IPS repository, here's a summary of the steps we will be taking.

  • Building the source code.
  • Depending on what software you are planning to package, this step might involve setting up a build environment and running a script to collect some basic information about the state of your system to ensure that dependent packages are installed, that a compiler is available, and how best to install files related to the software onto the file system. We will not go into too much detail for this step because it can vary significantly depending on the software that is to be packaged. We will build our software in our local workspace, $HOME.

  • Creating a manifest for your IPS package.
  • The main part of the process is creating an IPS manifest that describes how the package is put together, including basic information about the package name and version, what files or other content are installed as part of the software package, and what other software dependencies must be met prior to installing the package.

  • Setting up an IPS repository.
  • All software packages are hosted by a package repository that systems connect to in order to install software. Repositories can either be locally available on a file system or remote over the network through http:// or https:// connections. This article uses a repository over http:// and uses the Service Management Facility (SMF) to manage the repository.

  • Publishing the package to the repository.
  • After a package manifest has been created and a repository is provisioned to host the package, the final step of the process is to publish the package to the repository so the package can be installed by systems that connect to the repository.

Step One: Building the Source Code

The source code for Bazaar, a Python-based application, can be downloaded from http://launchpad.net/bzr/2.4/2.4.1/+download/bzr-2.4.1.tar.gz.

We're going to unpack the source tarball, run the configuration script and install the software into a temporary location in our workspace that is separate from our final destination file system. This method allows us to determine which files and directories should be part of our software package. This temporary location is sometimes known as a proto area.



# cd $HOME
# mkdir proto_install
# wget http://launchpad.net/bzr/2.4/2.4.1/+download/bzr-2.4.1.tar.gz
# tar -zxf bzr-2.4.1.tar.gz
# ls
bzr-2.4.1/         proto_install/

Let's now go into the Bazaar source directory.




# cd bzr-2.4.1
# ls
apport/            contrib./    man1/              README
BRANCH.TODO        COPYING.txt  MANIFEST.in        README_BDIST_RPM
bzr/               doc/         NEWS               setup.py
bzr.ico            INSTALL      po/                TODO
bzrlib             Makefile     profile_imports.po tools/

Bazaar uses the standard Python mechanism setup.py to configure, build, and install itself. We can start the build using the setup.py install target, providing it with the location of our proto area and the "prefix" location of the final destination where we would like to install on our file system, in this case $HOME/proto_install and /usr.

Building Bazaar requires a C compiler (for convenience, we chosen the GNU GCC compiler in this case) and necessary development headers, which we can quickly install using the Package Manager.



 # pkg install developer/gcc-3 system/header
# python setup.py install --root=$HOME/proto_install --prefix=/usr
 
 

After these commands have completed and a successful build has been achieved, a quick browse around the contents of proto_install shows the following layout:



 
 # cd $HOME
# cd proto_install
# ls
bin/  lib/  man/
# cd bin
# ls
bzr
  

As we can see, within the bin directory, we now have the recently built bzr binary, which we can run directly by setting an appropriate PYTHONPATH environmental variable, as shown in Listing 1.



 
 # export PYTHONPATH=$HOME/proto_install/usr/lib/python2.6/site-packages/
# ./bzr
Bazaar 2.4.1 - a free distributed version-control tool
http://bazaar-canonical.com/

Basic commands:
  bzr init           makes this directory a versioned branch
  bzr branch         makes a copy of another branch

  bzr add            makes files or directories versioned
  bzr ignore         ignore a file or pattern
  bzr mv             move or rename a versioned file

  bzr status         summarize changes in working copy
  bzr diff           show detailed diffs

  bzr merge          pull in changes from another branch
  bzr commit         save some or all changes
  bzr send           send changes via email

  bzr log            show history of changes
  bzr check          validate storage

  bzr help init      more help on e.g. init command
  bzr help commands  list all commands
  bzr help topics    list all help topics
 
   

Listing 1: Running the bzr Binary

We are now ready to take the next step to create an IPS package from the files that were just installed in the proto_install area.

Step Two: Creating a Manifest for the IPS Package

Before we create a manifest, let's explore an existing manifest.

About the Package Manifest

Behind every IPS package is a manifest that provides some basic metadata about the package (name, description, version, category, and so on), what files and directories are included, and what dependencies need to be installed for the package. Packages may specify what services to restart in order to refresh some configuration on the system. They may also specify what aliases to update for a given hardware driver or what users and groups to create as part of the package installation process.

To get familiar with a package manifest, we can use the pkg contents command to list a manifest that is already associated with the gzip package and output it into a file gzip.p5m (p5m is a standard file name extension convention we use for package manifests), as shown in Listing 2.



   
   
   # cd $HOME
# pkg contents -m gzip > gzip.p5m
# cat gzip.p5m
set name=pkg.fmri value=pkg://solaris/compress/gzip@1.3.5,5.11-0.174.0.0.0.0.504:20110920T223615Z
set name=info.source-url value=http://alpha.gnu.org/gnu/gzip/gzip-1.3.5.tar.gz
set name=pkg.summary value="GNU Zip (gzip)"
set name=pkg.description value="The GNU Zip (gzip) compression utility"
set name=info.classification value="org.opensolaris.category.2008:Applications/System 
Utilities"
set name=org.opensolaris.arc-caseid value=PSARC/2000/488
set name=info.upstream-url value=http://directory.fsf.org/GNU/gzip.html
set name=org.opensolaris.consolidation value=userland
license 91533ecafdca90d38563499351a030e497bc9dae chash=33000d74d113ed003308b6b2c6f6565597517ab8 
license=GPLv2 pkg.csize=657 pkg.size=1278
set name=variant.arch value=i386 value=sparc
depend fmri=pkg:/system/library@0.5.11-0.172.0.0.0.0.17571 type=require
depend fmri=pkg:/shell/bash@4.1.9-0.172 type=require
dir group=sys mode=0755 owner=root path=usr
dir group=bin mode=0755 owner=root path=usr/bin
dir group=sys mode=0755 owner=root path=usr/share
dir facet.doc.info=true group=bin mode=0755 owner=root path=usr/share/info
dir facet.doc.man=true group=bin mode=0755 owner=root path=usr/share/man
dir facet.doc.man=true group=bin mode=0755 owner=root path=usr/share/man/man1
...
   
     

Listing 2: Listing a Package Manifest

As you can see from Listing 2, each line specifies a part of the package, using a series of actions. Every action has a simple representation:

<action_name> <attribute1=value1> <attribute2=value2> ...

Table 1 lists what actions are available during package manifest creation.

Table 1. Package Manifest Actions

Action Name Description
set Specifies some basic metadata for the package such as a name, description, categorization, and so on.
license Specifies what license is associated with the package and whether, for example, the license must be acknowledged prior to package installation.
file Specifies a single file that is installed by the package. Attributes to the file action specify some basic permissions and where the file is installed.
dir Specifies a single directory that is installed by the package. Attributes to the dir action specify some basic permissions and where the directory is installed.
link Specifies a symbolic link. The link action can also manage mediated links when you want a single link to point to a preferred versioned binary, for example, /usr/bin/python linking to /usr/bin/python2.5.
hardlink Specifies a hard link.
depend Specifies any dependencies a package has on other software. Different types of dependencies can be specified, from simple required dependencies on other packages, to those that are optional or those that indicate that a package cannot be installed if other software is already installed.
driver Specifies a device driver that should be installed, along with any aliases that should be set up. The actual driver binary should be installed using a file action.
user Specifies that a user account should be created. Attributes to the user action specify the user name, password, home directory, and other information.
group Specifies that a group should be created. Attributes to the group action specify the group name and group ID.
legacy Specifies that information should be installed in the legacy package database for SVR4 compatibility to ensure that older packages can be installed that may have to satisfy particular dependencies.

The package manifest can generally be divided into three different parts:

  • Package metadata
  • Package contents
  • Package dependencies

As we start to generate a manifest for our package, we will tackle these different parts in turn.

Specifying Package Metadata

To set some of the package metadata, we use the set action. For this example, we'll pick a few important items, shown in Table 2, and fill in others at a later stage if we need them.

Table 2. Attributes for Specifying Metadata

Attribute Name Description
pkg.fmri Package name and version
pkg.description Package description
pkg.summary Package summary
variant.arch The architectures that the package supports
info.classification A classification scheme that is used to order packages in the Package Manager graphical client

So in our example, let's provide the following detail in a file called bzr.mog. We will use the mog file extension to indicate that this content needs to go through another processing step before we include it in the manifest.



      
   # cat > bzr.mog << EOF
set name=pkg.fmri value=developer/versioning/bzr@2.4.1,0.1
set name=pkg.description value="Bazaar (bzr) Source Version Control System"
set name=pkg.summary value="Bazaar is a source version control system that helps to 
track project changes over time"
set name=variant.arch value=$(ARCH)
set name=info.classification value="org.opensolaris.category.2008:Development/Source 
Code Management"
EOF
# ls
bzr-2.4.1/         gzip.p5m
bzr.mog            proto_install/
   

Listing 3: Providing Metadata

Let's quickly discuss the contents of the last two lines. Variants are a feature of IPS that allow multiple architectures to be included in a single package within the repository, reducing the amount of space consumed by multiple packages that might have mostly the same content but are built for different architectures. In this case, we could manually provide either i386 or sparc, but a useful way is to use a macro for which we will substitute later in the process.

Classification determines how the package will be shown within the Package Manager graphical interface. There is a list of classifications detailed in the appendix of the Packaging and Delivering Software with the Image Packaging System guide.

Specifying Package Contents

The next step of our manifest creation is specifying what files, directories, links and hard links should be installed as part of the package. In this step, we use the command pkgsend generate to parse through our proto area, recursively list what it is there with the appropriate manifest action, and then pass this output through the pkgfmt utility to give us a nicer formatting, as shown in Listing 4.





# pkgsend generate proto_install | pkgfmt > bzr.p5m.1
# cat bzr.p5m.1
dir  path=usr owner=root group=bin mode=0755
dir  path=usr/bin owner=root group=bin mode=0755
file usr/bin/bzr path=usr/bin/bzr owner=root group=bin mode=0755
dir  path=usr/lib owner=root group=bin mode=0755
dir  path=usr/lib/python2.6 owner=root group=bin mode=0755
dir  path=usr/lib/python2.6/site-packages owner=root group=bin mode=0755
file usr/lib/python2.6/site-packages/bzr-2.4.1-py2.6.egg-info \
    path=usr/lib/python2.6/site-packages/bzr-2.4.1-py2.6.egg-info owner=root \
    group=bin mode=0644
dir  path=usr/lib/python2.6/site-packages/bzrlib owner=root group=bin mode=0755
file usr/lib/python2.6/site-packages/bzrlib/__init__.py \
    path=usr/lib/python2.6/site-packages/bzrlib/__init__.py owner=root \
    group=bin mode=0644
file usr/lib/python2.6/site-packages/bzrlib/__init__.pyc \
    path=usr/lib/python2.6/site-packages/bzrlib/__init__.pyc owner=root \
    group=bin mode=0644
....
file usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc \
    path=usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc owner=root \
    group=bin mode=0644
dir  path=usr/man owner=root group=bin mode=0755
dir  path=usr/man/man1 owner=root group=bin mode=0755
file usr/man/man1/bzr.1 path=usr/man/man1/bzr.1 owner=root group=bin mode=0644


Listing 4: Parsing Through the Proto Area

Notice in Listing 4 that you can see a number of dir and file actions. In particular for the file action, you can see two paths being specified: one to the final location on the file system where we want to install the package and the other to the location within the proto_install area, as the following snippet shows:







file usr/lib/python2.6/site-packages/bzrlib/__init__.py \ 
    path=usr/lib/python2.6/site-packages/bzrlib/__init__.py owner=root \
    group=bin mode=0644

This is useful because we can directly modify where we want files and directories to be installed without requiring a similar set of modifications in the proto_installM area.

It's now a good time to review what contents are proposed to be included in this package. Prior to publishing this package, we can choose to drop certain content that we don't want installed, or we can correct any permissions that are inconsistent or incorrect when compared to the final install location on the file system.

Rather than modifying the manifest directly for these changes, we can simply use pkgmogrify to provide a set of transforms that we want to make. These transforms can be specified in our earlier bzr.mog file. We can then merge the contents of these two files, as shown in Listing 5.





# pkgmogrify -DARCH=`uname -p` bzr.p5m.1 bzr.mog | pkgfmt > bzr.p5m.2
# cat bzr.p5m.2
set name=pkg.fmri value=developer/versioning/bzr@2.4.1,0.1
set name=pkg.description value="Bazaar (bzr) Source Version Control System"
set name=pkg.summary value="Bazaar is a source version control system that helps to 
track project changes over time"
set name=variant.arch value=i386
set name=info.classification value="org.opensolaris.category.2008:Development/Source 
Code Management"
dir  path=usr owner=root group=bin mode=0755
dir  path=usr/bin owner=root group=bin mode=0755
file usr/bin/bzr path=usr/bin/bzr owner=root group=bin mode=0755
dir  path=usr/lib owner=root group=bin mode=0755
dir  path=usr/lib/python2.6 owner=root group=bin mode=0755
dir  path=usr/lib/python2.6/site-packages owner=root group=bin mode=0755
file usr/lib/python2.6/site-packages/bzr-2.4.1-py2.6.egg-info \
    path=usr/lib/python2.6/site-packages/bzr-2.4.1-py2.6.egg-info owner=root \
    group=bin mode=0644
....
file usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc \
    path=usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc owner=root \
    group=bin mode=0644
dir  path=usr/man owner=root group=bin mode=0755
dir  path=usr/man/man1 owner=root group=bin mode=0755
file usr/man/man1/bzr.1 path=usr/man/man1/bzr.1 owner=root group=bin mode=0644

# ls
bzr-2.4.1/         bzr.p5m.2
bzr.mog            gzip.p5m
bzr.p5m.1          proto_install/


Listing 5: Using pkgmogrify to Specify Transforms

In this step we also take the opportunity to define our architecture macro $(ARCH).

Having successfully identified the package contents, let's move to the next step and identify any package dependencies we should include.

Specifying Package Dependencies

As mentioned previously, there are a number of package dependencies that can be specified when creating a new package. In this example, we will just focus on require dependencies, that is, those software packages that must be installed in order for Bazaar to function correctly. Other dependency types are described in the Packaging and Delivering Software with the Image Packaging System guide.

Fortunately, we can automate this step using the pkgdepend generate command:




# pkgdepend generate -md proto_install bzr.p5m.2 | pkgfmt > bzr.p5m.3
# ls
bzr-2.4.1/         bzr.p5m.3
bzr.mog            gzip.p5m
bzr.p5m.1          proto_install/
bzr.p5m.2

In this step, we have taken the package manifest contents we generated earlier, and for each file listed in the manifest, we do some more analysis on the actual file located in the proto_install area. This step automatically identifies what file dependencies are required by taking a number of different analytical approaches, for example, ELF headers for compiled binaries, #! references in shell scripts, and import statements for Python files.

Looking through the resulting bzr.p5m.3 file, you can see some additional lines similar to those shown in Listing 6.



depend type=require fmri=__TBD \ 
   pkg.debug.depend.reason=usr/lib/python2.6/site-packages/bzrlib/tests/ssl_certs/create_ssls.py \
    pkg.debug.depend.type=python \
    pkg.debug.depend.file=cStringIO.py \
    pkg.debug.depend.file=cStringIO.pyc \
    pkg.debug.depend.file=cStringIO.pyo \
    pkg.debug.depend.file=cStringIO.so \
    pkg.debug.depend.file=cStringIO/__init__.py \
    pkg.debug.depend.file=cStringIOmodule.so \
    pkg.debug.depend.path=usr/lib/python2.6 \
    pkg.debug.depend.path=usr/lib/python2.6/lib-dynload \
    pkg.debug.depend.path=usr/lib/python2.6/lib-old \
    pkg.debug.depend.path=usr/lib/python2.6/lib-tk \
    pkg.debug.depend.path=usr/lib/python2.6/plat-sunos5 \
    pkg.debug.depend.path=usr/lib/python2.6/site-packages \
    pkg.debug.depend.path=usr/lib/python2.6/site-packages/bzrlib/tests/ssl_certs \
    pkg.debug.depend.path=usr/lib/python2.6/vendor-packages \
    pkg.debug.depend.path=usr/lib/python2.6/vendor-packages/gst-0.10 \
    pkg.debug.depend.path=usr/lib/python2.6/vendor-packages/gtk-2.0 \
    pkg.debug.depend.path=usr/lib/python26.zip

Listing 6: Additional Dependencies

In the output shown in Listing 6, we can see that the create_ssls.py file depends on a number of other Python files: cStringIO.py, cStringIO.pyc, cStringIO.pyo, and so on. The next step is resolving these file dependencies for package dependencies that are already installed by using the pkgdepend resolve command:



# pkgdepend resolve -m bzr.p5m.3
# ls
bzr-2.4.1/         bzr.p5m.3
bzr.mog            bzr.p5m.3.res
bzr.p5m.1          gzip.p5m
bzr.p5m.2          proto_install/

After a little while, the bzr.p5m.3.res file is created, which now has successfully resolved the file dependencies into packages, as shown in Listing 7.




# tail bzr.p5m.3
....
file usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc \
    path=usr/lib/python2.6/site-packages/bzrlib/xml_serializer.pyc owner=root \
    group=bin mode=0644
dir  path=usr/man owner=root group=bin mode=0755
dir  path=usr/man/man1 owner=root group=bin mode=0755
file usr/man/man1/bzr.1 path=usr/man/man1/bzr.1 owner=root group=bin mode=0644
depend fmri=pkg:/runtime/python-26@2.6.4-0.174.0.0.0.0.504 type=require
depend fmri=pkg:/system/library/gcc-3-runtime@3.4.3-0.174.0.0.0.0.504 type=require

Listing 7: Resolved File Dependencies

Now that we have completed this step, we have all the basic elements of a package manifest in place: metadata, file and directory contents, and package dependencies.

Checking Our Final Manifest

Now that we have our final manifest, it's a good idea to check it prior to publishing it and the package contents to the repository. This can be done manually or by using the pkglint tool, which helps check for consistency against other packages already published in the package repository by creating a local cache of content and checking for validity against it.

We won't get into the specifics of linting a package, but a simple lint check can be done using the following command:







# pkglint -c ./lint-cache -r http://pkg.oracle.com/solaris/release bzr.p5m.3.res
# ls
bzr-2.4.1/         bzr.p5m.3.res
bzr.mog            gzip.p5m
bzr.p5m.1          lint-cache/
bzr.p5m.2          proto_install/
bzr.p5m.3

Quite often file permissions are different on the system to which you are installing and the permissions need to be corrected. Also, default file locations for content such as man pages or system configuration can be different. If you need to correct these types of issues, you can apply additional transforms to the package manifest prior to publication.

In this example, it was necessary to add the following transforms to our original bzr.mog file to account for man pages in /usr/share/man and corrected group permissions for /usr:



<transform dir path=usr/man -> edit path usr/man usr/share/man>
<transform dir path=usr/man/man1 -> edit path usr/man/man1 usr/share/man/man1>
<transform file -> edit path usr/share/man1 usr/share/man/man1>
<transform dir path=usr$ -> edit group bin sys>

Reviewing the Steps We Used to Create the Manifest

We can start the process again at any stage until we are happy with our final file output. Let's review the steps again.

We start creating the initial manifest by using the pkgsend generate command to search through our proto area looking for files and directories we want to include in the package.

# pkgsend generate proto_install | pkgfmt > bzr.p5m.1

We then use the pkgmogrify command to add package metadata along with any transformations we want to make to the package contents.

# pkgmogrify -DARCH=`uname -p` bzr.p5m.1 bzr.mog | pkgfmt > bzr.p5m.2

We then use the pkgdepend generate command to start to identify any file dependencies we might have by looking at the list of files included in the proto area and identifying what files on the file system are required.

# pkgdepend generate -md proto_install bzr.p5m.2 | pkgfmt > bzr.p5m.3

Finally, we use the pkgdepend resolve command to take these file dependencies and resolve them into package dependencies.

# pkgdepend resolve -m bzr.p5m.3

Step Three: Setting Up an IPS Repository

The next step in the process is to create and configure an IPS repository that will host our software package. There are a number of different approaches we can take to create a repository (for example, whether we want a file-based repository or something that is available over http:// and https:// ). However, in this example, we will use SMF to create a new IPS repository service over http:// that will automatically restart itself in case of a failure, due to the advantages of SMF service restart.

The first thing to do is to create a new ZFS data set that can host our repository. Using a ZFS data set provides more flexibility in terms of storage as the IPS package repository grows, including the ability to snapshot, clone, or send backups to an alternate server. We use the zfs create command to achieve this by creating a new data set called repository on top of the existing root zpool called rpool:

# zfs create rpool/export/repository

Let's now create an IPS repository within that ZFS data set by using the pkgrepo create command:



# pkgrepo create /export/repository
# ls /export/repository
pkg5.repository

As you can see from the output shown above, we now have a new empty repository. We could stop at this step if we only cared about having a file system-based local repository available, but in this example, we would like a repository that is available through http://. The important thing to note here is that although we have created a place to store our IPS repository, the IPS repository service itself has not been started.

After we have created the initial repository, we need to set a few different properties to reflect our environment. We use the pkgrepo set command to set the prefix of the repository:

# pkgrepo set -s /export/repository publisher/prefix=bazaar

We then set a few different properties on the SMF service: the location of the repository itself and what port it should reside on, and we also change the state to make sure we can write to it during the publication process.




# svccfg -s application/pkg/server setprop \ 
pkg/inst_root=/export/repository
# svccfg -s application/pkg/server setprop pkg/port=9001
# svccfg -s application/pkg/server setprop pkg/readonly=false

We now need to start the SMF service using the svcadm command:





# svcadm enable application/pkg/server
# svcs application/pkg/server
STATE         STIME    FMRI
online        2:16:21  svc:/application/pkg/server:default


Now that we have a running service, we can use the pkgrepo info command to get some information about the repository:



# pkgrepo info -s http://localhost:9001
PUBLISHER  PACKAGES  STATUS        UPDATED
bazaar     0         online        2011-10-10T13:16:21.193453Z

We can see the repository contains no packages currently. We can now move on to the next step, which is publishing our package to the repository.

Step Four: Publishing the Package to the Repository

We are now in the position where we can publish our package to the repository. For this, we use the pkgsend publish command:




# pkgsend publish -s http://localhost:9001 -d proto_install bzr.p5m.3.res		
PUBLISHED
pkg://bazaar/developer/versioning/bzr-2.4.1,0.1:10111010T144709Z

As we can see, the package has successfully been published. We can now check the status of our repository again:




# pkgrepo info -s http://localhost:9001
PUBLISHER   PACKAGES  STATUS        UPDATED
bazaar      1         online        2011-10-10T14:47:29.298624Z

We can see that we now have one package available at this repository. We can add this repository to our configuration and install a package from it, as shown in Listing 8.




# pkg set-publisher -p http://localhost:9001
Added publisher(s): bazaar

# pkg info -r bzr
         Name: developer/versioning/bzr
       Summary: Bazaar is a source version control system that helps to track project changes over time
   Description: Bazaar (bzr) Source Version Control System
      Category: Development/Source Code Management
         State: Not installed
     Publisher: bazaar
       Version: 2.4.1
 Build Release: 0.1
        Branch: None
Packaging Date: October 10, 2011 02:47:09 PM 
          Size: 25.64 MB
          FMRI: pkg://bazaar/developer/versioning/bzr@2.4.1,0.1:20111010T144709Z

# pkg install bzr
           Packages to install:  1
       Create boot environment: No
Create backup boot environment: No

DOWNLOAD                                 PKGS     FILES    XFER (MB)
Completed                                 1/1 1617/1617      7.0/7.0

PHASE                                        ACTIONS
Install Phase                              1693/1693 

PHASE                                          ITEMS
Package State Update Phase                       1/1 
Image State Update Phase                         2/2

Listing 8: Adding the Repository and Installing a Package from It

Now that we see the package can be successfully installed, we should ensure that the repository is set to read-only once again:





# svccfg -s application/pkg/server setprop pkg/readonly=true
# svccfg -s application/pkg/server refresh
# svcadm restart application/pkg/server

Summary

Image Packaging System is a major advancement in software management on Oracle Solaris 11, providing a much-improved and automated way of distributing and installing software over the network across many different clients. After a few basics are understood, creating packages for your software is an easy process and helps reduce errors during software updates, providing a much more reliable and consistent experience in the data center.

See Also

About the Author

Glynn Foster is a Principal Product Manager for Oracle Solaris and works on technology areas that include the Image Packaging System and Service Management Facility. Glynn joined Oracle in 2010 as part of the Sun Microsystems acquisition.