Skip to main content

Source code file content

Revision: 3009

18116510 operation planning ignores removed facets if new are set at same time
» Project Revision History

» Checkout URL

pkg-gate / doc / mediated-links.txt

Size: 11910 bytes, 1 line
Problem Statement
=================

It's common to want multiple versions of a component installed on a system.
In order for this to work, each version must have no coincident pathnames.
For most pathnames, it's easy to put them in a versioned directory or give
them a versioned name.  But for some frequently used pathnames (an
executable expected to be in $PATH, or a man page), it's highly convenient
to provide an unversioned path (possibly as a link to a versioned path) for
casual use.

This of course leads to a conflict when multiple component versions all
want to provide the same unversioned path.  We need a mechanism by which we
can manage these paths.

The most typical desired behavior for these paths is that they refer to the
latest version available; that is, if component foo has versions 1.2, 1.3,
and 1.4 installed, then unversioned pathnames for foo should refer to the
1.4 version.  However, there may be reasons that the package vendor, the
site administrator, or even the local system administrator may want to
override this choice.  Since properly written code uses the versioned
pathnames, the reference should be allowed to switch at arbitrary times.

Another related problem is the delivery of different components which
provide similar functionality.  This differs from the previously stated
problem in that the components don't share the same versioning space, and
so need a different namespace from which the desired component can be
chosen.

Finally, a versioned component may also have different implementations
(indeed, there may be multiple implementation axes), so we need to handle
both problems at once.


Proposal
========

We assert that this problem can be restricted to pathnames which can be
replaced by symbolic links.  Although a solution could apply to other
filesystem entry types, the implementations would be significantly more
difficult, and likely wouldn't provide any real benefit.

To that, we introduce the notion of "mediated links", being symlinks or
hardlinks which are subject -- when necessary -- to mediation in the case of
conflict.  Mediated links are link or hardlink actions with some extra metadata
that allows the packaging system to treat conflicts specially.

The one required attribute is "mediator", whose value denotes the entry in
the namespace shared by all the pathnames participating in a given
mediation group.  For instance, the mediator attribute value for all
/usr/bin/python and /usr/share/man/man1/python.1 links might be "python".
The value of this attribute must be an alphanumeric string.

For a link mediated solely by version, the "mediator-version" attribute is
required.  This is the version (expressed as a dot-separated sequence of
nonnegative integers) of the interface described by the "mediator"
attribute, and not necessarily related to the version of the implementation
delivered by the package, or by the version in the package FMRI.  For
instance, links participating in the "python" mediation might have
"mediator-version" set to "2.4", "2.6", "3.2", etc.

When resolving the conflict in mediated links, pkg(5) will normally choose
the link with the greatest value of "mediator-version".  The package vendor
may override this selection by adding the attribute "mediator-priority"
with the value "vendor" to its preferred link in a package it delivers.
Similarly, site administrators may override the selection by version or the
vendor override by adding the attribute "mediator-priority" with the value
"site" to its preferred link.  The local system administrator may override
this selection with the commandline specified below.

Mediation may be performed by implementation in addition to or instead of
by version.  In this case, the attribute is "mediator-implementation" and
the value must be a string containing only alphanumeric characters and '-'
(preferably short and descriptive).  Implementation strings are not considered
to be ordered, and so one must be chosen explicitly, or the system will choose
arbitrarily (first in lexical order).  As with versioned mediation,
"mediator-priority=vendor" and "mediator-priority=site" can be used to override
the default behavior, and the local administrator can set the preference
explicitly.

If the implementation itself can be or is versioned, then the value may
have a '@' and a version appended to it.  If multiple versions of an
implementation exist, the default will be to choose the greatest as defined
by those versions, similarly to the purely version-mediated scenario.

By default, every time a package operation is performed, the "best" mediation
will be selected and then applied to all packages.  However, the local
administrator may explicitly set both the version and implementation for a
mediation, or only one of them, in which case the system will select the "best"
mediation with the matching component.

All links delivered to a given pathname must participate in mediation or not
at all.  If some links delivered to a given pathname are mediated, and some
are not, package operations will fail with a conflicting error message. Likewise,
all mediated links delivered to a given pathname must share the same mediator.

However, not all mediator versions and implementations need to provide a link at
a given path.  If a version and/or implementation doesn't provide a link, then the
link is removed when that version is selected.

The commandline used for locally administering mediated links is as
follows:

  - pkg set-mediator [-V <version>] [-I <implementation>] mediator ...

    Sets the mediator <mediator> to a given version and/or implementation.

  - pkg unset-mediator [-V] [-I] mediator ...

    Reverts the mediator <mediator> to the system default.  If the -V option is
    supplied, revert the version-mediated aspect to the system default, but leave
    the implementation mediation in place.  If the -I option is supplied,
    revert the implementation-mediated aspect to the system default, but
    leave the version mediation in place.  If neither -V or -I are specified,
    both the version and implementation will be reverted to the system default.

  - pkg mediator [<mediator> ...]

    Display information about the mediators on the system.  When one or
    more mediators are specified, display information only about the specified
    mediators.  The information should include the mediator name, selected
    version and implementation, and how each component was chosen by the system.

Examples
========

Mediation by version
--------------------

The canonical case for version mediation is a language platform.  In this
case, we'll investigate Python.  Two paths that might be mediated are the
python interpreter executable and its manpage.  The runtime/python-26
package would deliver

    file path=usr/bin/python2.6 ...
    file path=usr/share/man/man1/python2.6.1 ...
    link path=usr/bin/python target=python2.6 mediator=python \
        mediator-version=2.6
    link path=usr/share/man/man1/python.1 target=python2.6.1 mediator=python \
        mediator-version=2.6

and the runtime/python-24 package would deliver

    file path=usr/bin/python2.4 ...
    file path=usr/share/man/man1/python2.4.1 ...
    link path=usr/bin/python target=python2.4 mediator=python \
        mediator-version=2.4
    link path=usr/share/man/man1/python.1 target=python2.4.1 mediator=python \
        mediator-version=2.4

If only runtime/python-26 were installed, then /usr/bin/python would be
linked to python2.6.  Likewise, if only runtime/python-24 were installed,
then /usr/bin/python would be linked to python2.4.  If both were installed,
then by default, 2.6 would be found to be greater than 2.4, and the link
would point to python2.6.

If the vendor of the two packages wished, they could deliver a package
"runtime/python" which would simply have a dependency on the desired
default version.

If the local administrator preferred /usr/bin/python to be version 2.4,
then she could run

    pkg set-mediator -V 2.4 python

after which running "python" would run the 2.4 interpreter, and "man
python" would display the manual for the 2.4 interpreter.


Vendor override
---------------

If, in the above scenario, the vendor of runtime/python-26 and
runtime/python-24 wished to override the default behavior and have the 2.4
interpreter be the default, then the runtime/python-24 package would
deliver

    file path=usr/bin/python2.4 ...
    file path=usr/share/man/man1/python2.4.1 ...
    link path=usr/bin/python target=python2.4 mediator=python \
        mediator-version=2.4 mediator-priority=vendor
    link path=usr/share/man/man1/python.1 target=python2.4.1 mediator=python \
        mediator-version=2.4 mediator-priority=vendor

Thus in the case where both runtime/python-26 and runtime/python-24 were
installed, /usr/bin/python would point to python2.4, despite 2.6 being
greater than 2.4.  The "runtime/python" package would likely then contain a
a dependency on "runtime/python-24".  The local administrator could
override this choice to 2.6 by running

    pkg set-mediator -V 2.6 python


Mediation by implementation
---------------------------

The canonical case for implementation mediation is the editor vi.  There
are multiple implementations of vi, but there is no versioned specification
which each implements.  We will examine vim, nvi, and the legacy Solaris
vi.

In the package editor/vim, we deliver

    file path=usr/bin/vim
    link path=usr/bin/vi target=vim mediator=vi mediator-implementation=vim

In the package editor/svr4-vi, we deliver

    file path=usr/has/bin/vi
    link path=usr/bin/vi target=../has/bin/vi mediator=vi mediator-implementation=svr4

And in the package editor/nvi, we deliver

    file path=usr/bin/nvi
    link path=usr/bin/vi target=nvi mediator=vi mediator-implementation=nvi

If editor/vim were installed on the system without either of the others,
then /usr/bin/vi would point to vim.  If either of the other packages were
later added, the /usr/bin/vi would continue to run vim, until the local
administrator were to run

    pkg set-mediator -I svr4 vi

which would switch the link to run legacy Solaris vi.  If the packages were
all installed simultaneously, the link would be chosen arbitrarily.  The
vendor ought to deliver a vendor priority tag:

    link path=usr/bin/vi target=vim mediator=vi mediator-implementation=vim \
        mediator-priority=vendor

so that the desired default is always chosen.


Mediation with multiple implementations
---------------------------------------

Vim can be configured with a handful of different compile-time options.
For this example, we'll focus on --with-features=tiny (the minimal
configuration) and --with-features=huge (the maximal configuration, sans
GUI and external languages).

As before, we deliver the package editor/svr4-vi:

    file path=usr/has/bin/vi
    link path=usr/bin/vi target=../has/bin/vi mediator=vi mediator-implementation=svr4

We deliver two vim packages -- one for tiny, one for huge -- with a new
"vim" implementation-based mediator, set to "tiny" for the tiny package and
"huge" for the huge package.  In addition, an implementation-based mediated
link is delivered to /usr/bin/vi which targets vim if the vi mediator is
set to vim.  Since these two actions are identical, there is no conflict.

Here is vim-tiny:

    file path=usr/bin/vim-tiny
    link path=usr/bin/vim target=vim-tiny mediator=vim mediator-implementation=tiny
    link path=usr/bin/vi target=vim mediator=vi mediator-implementation=vim

and editor/vim-huge:

    file path=usr/bin/vim-huge
    link path=usr/bin/vim target=vim-huge mediator=vim mediator-implementation=huge
    link path=usr/bin/vi target=vim mediator=vi mediator-implementation=vim

Thus to ensure that /usr/bin/vi is the huge vim, the administrator would
have to run

    pkg set-mediator -I huge vim
    pkg set-mediator -I vim vi
 
 
Close
loading
Please Confirm
Close