mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 21:30:41 +00:00
193 lines
7.4 KiB
Text
193 lines
7.4 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 8
|
||
---------
|
||
|
||
Modifying Package Manifests Programmatically
|
||
............................................
|
||
|
||
This chapter explains how package manifests can be machine edited to permit the
|
||
automated annotation and checking of package manifests.
|
||
|
||
*Chapter 4* covers the basics for how to publish packages. These techniques are
|
||
all that is necessary to publish a package, but when publishing a large package,
|
||
a large number of packages, or publishing packages over a period of time, there
|
||
can be aspects which involve a significant time commitment for doing repetitive
|
||
tasks.
|
||
|
||
For example, one rule that's used when publishing OpenIndiana is that all
|
||
kernel modules should be tagged as requiring a reboot.
|
||
|
||
One option would be to impose this constraint through human examination and
|
||
intervention, but that would be costly and likely error prone.
|
||
|
||
A second option would be to write a script or program that would handle tagging
|
||
these actions. The difficulty here is that to be sure the program tagged
|
||
actions correctly, it would need to parse the actions. This can certainly be
|
||
done, but it duplicates a lot of functionality already in the IPS framework.
|
||
|
||
The third, and best, option is to use |pkgmogrify|, provided by IPS, to
|
||
transform the package manifests in repeatable ways.
|
||
|
||
There are two types of rules |pkgmogrify| understands, transform and include.
|
||
Transform rules are used to modify actions. Include rules cause other
|
||
files to be processed.
|
||
|
||
Transform Rules
|
||
~~~~~~~~~~~~~~~
|
||
|
||
When publishing OpenIndiana, we made the assumption that all files delivering
|
||
in a subdirectory named "``kernel``" should be treated as kernel modules. This
|
||
is the rule used to do the tagging::
|
||
|
||
<transform file path=.*kernel/.+ -> default reboot-needed true>
|
||
|
||
..
|
||
|
||
* The rule is enclosed with ‘``<``’ and ‘``>``’. The portion of the rule to
|
||
the left of the ‘``->``’ is the selection section or matching section. The
|
||
portion to the right of the ‘``->``’ is the execution section of the
|
||
operation.
|
||
|
||
* ‘``transform``’ is the type of the rule
|
||
|
||
* ‘``file``’ means this rule is for ``file`` actions
|
||
|
||
* ‘``path=.*kernel/.+``’ means that only file actions with a path attribute
|
||
that matches the regular expression ‘``.*kernel/.+``’ are transformed
|
||
|
||
* ‘``default``’ means that what follows should be added to a matching action
|
||
unless a value for the attribute has already been set
|
||
|
||
* ‘``reboot-needed``’ is the attribute being set
|
||
|
||
* ‘``true``’ is the value of the attribute
|
||
|
||
|
||
|
||
The selection or matching section of a transform rule can restrict by action
|
||
type and by action attribute values. The |pkgmogrify| man page goes into detail
|
||
about how these matching rules work, but the typical uses are for selecting
|
||
actions which deliver to certain areas of the file system.
|
||
|
||
.. raw:: pdf
|
||
|
||
PageBreak
|
||
|
||
For example, a rule that began like this
|
||
|
||
.. parsed-literal::
|
||
|
||
<transform file dir link hardlink path=usr/bin.\* -> *[operation]*>
|
||
|
||
could be used to ensure that ``usr/bin`` and everything delivered inside of it
|
||
defaulted to the correct user or group. There is a long list of operations
|
||
which |pkgmogrify| can perform, detailed in the man page, which enable a package
|
||
developer to programmatically add, remove, set, and edit actions' attributes as
|
||
well as add and remove entire actions.
|
||
|
||
Include Rules
|
||
~~~~~~~~~~~~~
|
||
|
||
Include rules enable transforms to be spread across multiple files and subsets
|
||
reused by different manifests. Suppose a developer needs to deliver two
|
||
packages: A and B. Both packages should have their ``source-url`` set to the
|
||
same url, but only package B should have its files in ``/etc`` set to be
|
||
``group=sys``.
|
||
|
||
In the manifest for package A, an include rule which pulls in the file with the
|
||
``source-url`` transform should be added. In package B, an include rule which
|
||
pulls in the file containing the file ``group`` setting transform should be
|
||
added.
|
||
|
||
Finally, an include rule which pulls in the file with the ``source-url``
|
||
transform should be added to either package B or the file with the transform
|
||
that sets the group.
|
||
|
||
Transform Order
|
||
~~~~~~~~~~~~~~~
|
||
|
||
Transforms are applied in the order in which they are encountered in a file.
|
||
The ordering can be used to simplify the matching portions of transforms.
|
||
|
||
Suppose all files delivered in ``/foo`` should have a default group of ``sys``,
|
||
except those delivered in ``/foo/bar``, which should have a default group of
|
||
``bin``.
|
||
|
||
It's certainly possible to write a complex regular expression which matches all
|
||
paths that begin with ``/foo``, except those that begin with ``/foo/bar``. Using
|
||
the ordering of transforms makes it much simpler.
|
||
|
||
When ordering default transforms, always go from most specific to most general.
|
||
Otherwise the latter rules will never be used.
|
||
|
||
In this case, the two rules would look like this::
|
||
|
||
<transform file path=foo/bar/.* -> default group bin>
|
||
<transform file path=foo/.* -> default group sys>
|
||
|
||
Using transforms to add an action using the matching described above would be
|
||
difficult since the package developer would need to find a pattern which matched
|
||
each package delivered once and only once.
|
||
|
||
|pkgmogrify| creates synthetic actions to help with this issue. As |pkgmogrify|
|
||
processes manifests, for each manifest that sets the ``pkg.fmri`` attribute,
|
||
a synthetic *pkg action* is created by |pkgmogrify|. The package developer can
|
||
match against the ``pkg`` action as if it was actually in the manifest.
|
||
|
||
For example, suppose a package developer wanted to add to every package an
|
||
action containing the website (foo.com) where the source code for the delivered
|
||
software can be found. The following transform accomplishes that::
|
||
|
||
<transform pkg -> emit set info.source-url=http://foo.com>
|
||
|
||
|
||
|
||
.. raw:: pdf
|
||
|
||
PageBreak
|
||
|
||
Packaged Transforms
|
||
~~~~~~~~~~~~~~~~~~~
|
||
|
||
As a convenience to developers, a set of the transforms that were used when
|
||
packaging OpenIndiana itself are available in ``/usr/share/pkg/transforms``.
|
||
At the time of writing, these are:
|
||
|
||
**developer**
|
||
Sets ``facet.devel`` on ``*.h`` header files delivered to
|
||
``/usr/.*/include``, archive and lint libraries, ``pkg-config(1)`` data
|
||
files, and ``autoconf(1)`` macros.
|
||
|
||
**documentation**
|
||
Sets a variety of ``facet.doc.*`` facets on documentation files.
|
||
|
||
**locale**
|
||
Sets a variety of ``facet.locale.*`` facets on files which are
|
||
locale-specific.
|
||
|
||
**smf-manifests**
|
||
Adds a ``restart_fmri`` actuator pointing to the
|
||
``svc:/system/manifest-import:default`` on any packaged SMF manifests
|
||
so that the system will import that manifest after the package is
|
||
installed.
|
||
|