summaryrefslogtreecommitdiffstats
path: root/doc/external-installation-planner-protocol.md
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:00:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:00:48 +0000
commit851b6a097165af4d51c0db01b5e05256e5006896 (patch)
tree5f7c388ec894a7806c49a99f3bdb605d0b299a7c /doc/external-installation-planner-protocol.md
parentInitial commit. (diff)
downloadapt-upstream/2.6.1.tar.xz
apt-upstream/2.6.1.zip
Adding upstream version 2.6.1.upstream/2.6.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/external-installation-planner-protocol.md')
-rw-r--r--doc/external-installation-planner-protocol.md301
1 files changed, 301 insertions, 0 deletions
diff --git a/doc/external-installation-planner-protocol.md b/doc/external-installation-planner-protocol.md
new file mode 100644
index 0000000..4bad9da
--- /dev/null
+++ b/doc/external-installation-planner-protocol.md
@@ -0,0 +1,301 @@
+# APT External Installation Planner Protocol (EIPP) - version 0.1
+
+This document describes the communication protocol between APT and
+external installation planner. The protocol is called APT EIPP, for "APT
+External Installation Planner Protocol".
+
+
+## Terminology
+
+In the following we use the term **architecture qualified package name**
+(or *arch-qualified package names* for short) to refer to package
+identifiers of the form "package:arch" where "package" is a package name
+and "arch" a dpkg architecture.
+
+
+## Components
+
+- **APT**: we know this one.
+- APT is equipped with its own **internal planner** for the order of
+ package installation (and removal) which is identified by the string
+ `internal`.
+- **External planner**: an *external* software component able to plan an
+ installation on behalf of APT.
+
+At each interaction with APT, a single planner is in use. When there is
+a total of 2 or more planners, internals or externals, the user can
+choose which one to use.
+
+Each planner is identified by an unique string, the **planner name**.
+Planner names must be formed using only alphanumeric ASCII characters,
+dashes, and underscores; planner names must start with a lowercase ASCII
+letter. The special name `internal` denotes APT's internal planner, is
+reserved, and cannot be used by external planners.
+
+
+## Installation
+
+Each external planner is installed as a file under Dir::Bin::Planners
+(see below), which defaults to `/usr/lib/apt/planners`. We will assume
+in the remainder of this section that such a default value is in effect.
+
+The naming scheme is `/usr/lib/apt/planners/NAME`, where `NAME` is the
+name of the external planner.
+
+Each file under `/usr/lib/apt/planners` corresponding to an external
+planner must be executable.
+
+No non-planner files must be installed under `/usr/lib/apt/planners`, so
+that an index of available external planners can be obtained by listing
+the content of that directory.
+
+
+## Configuration
+
+Several APT options can be used to affect installation planing in APT.
+An overview of them is given below. Please refer to proper APT
+configuration documentation for more, and more up to date, information.
+
+- **APT::Planner**: the name of the planner to be used for dependency
+ solving. Defaults to `internal`
+
+- **Dir::Bin::Planners**: absolute path of the directory where to look
+ for external solvers. Defaults to `/usr/lib/apt/planners`.
+
+
+## Protocol
+
+When configured to use an external planner, APT will resort to it to
+decide in which order packages should be installed, configured and
+removed.
+
+The interaction happens **in batch**: APT will invoke the external
+planner passing the current status of (half-)installed packages and of
+packages which should be installed, as well as a request denoting the
+packages to install, reinstall, remove and purge. The external planner
+will compute a valid plan of when and how to call the low-level package
+manager (like dpkg) with each package to satisfy the request.
+
+External planners are invoked by executing them. Communications happens
+via the file descriptors: **stdin** (standard input) and **stdout**
+(standard output). stderr is not used by the EIPP protocol. Planners can
+therefore use stderr to dump debugging information that could be
+inspected separately.
+
+After invocation, the protocol passes through a sequence of phases:
+
+1. APT invokes the external planner
+2. APT send to the planner an installation planner **scenario**
+3. The planner calculates the order. During this phase the planner may
+ send, repeatedly, **progress** information to APT.
+4. The planner sends back to APT an **answer**, i.e. either a *solution*
+ or an *error* report.
+5. The external planner exits
+
+
+### Scenario
+
+A scenario is a text file encoded in a format very similar to the "Deb
+822" format (AKA "the format used by Debian `Packages` files"). A
+scenario consists of two distinct parts: a **request** and a **package
+universe**, occurring in that order. The request consists of a single
+Deb 822 stanza, while the package universe consists of several such
+stanzas. All stanzas occurring in a scenario are separated by an empty
+line.
+
+
+#### Request
+
+Within an installation planner scenario, a request represents the action
+on packages requested by the user explicitly as well as potentially
+additions calculated by a dependency resolver which the user has
+accepted.
+
+An installation planner is not allowed to suggest the modification of
+package states (e.g. removing additional packages) even if it can't
+calculate a solution otherwise – the planner must error out in such
+a case. An exception is made for scenarios which contain packages which
+aren't completely installed (like half-installed or trigger-awaiting):
+Solvers are free to move these packages to a fully installed state (but
+are still forbidden to remove them).
+
+A request is a single Deb 822 stanza opened by a mandatory Request field
+and followed by a mixture of action, preference, and global
+configuration fields.
+
+The value of the **Request:** field is a string describing the EIPP
+protocol which will be used to communicate and especially which answers
+APT will understand. At present, the string must be `EIPP 0.1`. Request
+fields are mainly used to identify the beginning of a request stanza;
+their actual values are otherwise not used by the EIPP protocol.
+
+The following **configuration fields** are supported in request stanzas:
+
+- **Architecture:** (mandatory) The name of the *native* architecture on
+ the user machine (see also: `dpkg --print-architecture`)
+
+- **Architectures:** (optional, defaults to the native architecture) A
+ space separated list of *all* architectures known to APT (this is
+ roughly equivalent to the union of `dpkg --print-architecture` and
+ `dpkg --print-foreign-architectures`)
+
+The following **action fields** are supported in request stanzas:
+
+- **Install:** (optional, defaults to the empty string) A space
+ separated list of arch-qualified package names, with *no version
+ attached*, to install. This field denotes a list of packages that the
+ user wants to install, usually via an APT `install` request.
+
+- **Remove:** (optional, defaults to the empty string) Same syntax of
+ Install. This field denotes a list of packages that the user wants to
+ remove, usually via APT `remove` or `purge` requests.
+
+- **ReInstall:** (optional, defaults to the empty string) Same syntax of
+ Install. This field denotes a list of packages which are installed,
+ but should be reinstalled again e.g. because files shipped by that
+ package were removed or corrupted accidentally, usually requested via
+ an APT `install` request with the `--reinstall` flag.
+
+The following **preference fields** are supported in request stanzas:
+
+- **Planner:** (optional, defaults to the empty string) a purely
+ informational string specifying to which planner this request was send
+ initially.
+
+- **Immediate-Configuration:** (option, unset by default) A boolean
+ value defining if the planner should try to configure all packages as
+ quickly as possible (true) or shouldn't perform any kind of immediate
+ configuration at all (false). If not explicitly set with this field
+ the planner is free to pick either mode or implementing e.g. a mode
+ which configures only packages immediately if they are flagged as
+ `Essential` (or are dependencies of packages marked as `Essential`).
+
+- **Allow-Temporary-Remove-of-Essentials** (optional, defaults to `no`).
+ A boolean value allowing the planner (if set to yes) to temporarily
+ remove an essential package. Associated with the APT::Force-LoopBreak
+ configuration option its main use is highlighting that planners who do
+ temporary removes must take special care in terms of essentials. Legit
+ uses of this option by users is very uncommon, traditionally
+ a situation in which it is needed indicates a packaging error.
+
+
+#### Package universe
+
+A package universe is a list of Deb 822 stanzas, one per package, called
+**package stanzas**. Each package stanzas starts with a Package
+field. The following fields are supported in package stanzas:
+
+- The fields Package, Version, Architecture (all mandatory) and
+ Multi-Arch, Pre-Depends, Depends, Conflicts, Breaks, Essential
+ (optional) as they are contained in the dpkg database (see the manpage
+ `dpkg-query (1)`).
+
+- **Status:** (optional, defaults to `uninstalled`). Allowed values are
+ the "package status" names as listed in `dpkg-query (1)` and visible
+ e.g. in the dpkg database as the second value in the space separated
+ list of values in the Status field there. In other words: Neither
+ desired action nor error flags are present in this field in EIPP!
+
+- **APT-ID:** (mandatory). Unique package identifier, according to APT.
+
+
+### Answer
+
+An answer from the external planner to APT is either a *solution* or an
+*error*.
+
+The following invariant on **exit codes** must hold true. When the
+external planner is *able to find a solution*, it will write the
+solution to standard output and then exit with an exit code of 0. When
+the external planner is *unable to find a solution* (and is aware of
+that), it will write an error to standard output and then exit with an
+exit code of 0. An exit code other than 0 will be interpreted as
+a planner crash with no meaningful error about dependency resolution to
+convey to the user.
+
+
+#### Solution
+
+A solution is a list of Deb 822 stanzas. Each of them could be an:
+
+- unpack stanza to cause the extraction of a package to the disk
+
+- configure stanza to cause an unpacked package to be configured and
+ therefore the installation to be completed
+
+- remove stanza to cause the removal of a package from the system
+
+An **unpack stanza** starts with an Unpack field and supports the
+following fields:
+
+- **Unpack:** (mandatory). The value is a package identifier,
+ referencing one of the package stanzas of the package universe via its
+ APT-ID field.
+
+- All fields supported by package stanzas.
+
+**Configure** and **Remove stanzas** require and support the same
+fields with the exception of the Unpack field which is replaced in
+these instances with the Configure or Remove field respectively.
+
+The order of the stanzas is significant (unlike in the EDSP protocol),
+with the first stanza being the first performed action. If multiple
+stanzas of the same type appear in direct succession the order in such
+a set isn't significant through.
+
+The solution needs to be valid (it is not allowed to configure a package
+before it was unpacked, dependency relations must be satisfied, …), but
+they don't need to be complete: A planner can and should expect that any
+package which wasn't explicitly configured will be configured at the end
+automatically. That also means through that a planner is not allowed to
+produce a solution in which a package remains unconfigured. Also,
+packages which are requested to be removed will be automatically removed
+at the end if not marked for removal explicitly earlier.
+
+In terms of expressivity, all stanzas can carry one single field each, as
+APT-IDs are enough to pinpoint packages to be installed/removed.
+Nonetheless, for protocol readability, it is recommended that planners
+either add unconditionally the fields Package, Version, and Architecture
+to all install/remove stanzas or, alternatively, that they support
+a `--verbose` command line flag that explicitly enables the output of
+those fields in solutions.
+
+#### Error
+
+An error is a single Deb 822 stanza, starting the field Error. The
+following fields are supported in error stanzas:
+
+- **Error:** (mandatory). The value of this field is ignored, although
+ it should be a unique error identifier, such as a UUID.
+
+- **Message:** (mandatory). The value of this field is a text string,
+ meant to be read by humans, that explains the cause of the planner
+ error. Message fields might be multi-line, like the Description field
+ in the dpkg database. The first line conveys a short message, which
+ can be explained in more details using subsequent lines.
+
+
+### Progress
+
+During dependency solving, an external planner may send progress
+information to APT using **progress stanzas**. A progress stanza starts
+with the Progress field and might contain the following fields:
+
+- **Progress:** (mandatory). The value of this field is a date and time
+ timestamp from the UTC timezone, in RFC 2822 format (see 'date -uR' as
+ an example). The timestamp provides a time annotation for the
+ progress report.
+
+- **Percentage:** (optional). An integer from 0 to 100, representing the
+ completion of the installation planning process, as declared by the
+ planner.
+
+- **Message:** (optional). A textual message, meant to be read by the
+ APT user, telling what is going on within the installation planner
+ (e.g. the current phase of planning, as declared by the planner).
+
+
+# Future extensions
+
+Potential future extensions to this protocol are to be discussed on
+deity@lists.debian.org.