Version: 0.2
APT 1.6 introduces support for hooks that talk JSON-RPC 2.0. Hooks act as a server, and APT as a client.
APT communicates with hooks via a UNIX domain socket in file descriptor
$APT_HOOK_SOCKET
. The transport is a byte stream (SOCK_STREAM).
The byte stream contains multiple JSON objects, each representing a
JSON-RPC request or response, and each terminated by an empty line
(\n\n
). Therefore, JSON objects containing empty lines may not be
used.
Each JSON object must be encoded on a single line at the moment, but this may change in future versions.
The general life of a hook is as following.
- Hook is started
- Hello handshake is exchanged
- One or more calls or notifications are sent from apt to the hook
- Bye notification is sent
It is unspecified whether a hook is sent one or more messages. For example, a hook may be started only once for the lifetime of the apt process and receive multiple notifications, but a hook may also be started multiple times. Hooks should thus be stateless.
APT performs a call to the method org.debian.apt.hooks.hello
with
the named parameter versions
containing a list of supported protocol
versions, and an optional options
array. The hook picks the version it supports. The current version
is "0.2"
, and support for "0.1" or "0.2" is mandatory.
The options
array is an optional list of all options currently set in the apt
configuration object. Note that not all options are present, and the default can vary,
you cannot rely on the default being true
or false
for example for a boolean option
-- it depends on the context.
APT options are internally stored as a tree leading to the awkward situation that a list
item could have a name, e.g. APT::Architectures "unused" { first "amd64"; "i386"; };
. This will
be represented as
[
{"name": "APT::Architectures", "value": "unused"},
{"name": "APT::Architectures::first", "amd64"},
{"name": "APT::Architectures::", ""}
]
To interpret an option name as a list, with trailing ::
, for example, APT::Architectures
, you
will need to write a function similar to:
def get_list(options, key):
"""key includes trailing ::"""
return [value for name, value in options if name.startswith(key) and "::" not in name[len(key):]]
Example:
-
APT:
{"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1", "0.2"], "options": [{"name": "APT::Architecture", "value": "amd64"}]}}
-
Hook:
{"jsonrpc":"2.0","id":0,"result":{"version":"0.1"}}
Before closing the connection, APT sends a notification for the
method org.debian.apt.hooks.bye
.
The following methods are supported:
org.debian.apt.hooks.install.pre-prompt
- Run before the package list and y/n promptorg.debian.apt.hooks.install.package-list
- (optional in 0.1) Run after the package list. You could display additional lists of packages hereorg.debian.apt.hooks.install.statistics
- (optional in 0.1) Run after the count of packages to upgrade/install. You could display additional information here, such as5 security upgrades
org.debian.apt.hooks.install.post
- Run after successorg.debian.apt.hooks.install.fail
- Run after failed installorg.debian.apt.hooks.search.pre
- Run before searchorg.debian.apt.hooks.search.post
- Run after successful searchorg.debian.apt.hooks.search.fail
- Run after search without results
They can be registered by adding them to the list:
AptCli::Hooks::<name>
where <name>
is the name of the hook. It is recommended that these
option names are prefixed with Binary::apt
, so that they only take
effect for the apt
binary. Otherwise, there may be compatibility issues
with scripts and alike.
command: The command used on the command-line. For example, "purge"
.
search-terms: Any non-option arguments given to the command.
unknown-packages: For non-search hooks, a subset of search-terms that APT could not find packages in the cache for.
packages: An array of modified packages. This is mostly useful for install. Each package has the following attributes:
-
id: An unsigned integer describing the package
-
name: The name of the package
-
architecture: The architecture of the package. For
"all"
packages, this will be the native architecture; use per-version architecture fields to see"all"
. -
mode: One of
install
,upgrade
,downgrade
,reinstall
,deinstall
,purge
,keep
. Version 0.1 does not implementupgrade
,downgrade
, andreinstall
- all of them are represented asinstall
, and you have to compare thecurrent
version to theinstall
version to figure out if is one of those. -
One of the following optional fields may be set to true to indicate a change relative to an installed version:
-
downgrade: true if downgrading
-
upgrade: true if upgrading
-
reinstall: true if reinstall flag is set
-
automatic: Whether the package is/will be automatically installed
-
versions: An array with up to 3 fields:
-
candidate: The candidate version
-
install: The version to be installed
-
current: The version currently installed
Each version is represented as an object with the following fields:
-
id: An unsigned integer
-
version: The version as a string
-
architecture: Architecture of the version
-
pin: The pin priority (optional)
-
origins: Sources from which the package is retrieved (since 0.2)
Each origin is represented as an object with the following fields:
- archive: string (optional)
- codename: string (optional)
- version: string (optional)
- origin: string (optional)
- label: string (optional)
- site: string, empty for local repositories or when using mirror+file:/ method (optional)
{
"jsonrpc": "2.0",
"method": "org.debian.apt.hooks.install.pre",
"params": {
"command": "purge",
"search-terms": [
"petname-",
"lxd+"
],
"packages": [
{
"id": 1500,
"name": "ebtables",
"architecture": "amd64",
"mode": "install",
"automatic": 1,
"versions": {
"candidate": {
"id": 376,
"version": "2.0.10.4-3.5ubuntu2",
"architecture": "amd64",
"pin": 990
},
"install": {
"id": 376,
"version": "2.0.10.4-3.5ubuntu2",
"architecture": "amd64",
"pin": 990
}
}
}
]
}
}
Future versions of APT might make these calls instead of notifications.
New incompatible versions may be introduced with each new feature release of apt (1.7, 1.8, etc). No backward compatibility is promised until protocol 1.0: New stable feature releases may support a newer protocol version only (for example, 1.7 may only support 0.2).
Additional fields may be added to objects without bumping the protocol version.
The 0.2 protocol makes one incompatible change, and adds several new compatible changes, all of which are optional in 0.1, but mandatory in 0.2.
- (incompatible change) The
mode
flag of arguments gainedupgrade
,downgrade
,reinstall
modes. All of these areinstall
- (compatible change) The hooks
org.debian.apt.hooks.install.package-list
andorg.debian.apt.hooks.install.statistics
have been added - (compatible change) Version objects gained a new
origins
array