PKG(7) | Standards, Environments, and Macros | PKG(7) |
pkg
— Image
Packaging System
The image packaging system,
pkg
(7),
is a framework that provides for software lifecycle management
(installation, upgrade, and removal). Image packaging manages software in
units of packages, which are collections of actions, defined by a set of
key/value pairs and possibly a data payload. In many cases, actions are
files found in a file system, but they also represent other installable
objects, such as drivers, services, and users.
Each package is represented by a fault management resource identifier (FMRI) with the scheme pkg:. The full FMRI for a package consists of the scheme, a publisher, the package name, and a version string in the following format:
pkg://omnios/terminal/tmux@3.1.2-151036.0:20201029T171510Z
In this example, omnios is the publisher and terminal/tmux is the package name. Although the namespace is hierarchical and arbitrarily deep, there is no enforced containment; the name is essentially arbitrary. The publisher information is optional, but must be preceded by pkg:// if present. An FMRI that includes the publisher is often referred to as being "fully qualified." If publisher information is not present, then the package name should generally be preceded by pkg:/.
Packaging clients often allow the scheme of an FMRI to be omitted if it does not contain publisher information. For example, pkg:/terminal/tmux can be written as terminal/tmux. If the scheme is omitted, clients also allow omission of all but the last component of a package name for matching purposes. For example, terminal/tmux could be written as just tmux, which would then match packages named tmux or package names ending in /tmux.
A publisher name identifies a person, group of persons, or an organisation as the source of one or more packages. To avoid publisher name collisions and help identify the publisher, a best practice is to use a domain name that represents the entity publishing the packages as a publisher name.
The version follows the package name, separated by an at sign (@). The version consists of four sequences of numbers, separated by punctuation. The elements in the first three sequences are separated by dots, and the sequences are arbitrarily long. Leading zeros in version components (for example, (for example, 01.1 or 1.01) are not permitted. Trailing zeros (for example, 1.10) are permitted.
The first part of the version is the component version. For
components tightly bound to the operating system, this is usually the value
of ‘uname -r
’ for that version of the
operating system. For a component with its own development lifecycle, this
sequence is a dotted release number, such as 2.4.10.
The second part of the version, which if present must follow a comma (,), is the build version. The build version specifies what version of the operating system the contents of the package were built on, providing a minimum bound on which operating system version the contents can be expected to run successfully.
The third part of the version, which if present must follow a hyphen (-), is the branch version. The branch version is a versioning component that provides vendor-specific information. The branch version can be incremented when the packaging metadata is changed, independently of the component version. The branch version might contain a build number or other information.
The fourth part of the version, which if present must follow a colon (:), is a timestamp. The timestamp represents when the package was published.
When performing comparisons between versions, no component of the full version is considered unless the components to its left are the same. Thus, 4.3-1 is greater than 4.2-7 because 4.3 is greater than 4.2, and 4.3-3 is greater than 4.3-1 because 3 is greater than 1.
The pkg.human-version attribute can be used to provide a human-readable version string. The value of the pkg.human-version attribute can be provided in addition to the package version described above for the package FMRI but cannot replace the package FMRI version. The human-readable version string is only used for display purposes. See "Set Actions" for more information.
Many parts of the system, when appropriate, abridge FMRIs when displaying them, and accept input in shorter forms to reduce the volume of information displayed or required. Typically, the scheme, publisher, build version, and timestamp can be elided. Sometimes all of the versioning information can be omitted.
Actions represent the installable objects on a system. Actions are described in the manifest of a package. Every action consists primarily of its name and a key attribute. Together, these refer to a unique object as it follows a version history. Actions can have other attributes. Some attributes are interpreted directly by the packaging system. Other attributes might be useful only to the system administrator or the end-user.
Actions have a simple text representation:
Names of attributes cannot have whitespace, quotation marks, or equals signs (=) in them. All characters after the first equals sign belong to the value. Values can have all of those, though spaces must be enclosed in single or double quotation marks. Single quotation marks do not need to be escaped inside a string that is enclosed in double quotation marks, and double quotation marks do not need to be escaped inside a string that is enclosed in single quotation marks. A quotation mark can be prefixed with a backslash (\) character to avoid terminating the quoted string. A backslash can itself be escaped with a backslash.
Actions can have multiple attributes. Some attributes can be named multiple times with different values for a single action. Multiple attributes with the same name are treated as unordered lists.
Actions with many attributes can create long lines in a manifest file. Such lines can be wrapped by terminating each incomplete line with a backslash. Note that this continuation character must occur between attribute/value pairs. Neither attributes nor their values nor the combination can be split.
The attributes listed below are not an exhaustive set. In fact, the attributes that can be attached to an action are arbitrary, and the standard sets of attributes are easy to augment to incorporate future developments.
Some attributes cause additional operations to be executed outside of the packaging context. These attributes are documented in the Actuators section below.
Actions that are installed to a path must not deliver content to any of the following paths:
Additionally, the following directories are reserved for use by the system and should also not be used by actions:
The file action represents an ordinary file. The file action references a payload, and has four standard attributes:
The payload is a positional attribute in that it is not named. It is the first word after the action name. In a published manifest, it is the SHA-1 hash of the file contents. If present in a manifest that has yet to be published, it represents the path where the payload can be found. See pkgsend(1). The hash attribute can be used instead of the positional attribute, should the value include an equals sign. Both can be used in the same action, however, the hashes must be identical.
The preserve and overlay attributes affect whether and how a file action is installed.
When a package is initially installed, if a file delivered by the package has a preserve attribute defined with any value except abandon or install-only and the file already exists in the image, the existing file is stored in /var/pkg/lost+found and the packaged file is installed.
When a package is initially installed, if a file delivered by the package has a preserve attribute defined and the file does not already exist in the image, whether that file is installed depends on the value of the preserve attribute:
When a package is downgraded, if a file delivered by the downgraded version of the package has a preserve attribute defined with any value except abandon or install-only and all of the following conditions are true, the file that currently exists in the image is renamed with the extension .update, and the file from the downgraded package is installed.
If any of the above conditions is not true, the file is treated the same as if the package is being upgraded, rather than downgraded.
When a package is upgraded, if a file action delivered by the upgraded version of the package has a preserve attribute defined with any value and the file action is the same as the file action delivered by the currently installed version of the package, the file is not installed, and the file that exists in the image is not modified. Any modifications made since the previous version was installed are preserved.
When a package is upgraded, if a file action delivered by the upgraded version of the package has a preserve attribute defined and the file action is new or is different from the file action delivered by the currently installed version of the package, the upgrade is done in the following way:
When a package is uninstalled, if a file action delivered by the currently installed version of the package has a preserve value of abandon or install-only and the file exists in the image, the file will not be removed.
If overlay is not specified, multiple packages cannot deliver files to the same location.
The overlay attribute can have one of the following values:
Changes to the installed file are preserved based on the value of the preserve attribute of the overlaying file. On removal, the contents of the file are preserved if the action being overlaid is still installed, regardless of whether the preserve attribute was specified. Only one action can overlay another, and the mode, owner, and group attributes must match.
file path=etc/zones/SYSdefault.xml dehydrate=false ...
The following attributes are recognised for ELF files:
uname -p
’ on the architecture for
which the file is built.The following additional attributes are recognised for file actions:
The revert-tag attribute can also be specified at the directory level. See Directory Actions below.
file path=opt/secret_file sysattr=hidden,immutable file path=opt/secret_file sysattr=Hi
The timestamp attribute is essential when packaging .pyc or .pyo files for Python. The related .py file for the .pyc or .pyo files must be marked with the timestamp embedded within those files, as shown in the following example:
file path=usr/lib/python/packages/pkg/__init__.pyc ... file path=usr/lib/python/packages/pkg/__init__.py \ timestamp=20130311T221521Z ...
The following attributes for file actions are automatically generated by the system and should not be specified by package developers:
The dir action is like the file action in that it represents a file system object. The dir action represents a directory instead of an ordinary file. The dir action has the same path, mode, owner, and group attributes that the file action has, and path is the key attribute. The dir action also accepts the revert-tag attribute. The value of the revert-tag attribute is different for file and dir actions.
Directories are reference counted in IPS. When the last package that either explicitly or implicitly references a directory no longer does so, that directory is removed. If that directory contains unpackaged file system objects, those items are moved into $IMAGE_META/lost+found. See the Files section for more information about $IMAGE_META.
The link action represents a symbolic link. The link action has the following standard attributes:
When a package is modified, if a link delivered by the package has a preserve attribute set to true and that link has been removed or modified in the image, then the packaged link will not be installed.
pkg
(7) if not explicitly specified by a system
administrator.
The value can be a string of arbitrary length composed of alphanumeric characters and spaces. If the implementation itself can be versioned or is versioned, then the version should be specified at the end of the string, after a @ (expressed as a dot-separated sequence of non-negative integers). If multiple versions of an implementation exist, the default behaviour is to select the implementation with the greatest version.
If only one instance of an implementation mediation link at a particular path is installed on a system, then that one is chosen automatically. If future links at the path are installed, the link is not switched unless a vendor, site, or local override applies, or if one of the links is version mediated.
pkg
(7)
normally chooses the link with the greatest value of
mediator-version or based on
mediator-implementation if that is not possible. This
attribute is used to specify an override for the normal conflict
resolution process.
If this attribute is not specified, the default mediator selection logic is applied.
If the value is vendor, the link is preferred over those that do not have a mediator-priority specified.
If the value is site, the link is preferred over those that have a value of vendor or that do not have a mediator-priority specified.
A local system administrator can override the selection logic described above.
The hardlink action represents a hard link. It has the same attributes as the link action, and path is also its key attribute.
The driver action represents a device driver. The driver action does not reference a payload. The driver files themselves must be installed as file actions. The following attributes are recognised (see add_drv(8) for more information):
The depend action represents an inter-package dependency. A package can depend on another package because the first requires functionality in the second for the functionality in the first to work, or even to install. Dependencies can be optional. If a dependency is not met at the time of installation, the packaging system attempts to install or update the dependent package to a sufficiently new version, subject to other constraints.
The following attributes are recognised:
The license action represents a license or other informational file associated with the package contents. A package can deliver licenses, disclaimers, or other guidance to the package installer through the use of the license action.
The payload of the license action is delivered into the image metadata directory related to the package, and should only contain human-readable text data. It should not contain HTML or any other form of markup. Through attributes, license actions can indicate to clients that the related payload must be displayed and/or require acceptance of it. The method of display and/or acceptance is at the discretion of clients.
The following attributes are recognised:
The license value must be unique within a package. Including the version of the license in the description, as shown in several of the examples above, is recommended. If a package has code under multiple licenses, use multiple license actions. The length of the license attribute value should not be more than 64 characters.
This attribute should not be used for copyright notices. This attribute should only be used for licenses or other material that must be displayed during operations. The method of display is at the discretion of clients. For package updates, this attribute is ignored if the license action or payload has not changed.
The legacy action represents package data used by a legacy packaging system. The attributes associated with this action are added into the legacy system's databases so that the tools querying those databases can operate as if the legacy package were actually installed. In particular, this should be sufficient to convince the legacy system that the package named by the pkg attribute is installed on the system, so that the package can be used to satisfy dependencies.
The following attributes, named in accordance with the parameters on pkginfo(7), are recognised:
The set action represents a package-level attribute, or metadata, such as the package description.
The following attributes are recognised:
The set action can deliver any metadata the package author chooses. However, there are a number of well defined attribute names that have specific meaning to the packaging system.
pkg
(7) client can use to
classify the package. The value should have a scheme (such as
“org.opensolaris.category.2008” or
“org.acm.class.1998”) and the actual classification, such as
“Applications/Games”, separated by a colon (:).The group action defines a UNIX group as defined in group(7). No support is present for group passwords. Groups defined with this action initially have no user list. Users can be added with the user action. The following attributes are recognised:
The user action defines a UNIX user as defined in /etc/passwd, /etc/shadow, /etc/group, and /etc/ftpd/ftpusers files. Entries are added to the appropriate files for users defined with this user action.
The user action is intended to define a user for a daemon or other software to use. Do not use the user action to define administrative or interactive accounts.
The following attributes are recognised:
In certain contexts, additional operations can be appropriate to execute in preparation for or following the introduction of a particular action. These additional operations are operating system specific and are generally needed only on a live system image. A live image is the image mounted at ‘/’ of the active, running boot environment of the current zone. When multiple actions involved in a package installation or removal have identical actuators, then the operation corresponding to actuator presence is executed once for that installation or removal.
Incorrectly specified actuators can result in package installation failure if the actuator cannot determine a means of making safe installation progress.
The following actuators are defined:
The value can contain a pattern that matches multiple service instances. However, it must do so explicitly with a glob as accepted by svcs(1), rather than doing so implicitly by not indicating any instances.
A mediator is a name that represents a set of related symbolic or hard links. If two or more link actions have the same path and mediator name, the user or the package system selects the link target based on version, implementation, or priority. See Link Actions for information about mediator attributes.
The following example shows two different instances of a mediator named java where the link choices are between versions. These two link actions would appear in two different packages.
link mediator=java mediator-version=1.6 path=usr/java target=jdk1.6 link mediator=java mediator-version=1.7 path=usr/java target=jdk1.7
See the set-mediator subcommand in the pkg(1) man page for information about how to select the version you want for this link path. To have a choice of versions, both packages must be installed.
When a package is transitioned to a new version, or when it is added to or removed from the system, the version that is chosen, or whether removal is allowed, is determined by a variety of constraints put on the package. Those constraints can be defined by other packages in the form of dependencies, or by the administrator in the form of freezes.
The most common form of constraint is delivered by the require dependency, as described in Depend Actions above. Such a constraint prevents the package from being downgraded or removed.
Most parts of the operating system are encapsulated by packages called incorporations. These packages primarily deliver constraints represented by the incorporate dependency.
As described above, an incorporated package need not be present on the system, but if it is, then it specifies both an inclusive minimum version and an exclusive maximum version. For example, if the dependent FMRI has a version of 1.4.3, then no version less than 1.4.3 would satisfy the dependency, and neither would any version greater than or equal to 1.4.4. However, versions that merely extended the dotted sequence, such as 1.4.3.7, would be allowed.
Incorporations are used to force parts of the system to upgrade synchronously. For some components, such as the C library and the kernel, this is a basic requirement. For others, such as a simple userland component on which nothing else has a dependency, the synchronous upgrade is used merely to provide a known and tested set of package versions that can be referred to by a particular version of the incorporation.
Since an incorporation is simply a package, it can be removed, and all the constraints it delivers are therefore relaxed. However, many of the incorporations delivered by OmniOS are required by the packages they incorporate because that relaxation would not be safe.
Attempting an upgrade of a package to a version that is not allowed by an installed incorporation will not attempt to find a newer version of the incorporation in order to satisfy the request, but will instead fail. If the constraint itself must be moved, and the incorporation specifying it cannot be removed, then the incorporation must be upgraded to a version that specifies a desired version of the constraint. Upgrading an incorporation causes all of the incorporated packages that would not satisfy the constraints delivered by the new version to be upgraded as well.
A system administrator can constrain a package by using the pkg freeze command. The named package is constrained to the version installed on the system if no version is provided. If a versioned package is provided, then this administrative constraint, or freeze, acts as if an incorporate dependency were installed where the fmri attribute had the value of the provided package version.
A freeze is never lifted automatically by the packaging system. To relax a constraint, use the pkg unfreeze command.
As detailed above, a publisher is simply a name that package clients use to identify the provider of packages. Publishers can distribute their packages using package repositories and/or package archives. There are two types of repositories currently supported by the package system: origin repositories and mirror repositories.
An origin is a package repository that contains all of the metadata (such as catalogues, manifests, and search indexes) and content (files) for one or more packages. If multiple origins are configured for a given publisher in an image, the package client API attempts to choose the best origin to retrieve package data from. This is the most common type of repository, and is implicitly created whenever pkgsend or pkgrecv is used on a package repository.
A mirror is a package repository that contains only package content (files). If one or more mirrors are configured for a given publisher in an image, the client API prefers the mirrors for package content retrieval and attempts to choose the best one to retrieve package content from. If the mirror is unreachable, does not have the required content, or is slower, the client API retrieves the content from any configured origin repositories. Mirrors are intended for content sharing among a trusted set of clients using the dynamic mirror functionality of pkg.depotd(8). Mirrors are also intended to be used to authenticate access to package metadata, but distribute the package content without authentication. For example, a client might be configured with an https origin that requires an SSL key and certificate pair to access, and with an http mirror that provides the package content. In this way, only authorised clients can install or update the packages, while the overhead of authentication for package content retrieval is avoided. A mirror can be created by removing all subdirectories of a repository except those named file and their parents. An origin repository can be also be provisioned as a mirror by using the mirror mode of pkg.depotd(8).
The pkg
system forces non-global zones to
be kept in sync with the global zone. This means that certain packages must
be at the same version in the global zone and all non-global zones to ensure
the same kernel is run. To do this, pkg
uses
parent dependencies to impose certain constraints on
non-global zones. See Depend
Actions above for more information about parent
dependencies.
Because of restrictions that the global zone imposes on non-global zones, the non-global zones must have access to the packages of the global zone and must have a similar publisher configuration. Both of these objectives are achieved by using a system repository (see the pkg.sysrepo(8) man page). The system repository provides access to the publishers configured in the global zone and information about how those publishers are configured. To prevent non-global zones from choosing different packages during installation or update, system publishers are ranked higher in the publisher search order than publishers configured in the non-global zone. See the pkg set-publisher command in the pkg(1) man page for information about publisher search order.
To update all non-global zones on the system, use the pkg update command with no arguments in the global zone. This command operates on the global zone and on each non-global zone recursively. The minimal changes necessary are made to non-global zones to bring them in sync with the changes made in the global zone. For example, suppose package foo is installed at version 1 in both the global zone and non-global zones, and suppose version 2 is available in a system repository. If foo has a parent dependency, then pkg update foo updates foo to version 2 in both the global zone and the non-global zones because the parent dependency forces the package to stay in sync. If foo does not have a parent dependency, then foo is updated to version 2 in the global zone but remains at version 1 in the non-global zones.
Software can have components that are optional and components that are mutually exclusive. Examples of optional components include locales and documentation. Examples of mutually exclusive components include architecture (e.g. SPARC or x86) and debug or non-debug binaries.
In IPS, optional components are called facets and mutually exclusive components are called variants. Facets and variants are specified as tags on package actions. Each facet and variant tag has a name and a value. A single action can have multiple facet and variant tags. Examples of components with multiple facet and variant tags include an architecture-specific header file that is used by developers, or a component that is only for a SPARC global zone.
An example of a variant tag is variant.arch=sparc. An example of a facet tag is facet.devel=true. Facets and variants are often referred to without the leading ‘facet.’ and ‘variant.’.
Facets and variants are special properties of the image and cannot be set on individual packages. To view the current values of the facets and variants set on the image, use the pkg facet and pkg variant commands as shown in the pkg(1) man page. To modify the values of the facets and variants set on the image, use the pkg change-facet and pkg change-variant commands.
Facets are treated as boolean values by package clients: Facets can be set only to true (enabled) or false (disabled) in the image. By default, all facets are considered to be set to true in the image except for those that begin with ‘facet.debug.’ or ‘facet.optional.’.
Facets can be either set locally within an image using the pkg change-facet command or inherited from a parent image. For example, a non-global zone can inherit a facet from the global zone. Inherited facets are evaluated before, and take priority over, any locally set facets. If the same facet is both inherited and locally set, the inherited facet value masks the locally set value. Masked facets have no effect on facet evaluation and package actions. Facet changes made by using the pkg change-facet command only affect locally set facets. Inherited facets can only be changed by making the change in the parent image. By default, the pkg facet command does not display masked facets.
The value of a facet tag on an action can be set to all or true to control how clients filter faceted actions. All values other than all or true have undefined behaviour. See below for a description of the conditions that must exist in the image to install an action that has facet tags.
The all value for a facet is useful when more than a single level of filtering is required. In the following example, foo.txt is installed only if the doc facet and at least one of the locale facets is true in the image. This enables administrators to exclude documentation, but still enable or disable support for specific locales. In addition, api.txt is only installed if both the doc and devel facets are true in the image.
file path=usr/share/doc/foo/foo.txt facet.doc=all \ facet.locale.en_GB=true facet.locale.en_US=true file path=usr/share/doc/foo/api.txt facet.doc=all facet.devel=all
A facet set on the image can be a full facet such as doc.man or a pattern such as locale.*. This is useful when you want to disable a portion of the facet namespace, and only enable individual facets within it. For example, you could disable all locales and then only enable one or two specific locales, as shown in the following example:
# pkg change-facet locale.*=false [output about packages being updated] # pkg change-facet locale.en_US=true [output about packages being updated]
Most variants can have any number of values. For example, the arch variant can be set to i386, sparc, ppc, arm, aarch64, or whatever architectures the distribution supports (only i386 and aarch64 are used in OmniOS). The exceptions are the debug variants. The debug variants should only be set to true or false; other values have undefined behaviour. If a file action has both non-debug and debug versions, both versions must have the applicable debug variant explicitly set, as shown in the following example:
file group=sys mode=0644 overlay=allow owner=root \ path=etc/motd pkg.csize=115 pkg.size=103 preserve=true \ variant.debug.osnet=true file group=sys mode=0644 overlay=allow owner=root \ path=etc/motd pkg.csize=68 pkg.size=48 preserve=true \ variant.debug.osnet=false
The variant value must be set on the image in order for a package using the variant to be installed; by default all unspecified variants have the value false, which may or may not make the package installable. The arch and zone variants are set by the program that creates the image and installs its initial contents. The debug.* variants are false in the image by default.
The facets and variants set on the image affect whether a particular action is installed.
You can create your own facet and variant tags. The following tags are in common use.
Variant Name | Possible Values |
------------ | --------------- |
variant.arch | sparc, i386 |
variant.opensolaris.zone | global, nonglobal |
variant.debug.* | true, false |
The following list shows a small sample of the facet tags that are used:
facet.devel | facet.doc |
facet.doc.html | facet.doc.info |
facet.doc.man | facet.doc.pdf |
facet.locale.de | facet.locale.en_GB |
facet.locale.en_US | facet.locale.fr |
facet.locale.ja_JP | facet.locale.zh_CN |
Image policies are defined by image properties with boolean values. See "Image Properties" in the pkg(1) man page for descriptions of the flush-content-cache-on-success and send-uuid properties and information about how to view and modify their values.
Since pkg
(7) images can be located
arbitrarily within a larger file system, the token
$IMAGE_ROOT is used to distinguish relative paths. For a
typical system installation, $IMAGE_ROOT is equivalent to
‘/’.
Within the metadata of a particular image, certain files and directories can contain information useful during repair and recovery. The token $IMAGE_META is used to refer to the top-level directory that contains the metadata. $IMAGE_META is typically one of the two paths given above.
Other paths within the $IMAGE_META directory hierarchy are Private, and are subject to change.
chmod(1), passwd(1), pkg(1), pkgsend(1), svcs(1), ftpusers(7), group(7), pkginfo(7), shadow(7), add_drv(8), devlinks(8), pkg.depotd(8), pkg.sysrepo(8), svcadm(8)
November 16, 2022 | OmniOS |