← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad-buildd:avoid-apt-key into launchpad-buildd:master

 

Colin Watson has proposed merging ~cjwatson/launchpad-buildd:avoid-apt-key into launchpad-buildd:master.

Commit message:
Avoid using the deprecated apt-key

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #1938704 in launchpad-buildd: "Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8))."
  https://bugs.launchpad.net/launchpad-buildd/+bug/1938704

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad-buildd/+git/launchpad-buildd/+merge/424014

Launchpad sends us ASCII-armored key data.  Dearmor it (for compatibility with apt < 1.4) and drop it into `/etc/apt/trusted.gpg.d/`, which is now preferred over using apt-key(8).
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad-buildd:avoid-apt-key into launchpad-buildd:master.
diff --git a/debian/changelog b/debian/changelog
index 2924a63..156ec66 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+launchpad-buildd (214) UNRELEASED; urgency=medium
+
+  * Avoid using the deprecated apt-key (LP: #1938704).
+
+ -- Colin Watson <cjwatson@xxxxxxxxxx>  Mon, 06 Jun 2022 21:41:22 +0100
+
 launchpad-buildd (213) focal; urgency=medium
 
   [ Colin Watson ]
diff --git a/lpbuildd/target/apt.py b/lpbuildd/target/apt.py
index ca6fb7f..ebd4683 100644
--- a/lpbuildd/target/apt.py
+++ b/lpbuildd/target/apt.py
@@ -82,13 +82,26 @@ class AddTrustedKeys(Operation):
 
     def __init__(self, args, parser):
         super().__init__(args, parser)
-        self.input_file = sys.stdin
+        self.input_file = sys.stdin.buffer
+        self.show_keys_file = sys.stdout.buffer
 
     def run(self):
         """Add trusted keys from an input file."""
         logger.info("Adding trusted keys to build-%s", self.args.build_id)
-        self.backend.run(["apt-key", "add", "-"], stdin=self.input_file)
-        self.backend.run(["apt-key", "list"])
+        gpg_cmd = [
+            "gpg", "--ignore-time-conflict", "--no-options", "--no-keyring",
+            ]
+        with tempfile.NamedTemporaryFile(mode="wb+") as keyring:
+            subprocess.check_call(
+                gpg_cmd + ["--dearmor"], stdin=self.input_file, stdout=keyring)
+            keyring.seek(0)
+            subprocess.check_call(
+                gpg_cmd +
+                ["--show-keys", "--keyid-format", "long", "--fingerprint"],
+                stdin=keyring, stdout=self.show_keys_file)
+            os.fchmod(keyring.fileno(), 0o644)
+            self.backend.copy_in(
+                keyring.name, "/etc/apt/trusted.gpg.d/launchpad-buildd.gpg")
         return 0
 
 
diff --git a/lpbuildd/target/tests/test_apt.py b/lpbuildd/target/tests/test_apt.py
index 749fd93..380f735 100644
--- a/lpbuildd/target/tests/test_apt.py
+++ b/lpbuildd/target/tests/test_apt.py
@@ -1,9 +1,9 @@
 # Copyright 2017-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-import io
 import stat
 import subprocess
+import tempfile
 from textwrap import dedent
 import time
 
@@ -101,6 +101,46 @@ class TestOverrideSourcesList(TestCase):
                 "/etc/apt/apt.conf.d/99proxy"])
 
 
+# Output of:
+#     gpg --no-default-keyring \
+#         --keyring /usr/share/keyrings/ubuntu-archive-keyring.gpg \
+#         --armor --export --export-options export-minimal,export-clean \
+#         F6ECB3762474EDA9D21B7022871920D1991BC93C
+# (For test purposes, the exact key ID isn't particularly important.  This
+# just needs to be some kind of valid GPG public key.)
+TEST_GPG_KEY = dedent("""\
+    -----BEGIN PGP PUBLIC KEY BLOCK-----
+
+    mQINBFufwdoBEADv/Gxytx/LcSXYuM0MwKojbBye81s0G1nEx+lz6VAUpIUZnbkq
+    dXBHC+dwrGS/CeeLuAjPRLU8AoxE/jjvZVp8xFGEWHYdklqXGZ/gJfP5d3fIUBtZ
+    HZEJl8B8m9pMHf/AQQdsC+YzizSG5t5Mhnotw044LXtdEEkx2t6Jz0OGrh+5Ioxq
+    X7pZiq6Cv19BohaUioKMdp7ES6RYfN7ol6HSLFlrMXtVfh/ijpN9j3ZhVGVeRC8k
+    KHQsJ5PkIbmvxBiUh7SJmfZUx0IQhNMaDHXfdZAGNtnhzzNReb1FqNLSVkrS/Pns
+    AQzMhG1BDm2VOSF64jebKXffFqM5LXRQTeqTLsjUbbrqR6s/GCO8UF7jfUj6I7ta
+    LygmsHO/JD4jpKRC0gbpUBfaiJyLvuepx3kWoqL3sN0LhlMI80+fA7GTvoOx4tpq
+    VlzlE6TajYu+jfW3QpOFS5ewEMdL26hzxsZg/geZvTbArcP+OsJKRmhv4kNo6Ayd
+    yHQ/3ZV/f3X9mT3/SPLbJaumkgp3Yzd6t5PeBu+ZQk/mN5WNNuaihNEV7llb1Zhv
+    Y0Fxu9BVd/BNl0rzuxp3rIinB2TX2SCg7wE5xXkwXuQ/2eTDE0v0HlGntkuZjGow
+    DZkxHZQSxZVOzdZCRVaX/WEFLpKa2AQpw5RJrQ4oZ/OfifXyJzP27o03wQARAQAB
+    tEJVYnVudHUgQXJjaGl2ZSBBdXRvbWF0aWMgU2lnbmluZyBLZXkgKDIwMTgpIDxm
+    dHBtYXN0ZXJAdWJ1bnR1LmNvbT6JAjgEEwEKACIFAlufwdoCGwMGCwkIBwMCBhUI
+    AgkKCwQWAgMBAh4BAheAAAoJEIcZINGZG8k8LHMQAKS2cnxz/5WaoCOWArf5g6UH
+    beOCgc5DBm0hCuFDZWWv427aGei3CPuLw0DGLCXZdyc5dqE8mvjMlOmmAKKlj1uG
+    g3TYCbQWjWPeMnBPZbkFgkZoXJ7/6CB7bWRht1sHzpt1LTZ+SYDwOwJ68QRp7DRa
+    Zl9Y6QiUbeuhq2DUcTofVbBxbhrckN4ZteLvm+/nG9m/ciopc66LwRdkxqfJ32Cy
+    q+1TS5VaIJDG7DWziG+Kbu6qCDM4QNlg3LH7p14CrRxAbc4lvohRgsV4eQqsIcdF
+    kuVY5HPPj2K8TqpY6STe8Gh0aprG1RV8ZKay3KSMpnyV1fAKn4fM9byiLzQAovC0
+    LZ9MMMsrAS/45AvC3IEKSShjLFn1X1dRCiO6/7jmZEoZtAp53hkf8SMBsi78hVNr
+    BumZwfIdBA1v22+LY4xQK8q4XCoRcA9G+pvzU9YVW7cRnDZZGl0uwOw7z9PkQBF5
+    KFKjWDz4fCk+K6+YtGpovGKekGBb8I7EA6UpvPgqA/QdI0t1IBP0N06RQcs1fUaA
+    QEtz6DGy5zkRhR4pGSZn+dFET7PdAjEK84y7BdY4t+U1jcSIvBj0F2B7LwRL7xGp
+    SpIKi/ekAXLs117bvFHaCvmUYN7JVp1GMmVFxhIdx6CFm3fxG8QjNb5tere/YqK+
+    uOgcXny1UlwtCUzlrSaP
+    =9AdM
+    -----END PGP PUBLIC KEY BLOCK-----
+    """)
+
+
 class TestAddTrustedKeys(TestCase):
 
     def test_add_trusted_keys(self):
@@ -108,15 +148,27 @@ class TestAddTrustedKeys(TestCase):
             "add-trusted-keys",
             "--backend=fake", "--series=xenial", "--arch=amd64", "1",
             ]
-        input_file = io.BytesIO()
         add_trusted_keys = parse_args(args=args).operation
-        add_trusted_keys.input_file = input_file
-        self.assertEqual(0, add_trusted_keys.run())
-        expected_run = [
-            ((["apt-key", "add", "-"],), {"stdin": input_file}),
-            ((["apt-key", "list"],), {}),
-            ]
-        self.assertEqual(expected_run, add_trusted_keys.backend.run.calls)
+        with tempfile.NamedTemporaryFile(mode="wb+") as keys_file:
+            keys_file.write(TEST_GPG_KEY.encode())
+            keys_file.seek(0)
+            add_trusted_keys.input_file = keys_file
+            with tempfile.NamedTemporaryFile(mode="wb+") as show_keys_file:
+                add_trusted_keys.show_keys_file = show_keys_file
+                self.assertEqual(0, add_trusted_keys.run())
+                expected_dearmored_key = subprocess.run(
+                    ["gpg", "--ignore-time-conflict", "--no-options",
+                     "--no-keyring", "--dearmor"],
+                    input=TEST_GPG_KEY.encode(), capture_output=True).stdout
+                self.assertEqual(
+                    (expected_dearmored_key, stat.S_IFREG | 0o644),
+                    add_trusted_keys.backend.backend_fs[
+                        "/etc/apt/trusted.gpg.d/launchpad-buildd.gpg"])
+                show_keys_file.seek(0)
+                self.assertIn(
+                    "Key fingerprint = F6EC B376 2474 EDA9 D21B  "
+                    "7022 8719 20D1 991B C93C",
+                    show_keys_file.read().decode())
 
 
 class RanAptGet(MatchesListwise):