Merge lp:~ubuntu-cdimage/ubuntu-cdimage/focal into lp:ubuntu-cdimage

Proposed by Iain Lane
Status: Merged
Approved by: Steve Langasek
Approved revision: 1878
Merged at revision: 1879
Proposed branch: lp:~ubuntu-cdimage/ubuntu-cdimage/focal
Merge into: lp:ubuntu-cdimage
Diff against target: 310 lines (+58/-53)
6 files modified
lib/cdimage/launchpad.py (+14/-1)
lib/cdimage/sign.py (+9/-9)
lib/cdimage/tests/test_checksums.py (+2/-1)
lib/cdimage/tests/test_sign.py (+14/-17)
lib/cdimage/tests/test_tree.py (+17/-17)
lib/cdimage/tree.py (+2/-8)
To merge this branch: bzr merge lp:~ubuntu-cdimage/ubuntu-cdimage/focal
Reviewer Review Type Date Requested Status
Steve Langasek Approve
Review via email: mp+386317@code.launchpad.net

Description of the change

Various fixes to make cdimage work on focal (ancientminister, new cdimage host). I tried to retain compatibility with xenial (nusakan) - the changes have been tested there in isolation but I've not actually pulled an updated cdimage to test them end-to-end.

Mainly launchpadlib, gpg and bittorrent-related changes.

I could split this up into logical MPs if you want (but bzr...).

To post a comment you must log in.
Revision history for this message
Iain Lane (laney) wrote :
Revision history for this message
Iain Lane (laney) wrote :
Revision history for this message
Steve Langasek (vorlon) wrote :

when you say they depend on each other, do you mean that they need to land together in order to not break builds on nusakan?

Revision history for this message
Steve Langasek (vorlon) :
review: Needs Fixing
Revision history for this message
Iain Lane (laney) wrote :

Nah, that's not the best wording. It's more that they both need to land to work on focal.

Revision history for this message
Iain Lane (laney) :
Revision history for this message
Steve Langasek (vorlon) wrote :

ok, lgtm then

review: Approve
1879. By Iain Lane

sign: Drop privkeydir in _signing_command(), it's unused there

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/cdimage/launchpad.py'
--- lib/cdimage/launchpad.py 2019-01-11 17:45:45 +0000
+++ lib/cdimage/launchpad.py 2020-06-29 11:27:35 +0000
@@ -148,7 +148,20 @@
148148
149149
150def login(instance):150def login(instance):
151 return Launchpad.login_with("ubuntu-cdimage", instance, version="devel")151 try:
152 import launchpadlib.credentials
153 store = launchpadlib.credentials.KeyringCredentialStore(None,
154 fallback=True)
155 return Launchpad.login_with("ubuntu-cdimage",
156 instance,
157 version="devel",
158 credential_store=store)
159 except TypeError:
160 # prior to focal (1.10.13), the fallback= kwarg didn't exist and
161 # Launchpadlib worked under sudo
162 return Launchpad.login_with("ubuntu-cdimage",
163 instance,
164 version="devel")
152165
153166
154class _LaunchpadCache:167class _LaunchpadCache:
155168
=== modified file 'lib/cdimage/sign.py'
--- lib/cdimage/sign.py 2015-11-11 20:06:02 +0000
+++ lib/cdimage/sign.py 2020-06-29 11:27:35 +0000
@@ -23,30 +23,30 @@
2323
2424
25def _gnupg_files(config):25def _gnupg_files(config):
26 gpgdir = config["GNUPG_DIR"]
26 gpgconf = os.path.join(config["GNUPG_DIR"], "gpg.conf")27 gpgconf = os.path.join(config["GNUPG_DIR"], "gpg.conf")
27 secring = os.path.join(config["GNUPG_DIR"], "secring.gpg")28 secring = os.path.join(config["GNUPG_DIR"], "secring.gpg")
29 privkeydir = os.path.join(config["GNUPG_DIR"], "private-keys-v1.d")
28 pubring = os.path.join(config["GNUPG_DIR"], "pubring.gpg")30 pubring = os.path.join(config["GNUPG_DIR"], "pubring.gpg")
29 trustdb = os.path.join(config["GNUPG_DIR"], "trustdb.gpg")31 trustdb = os.path.join(config["GNUPG_DIR"], "trustdb.gpg")
30 return gpgconf, secring, pubring, trustdb32 return gpgdir, gpgconf, secring, privkeydir, pubring, trustdb
3133
3234
33def can_sign(config):35def can_sign(config):
34 gpgconf, secring, pubring, trustdb = _gnupg_files(config)36 _, _, secring, privkeydir, pubring, trustdb = _gnupg_files(config)
35 if (not os.path.exists(secring) or not os.path.exists(pubring) or37 if (not (os.path.exists(privkeydir) or os.path.exists(secring)) or
36 not os.path.exists(trustdb) or not config["SIGNING_KEYID"]):38 not os.path.exists(pubring) or not os.path.exists(trustdb) or
39 not config["SIGNING_KEYID"]):
37 logger.warning("No keys found; not signing images.")40 logger.warning("No keys found; not signing images.")
38 return False41 return False
39 return True42 return True
4043
4144
42def _signing_command(config):45def _signing_command(config):
43 gpgconf, secring, pubring, trustdb = _gnupg_files(config)46 gpgdir, gpgconf, _, _, _, _ = _gnupg_files(config)
44 cmd = [47 cmd = [
45 "gpg", "--options", gpgconf,48 "gpg", "--options", gpgconf,
46 "--no-default-keyring",49 "--homedir", gpgdir,
47 "--secret-keyring", secring,
48 "--keyring", pubring,
49 "--trustdb-name", trustdb,
50 "--no-options", "--batch", "--no-tty",50 "--no-options", "--batch", "--no-tty",
51 "--armour", "--detach-sign",51 "--armour", "--detach-sign",
52 # FBB75451 and EFE21092 have different digest preferences. GnuPG52 # FBB75451 and EFE21092 have different digest preferences. GnuPG
5353
=== modified file 'lib/cdimage/tests/test_checksums.py'
--- lib/cdimage/tests/test_checksums.py 2020-06-17 00:21:41 +0000
+++ lib/cdimage/tests/test_checksums.py 2020-06-29 11:27:35 +0000
@@ -88,7 +88,8 @@
88 checksum_file = ChecksumFile(88 checksum_file = ChecksumFile(
89 self.config, self.temp_dir, "SHA256SUMS", hashlib.sha256)89 self.config, self.temp_dir, "SHA256SUMS", hashlib.sha256)
90 self.assertEqual(90 self.assertEqual(
91 hashlib.sha256(data).hexdigest(), checksum_file.checksum(entry_path))91 hashlib.sha256(data).hexdigest(),
92 checksum_file.checksum(entry_path))
9293
93 def test_add(self):94 def test_add(self):
94 entry_path = os.path.join(self.temp_dir, "entry")95 entry_path = os.path.join(self.temp_dir, "entry")
9596
=== modified file 'lib/cdimage/tests/test_sign.py'
--- lib/cdimage/tests/test_sign.py 2015-11-11 20:06:02 +0000
+++ lib/cdimage/tests/test_sign.py 2020-06-29 11:27:35 +0000
@@ -34,9 +34,12 @@
34 def test_gnupg_files(self):34 def test_gnupg_files(self):
35 config = Config(read=False)35 config = Config(read=False)
36 config["GNUPG_DIR"] = "/path"36 config["GNUPG_DIR"] = "/path"
37 gpgconf, secring, pubring, trustdb = _gnupg_files(config)37 gpgdir, gpgconf, secring, privkeydir, pubring, trustdb = \
38 _gnupg_files(config)
39 self.assertEqual("/path", gpgdir)
38 self.assertEqual("/path/gpg.conf", gpgconf)40 self.assertEqual("/path/gpg.conf", gpgconf)
39 self.assertEqual("/path/secring.gpg", secring)41 self.assertEqual("/path/secring.gpg", secring)
42 self.assertEqual("/path/private-keys-v1.d", privkeydir)
40 self.assertEqual("/path/pubring.gpg", pubring)43 self.assertEqual("/path/pubring.gpg", pubring)
41 self.assertEqual("/path/trustdb.gpg", trustdb)44 self.assertEqual("/path/trustdb.gpg", trustdb)
4245
@@ -47,10 +50,7 @@
47 command = _signing_command(config)50 command = _signing_command(config)
48 self.assertEqual([51 self.assertEqual([
49 "gpg", "--options", "/path/gpg.conf",52 "gpg", "--options", "/path/gpg.conf",
50 "--no-default-keyring",53 "--homedir", "/path",
51 "--secret-keyring", "/path/secring.gpg",
52 "--keyring", "/path/pubring.gpg",
53 "--trustdb-name", "/path/trustdb.gpg",
54 "--no-options", "--batch", "--no-tty",54 "--no-options", "--batch", "--no-tty",
55 "--armour", "--detach-sign",55 "--armour", "--detach-sign",
56 "--digest-algo", "SHA512",56 "--digest-algo", "SHA512",
@@ -64,10 +64,7 @@
64 command = _signing_command(config)64 command = _signing_command(config)
65 self.assertEqual([65 self.assertEqual([
66 "gpg", "--options", "/path/gpg.conf",66 "gpg", "--options", "/path/gpg.conf",
67 "--no-default-keyring",67 "--homedir", "/path",
68 "--secret-keyring", "/path/secring.gpg",
69 "--keyring", "/path/pubring.gpg",
70 "--trustdb-name", "/path/trustdb.gpg",
71 "--no-options", "--batch", "--no-tty",68 "--no-options", "--batch", "--no-tty",
72 "--armour", "--detach-sign",69 "--armour", "--detach-sign",
73 "--digest-algo", "SHA512",70 "--digest-algo", "SHA512",
@@ -97,7 +94,8 @@
97 config = Config(read=False)94 config = Config(read=False)
98 config["GNUPG_DIR"] = self.use_temp_dir()95 config["GNUPG_DIR"] = self.use_temp_dir()
99 config["SIGNING_KEYID"] = "01234567"96 config["SIGNING_KEYID"] = "01234567"
100 gpgconf, secring, pubring, trustdb = _gnupg_files(config)97 gpgdir, gpgconf, secring, privkeydir, pubring, trustdb = \
98 _gnupg_files(config)
101 sign_path = os.path.join(self.temp_dir, "to-sign")99 sign_path = os.path.join(self.temp_dir, "to-sign")
102 for path in gpgconf, secring, pubring, trustdb, sign_path:100 for path in gpgconf, secring, pubring, trustdb, sign_path:
103 touch(path)101 touch(path)
@@ -106,10 +104,7 @@
106 self.assertLogEqual([])104 self.assertLogEqual([])
107 expected_command = [105 expected_command = [
108 "gpg", "--options", gpgconf,106 "gpg", "--options", gpgconf,
109 "--no-default-keyring",107 "--homedir", config["GNUPG_DIR"],
110 "--secret-keyring", secring,
111 "--keyring", pubring,
112 "--trustdb-name", trustdb,
113 "--no-options", "--batch", "--no-tty",108 "--no-options", "--batch", "--no-tty",
114 "--armour", "--detach-sign",109 "--armour", "--detach-sign",
115 "--digest-algo", "SHA512",110 "--digest-algo", "SHA512",
@@ -127,13 +122,15 @@
127 config = Config(read=False)122 config = Config(read=False)
128 config["GNUPG_DIR"] = self.use_temp_dir()123 config["GNUPG_DIR"] = self.use_temp_dir()
129 config["SIGNING_KEYID"] = "01234567"124 config["SIGNING_KEYID"] = "01234567"
130 gpgconf, secring, pubring, trustdb = _gnupg_files(config)125 gpgdir, gpgconf, secring, privkeydir, pubring, trustdb = \
126 _gnupg_files(config)
131 sign_path = os.path.join(self.temp_dir, "to-sign")127 sign_path = os.path.join(self.temp_dir, "to-sign")
132 for path in gpgconf, secring, pubring, trustdb, sign_path:128 for path in gpgconf, secring, pubring, trustdb, sign_path:
133 touch(path)129 touch(path)
134 touch("%s.gpg" % sign_path)130 touch("%s.gpg" % sign_path)
135 self.capture_logging()131 self.capture_logging()
136 self.assertRaises(132 with self.assertRaises(subprocess.CalledProcessError):
137 subprocess.CalledProcessError, sign_cdimage, config, sign_path)133 sign_cdimage(config, sign_path)
134 mock_check_call.assert_called()
138 self.assertLogEqual([])135 self.assertLogEqual([])
139 self.assertFalse(os.path.exists("%s.gpg" % sign_path))136 self.assertFalse(os.path.exists("%s.gpg" % sign_path))
140137
=== modified file 'lib/cdimage/tests/test_tree.py'
--- lib/cdimage/tests/test_tree.py 2020-06-19 00:57:47 +0000
+++ lib/cdimage/tests/test_tree.py 2020-06-29 11:27:35 +0000
@@ -2293,8 +2293,8 @@
2293 "preinstalled-netbook"))2293 "preinstalled-netbook"))
22942294
22952295
2296def call_btmakemetafile_zsyncmake(command, *args, **kwargs):2296def call_mktorrent_zsyncmake(command, *args, **kwargs):
2297 if command[0] == "btmakemetafile":2297 if command[0] == "mktorrent":
2298 touch("%s.torrent" % command[-1])2298 touch("%s.torrent" % command[-1])
2299 elif command[0] == "zsyncmake":2299 elif command[0] == "zsyncmake":
2300 for i in range(1, len(command)):2300 for i in range(1, len(command)):
@@ -2396,7 +2396,7 @@
2396 self.assertLogEqual(2396 self.assertLogEqual(
2397 ["Creating torrent for %s ..." % path for path in paths])2397 ["Creating torrent for %s ..." % path for path in paths])
2398 command_base = [2398 command_base = [
2399 "btmakemetafile", "https://torrent.ubuntu.com/announce",2399 "mktorrent", "-a", "https://torrent.ubuntu.com/announce",
2400 "--comment", "Ubuntu CD cdimage.ubuntu.com",2400 "--comment", "Ubuntu CD cdimage.ubuntu.com",
2401 ]2401 ]
2402 mock_check_call.assert_has_calls([2402 mock_check_call.assert_has_calls([
@@ -2417,7 +2417,7 @@
2417 self.get_publisher(official="named").publish_release_prefixes())2417 self.get_publisher(official="named").publish_release_prefixes())
24182418
2419 @mock.patch("cdimage.osextras.find_on_path", return_value=True)2419 @mock.patch("cdimage.osextras.find_on_path", return_value=True)
2420 @mock.patch("subprocess.call", side_effect=call_btmakemetafile_zsyncmake)2420 @mock.patch("subprocess.call", side_effect=call_mktorrent_zsyncmake)
2421 def test_publish_release_arch_ubuntu_desktop_named(self, mock_call, *args):2421 def test_publish_release_arch_ubuntu_desktop_named(self, mock_call, *args):
2422 self.config["PROJECT"] = "ubuntu"2422 self.config["PROJECT"] = "ubuntu"
2423 self.config["CAPPROJECT"] = "Ubuntu"2423 self.config["CAPPROJECT"] = "Ubuntu"
@@ -2461,7 +2461,7 @@
2461 "%s.iso" % target_base,2461 "%s.iso" % target_base,
2462 ]),2462 ]),
2463 mock.call([2463 mock.call([
2464 "btmakemetafile", mock.ANY,2464 "mktorrent", mock.ANY, mock.ANY,
2465 "--comment", "Ubuntu CD cdimage.ubuntu.com",2465 "--comment", "Ubuntu CD cdimage.ubuntu.com",
2466 "%s.iso" % target_base,2466 "%s.iso" % target_base,
2467 ], stdout=mock.ANY),2467 ], stdout=mock.ANY),
@@ -2479,7 +2479,7 @@
2479 os.stat("%s.iso.torrent" % torrent_base))2479 os.stat("%s.iso.torrent" % torrent_base))
24802480
2481 @mock.patch("cdimage.osextras.find_on_path", return_value=True)2481 @mock.patch("cdimage.osextras.find_on_path", return_value=True)
2482 @mock.patch("subprocess.call", side_effect=call_btmakemetafile_zsyncmake)2482 @mock.patch("subprocess.call", side_effect=call_mktorrent_zsyncmake)
2483 def test_publish_release_arch_ubuntu_desktop_no(self, mock_call, *args):2483 def test_publish_release_arch_ubuntu_desktop_no(self, mock_call, *args):
2484 self.config["PROJECT"] = "ubuntu"2484 self.config["PROJECT"] = "ubuntu"
2485 self.config["CAPPROJECT"] = "Ubuntu"2485 self.config["CAPPROJECT"] = "Ubuntu"
@@ -2512,7 +2512,7 @@
2512 self.assertFalse(os.path.islink("%s.iso" % target_base))2512 self.assertFalse(os.path.islink("%s.iso" % target_base))
2513 self.assertFalse(os.path.islink("%s.manifest" % target_base))2513 self.assertFalse(os.path.islink("%s.manifest" % target_base))
2514 mock_call.assert_called_once_with([2514 mock_call.assert_called_once_with([
2515 "btmakemetafile", mock.ANY,2515 "mktorrent", mock.ANY, mock.ANY,
2516 "--comment", "Ubuntu CD cdimage.ubuntu.com",2516 "--comment", "Ubuntu CD cdimage.ubuntu.com",
2517 "%s.iso" % target_base,2517 "%s.iso" % target_base,
2518 ], stdout=mock.ANY)2518 ], stdout=mock.ANY)
@@ -2527,7 +2527,7 @@
2527 os.stat("%s.iso.torrent" % torrent_base))2527 os.stat("%s.iso.torrent" % torrent_base))
25282528
2529 @mock.patch("cdimage.osextras.find_on_path", return_value=True)2529 @mock.patch("cdimage.osextras.find_on_path", return_value=True)
2530 @mock.patch("subprocess.call", side_effect=call_btmakemetafile_zsyncmake)2530 @mock.patch("subprocess.call", side_effect=call_mktorrent_zsyncmake)
2531 def test_publish_release_kubuntu_desktop_named(self, mock_call, *args):2531 def test_publish_release_kubuntu_desktop_named(self, mock_call, *args):
2532 self.config["PROJECT"] = "kubuntu"2532 self.config["PROJECT"] = "kubuntu"
2533 self.config["CAPPROJECT"] = "Kubuntu"2533 self.config["CAPPROJECT"] = "Kubuntu"
@@ -2685,10 +2685,9 @@
2685 publisher.make_torrents(2685 publisher.make_torrents(
2686 os.path.join(self.temp_dir, "dir"), "ubuntu-13.04")2686 os.path.join(self.temp_dir, "dir"), "ubuntu-13.04")
2687 command_base = [2687 command_base = [
2688 "btmakemetafile", "https://torrent.ubuntu.com/announce",2688 "mktorrent",
2689 "--announce_list",2689 "-a", "https://torrent.ubuntu.com/announce",
2690 ("https://torrent.ubuntu.com/announce|"2690 "-a", "https://ipv6.torrent.ubuntu.com/announce",
2691 "https://ipv6.torrent.ubuntu.com/announce"),
2692 "--comment", "Ubuntu CD releases.ubuntu.com",2691 "--comment", "Ubuntu CD releases.ubuntu.com",
2693 ]2692 ]
2694 mock_check_call.assert_has_calls([2693 mock_check_call.assert_has_calls([
@@ -2708,7 +2707,7 @@
2708 self.get_publisher().publish_release_prefixes())2707 self.get_publisher().publish_release_prefixes())
27092708
2710 @mock.patch("cdimage.osextras.find_on_path", return_value=True)2709 @mock.patch("cdimage.osextras.find_on_path", return_value=True)
2711 @mock.patch("subprocess.call", side_effect=call_btmakemetafile_zsyncmake)2710 @mock.patch("subprocess.call", side_effect=call_mktorrent_zsyncmake)
2712 def test_publish_release_arch_ubuntu_desktop_yes(self, mock_call, *args):2711 def test_publish_release_arch_ubuntu_desktop_yes(self, mock_call, *args):
2713 self.config["PROJECT"] = "ubuntu"2712 self.config["PROJECT"] = "ubuntu"
2714 self.config["CAPPROJECT"] = "Ubuntu"2713 self.config["CAPPROJECT"] = "Ubuntu"
@@ -2766,8 +2765,9 @@
2766 "%s.iso" % pool_base,2765 "%s.iso" % pool_base,
2767 ]),2766 ]),
2768 mock.call([2767 mock.call([
2769 "btmakemetafile", mock.ANY,2768 "mktorrent",
2770 "--announce_list", mock.ANY,2769 "-a", mock.ANY,
2770 "-a", mock.ANY,
2771 "--comment", "Ubuntu CD releases.ubuntu.com",2771 "--comment", "Ubuntu CD releases.ubuntu.com",
2772 "%s.iso" % target_base,2772 "%s.iso" % target_base,
2773 ], stdout=mock.ANY),2773 ], stdout=mock.ANY),
@@ -2785,7 +2785,7 @@
2785 os.stat("%s.iso.torrent" % torrent_base))2785 os.stat("%s.iso.torrent" % torrent_base))
27862786
2787 @mock.patch("cdimage.osextras.find_on_path", return_value=True)2787 @mock.patch("cdimage.osextras.find_on_path", return_value=True)
2788 @mock.patch("subprocess.call", side_effect=call_btmakemetafile_zsyncmake)2788 @mock.patch("subprocess.call", side_effect=call_mktorrent_zsyncmake)
2789 def test_publish_release_arch_ubuntu_desktop_poolonly(self, mock_call,2789 def test_publish_release_arch_ubuntu_desktop_poolonly(self, mock_call,
2790 *args):2790 *args):
2791 self.config["PROJECT"] = "ubuntu"2791 self.config["PROJECT"] = "ubuntu"
@@ -2823,7 +2823,7 @@
2823 ])2823 ])
28242824
2825 @mock.patch("cdimage.osextras.find_on_path", return_value=True)2825 @mock.patch("cdimage.osextras.find_on_path", return_value=True)
2826 @mock.patch("subprocess.call", side_effect=call_btmakemetafile_zsyncmake)2826 @mock.patch("subprocess.call", side_effect=call_mktorrent_zsyncmake)
2827 def test_publish_release_kubuntu_desktop_yes(self, mock_call, *args):2827 def test_publish_release_kubuntu_desktop_yes(self, mock_call, *args):
2828 self.config["PROJECT"] = "kubuntu"2828 self.config["PROJECT"] = "kubuntu"
2829 self.config["CAPPROJECT"] = "Kubuntu"2829 self.config["CAPPROJECT"] = "Kubuntu"
28302830
=== modified file 'lib/cdimage/tree.py'
--- lib/cdimage/tree.py 2020-06-19 00:57:47 +0000
+++ lib/cdimage/tree.py 2020-06-29 11:27:35 +0000
@@ -2971,15 +2971,9 @@
2971 if not self.dry_run:2971 if not self.dry_run:
2972 logger.info("Creating torrent for %s ..." % path)2972 logger.info("Creating torrent for %s ..." % path)
2973 osextras.unlink_force("%s.torrent" % path)2973 osextras.unlink_force("%s.torrent" % path)
2974 command = ["btmakemetafile", self.torrent_tracker]2974 command = ["mktorrent", "-a", self.torrent_tracker]
2975 if isinstance(self.tree, SimpleReleaseTree):2975 if isinstance(self.tree, SimpleReleaseTree):
2976 # N.B.: Only the bittornado version of btmakemetafile has2976 command.extend(["-a", self.ipv6_torrent_tracker])
2977 # the --announce_list flag.
2978 command.extend([
2979 "--announce_list",
2980 "%s|%s" % (
2981 self.torrent_tracker, self.ipv6_torrent_tracker),
2982 ])
2983 command.extend([2977 command.extend([
2984 "--comment",2978 "--comment",
2985 "%s CD %s" % (self.config.capproject, self.tree.site_name),2979 "%s CD %s" % (self.config.capproject, self.tree.site_name),

Subscribers

People subscribed via source and target branches