Merge lp:~cjwatson/launchpad-buildd/snap-source-tarball into lp:launchpad-buildd

Proposed by Colin Watson
Status: Merged
Merged at revision: 334
Proposed branch: lp:~cjwatson/launchpad-buildd/snap-source-tarball
Merge into: lp:launchpad-buildd
Diff against target: 205 lines (+104/-10)
5 files modified
debian/changelog (+2/-0)
lpbuildd/snap.py (+16/-8)
lpbuildd/target/build_snap.py (+11/-0)
lpbuildd/target/tests/test_build_snap.py (+24/-0)
lpbuildd/tests/test_snap.py (+51/-2)
To merge this branch: bzr merge lp:~cjwatson/launchpad-buildd/snap-source-tarball
Reviewer Review Type Date Requested Status
William Grant (community) code Approve
Review via email: mp+343721@code.launchpad.net

Commit message

Add an option to generate source tarballs for snaps after pulling external dependencies.

To post a comment you must log in.
335. By Colin Watson

source_tarball → build_source_tarball

336. By Colin Watson

Only try to gather a source tarball if we intended to build one.

Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2018-04-04 16:25:31 +0000
3+++ debian/changelog 2018-04-21 10:04:48 +0000
4@@ -1,6 +1,8 @@
5 launchpad-buildd (161) UNRELEASED; urgency=medium
6
7 * Pass build URL to snapcraft using SNAPCRAFT_IMAGE_INFO.
8+ * Add an option to generate source tarballs for snaps after pulling
9+ external dependencies (LP: #1763639).
10
11 -- Colin Watson <cjwatson@ubuntu.com> Wed, 04 Apr 2018 17:03:14 +0100
12
13
14=== modified file 'lpbuildd/snap.py'
15--- lpbuildd/snap.py 2018-03-21 09:17:50 +0000
16+++ lpbuildd/snap.py 2018-04-21 10:04:48 +0000
17@@ -45,6 +45,8 @@
18 self.git_path = extra_args.get("git_path")
19 self.proxy_url = extra_args.get("proxy_url")
20 self.revocation_endpoint = extra_args.get("revocation_endpoint")
21+ self.build_source_tarball = extra_args.get(
22+ "build_source_tarball", False)
23
24 super(SnapBuildManager, self).initiate(files, chroot, extra_args)
25
26@@ -86,6 +88,8 @@
27 args.extend(["--git-repository", self.git_repository])
28 if self.git_path is not None:
29 args.extend(["--git-path", self.git_path])
30+ if self.build_source_tarball:
31+ args.append("--build-source-tarball")
32 args.append(self.name)
33 self.runTargetSubProcess("buildsnap", *args)
34
35@@ -115,11 +119,15 @@
36 def gatherResults(self):
37 """Gather the results of the build and add them to the file cache."""
38 output_path = os.path.join("/build", self.name)
39- if not self.backend.path_exists(output_path):
40- return
41- for entry in sorted(self.backend.listdir(output_path)):
42- path = os.path.join(output_path, entry)
43- if self.backend.islink(path):
44- continue
45- if entry.endswith(".snap") or entry.endswith(".manifest"):
46- self.addWaitingFileFromBackend(path)
47+ if self.backend.path_exists(output_path):
48+ for entry in sorted(self.backend.listdir(output_path)):
49+ path = os.path.join(output_path, entry)
50+ if self.backend.islink(path):
51+ continue
52+ if entry.endswith(".snap") or entry.endswith(".manifest"):
53+ self.addWaitingFileFromBackend(path)
54+ if self.build_source_tarball:
55+ source_tarball_path = os.path.join(
56+ "/build", "%s.tar.gz" % self.name)
57+ if self.backend.path_exists(source_tarball_path):
58+ self.addWaitingFileFromBackend(source_tarball_path)
59
60=== modified file 'lpbuildd/target/build_snap.py'
61--- lpbuildd/target/build_snap.py 2018-04-04 16:25:31 +0000
62+++ lpbuildd/target/build_snap.py 2018-04-21 10:04:48 +0000
63@@ -71,6 +71,11 @@
64 parser.add_argument(
65 "--revocation-endpoint",
66 help="builder proxy token revocation endpoint")
67+ parser.add_argument(
68+ "--build-source-tarball", default=False, action="store_true",
69+ help=(
70+ "build a tarball containing all source code, including "
71+ "external dependencies"))
72 parser.add_argument("name", help="name of snap to build")
73
74 def __init__(self, args, parser):
75@@ -214,6 +219,12 @@
76 ["snapcraft", "pull"],
77 cwd=os.path.join("/build", self.args.name),
78 env=env)
79+ if self.args.build_source_tarball:
80+ self.run_build_command(
81+ ["tar", "-czf", "%s.tar.gz" % self.args.name,
82+ "--format=gnu", "--sort=name", "--exclude-vcs",
83+ "--numeric-owner", "--owner=0", "--group=0",
84+ self.args.name])
85
86 def build(self):
87 """Run all build, stage and snap phases."""
88
89=== modified file 'lpbuildd/target/tests/test_build_snap.py'
90--- lpbuildd/target/tests/test_build_snap.py 2018-04-04 16:25:31 +0000
91+++ lpbuildd/target/tests/test_build_snap.py 2018-04-21 10:04:48 +0000
92@@ -310,6 +310,30 @@
93 ["snapcraft", "pull"], cwd="/build/test-snap", **env),
94 ]))
95
96+ def test_pull_build_source_tarball(self):
97+ args = [
98+ "buildsnap",
99+ "--backend=fake", "--series=xenial", "--arch=amd64", "1",
100+ "--branch", "lp:foo", "--build-source-tarball", "test-snap",
101+ ]
102+ build_snap = parse_args(args=args).operation
103+ build_snap.pull()
104+ env = {
105+ "SNAPCRAFT_LOCAL_SOURCES": "1",
106+ "SNAPCRAFT_SETUP_CORE": "1",
107+ "SNAPCRAFT_BUILD_INFO": "1",
108+ "SNAPCRAFT_IMAGE_INFO": "{}",
109+ }
110+ self.assertThat(build_snap.backend.run.calls, MatchesListwise([
111+ RanBuildCommand(
112+ ["snapcraft", "pull"], cwd="/build/test-snap", **env),
113+ RanBuildCommand(
114+ ["tar", "-czf", "test-snap.tar.gz",
115+ "--format=gnu", "--sort=name", "--exclude-vcs",
116+ "--numeric-owner", "--owner=0", "--group=0",
117+ "test-snap"]),
118+ ]))
119+
120 def test_build(self):
121 args = [
122 "buildsnap",
123
124=== modified file 'lpbuildd/tests/test_snap.py'
125--- lpbuildd/tests/test_snap.py 2017-08-25 16:05:49 +0000
126+++ lpbuildd/tests/test_snap.py 2018-04-21 10:04:48 +0000
127@@ -52,7 +52,7 @@
128 """Retrieve build manager's state."""
129 return self.buildmanager._state
130
131- def startBuild(self):
132+ def startBuild(self, args=None, options=None):
133 # The build manager's iterate() kicks off the consecutive states
134 # after INIT.
135 extra_args = {
136@@ -62,6 +62,8 @@
137 "git_repository": "https://git.launchpad.dev/~example/+git/snap",
138 "git_path": "master",
139 }
140+ if args is not None:
141+ extra_args.update(args)
142 original_backend_name = self.buildmanager.backend_name
143 self.buildmanager.backend_name = "fake"
144 self.buildmanager.initiate({}, "chroot.tar.gz", extra_args)
145@@ -80,8 +82,10 @@
146 "--backend=lxd", "--series=xenial", "--arch=i386", self.buildid,
147 "--git-repository", "https://git.launchpad.dev/~example/+git/snap",
148 "--git-path", "master",
149- "test-snap",
150 ]
151+ if options is not None:
152+ expected_command.extend(options)
153+ expected_command.append("test-snap")
154 self.assertEqual(expected_command, self.buildmanager.commands[-1])
155 self.assertEqual(
156 self.buildmanager.iterate, self.buildmanager.iterators[-1])
157@@ -180,3 +184,48 @@
158 self.assertEqual(
159 self.buildmanager.iterate, self.buildmanager.iterators[-1])
160 self.assertFalse(self.slave.wasCalled("buildFail"))
161+
162+ def test_iterate_with_build_source_tarball(self):
163+ # The build manager iterates a build that uploads a source tarball
164+ # from start to finish.
165+ self.startBuild(
166+ {"build_source_tarball": True}, ["--build-source-tarball"])
167+
168+ log_path = os.path.join(self.buildmanager._cachepath, "buildlog")
169+ with open(log_path, "w") as log:
170+ log.write("I am a build log.")
171+
172+ self.buildmanager.backend.add_file(
173+ "/build/test-snap/test-snap_0_all.snap", b"I am a snap package.")
174+ self.buildmanager.backend.add_file(
175+ "/build/test-snap.tar.gz", b"I am a source tarball.")
176+
177+ # After building the package, reap processes.
178+ self.buildmanager.iterate(0)
179+ expected_command = [
180+ "sharepath/slavebin/in-target", "in-target",
181+ "scan-for-processes",
182+ "--backend=lxd", "--series=xenial", "--arch=i386", self.buildid,
183+ ]
184+ self.assertEqual(SnapBuildState.BUILD_SNAP, self.getState())
185+ self.assertEqual(expected_command, self.buildmanager.commands[-1])
186+ self.assertNotEqual(
187+ self.buildmanager.iterate, self.buildmanager.iterators[-1])
188+ self.assertFalse(self.slave.wasCalled("buildFail"))
189+ self.assertThat(self.slave, HasWaitingFiles.byEquality({
190+ "test-snap_0_all.snap": b"I am a snap package.",
191+ "test-snap.tar.gz": b"I am a source tarball.",
192+ }))
193+
194+ # Control returns to the DebianBuildManager in the UMOUNT state.
195+ self.buildmanager.iterateReap(self.getState(), 0)
196+ expected_command = [
197+ "sharepath/slavebin/in-target", "in-target",
198+ "umount-chroot",
199+ "--backend=lxd", "--series=xenial", "--arch=i386", self.buildid,
200+ ]
201+ self.assertEqual(SnapBuildState.UMOUNT, self.getState())
202+ self.assertEqual(expected_command, self.buildmanager.commands[-1])
203+ self.assertEqual(
204+ self.buildmanager.iterate, self.buildmanager.iterators[-1])
205+ self.assertFalse(self.slave.wasCalled("buildFail"))

Subscribers

People subscribed via source and target branches

to all changes: