]>
Commit | Line | Data |
---|---|---|
798d79f1 SZ |
1 | ** TENTATIVE PROPOSAL, VERY VERY VERY DRAFT ** |
2 | ||
3 | # APT External Dependency Solver Protocol (EDSP) - version 0.1 | |
4 | ||
5 | This document describes the communication protocol between APT and | |
6 | external dependency solvers. The protocol is called APT EDSP, for "APT | |
7 | External Dependency Solver Protocol". | |
8 | ||
9 | ||
10 | ## Components | |
11 | ||
12 | - **APT**: we know this one. | |
13 | - APT is equipped with its own **internal solver** for dependencies, | |
14 | which is identified by the string `internal`. | |
15 | - **External solver**: an *external* software component able to resolve | |
16 | dependencies on behalf of APT. Each external solver is identified by | |
17 | an unique string (other than `internal`) called the solver **name**. | |
18 | ||
19 | At each interaction with APT, a single solver is in use. When there is | |
20 | a total of 2 or more solvers, internals or externals, the user can | |
21 | choose which one to use. | |
22 | ||
23 | ||
24 | ## Installation | |
25 | ||
26 | Each external solver is installed as a file under | |
27 | `/usr/lib/apt/solvers`. The naming scheme is | |
28 | `/usr/lib/apt/solvers/NAME`, where `NAME` is the name of the external | |
29 | solver. | |
30 | ||
31 | Each file under `/usr/lib/apt/solvers` corresponding to an external | |
32 | solver must be executable. | |
33 | ||
34 | No non-solver files must be installed under `/usr/lib/apt/solvers`, so | |
35 | that an index of available external solvers can be obtained by simply | |
36 | looking at the content of that directory. | |
37 | ||
38 | ||
39 | ## Configuration | |
40 | ||
41 | Several APT options can be used to affect dependency solving in APT. An | |
42 | overview of them is given below. Please refer to proper APT | |
43 | configuration documentation for more, and more up to date, information. | |
44 | ||
45 | - **APT::Solver::Name**: the name of the solver to be used for | |
46 | dependency solving. Defaults to `internal` | |
47 | ||
48 | - **APT::Solver::Strict-Pinning**: whether pinning must be strictly | |
49 | respected (as the internal solver does) or can be slightly deviated | |
50 | from. Defaults to `yes`. | |
51 | ||
52 | - **APT::Solver::Preferences**: solver-specific user preferences used | |
53 | during dependency solving. Check your solver documentation for what is | |
54 | supported here. Default to empty. | |
55 | ||
56 | ||
57 | ## Protocol | |
58 | ||
59 | When configured to use an external solver, APT will resort to it to | |
60 | decide which packages should be installed or removed. | |
61 | ||
62 | The interaction happens **in batch**: APT will invoke the external | |
63 | solver passing the current status of installed and available packages, | |
64 | as well as the user request to alter the set of installed packages. The | |
65 | external solver will compute a new complete set of installed packages | |
66 | and gives APT a "diff" listing of which *additional* packages should be | |
67 | installed and of which currently installed packages should be | |
68 | *removed*. (Note: the order in which those actions have to be performed | |
69 | will be up to APT to decide.) | |
70 | ||
71 | External solvers are invoked by executing them. Communications happens | |
72 | via the file descriptors: **stdin** (standard input) and **stdout** | |
73 | (standard output). stderr is not used by the EDSP protocol. Solvers can | |
74 | therefore use stderr to dump debugging information that could be | |
75 | inspected separately. | |
76 | ||
77 | After invocation, the protocol passes through 3 separate phases: | |
78 | ||
79 | 1. APT send to the solver a dependency solving **scenario** | |
80 | 2. The solver solves dependencies. No communication with APT happens | |
81 | during this phase. | |
82 | 3. The solver sends back to APT an **answer**, i.e. either a *solution* | |
83 | or an *error* report. | |
84 | ||
85 | ||
86 | ### Scenario | |
87 | ||
88 | A scenario is a text file encoded in a format very similar to the "Deb | |
89 | 822" format (AKA "the format used by Debian `Packages` files"). A | |
90 | scenario consists of two distinct parts: a **request** and a **package | |
91 | universe**, occurring in that order. The request consists of a single | |
92 | Deb 822 stanza, while the package universe consists of several such | |
93 | stanzas. All stanzas occurring in a scenario are separated by an empty | |
94 | line. | |
95 | ||
96 | ||
97 | #### Request | |
98 | ||
99 | Within a dependency solving scenario, a request represents the action on | |
100 | installed packages requested by the user. | |
101 | ||
102 | A request is a single Deb 822 stanza opened by a mandatory Request field | |
103 | and followed by a mixture of action and preference fields. | |
104 | ||
105 | The value of the **Request:** field is a string describing the EDSP | |
106 | protocol which will be used to communicate. At present, the string must | |
107 | be `EDSP 0.1`. | |
108 | ||
109 | a unique request identifier, such as an | |
110 | UUID. Request fields are mainly used to identify the beginning of a | |
111 | request stanza; their actual values are otherwise not used by the EDSP | |
112 | protocol. | |
113 | ||
114 | The following **action fields** are supported in request stanzas: | |
115 | ||
116 | - **Install:** (optional, defaults to the empty string) A space | |
117 | separated list of package names, with *no version attached*, to | |
118 | install. This field denotes a list of packages that the user wants to | |
119 | install, usually via an APT `install` request. | |
120 | ||
121 | - **Remove:** (optional, defaults to the empty string) Same syntax of | |
122 | Install. This field denotes a list of packages that the user wants to | |
123 | remove, usually via APT `remove` or `purge` requests. | |
124 | ||
125 | - **Upgrade:** (optional, defaults to `no`). Allowed values: `yes`, | |
126 | `no`. When set to `yes`, an upgrade of all installed packages has been | |
127 | requested, usually via an APT `upgrade` request. | |
128 | ||
129 | - **Dist-Upgrade:** (optional, defaults to `no`). Allowed values: `yes`, | |
130 | `no`. Same as Upgrade, but for APT `dist-upgrade` requests. | |
131 | ||
132 | - **Autoremove:** (optional, defaults to `no`). Allowed values: `yes`, | |
133 | `no`. When set to `yes`, a clean up of unused automatically installed | |
134 | packages has been requested, usually via an APT `autoremove` request. | |
135 | ||
136 | The following **preference fields** are supported in request stanzas: | |
137 | ||
138 | - **Strict-Pinning:** (optional, defaults to `yes`). Allowed values: | |
139 | `yes`, `no`. When set to `yes`, APT pinning is strict, in the sense | |
140 | that the solver must not propose to install packages which are not APT | |
141 | candidates (see the `APT-Pin` and `APT-Candidate` fields in the | |
142 | package universe). When set to `no`, the solver does only a best | |
143 | effort attempt to install APT candidates. Usually, the value of this | |
144 | field comes from the `APT::Solver::Strict-Pinning` configuration | |
145 | option. | |
146 | ||
147 | - **Preferences:** a solver-specific optimization string, usually coming | |
148 | from the `APT::Solver::Preferences` configuration option. | |
149 | ||
150 | ||
151 | #### Package universe | |
152 | ||
153 | A package universe is a list of Deb 822 stanzas, one per package, called | |
154 | **package stanzas**. Each package stanzas starts with a Package | |
155 | field. The following fields are supported in package stanzas: | |
156 | ||
157 | - All fields supported by Debian Packages file (see one of the | |
158 | `/var/lib/apt/lists/*Packages` file for an example), *with the | |
159 | exception of the Description field* that is not allowed. | |
160 | ||
161 | Among those fields, the following are mandatory: Package, Version, | |
162 | Architecture. | |
163 | ||
164 | - **Installed:** (optional, default value `no`). Allowed values: `yes`, | |
165 | `no`. When set to `yes`, the corresponding package is currently | |
166 | installed. | |
167 | ||
168 | ##TODO## changed with respect to current prototype, which uses Status | |
169 | ||
170 | - **APT-ID:** (mandatory). Unique package identifier, according to APT. | |
171 | ||
172 | - **APT-Pin:** (mandatory). Must be a non-negative integer. Package pin | |
173 | value, according to current APT policy. | |
174 | ||
175 | - **APT-Candidate:** (optional, default value `no`). Allowed values: | |
176 | `yes`, `no`. When set to `yes`, the corresponding package is granted | |
177 | to have the highest pinning value among all the packages having the | |
178 | same name. | |
179 | ||
180 | ##TODO## what about multi-arch? is the pin value granted to be the | |
181 | higest also across different architectures? | |
182 | ||
183 | ||
184 | ### Answer | |
185 | ||
186 | An answer from the external solver to APT is either a *solution* or an | |
187 | *error*. | |
188 | ||
189 | The following invariant on **exit codes** must hold true. When the | |
190 | external solver is *able to find a solution*, it will write the solution | |
191 | to standard output and then exit with an exit code of 0. When the | |
192 | external solver is *unable to find a solution* (and aware of that), it | |
193 | will write an error to standard output and then exit with an exit code | |
194 | of 0. An exit code other than 0 will be interpreted as a solver crash | |
195 | with no meaningful error about dependency resolution to convey to the | |
196 | user. | |
197 | ||
198 | ||
199 | #### Solution | |
200 | ||
201 | A solution is a single Deb 822 stanza, starting with the field | |
202 | Solution. The following fields are supported in solution stanzas: | |
203 | ||
204 | - **Solution:** (mandatory). The value of this field is ignored, | |
205 | although it should be a unique solution identifier, such as a UUID. | |
206 | ||
207 | - **Install:** (optional, defaults to the empty string). A space | |
208 | separated list of strings of the form `PACKAGE=VERSION` where | |
209 | `PACKAGE` is a package name and `VERSION` is an available version of | |
210 | that package. The list denotes a set of packages that must be | |
211 | installed to satisfy user request. | |
212 | ||
213 | - **Remove:** (optional, defaults to the empty string). Same as Install, | |
214 | but denoting a set of packages that must be removed to satisfy user | |
215 | request. | |
216 | ||
217 | ||
218 | #### Error | |
219 | ||
220 | An error is a single Deb 822 stanza, starting the field Error. The | |
221 | following fields are supported in error stanzas: | |
222 | ||
223 | - **Error:** (mandatory). The value of this field is ignored, although | |
224 | it should be a unique error identifier, such as a UUID. | |
225 | ||
226 | - **Message:** (mandatory). The value of this field is a text string, | |
227 | meant to be read by humans, that explains the cause of the solver | |
228 | error. | |
229 | ||
230 | ##TODO## can we support line continuations throughout this format? If | |
231 | yes, they might come handy both for error stanzas and for solution | |
232 | stanzas (which might have very long install/remove lines) | |
233 | ||
234 | ||
235 | ** TENTATIVE PROPOSAL, VERY VERY VERY DRAFT ** |