diff options
author | Julian Andres Klode <julian.klode@canonical.com> | 2021-04-23 11:37:28 +0200 |
---|---|---|
committer | Julian Andres Klode <julian.klode@canonical.com> | 2021-04-23 12:26:46 +0200 |
commit | 80dd1447595c536d31912c486ac5e96f983ccc7a (patch) | |
tree | 1253ecca8e3d9c609ce0a09417f2a1b900358f2a | |
parent | dc11a4422d99cb49817c827b9f827617b5880600 (diff) |
json: Hook protocol 0.2 (added upgrade,downgrade,reinstall modes)
Hook protocol 0.2 makes the new fields we added mandatory, and
replaces `install` mode with `upgrade`, `downgrade`, `reinstall`
where appropriate.
Hook negotiation is hacky, but it's the best we can do for now.
Users are advised to upgrade to 0.2
-rw-r--r-- | apt-private/private-json-hooks.cc | 49 | ||||
-rw-r--r-- | doc/json-hooks-protocol.md | 48 | ||||
-rwxr-xr-x | test/integration/test-apt-cli-json-hooks | 88 |
3 files changed, 144 insertions, 41 deletions
diff --git a/apt-private/private-json-hooks.cc b/apt-private/private-json-hooks.cc index a40597e0a..957140525 100644 --- a/apt-private/private-json-hooks.cc +++ b/apt-private/private-json-hooks.cc @@ -17,6 +17,7 @@ #include <ostream> #include <sstream> #include <stack> +#include <unordered_map> #include <signal.h> #include <sys/socket.h> @@ -265,7 +266,7 @@ static void DpkgChrootDirectory() /** * @brief Send a notification to the hook's stream */ -static void NotifyHook(std::ostream &os, std::string const &method, const char **FileList, CacheFile &Cache, std::set<std::string> const &UnknownPackages) +static void NotifyHook(std::ostream &os, std::string const &method, const char **FileList, CacheFile &Cache, std::set<std::string> const &UnknownPackages, int hookVersion) { SortedPackageUniverse Universe(Cache); JsonWriter jsonWriter{os}; @@ -311,7 +312,14 @@ static void NotifyHook(std::ostream &os, std::string const &method, const char * switch (Cache[Pkg].Mode) { case pkgDepCache::ModeInstall: - jsonWriter.name("mode").value("install"); + if (Pkg->CurrentVer != 0 && Cache[Pkg].Upgrade() && hookVersion >= 0x020) + jsonWriter.name("mode").value("upgrade"); + else if (Pkg->CurrentVer != 0 && Cache[Pkg].Downgrade() && hookVersion >= 0x020) + jsonWriter.name("mode").value("downgrade"); + else if (Pkg->CurrentVer != 0 && Cache[Pkg].ReInstall() && hookVersion >= 0x020) + jsonWriter.name("mode").value("reinstall"); + else + jsonWriter.name("mode").value("install"); break; case pkgDepCache::ModeDelete: jsonWriter.name("mode").value(Cache[Pkg].Purge() ? "purge" : "deinstall"); @@ -344,7 +352,7 @@ static void NotifyHook(std::ostream &os, std::string const &method, const char * static std::string BuildHelloMessage() { std::stringstream Hello; - JsonWriter(Hello).beginObject().name("jsonrpc").value("2.0").name("method").value("org.debian.apt.hooks.hello").name("id").value(0).name("params").beginObject().name("versions").beginArray().value("0.1").endArray().endObject().endObject(); + JsonWriter(Hello).beginObject().name("jsonrpc").value("2.0").name("method").value("org.debian.apt.hooks.hello").name("id").value(0).name("params").beginObject().name("versions").beginArray().value("0.1").value("0.2").endArray().endObject().endObject(); return Hello.str(); } @@ -361,11 +369,10 @@ static std::string BuildByeMessage() /// @brief Run the Json hook processes in the given option. bool RunJsonHook(std::string const &option, std::string const &method, const char **FileList, CacheFile &Cache, std::set<std::string> const &UnknownPackages) { - std::stringstream ss; - NotifyHook(ss, method, FileList, Cache, UnknownPackages); - std::string TheData = ss.str(); + std::unordered_map<int, std::string> notifications; std::string HelloData = BuildHelloMessage(); std::string ByeData = BuildByeMessage(); + int hookVersion; bool result = true; @@ -465,6 +472,20 @@ bool RunJsonHook(std::string const &option, std::string const &method, const cha goto out; } + if (strstr(line, "\"0.1\"")) + { + hookVersion = 0x010; + } + else if (strstr(line, "\"0.2\"")) + { + hookVersion = 0x020; + } + else + { + _error->Error("Unknown hook version in handshake from hook %s: %s", Opts->Value.c_str(), line); + goto out; + } + size = getline(&line, &linesize, F); if (size < 0) { @@ -476,9 +497,18 @@ bool RunJsonHook(std::string const &option, std::string const &method, const cha _error->Error("Expected empty line after handshake from %s, received %s", Opts->Value.c_str(), line); goto out; } - - fwrite(TheData.data(), TheData.size(), 1, F); - fwrite("\n\n", 2, 1, F); + { + std::string &data = notifications[hookVersion]; + if (data.empty()) + { + std::stringstream ss; + NotifyHook(ss, method, FileList, Cache, UnknownPackages, hookVersion); + ; + data = ss.str(); + } + fwrite(data.data(), data.size(), 1, F); + fwrite("\n\n", 2, 1, F); + } fwrite(ByeData.data(), ByeData.size(), 1, F); fwrite("\n\n", 2, 1, F); @@ -490,6 +520,7 @@ bool RunJsonHook(std::string const &option, std::string const &method, const cha result = _error->Error("Failure running hook %s", Opts->Value.c_str()); break; } + } signal(SIGINT, old_sigint); signal(SIGPIPE, old_sigpipe); diff --git a/doc/json-hooks-protocol.md b/doc/json-hooks-protocol.md index 3c7f6e4f2..4c0429d06 100644 --- a/doc/json-hooks-protocol.md +++ b/doc/json-hooks-protocol.md @@ -1,3 +1,5 @@ +Version: 0.2 + ## JSON Hooks APT 1.6 introduces support for hooks that talk JSON-RPC 2.0. Hooks act @@ -59,7 +61,7 @@ The following methods are supported: 1. `org.debian.apt.hooks.install.pre-prompt` - Run before the package list and y/n prompt 1. `org.debian.apt.hooks.install.package-list` - (optional in 0.1) Run after the package list. You could display additional lists of packages here -1. `org.debian.apt.hooks.install.statistics` - (optional in 0.1) Run after the package list. You could display additional lists of packages here +1. `org.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 as `5 security upgrades` 1. `org.debian.apt.hooks.install.post` - Run after success 1. `org.debian.apt.hooks.install.fail` - Run after failed install 1. `org.debian.apt.hooks.search.pre` - Run before search @@ -90,29 +92,30 @@ 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"`. + use per-version architecture fields to see `"all"`. -- *mode*: One of `install`, `deinstall`, `purge`, or `keep`. `keep` - is not exposed in 0.1. To determine an upgrade, check - that a current version is installed. +- *mode*: One of `install`, `upgrade`, `downgrade`, `reinstall`, `deinstall`, `purge`, `keep`. + Version 0.1 does not implement `upgrade`, `downgrade`, and `reinstall` - all of them are represented + as `install`, and you have to compare the `current` version to the `install` 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 +- *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 +- *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: +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 (optional, not in older versions) +- *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: @@ -173,3 +176,14 @@ protocol version only (for example, 1.7 may only support 0.2). Additional fields may be added to objects without bumping the protocol version. + +# Changes: + +## Version 0.2 + +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 gained `upgrade`, `downgrade`, `reinstall` modes. All of these are `install` +* (compatible change) The hooks `org.debian.apt.hooks.install.package-list` and `org.debian.apt.hooks.install.statistics` have been added +* (compatible change) Version objects gained a new `origins` array diff --git a/test/integration/test-apt-cli-json-hooks b/test/integration/test-apt-cli-json-hooks index 0e6745d00..59cf6e5ef 100755 --- a/test/integration/test-apt-cli-json-hooks +++ b/test/integration/test-apt-cli-json-hooks @@ -24,6 +24,7 @@ insertinstalledpackage 'upgrade' 'i386' '1.0' setupaptarchive APTARCHIVE="$(readlink -f ./aptarchive)" +export TEST_HOOK_VERSION=0.2 cat >> json-hook.sh << EOF #!/bin/bash @@ -34,7 +35,7 @@ while true; do if echo "\$request" | grep -q ".hello"; then echo "HOOK: HELLO" - printf '{"jsonrpc": "2.0", "result": {"version": "0.1"}, "id": 0}\n\n' >&\$APT_HOOK_SOCKET + printf '{"jsonrpc": "2.0", "result": {"version": "'\$TEST_HOOK_VERSION'"}, "id": 0}\n\n' >&\$APT_HOOK_SOCKET fi if echo "\$request" | grep -q ".bye"; then @@ -61,7 +62,7 @@ EOF ############################# Success search ####################### testsuccessequal 'HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.search.pre","params":{"command":"search","search-terms":["foo"],"unknown-packages":[],"packages":[]}} HOOK: empty @@ -72,7 +73,7 @@ foo/unstable 1.0 all Some description that has a unusual word xxyyzz and aabbcc and a UPPERCASE HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.search.post","params":{"command":"search","search-terms":["foo"],"unknown-packages":[],"packages":[]}} HOOK: empty @@ -80,7 +81,7 @@ HOOK: BYE' apt search foo ############################# Failed search ####################### testsuccessequal 'HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.search.pre","params":{"command":"search","search-terms":["foox"],"unknown-packages":[],"packages":[]}} HOOK: empty @@ -88,7 +89,7 @@ HOOK: BYE Sorting... Full Text Search... HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.search.fail","params":{"command":"search","search-terms":["foox"],"unknown-packages":[],"packages":[]}} HOOK: empty @@ -100,7 +101,7 @@ HOOK: BYE' apt search foox testfailureequal 'Reading package lists... Building dependency tree... HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.fail","params":{"command":"install","search-terms":["foxxx"],"unknown-packages":["foxxx"],"packages":[]}} HOOK: empty @@ -112,7 +113,7 @@ E: Unable to locate package foxxx' apt install foxxx testsuccessequal 'Reading package lists... Building dependency tree... HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.pre-prompt","params":{"command":"install","search-terms":["foo"],"unknown-packages":[],"packages":[{"id":2,"name":"foo","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]}}}]}} HOOK: empty @@ -120,14 +121,14 @@ HOOK: BYE The following NEW packages will be installed: foo HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.package-list","params":{"command":"install","search-terms":["foo"],"unknown-packages":[],"packages":[{"id":2,"name":"foo","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]}}}]}} HOOK: empty HOOK: BYE 0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded. HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.statistics","params":{"command":"install","search-terms":["foo"],"unknown-packages":[],"packages":[{"id":2,"name":"foo","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]}}}]}} HOOK: empty @@ -135,7 +136,7 @@ HOOK: BYE Inst foo (1.0 Lemons:unstable [all]) Conf foo (1.0 Lemons:unstable [all]) HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.post","params":{"command":"install","search-terms":["foo"],"unknown-packages":[],"packages":[{"id":2,"name":"foo","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]}}}]}} HOOK: empty @@ -146,7 +147,7 @@ HOOK: BYE' apt install foo -s testfailureequal 'Reading package lists... Building dependency tree... HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.fail","params":{"command":"dist-upgrade","search-terms":["foxxx"],"unknown-packages":["foxxx"],"packages":[]}} HOOK: empty @@ -159,7 +160,44 @@ testsuccessequal 'Reading package lists... Building dependency tree... Calculating upgrade... HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.pre-prompt","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"upgrade","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE +The following packages will be upgraded: + upgrade +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.package-list","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"upgrade","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE +1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.statistics","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"upgrade","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE +Inst upgrade [1.0] (2.0 Lemons:testing [i386]) +Conf upgrade (2.0 Lemons:testing [i386]) +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.post","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"upgrade","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE' apt dist-upgrade -s + + +################## version 0.1 ######################### +TEST_HOOK_VERSION=0.1 + +testsuccessequal 'Reading package lists... +Building dependency tree... +Calculating upgrade... +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.pre-prompt","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} HOOK: empty @@ -167,14 +205,14 @@ HOOK: BYE The following packages will be upgraded: upgrade HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.package-list","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} HOOK: empty HOOK: BYE 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.statistics","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} HOOK: empty @@ -182,11 +220,31 @@ HOOK: BYE Inst upgrade [1.0] (2.0 Lemons:testing [i386]) Conf upgrade (2.0 Lemons:testing [i386]) HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.post","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} HOOK: empty HOOK: BYE' apt dist-upgrade -s + + +################## Wrong version ######################### +TEST_HOOK_VERSION=42 + +testfailureequal 'Reading package lists... +Building dependency tree... +Calculating upgrade... +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +E: Unknown hook version in handshake from hook '$HOOK': {"jsonrpc": "2.0", "result": {"version": "42"}, "id": 0} +E: Sub-process '$HOOK' returned an error code (1) +E: Failure running hook '$HOOK' +E: Unknown hook version in handshake from hook '$HOOK': {"jsonrpc": "2.0", "result": {"version": "42"}, "id": 0} +E: Sub-process '$HOOK' returned an error code (1) +E: Failure running hook '$HOOK'' apt dist-upgrade -s ################## Error in hello response ######################### cat > json-hook.sh << EOF |