.. 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
or http://www.opensolaris.org/os/licensing.
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:
======================== ================== ==================
facet.devel facet.locale.es_BO facet.locale.lt_LT
facet.doc facet.locale.es_CL facet.locale.lv
facet.doc.man facet.locale.es_CO facet.locale.lv_LV
facet.doc.pdf facet.locale.es_CR facet.locale.mk
facet.doc.info facet.locale.es_DO facet.locale.mk_MK
facet.doc.html facet.locale.es_EC facet.locale.ml
facet.locale facet.locale.es_ES facet.locale.ml_IN
facet.locale.af facet.locale.es_GT facet.locale.mr
facet.locale.af_ZA facet.locale.es_HN facet.locale.mr_IN
facet.locale.ar facet.locale.es_MX facet.locale.ms
facet.locale.ar_AE facet.locale.es_NI facet.locale.ms_MY
facet.locale.ar_BH facet.locale.es_PA facet.locale.mt
facet.locale.ar_DZ facet.locale.es_PE facet.locale.mt_MT
facet.locale.ar_EG facet.locale.es_PR facet.locale.nb
facet.locale.ar_IQ facet.locale.es_PY facet.locale.nb_NO
facet.locale.ar_JO facet.locale.es_SV facet.locale.nl
facet.locale.ar_KW facet.locale.es_US facet.locale.nl_BE
facet.locale.ar_LY facet.locale.es_UY facet.locale.nl_NL
facet.locale.ar_MA facet.locale.es_VE facet.locale.nn
facet.locale.ar_OM facet.locale.et facet.locale.nn_NO
facet.locale.ar_QA facet.locale.et_EE facet.locale.no
facet.locale.ar_SA facet.locale.eu facet.locale.or
facet.locale.ar_TN facet.locale.fi facet.locale.or_IN
facet.locale.ar_YE facet.locale.fi_FI facet.locale.pa
facet.locale.as facet.locale.fr facet.locale.pa_IN
facet.locale.as_IN facet.locale.fr_BE facet.locale.pl
facet.locale.az facet.locale.fr_CA facet.locale.pl_PL
facet.locale.az_AZ facet.locale.fr_CH facet.locale.pt
facet.locale.be facet.locale.fr_FR facet.locale.pt_BR
facet.locale.be_BY facet.locale.fr_LU facet.locale.pt_PT
facet.locale.bg facet.locale.ga facet.locale.ro
facet.locale.bg_BG facet.locale.gl facet.locale.ro_RO
facet.locale.bn facet.locale.gu facet.locale.ru
facet.locale.bn_IN facet.locale.gu_IN facet.locale.ru_RU
facet.locale.bs facet.locale.he facet.locale.ru_UA
facet.locale.bs_BA facet.locale.he_IL facet.locale.rw
facet.locale.ca facet.locale.hi facet.locale.sa
facet.locale.ca_ES facet.locale.hi_IN facet.locale.sa_IN
facet.locale.cs facet.locale.hr facet.locale.sk
facet.locale.cs_CZ facet.locale.hr_HR facet.locale.sk_SK
facet.locale.da facet.locale.hu facet.locale.sl
facet.locale.da_DK facet.locale.hu_HU facet.locale.sl_SI
facet.locale.de facet.locale.hy facet.locale.sq
facet.locale.de_AT facet.locale.hy_AM facet.locale.sq_AL
facet.locale.de_BE facet.locale.id facet.locale.sr
facet.locale.de_CH facet.locale.id_ID facet.locale.sr_ME
facet.locale.de_DE facet.locale.is facet.locale.sr_RS
facet.locale.de_LI facet.locale.is_IS facet.locale.sv
facet.locale.de_LU facet.locale.it facet.locale.sv_SE
facet.locale.el facet.locale.it_CH facet.locale.ta
facet.locale.el_CY facet.locale.it_IT facet.locale.ta_IN
facet.locale.el_GR facet.locale.ja facet.locale.te
facet.locale.en facet.locale.ja_JP facet.locale.te_IN
facet.locale.en_AU facet.locale.ka facet.locale.th
facet.locale.en_BW facet.locale.ka_GE facet.locale.th_TH
facet.locale.en_CA facet.locale.kk facet.locale.tr
facet.locale.en_GB facet.locale.kk_KZ facet.locale.tr_TR
facet.locale.en_HK facet.locale.kn facet.locale.uk
facet.locale.en_IE facet.locale.kn_IN facet.locale.uk_UA
facet.locale.en_IN facet.locale.ko facet.locale.vi
facet.locale.en_MT facet.locale.ko_KR facet.locale.vi_VN
facet.locale.en_NZ facet.locale.ks facet.locale.zh
facet.locale.en_PH facet.locale.ks_IN facet.locale.zh_CN
facet.locale.en_SG facet.locale.ku facet.locale.zh_HK
facet.locale.en_US facet.locale.ku_TR facet.locale.zh_HK
facet.locale.en_ZW facet.locale.ky facet.locale.zh_SG
facet.locale.eo facet.locale.ky_KG facet.locale.zh_TW
facet.locale.es_AR facet.locale.lg
======================== ================== ==================