Merge ~twom/launchpad-buildd:fix-scratch-oci-builds into launchpad-buildd:master

Proposed by Tom Wardill
Status: Merged
Approved by: Tom Wardill
Approved revision: 27fc8597114aef96fab0210cd4ec234116a97ca7
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~twom/launchpad-buildd:fix-scratch-oci-builds
Merge into: launchpad-buildd:master
Diff against target: 99 lines (+46/-10)
3 files modified
debian/changelog (+4/-0)
lpbuildd/oci.py (+14/-8)
lpbuildd/tests/test_oci.py (+28/-2)
Reviewer Review Type Date Requested Status
Thiago F. Pappacena (community) Approve
Review via email: mp+395241@code.launchpad.net

Commit message

Fix scratch OCI builds

Description of the change

FROM scratch OCI builds, or other builds that don't pull an image, don't create the metadata directory on disk.
Check if it exists before we attempt to read from it.

To post a comment you must log in.
Revision history for this message
Thiago F. Pappacena (pappacena) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 6f57d8a..6728dae 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,9 +1,13 @@
6 launchpad-buildd (194) UNRELEASED; urgency=medium
7
8+ [ Colin Watson ]
9 * Stop setting $mailto in .sbuildrc, to work around LP #1859010.
10 * Stop overquoting OCI --build-arg options (LP: #1902007).
11 * Update production deployment documentation in README.
12
13+ [ Tom Wardill ]
14+ * Fix OCI builds that don't pull another image.
15+
16 -- Colin Watson <cjwatson@ubuntu.com> Tue, 27 Oct 2020 13:22:05 +0000
17
18 launchpad-buildd (193) bionic; urgency=medium
19diff --git a/lpbuildd/oci.py b/lpbuildd/oci.py
20index 6a404fd..cf8d1d7 100644
21--- a/lpbuildd/oci.py
22+++ b/lpbuildd/oci.py
23@@ -209,14 +209,20 @@ class OCIBuildManager(SnapBuildProxyMixin, DebianBuildManager):
24 # used. This is correct for bionic buildd image
25 # with apt installed docker.
26 sha_path = ('/var/lib/docker/image/'
27- 'vfs/distribution/v2metadata-by-diffid/sha256/')
28- sha_files = [x for x in self.backend.listdir(sha_path)
29- if not x.startswith('.')]
30- for file in sha_files:
31- self.backend.copy_out(
32- os.path.join(sha_path, file),
33- os.path.join(sha_directory, file)
34- )
35+ 'vfs/distribution/v2metadata-by-diffid/sha256')
36+ # If there have been no images pulled in the build process
37+ # (FROM scratch), then this directory will not exist and
38+ # we will have no contents from it.
39+ if self.backend.path_exists(sha_path):
40+ sha_files = [x for x in self.backend.listdir(sha_path)
41+ if not x.startswith('.')]
42+ for file in sha_files:
43+ self.backend.copy_out(
44+ os.path.join(sha_path, file),
45+ os.path.join(sha_directory, file)
46+ )
47+ else:
48+ self._builder.log("No metadata directory at {}".format(sha_path))
49
50 # Parse the manifest for the other files we need
51 manifest_path = os.path.join(extract_path, 'manifest.json')
52diff --git a/lpbuildd/tests/test_oci.py b/lpbuildd/tests/test_oci.py
53index 23641e4..15a4d64 100644
54--- a/lpbuildd/tests/test_oci.py
55+++ b/lpbuildd/tests/test_oci.py
56@@ -130,8 +130,7 @@ class TestOCIBuildManagerIteration(TestCase):
57 self.buildmanager.backend.add_file(
58 '/var/lib/docker/image/'
59 'vfs/distribution/v2metadata-by-diffid/sha256/diff1',
60- b"""[{"Digest": "test_digest", "SourceRepository": "test"}]"""
61- )
62+ b"""[{"Digest": "test_digest", "SourceRepository": "test"}]""")
63
64 # After building the package, reap processes.
65 yield self.buildmanager.iterate(0)
66@@ -271,6 +270,33 @@ class TestOCIBuildManagerIteration(TestCase):
67 self.assertFalse(self.builder.wasCalled("buildFail"))
68
69 @defer.inlineCallbacks
70+ def test_iterate_no_pull(self):
71+ # check with no pulled images.
72+ # This sha would change as it includes file attributes in the
73+ # tar file. Fix it so we can test against a known value.
74+ sha_mock = self.useFixture(
75+ MockPatch('lpbuildd.oci.OCIBuildManager._calculateLayerSha'))
76+ sha_mock.mock.return_value = "testsha"
77+ # The build manager iterates a normal build from start to finish.
78+ args = {
79+ "git_repository": "https://git.launchpad.dev/~example/+git/snap",
80+ "git_path": "master",
81+ }
82+ expected_options = [
83+ "--git-repository", "https://git.launchpad.dev/~example/+git/snap",
84+ "--git-path", "master",
85+ ]
86+ yield self.startBuild(args, expected_options)
87+
88+ log_path = os.path.join(self.buildmanager._cachepath, "buildlog")
89+ with open(log_path, "w") as log:
90+ log.write("I am a build log.")
91+
92+ self.buildmanager.backend.run.result = MockOCITarSave()
93+ yield self.buildmanager.iterate(0)
94+ self.assertFalse(self.builder.wasCalled("buildFail"))
95+
96+ @defer.inlineCallbacks
97 def test_iterate_snap_store_proxy(self):
98 # The build manager can be told to use a snap store proxy.
99 self.builder._config.set(

Subscribers

People subscribed via source and target branches