.. 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
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 1
---------
Design Goals and Concepts
.........................
This chapter discusses IPS design goals and concepts, and discusses
some of the implications of those choices.
IPS is designed to eliminate some long-standing issues with previous
software distribution, installation and maintenance mechanisms
that have caused significant problems for Oracle Solaris customers,
developers/maintainers and ISVs.
Principle IPS design concepts and goals include:
* Minimize planned downtime by making software update possible
while machines are in production.
* Minimize unplanned downtime by supporting quick reboot to
known working software configurations.
* Automate, as much as possible, the installation of new software or
updates to existing software.
* Resolve the difficulties with ever-increasing software size and
limited distribution media space.
* Ensure that it is possible to determine whether or not a package is
correctly installed as defined by the author (publisher) of the
package; such a check should not be spoofable.
* Incorporate mechanisms to allow for the easy virtualization of Oracle Solaris
at a variety of levels - and zones in particular.
* Reduce the effort required to generate patches/upgrades for existing
systems.
* Allow other software publishers (ISVs and end-users themselves) to
create and publish packages using IPS.
These goals led fairly directly to the following ideas:
* Leverage ZFS snapshot and clone facilities to dynamically create
boot environments on an as-needed basis.
This means that:
* Oracle Solaris 11 requires ZFS as the root file system; zone
file systems need to be on ZFS as well.
* Users can create as many boot environments as desired.
* The packaging system can automatically create boot environments
on an as-needed basis, either for backup purposes prior to
modifying the running system, or for installation of a new
version of the OS.
* Eliminate duplicated mechanisms and code used to install, patch
and update Oracle Solaris.
This results in several significant changes to the way Oracle Solaris
is maintained. In particular:
* All OS software updates and patching are done directly with
IPS.
* Any time a new package is installed, it is already exactly
at the correct version.
* The requirement for unspoofable verification of package installation
has interesting consequences:
* If a package needs to support installation in multiple ways, those ways
must be specified by the developer, so the verification process could
take this into account.
* Scripting is inherently unverifiable since we cannot determine the
intent of the script writer. This, along with other issues
mentioned later, led to the elimination of scripting during
packaging operations.
* There can be no mechanism for the package to edit its own manifest,
since verification is then impossible.
* If the administrator wants to install a package in a manner
incompatible with the original publisher's definition, we should
enable the administrator to easily republish the package he wants
to alter so that the scope of his changes are clear, not lost
across upgrades, and can be verified in the same manner as the
original package.
* The need to avoid size restrictions led to a software repository
model, accessed using several different methods. Different
repository sources can be composited to provide a complete set of
packages, and repositories can be distributed as a single file. In
this manner, no single media is ever required to contain all the
available software. In order to support disconnected/firewalled
operations, tools are provided to copy and merge repositories.
* The desire to enable multiple (possibly competing) software
publishers led us to driving all the packaging metadata into the
packages themselves, so no master database of all packages,
dependencies, etc. exists. A catalog of available packages from a
software publisher is part of the repository for performance
reasons, but it can be regenerated from the data contained in the
packages at will.
Software Self-Assembly
......................
Given the goals and ideas above, IPS introduces the general concept of *software
self-assembly*: Any collection of installed software on a system should be able
to build itself into a working configuration when that system is booted, by the
time the packaging operation completes, or at software runtime.
Software self-assembly eliminates the need for install-time scripting in IPS. The
software is responsible for its own configuration rather than relying on the
packaging system to perform that configuration on behalf of the software.
Software self-assembly also enables the packaging system to safely operate on
alternate images, such as boot environments that are not currently booted, or
offline zone roots. In addition, since the self-assembly is performed only on
the running image, the package developer does not need to cope with
cross-version or cross-architecture run-time contexts.
There are obviously some aspects of preparing an operating system image that
must be done before boot, and IPS manages this transparently. These items
include updating boot blocks, preparing a boot archive (ramdisk), and on some
architectures, managing the menu of boot choices.
Several idioms are employed to facilitate software self-assembly:
* **Actions**
*Actions* are the atomic units of software delivery in IPS. Each action
delivers a single software object - either a file system object, such as a
*file*, *directory* or *link*, or a more complex software construct, such
as a *user*, *group* or *driver*. These more complex action types,
previously handled by SVR4 class action scripts in older Oracle Solaris
releases no longer require scripting.
Actions, grouped together into *packages*, can be installed, updated and
removed from both live images as well as offline images.
While IPS allows for the set of known action types to be extended in the
packaging system, during development we have found that the action types
delivered at present are sufficient for all packaged software in
Oracle Solaris. It is not expected that package developers will need to
create new action types.
Actions are discussed in more detail in *Chapter 3*.
* **Composition**
Rather than maintaining complex configuration files, that require
extensive scripting in order to update each configuration file during
packaging operations, IPS encourages package authors to deliver fragments
of the complete configuration file.
The packaged application either accesses those fragments directly when
reading its configuration, or the fragments can be assembled into the
complete configuration file before reading it.
A good example of this is the ``/etc/user_attr`` configuration file, used
by Oracle Solaris to configure extended attributes for roles and users on
the system.
This file is now used for local changes only, and Oracle Solaris has been
modified to read its complete configuration from the separate files
delivered into the directory ``/etc/user_attr.d``. Multiple packages
deliver fragments of the complete configuration, with no additional
scripting needed when fragments are installed, removed or updated.
Obviously this requires that the software is written with composition in
mind, which isn't always possible.
An alternative way to support the concept of composition, is for a service
to treat the configuration file as volatile, and re-assemble it when when
fragments of the configuration are installed, removed, or updated.
Typically, this assembly is performed by an SMF service. We will discuss
this idiom in the next item.
* **Actuators & SMF services**
An *actuator* is a tag applied to any *action* delivered by the packaging
system that causes a system change when that action is installed, removed,
or updated.
These changes are typically implemented as SMF services.
We can create SMF services that are responsible for configuring software
directly, or constructing configuration files using data delivered in the
SMF manifest or sourced from files installed on the system.
Since SMF services have a rich syntax to express dependencies, we can
ensure that each service only runs when all of its dependencies have been
met.
Oracle Solaris includes an SMF milestone,
``svc:/milestone/self-assembly-complete:default``, upon which can any
service can add itself as a dependency. The intention is that once the
booting operating system has reached this milestone, all self-assembly
operations have completed.
Oracle Solaris supports a special type of zone called an |Immutable Zone|,
where the zone can be configured to have restricted write-access to
portions of it's file system (see the discussion of ``file-mac-profile``
in the |zonecfg| manual page)
In these types of zones, to complete self-assembly, they are first booted
read/write as far as the ``self-assembly-complete`` SMF milestone, after
which they are automatically booted to the required ``file-mac-profile``
setting.
Designing Your Package
......................
Many of the good packaging criteria present trade-offs among themselves. It
will often be difficult to satisfy all requirements equally. These criteria are
presented in order of importance; however, this sequence is meant to serve as a
flexible guide depending on the circumstances. Although each of these criteria
is important, it is up to you to optimize these requirements to
produce a good set of packages.
Naming Your Package
~~~~~~~~~~~~~~~~~~~
Oracle Solaris uses a hierarchical naming strategy for IPS packages. Wherever
possible, design your package names to fit into the same scheme. Try to keep the
last part of your package name reasonably unique such that ``pkg install
<name>`` doesn't report conflicts.
Optimize for Client-Server Configurations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You should consider the various patterns of software use (client and
server) when laying out packages. Good packaging design divides the
affected files to optimize installation of each configuration
type. For example, for a network protocol implementation, it should be
possible to install the client without necessarily installing the
server. Note that if client and server share implementation
components, a base package containing the shared bits is necessary.
Package by Functional Boundaries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Packages should be self-contained and distinctly identified with a set of
functionality. For example, a package containing ZFS should contain all ZFS
utilities and be limited to only ZFS binaries.
Packages should be organized from a customer's point of view into functional
units.
Package Along License or Royalty Boundaries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Put code that requires royalty payments due to contractual agreements or
that has distinct software license terms in a dedicated package or group
of packages. Do not disperse the code into more packages than
necessary.
Overlap in Packages
~~~~~~~~~~~~~~~~~~~
Packages that overlap (deliver differing content to the same
file system locations, for example) cannot be installed at the same
time. Since this error might not be caught until final planning for
installation, it can provide a poor user experience, though
|pkglint| can help to detect this during the package authoring process.
If the package content must differ, declare an exclude dependency so that
IPS will understand that these packages are not to be installed together.
Sizing Considerations
~~~~~~~~~~~~~~~~~~~~~
A package represents (modulo *facets*, discussed later) a single unit
of software, and is either installed or not installed. Packages that are
always installed together should be combined. Since IPS downloads only
changed files on update, even large packages update quickly if change is
limited.