.. CDDL HEADER START
.. The contents of this file are subject to the terms of the
Common Development and Distribution License (the "License").
You may not use this file except in compliance with the License.
.. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
See the License for the specific language governing permissions
and limitations under the License.
.. When distributing Covered Code, include this CDDL HEADER in each
file and include the License file at usr/src/OPENSOLARIS.LICENSE.
If applicable, add the following below this CDDL HEADER, with the
fields enclosed by brackets "[]" replaced with your own identifying
information: Portions Copyright [yyyy] [name of copyright owner]
.. CDDL HEADER END
.. Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
Chapter 7
---------
Allowing Variations
...................
In this chapter we explore how variants and facets are used in
IPS to provide different installation options to the end user.
Variants
~~~~~~~~
Since Oracle Solaris supports multiple architectures, one common error
made with the SVR4 packaging system was the accidental installation
of packages for an incorrect architecture. With the introduction of
software repositories, the prospect of maintaining a separate
repository for each supported architecture seemed unappealing
to ISVs and error prone for customers. As a result, IPS supports
installation of a single package on multiple architectures.
The mechanism that implements this feature is called a
*variant*. A variant enables the properties of the target image
to determine which software components are actually installed.
A variant has two parts: its name, and the list of possible values.
The variants defined in Oracle Solaris 11 are:
======================== =================
Name Values
======================== =================
variant.arch sparc, i386
variant.opensolaris.zone global, nonglobal
variant.debug.* true, false
======================== =================
Variants appear in two places in a package:
* A ``set`` action names the variant and defines the values that
apply to this package.
* Any action that can only be installed for a subset of the
variant values has a tag that specifies the name of the
variant and the value on which it is installed.
For example, a package that delivers the symbolic link ``/var/ld/64``
might include::
set name=variant.arch value=sparc value=i386
dir group=bin mode=0755 owner=root path=var/ld
dir group=bin mode=0755 owner=root path=var/ld/amd64 \
variant.arch=i386
dir group=bin mode=0755 owner=root path=var/ld/sparcv9 \
variant.arch=sparc
link path=var/ld/32 target=.
link path=var/ld/64 target=sparcv9 variant.arch=sparc
link path=var/ld/64 target=amd64 variant.arch=i386
Note that components that are delivered on both sparc and i386 receive
no variant tag, but those delivered to one architecture or the other
receive the appropriate tag. It is perfectly reasonable for actions
to contain multiple tags for different variant names; there might be
debug and nondebug binaries for both sparc and i386.
In Oracle Solaris, kernel components are commonly elided from packages
installed in zones, as they serve no useful purpose. Thus, they are
marked with the ``opensolaris.zone`` variant set to ``global`` so that they
are not installed in non-global zones. This is typically done in the
manifest during publication with a |pkgmogrify| rule. Thus the packages
from the i386 and sparc builds are already marked for zones. We then
use the |pkgmerge| command to take the packages from the sparc and i386
builds and merge them together. This is far more reliable and faster
than attempting to construct such packages manually.
The ``variant.debug.*`` portion of the variant namespace is explicitly
predefined to have a default version of ``false``; thus, developers
can provide debug versions of their components, tagged with the
appropriate variant, and users can select that variant if problems
arise. Remember that variants are set per image, so selecting a
suitable name that is unique at the appropriate resolution for that
piece of software is important.
In addition, any variant tags not described here are assumed to
have a default value of ``false`` in the image. This allows
the definition of custom variants not explicitly set in the
image for use in packages.
Note that variant tags are applied to any actions that differ between
architectures during merging; this includes dependencies, ``set`` actions,
etc. Packages that are marked as not supporting one of the variant values
of the current image are not considered for installation.
The |pkgmerge| man page provides several examples of merging packages. Note
that it will merge across multiple different variants at the same time if
needed.
Facets
~~~~~~
Often, package developers have optional portions of their software
that actually belong with the main body, but some people might not
want to install. Some examples are localization files for different
locales, man pages and other documentation, header files needed
only by developers or DTrace users.
Traditionally, such optional content has been placed in separate
packages with an arbitrarily selected naming convention (such as
appending ``-dev`` or ``-devel`` to the package name) enabling administrators
to select the optional content.
This has led to various problems, such as adding a new locale
for all the software on a system being a rather irritating task,
as the admin has to discover all the necessary packages by examining
the lists of available packages.
IPS has implemented a mechanism similar to variants called *facets*
to deal with this problem. Like variants, facets have a name and
a value. The value is either set to ``true`` or ``false`` in the
image. The default value is ``true``. The facet namespace is hierarchal,
with matching rules such that the longest match wins.
For example, the default value for all facets is ``true``; the |pkg| client
implicitly sets ``facet.*`` to ``true``.
Documentation in Oracle Solaris packages is tagged with the type of
documentation. For example, man pages are tagged with
``facet.doc.man=true`` in the package manifests.
The following commands include man pages but exclude all other documentation
from being installed in this image::
# pkg change-facet facet.doc.*=false
# pkg change-facet facet.doc.man=true
Similarly, the following commands install only the German localization in this
image::
# pkg change-facet facet.locale.*=false
# pkg change-facet facet.locale.de=true
If an action contains multiple facet tags, the action is installed if the value
of any of the facet tags is ``true``.
The ``pkg facet`` command is useful in determining which facets are
set in the image.
The package developer can use |pkgmogrify| to quickly tag his
man pages, localizations, etc. using regular expressions to
match the different types of files. This is described in detail
in *Chapter 8*.
Facets can also be used to manage dependencies, essentially turning
dependencies on and off, depending on whether the facet is set. See
*Chapter 6* for a discussion of ``facet.version-lock.*``.
Oracle Solaris facets that might be of use for software developers include:
======================== ================== ==================
======================== ================== ==================