mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 13:20:42 +00:00
369 lines
14 KiB
Text
369 lines
14 KiB
Text
.. 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 6
|
|
---------
|
|
|
|
Specifying Dependencies
|
|
.......................
|
|
|
|
Dependencies define how packages are related.
|
|
|
|
IPS provide a variety of different dependency types as discussed in
|
|
*Chapter 3*. In this chapter we go into more detail about how each
|
|
dependency type can be used to control the software that is installed.
|
|
|
|
In IPS, a package cannot be installed unless all package dependencies are
|
|
satisfied. IPS allows packages to be mutually dependent (to have circular
|
|
dependencies). IPS also allows packages to have different kinds of
|
|
dependencies on the same package at the same time.
|
|
|
|
Dependency Types
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
Each section below contains an example ``depend`` action, as it would appear in
|
|
a manifest during package creation.
|
|
|
|
``require``
|
|
```````````
|
|
|
|
The most basic type of dependency is the ``require`` dependency.
|
|
|
|
If a package A@1.0 contains a ``require`` dependency on package B@2,
|
|
it means that if A@1.0 is installed, a version of B at 2 or higher
|
|
must be installed as well.
|
|
|
|
This acceptance of higher versioned packages reflects the implicit
|
|
expectation of binary compatibility in newer versions of existing
|
|
packages.
|
|
|
|
These dependencies are typically used to express functional dependencies
|
|
such as libraries or interpreters such as Python, Perl, etc. The version
|
|
portion of the specified FMRI can be omitted; it indicates that any
|
|
version will suffice. The latter might not be actually true, but
|
|
if other dependencies constrain the version adequately, this might
|
|
save some effort.
|
|
|
|
An example ``require`` dependency is::
|
|
|
|
depend fmri=pkg:/system/library type=require
|
|
|
|
|
|
``require-any``
|
|
```````````````
|
|
|
|
The ``require-any`` dependency is used if more than one package will
|
|
satisfy a functional requirement. IPS will pick one of the packages to
|
|
install if the dependency is not already satisfied.
|
|
|
|
A typical use might be to ensure that at least one version of Perl
|
|
was installed on the system, for example. The versioning is handled
|
|
in the same manner as for the ``require`` dependency.
|
|
|
|
An example ``require-any`` dependency is::
|
|
|
|
depend type=require-any fmri=pkg:/editor/gnu-emacs/gnu-emacs-gtk \
|
|
fmri=pkg:/editor/gnu-emacs/gnu-emacs-no-x11 \
|
|
fmri=pkg:/editor/gnu-emacs/gnu-emacs-x11
|
|
|
|
``optional``
|
|
````````````
|
|
|
|
The ``optional`` dependency is similar to the ``require`` dependency, but
|
|
the specified package need not be installed. However, if it is present,
|
|
it must be at the specified version or greater.
|
|
|
|
This type of dependency is typically used to handle cases where packages
|
|
transfer content.
|
|
|
|
In this case, each version of the package post-transfer
|
|
would contain an optional dependency on the other package's
|
|
post-transfer version, so it would be impossible to install
|
|
incompatible versions of the two packages.
|
|
|
|
Omitting the version on an optional dependency makes the dependency a no-op,
|
|
but is permitted.
|
|
|
|
An example ``optional`` dependency is::
|
|
|
|
depend fmri=pkg:/x11/server/xorg@1.9.99 type=optional
|
|
|
|
``conditional``
|
|
```````````````
|
|
|
|
The ``conditional`` dependency is similar to the ``require`` dependency as
|
|
well, except that a predicate attribute is present. If the package specified
|
|
in the value of the predicate attribute is present on the system at the
|
|
specified or greater version, the conditional dependency is treated as a
|
|
``require`` dependency, otherwise it is ignored.
|
|
|
|
This type of dependency is most often used to install optional extensions
|
|
to a package if the requisite base packages are present on the system.
|
|
|
|
For example, an editor package that has both X11 and terminal versions might
|
|
place the X11 version in a separate package, and include a conditional
|
|
dependency on the X11 version from the text version with the existence
|
|
of the requisite X client library package as the predicate.
|
|
|
|
An example conditional dependency is::
|
|
|
|
depend type=conditional fmri=library/python-2/pycurl-26 \
|
|
predicate=runtime/python-26
|
|
|
|
``group``
|
|
`````````
|
|
|
|
The ``group`` dependency is used to construct groups of packages.
|
|
|
|
The group dependency will ignore the version specified; any version of the
|
|
named package satisfies this dependency. The named package
|
|
is required unless the package has been placed on the avoid list (see |pkg|),
|
|
the package is rejected with ``pkg install --reject``, or the package is
|
|
uninstalled with ``pkg uninstall``.
|
|
|
|
These three options enable administrators to 'deselect' packages that are the
|
|
subject of a group dependency. IPS will remember this and not re-install the
|
|
package during an update unless it becomes required by another dependency.
|
|
If the new dependency is removed by another subsequent operation, then the
|
|
package is uninstalled again.
|
|
|
|
A good example of how to use these dependencies is to construct packages
|
|
containing group dependencies on packages that are needed for typical uses
|
|
of a system.
|
|
|
|
The administrator could install all that apply and know that over subsequent
|
|
updates to newer versions of the OS, the appropriate packages would be added
|
|
to his system.
|
|
|
|
An example ``group`` dependency is::
|
|
|
|
depend fmri=package/pkg type=group
|
|
|
|
|
|
``origin``
|
|
``````````
|
|
|
|
The ``origin`` dependency exists to resolve upgrade issues that require
|
|
intermediate transitions. The default behavior is to specify the minimum
|
|
version of a package (if installed) that must be present on the system being
|
|
updated.
|
|
|
|
For example, a typical use might be a database package version 5 that supports
|
|
upgrade from version 3 or greater, but not earlier versions.
|
|
|
|
In this case, version 5 would have an origin dependency on itself at version 3.
|
|
Thus, if version 5 was being fresh installed, installation would proceed; but
|
|
if version 1 of the package was installed, one could not upgrade directly to this
|
|
version.
|
|
|
|
Thus, ``pkg update database-package`` would not select version 5
|
|
in this case but would pick version 3 instead as the latest possible
|
|
version it could upgrade to.
|
|
|
|
The behavior of this dependency can be modified by the ``root-image`` attribute
|
|
being set to ``true``; in this case the named package must be at the specified
|
|
version or greater if it is present in the running system, rather than the image
|
|
being updated.
|
|
|
|
This is generally used for operating system issues such as dependencies on boot
|
|
block installers.
|
|
|
|
An example ``origin`` dependency is::
|
|
|
|
depend fmri=pkg:/database/mydb@3.0 type=origin
|
|
|
|
|
|
``parent``
|
|
``````````
|
|
|
|
The ``parent`` dependency is used for zones or other child images. In
|
|
this case, the dependency is only checked in the child image, and specifies a
|
|
package and version that must be present in the parent image or global
|
|
zone. The version specified must match to the level of precision
|
|
specified.
|
|
|
|
For example, if the ``parent`` dependency is on A@2.1, then any version of A
|
|
beginning with 2.1. will match. This dependency is often used to require that
|
|
packages are kept in sync between non-global zones and the global zone, and as
|
|
a short cut a special package name ``feature/package/dependency/self`` is used
|
|
as a synonym for the exact version of the package that contains this dependency.
|
|
|
|
This is used to keep key operating system components, such as ``libc.so.1``
|
|
installed in the zone synchronized with the kernel installed in the global zone.
|
|
The ``parent`` dependency is also discussed in *Chapter 12*.
|
|
|
|
An example ``parent`` dependency is::
|
|
|
|
depend type=parent fmri=feature/package/dependency/self \
|
|
variant.opensolaris.zone=nonglobal
|
|
|
|
|
|
``incorporate``
|
|
```````````````
|
|
|
|
The ``incorporate`` dependency is heavily used in OpenIndiana to ensure that
|
|
compatible versions of software are installed together.
|
|
|
|
The basic mechanism is like that of an ``optional`` dependency, except
|
|
that the version matching is that of the ``parent`` dependency: if this package
|
|
is present, it must be at the specified version to the level
|
|
specified.
|
|
|
|
How these dependencies are typically used is that many of
|
|
them are placed in the same package to define a surface in the package
|
|
version space that is compatible. Packages that contain such sets of
|
|
incorporate dependencies are often called *incorporations*; it is
|
|
typical to define such for sets of software packages that are built
|
|
together and are not separately versioned, like much of the kernel.
|
|
|
|
An example ``incorporate`` dependency is::
|
|
|
|
depend type=incorporate \
|
|
fmri=pkg:/driver/network/e1000g@0.5.11,5.11-2018.0.0.18233
|
|
|
|
|
|
``exclude``
|
|
```````````
|
|
|
|
The ``exclude`` dependency is seldom used. It allows the containing
|
|
package to preclude installation with the specified package at the
|
|
specified version or higher.
|
|
|
|
Note that if the version is omitted, no version of the specified package
|
|
can be installed with the containing package. These constraints can be
|
|
frustrating to administrators, and should be avoided where possible.
|
|
|
|
An example exclude dependency is::
|
|
|
|
depend fmri=pkg:/x11/server/xorg@1.10.99 type=exclude
|
|
|
|
|
|
Constraints and Freezing
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Constraints
|
|
```````````
|
|
|
|
Through the careful use of the various types of ``depend`` actions described
|
|
above, packages can define the ways in which they are allowed to be upgraded.
|
|
|
|
In general, we often desire that a group of packages installed on a system
|
|
be supported and upgraded as a group: Either all packages in the group are
|
|
updated, or none of the packages in the group are updated. As mentioned earlier,
|
|
this is the reason for using the ``incorporate`` dependency in OpenIndiana.
|
|
|
|
The following three partial package manifests show the relationship
|
|
between the ``foo`` and ``bar`` packages and the ``myincorp`` incorporation
|
|
package:
|
|
|
|
::
|
|
|
|
set name=pkg.fmri value=foo@1.0
|
|
dir path=foo owner=root group=bin mode=0755
|
|
depend fmri=myincorp type=require
|
|
|
|
::
|
|
|
|
set name=pkg.fmri value=bar@1.0
|
|
dir path=bar owner=root group=bin mode=0755
|
|
depend fmri=myincorp type=require
|
|
|
|
::
|
|
|
|
set name=pkg.fmri value=myincorp@1.0
|
|
depend fmri=foo@1.0 type=incorporate
|
|
depend fmri=bar@1.0 type=incorporate
|
|
|
|
The ``foo`` and ``bar`` packages both have a ``require`` dependency on the
|
|
``myincorp`` incorporation. The ``myincorp`` package has ``incorporate``
|
|
dependencies such that ``foo`` and ``bar`` can be upgraded to
|
|
**at most** version 1.0, to the level of granularity defined by the version
|
|
number and, if installed, must be **at least** at version 1.0 or greater.
|
|
|
|
That is, an ``incorporate`` dependency on version 1.0 allows for
|
|
1.0.1, 1.0.2.1, etc. but doesn't allow version 1.1, version 2.0, version 0.9,
|
|
etc. When we deliver a new incorporation package, one that has ``incorporate``
|
|
dependencies at a higher version, we will allow ``foo`` and ``bar`` to upgrade
|
|
to those versions instead (assuming that the incorporation package is also being
|
|
upgraded).
|
|
|
|
Note here that because ``foo`` and ``bar`` both have ``require`` dependencies on
|
|
the ``myincorp`` package, the incorporation package must always be installed.
|
|
|
|
|
|
However, conflicting with the requirement we stated at the beginning of this
|
|
section, there are some situations where we might want to relax the
|
|
incorporation constraint.
|
|
|
|
Perhaps ``bar`` can function independently of ``foo``, but we'd like ``foo``
|
|
to remain within the series of versions our incorporation constrains it to.
|
|
|
|
|
|
We can relax the incorporation constraints using *facets*, allowing the
|
|
administrator to effectively *disable* certain ``incorporate`` dependencies.
|
|
Facets are discussed in more detail in *Chapter 7*. Briefly, facets
|
|
are special attributes that can be applied to actions within a package to enable
|
|
authors to mark those actions as optional.
|
|
|
|
When actions are marked with facet attributes in this manner, the actions
|
|
containing those facets can be enabled or disabled using the
|
|
``pkg change-facet`` command.
|
|
|
|
By convention, facets that optionally install ``incorporate`` dependencies are
|
|
named ``facet.version-lock.<name>``, where *name* is the package name containing
|
|
that ``depend`` action.
|
|
|
|
So, for example, using the example above, we could have the following
|
|
incorporation::
|
|
|
|
set name=pkg.fmri value=myincorp@1.0
|
|
depend fmri=foo@1.0 type=incorporate
|
|
depend fmri=bar@1.0 type=incorporate facet.version-lock.bar=true
|
|
|
|
This incorporation includes our ``depend`` action by default, constraining
|
|
``bar`` to version 1.0. The following command relaxes this constraint::
|
|
|
|
pkg change-facet version-lock.bar=false
|
|
|
|
The ``bar`` package is free from the incorporation constraints, and can be
|
|
upgraded to version 2.0 if necessary.
|
|
|
|
|
|
Freezing
|
|
````````
|
|
|
|
So far, all of the discussion has been around constraints that have been applied
|
|
during the package authoring process, by modifying the package manifests
|
|
themselves.
|
|
|
|
|pkg| also has a means for the administrator to apply constraints to the system
|
|
at runtime.
|
|
|
|
Using the ``pkg freeze`` command, the administrator can prevent a given
|
|
package from being updated past either its current version, or a version
|
|
specified on the command line. This capability is effectively the same as an
|
|
``incorporate`` dependency.
|
|
|
|
See the |pkg| man page for more information on the ``freeze`` command.
|
|
|
|
In order to apply more complex dependencies to an image, it is necessary to
|
|
create and install a package that includes those dependencies.
|
|
|