Merge lp:~tobijk/launchpad-buildd/launchpad-buildd-bionic into lp:launchpad-buildd
- launchpad-buildd-bionic
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 353 |
Proposed branch: | lp:~tobijk/launchpad-buildd/launchpad-buildd-bionic |
Merge into: | lp:launchpad-buildd |
Diff against target: |
304 lines (+116/-37) 3 files modified
debian/changelog (+4/-0) lpbuildd/target/lxd.py (+37/-7) lpbuildd/target/tests/test_lxd.py (+75/-30) |
To merge this branch: | bzr merge lp:~tobijk/launchpad-buildd/launchpad-buildd-bionic |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Colin Watson (community) | Approve | ||
Tobias Koch (community) | Needs Resubmitting | ||
Launchpad code reviewers | Pending | ||
Review via email: mp+354331@code.launchpad.net |
Commit message
Update LXD backend to work with newer LXD versions.
Description of the change
This patch makes the buildd's LXD backend work on Bionic:
* Based on LXD version modify raw.lxc settings (some parameter names have changed)
* Fix a problem with header checks where uid and gid are set to 0, but need to be strings
* Explicitly specify a root device, which seems to be mandatory now
Tobias Koch (tobijk) wrote : | # |
Thanks a lot for the initial review! When you find the time, maybe you can skim over this and see if it is better now. I'll see what I can do about the tests.
Tobias Koch (tobijk) wrote : | # |
@cjwatson, please review.
Colin Watson (cjwatson) : | # |
- 348. By Colin Watson
-
[r=cjwatson] buildlivefs: support passing an IMAGE_TARGETS variable into the environment
This is needed for projects, such as ubuntu-cpc, that produce multiple
images as part of a single build, in order to be selective about which image
sets to produce. - 349. By Colin Watson
-
[r=wgrant] Set SNAPCRAFT_
BUILD_ENVIRONME NT=host when building snaps (LP: #1791201). - 350. By Colin Watson
-
[r=wgrant] Call gatherResults in a different thread so that it doesn't block responses to XML-RPC requests.
- 351. By Colin Watson
-
releasing package launchpad-buildd version 165
Tobias Koch (tobijk) wrote : | # |
@cjwatson, ready for re-review.
Tobias Koch (tobijk) wrote : | # |
Is there a reason why only tests in lpbuildd/tests are run during package build?
- 352. By Colin Watson
-
Run all tests at package build time, not just those in lpbuildd.tests.
Colin Watson (cjwatson) wrote : | # |
(The "Resubmit" vote is something that your reviewer might use to indicate that the MP needs to be entirely withdrawn and resubmitted, perhaps against a different branch. It isn't something you do when you've made revisions in response to a review.)
Regarding tests at package build time, oops; I've fixed that in trunk. Thanks for pointing it out.
- 353. By Tobias Koch
-
Update LXD backend to work with LXD 3.
Tobias Koch (tobijk) wrote : | # |
@cjwatson, thanks for the clarification on the "resubmit". I'm not sure how you want the re-factoring on `raw_lxc_config` to look like, so maybe it's better if you just mold it to your liking. Thanks.
Colin Watson (cjwatson) : | # |
Preview Diff
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2018-10-25 09:04:12 +0000 |
3 | +++ debian/changelog 2018-10-25 09:55:10 +0000 |
4 | @@ -1,7 +1,11 @@ |
5 | launchpad-buildd (166) UNRELEASED; urgency=medium |
6 | |
7 | + [Colin Watson] |
8 | * Run all tests at package build time, not just those in lpbuildd.tests. |
9 | |
10 | + [Tobias Koch] |
11 | + * Update LXD backend to work with LXD 3. |
12 | + |
13 | -- Colin Watson <cjwatson@ubuntu.com> Thu, 25 Oct 2018 10:03:14 +0100 |
14 | |
15 | launchpad-buildd (165) xenial; urgency=medium |
16 | |
17 | === modified file 'lpbuildd/target/lxd.py' |
18 | --- lpbuildd/target/lxd.py 2018-06-12 23:23:13 +0000 |
19 | +++ lpbuildd/target/lxd.py 2018-10-25 09:55:10 +0000 |
20 | @@ -277,16 +277,30 @@ |
21 | old_profile.delete() |
22 | |
23 | raw_lxc_config = [ |
24 | - ("lxc.aa_profile", "unconfined"), |
25 | ("lxc.cap.drop", ""), |
26 | ("lxc.cap.drop", "sys_time sys_module"), |
27 | ("lxc.cgroup.devices.deny", ""), |
28 | ("lxc.cgroup.devices.allow", ""), |
29 | ("lxc.mount.auto", ""), |
30 | ("lxc.mount.auto", "proc:rw sys:rw"), |
31 | - ("lxc.network.0.ipv4", ipv4_address), |
32 | - ("lxc.network.0.ipv4.gateway", self.ipv4_network.ip), |
33 | ] |
34 | + |
35 | + lxc_version = self._client.host_info["environment"]["driver_version"] |
36 | + major, minor = [int(v) for v in lxc_version.split(".")[0:2]] |
37 | + |
38 | + if major >= 3: |
39 | + raw_lxc_config.extend([ |
40 | + ("lxc.apparmor.profile", "unconfined"), |
41 | + ("lxc.net.0.ipv4.address", ipv4_address), |
42 | + ("lxc.net.0.ipv4.gateway", self.ipv4_network.ip), |
43 | + ]) |
44 | + else: |
45 | + raw_lxc_config.extend([ |
46 | + ("lxc.aa_profile", "unconfined"), |
47 | + ("lxc.network.0.ipv4", ipv4_address), |
48 | + ("lxc.network.0.ipv4.gateway", self.ipv4_network.ip), |
49 | + ]) |
50 | + |
51 | # Linux 4.4 on powerpc doesn't support all the seccomp bits that LXD |
52 | # needs. |
53 | if self.arch == "powerpc": |
54 | @@ -296,7 +310,7 @@ |
55 | "security.nesting": "true", |
56 | "raw.lxc": "".join( |
57 | "{key}={value}\n".format(key=key, value=value) |
58 | - for key, value in raw_lxc_config), |
59 | + for key, value in sorted(raw_lxc_config)), |
60 | } |
61 | devices = { |
62 | "eth0": { |
63 | @@ -306,6 +320,12 @@ |
64 | "type": "nic", |
65 | }, |
66 | } |
67 | + if major >= 3: |
68 | + devices["root"] = { |
69 | + "path": "/", |
70 | + "pool": "default", |
71 | + "type": "disk", |
72 | + } |
73 | self.client.profiles.create(self.profile_name, config, devices) |
74 | |
75 | def start(self): |
76 | @@ -341,7 +361,17 @@ |
77 | hostname_file.flush() |
78 | os.fchmod(hostname_file.fileno(), 0o644) |
79 | self.copy_in(hostname_file.name, "/etc/hostname") |
80 | - self.copy_in("/etc/resolv.conf", "/etc/resolv.conf") |
81 | + |
82 | + resolv_conf = "/etc/resolv.conf" |
83 | + |
84 | + if os.path.islink(resolv_conf): |
85 | + resolv_conf = os.path.realpath(resolv_conf) |
86 | + if (resolv_conf == "/run/systemd/resolve/stub-resolv.conf" and |
87 | + os.path.isfile("/run/systemd/resolve/resolv.conf")): |
88 | + resolv_conf = "/run/systemd/resolve/resolv.conf" |
89 | + |
90 | + self.copy_in(resolv_conf, "/etc/resolv.conf") |
91 | + |
92 | with tempfile.NamedTemporaryFile(mode="w+") as policy_rc_d_file: |
93 | policy_rc_d_file.write(policy_rc_d) |
94 | policy_rc_d_file.flush() |
95 | @@ -481,8 +511,8 @@ |
96 | data = source_file.read() |
97 | mode = stat.S_IMODE(os.fstat(source_file.fileno()).st_mode) |
98 | headers = { |
99 | - "X-LXD-uid": 0, |
100 | - "X-LXD-gid": 0, |
101 | + "X-LXD-uid": "0", |
102 | + "X-LXD-gid": "0", |
103 | "X-LXD-mode": "%#o" % mode, |
104 | } |
105 | try: |
106 | |
107 | === modified file 'lpbuildd/target/tests/test_lxd.py' |
108 | --- lpbuildd/target/tests/test_lxd.py 2018-05-08 09:37:16 +0000 |
109 | +++ lpbuildd/target/tests/test_lxd.py 2018-10-25 09:55:10 +0000 |
110 | @@ -155,23 +155,45 @@ |
111 | image.add_alias.assert_called_once_with( |
112 | "lp-xenial-amd64", "lp-xenial-amd64") |
113 | |
114 | - def assert_correct_profile(self, extra_raw_lxc_config=""): |
115 | + def assert_correct_profile(self, extra_raw_lxc_config=None, |
116 | + driver_version="2.0"): |
117 | + if extra_raw_lxc_config is None: |
118 | + extra_raw_lxc_config = [] |
119 | + |
120 | client = pylxd.Client() |
121 | client.profiles.get.assert_called_once_with("lpbuildd") |
122 | + |
123 | + raw_lxc_config = [ |
124 | + ("lxc.cap.drop", ""), |
125 | + ("lxc.cap.drop", "sys_time sys_module"), |
126 | + ("lxc.cgroup.devices.deny", ""), |
127 | + ("lxc.cgroup.devices.allow", ""), |
128 | + ("lxc.mount.auto", ""), |
129 | + ("lxc.mount.auto", "proc:rw sys:rw"), |
130 | + ] |
131 | + |
132 | + major, minor = [int(v) for v in driver_version.split(".")[0:2]] |
133 | + |
134 | + if major >= 3: |
135 | + raw_lxc_config.extend([ |
136 | + ("lxc.apparmor.profile", "unconfined"), |
137 | + ("lxc.net.0.ipv4.address", "10.10.10.2/24"), |
138 | + ("lxc.net.0.ipv4.gateway", "10.10.10.1"), |
139 | + ]) |
140 | + else: |
141 | + raw_lxc_config.extend([ |
142 | + ("lxc.aa_profile", "unconfined"), |
143 | + ("lxc.network.0.ipv4", "10.10.10.2/24"), |
144 | + ("lxc.network.0.ipv4.gateway", "10.10.10.1"), |
145 | + ]) |
146 | + |
147 | + raw_lxc_config = "".join("{key}={val}\n".format(key=key, val=val) |
148 | + for key, val in sorted(raw_lxc_config + extra_raw_lxc_config)) |
149 | + |
150 | expected_config = { |
151 | "security.privileged": "true", |
152 | "security.nesting": "true", |
153 | - "raw.lxc": dedent("""\ |
154 | - lxc.aa_profile=unconfined |
155 | - lxc.cap.drop= |
156 | - lxc.cap.drop=sys_time sys_module |
157 | - lxc.cgroup.devices.deny= |
158 | - lxc.cgroup.devices.allow= |
159 | - lxc.mount.auto= |
160 | - lxc.mount.auto=proc:rw sys:rw |
161 | - lxc.network.0.ipv4=10.10.10.2/24 |
162 | - lxc.network.0.ipv4.gateway=10.10.10.1 |
163 | - """) + extra_raw_lxc_config, |
164 | + "raw.lxc": raw_lxc_config, |
165 | } |
166 | expected_devices = { |
167 | "eth0": { |
168 | @@ -181,22 +203,42 @@ |
169 | "type": "nic", |
170 | }, |
171 | } |
172 | + if driver_version == "3.0": |
173 | + expected_devices["root"] = { |
174 | + "path": "/", |
175 | + "pool": "default", |
176 | + "type": "disk", |
177 | + } |
178 | client.profiles.create.assert_called_once_with( |
179 | "lpbuildd", expected_config, expected_devices) |
180 | |
181 | def test_create_profile_amd64(self): |
182 | - self.useFixture(MockPatch("pylxd.Client")) |
183 | - client = pylxd.Client() |
184 | - client.profiles.get.side_effect = FakeLXDAPIException |
185 | - LXD("1", "xenial", "amd64").create_profile() |
186 | - self.assert_correct_profile() |
187 | + with MockPatch("pylxd.Client"): |
188 | + for driver_version in ["2.0", "3.0"]: |
189 | + client = pylxd.Client() |
190 | + client.reset_mock() |
191 | + client.profiles.get.side_effect = FakeLXDAPIException |
192 | + client.host_info = { |
193 | + "environment": {"driver_version": driver_version} |
194 | + } |
195 | + LXD("1", "xenial", "amd64").create_profile() |
196 | + self.assert_correct_profile( |
197 | + driver_version=driver_version or "3.0") |
198 | |
199 | def test_create_profile_powerpc(self): |
200 | - self.useFixture(MockPatch("pylxd.Client")) |
201 | - client = pylxd.Client() |
202 | - client.profiles.get.side_effect = FakeLXDAPIException |
203 | - LXD("1", "xenial", "powerpc").create_profile() |
204 | - self.assert_correct_profile("lxc.seccomp=\n") |
205 | + with MockPatch("pylxd.Client"): |
206 | + for driver_version in ["2.0", "3.0"]: |
207 | + client = pylxd.Client() |
208 | + client.reset_mock() |
209 | + client.profiles.get.side_effect = FakeLXDAPIException |
210 | + client.host_info = { |
211 | + "environment": {"driver_version": driver_version} |
212 | + } |
213 | + LXD("1", "xenial", "powerpc").create_profile() |
214 | + self.assert_correct_profile( |
215 | + extra_raw_lxc_config=[("lxc.seccomp", ""),], |
216 | + driver_version=driver_version or "3.0" |
217 | + ) |
218 | |
219 | def test_start(self): |
220 | fs_fixture = self.useFixture(FakeFilesystem()) |
221 | @@ -213,6 +255,7 @@ |
222 | client.profiles.get.side_effect = FakeLXDAPIException |
223 | container = client.containers.create.return_value |
224 | client.containers.get.return_value = container |
225 | + client.host_info = {"environment": {"driver_version": "2.0"}} |
226 | container.start.side_effect = ( |
227 | lambda wait=False: setattr(container, "status_code", LXD_RUNNING)) |
228 | files_api = container.api.files |
229 | @@ -298,19 +341,19 @@ |
230 | data=( |
231 | b"127.0.0.1\tlocalhost\n\n" |
232 | b"127.0.1.1\texample.buildd example\n"), |
233 | - headers={"X-LXD-uid": 0, "X-LXD-gid": 0, "X-LXD-mode": "0644"}) |
234 | + headers={"X-LXD-uid": "0", "X-LXD-gid": "0", "X-LXD-mode": "0644"}) |
235 | files_api.post.assert_any_call( |
236 | params={"path": "/etc/hostname"}, |
237 | data=b"example\n", |
238 | - headers={"X-LXD-uid": 0, "X-LXD-gid": 0, "X-LXD-mode": "0644"}) |
239 | + headers={"X-LXD-uid": "0", "X-LXD-gid": "0", "X-LXD-mode": "0644"}) |
240 | files_api.post.assert_any_call( |
241 | params={"path": "/etc/resolv.conf"}, |
242 | data=b"host resolv.conf\n", |
243 | - headers={"X-LXD-uid": 0, "X-LXD-gid": 0, "X-LXD-mode": "0644"}) |
244 | + headers={"X-LXD-uid": "0", "X-LXD-gid": "0", "X-LXD-mode": "0644"}) |
245 | files_api.post.assert_any_call( |
246 | params={"path": "/usr/local/sbin/policy-rc.d"}, |
247 | data=policy_rc_d.encode("UTF-8"), |
248 | - headers={"X-LXD-uid": 0, "X-LXD-gid": 0, "X-LXD-mode": "0755"}) |
249 | + headers={"X-LXD-uid": "0", "X-LXD-gid": "0", "X-LXD-mode": "0755"}) |
250 | files_api.session.get.assert_any_call( |
251 | "/1.0/containers/lp-xenial-amd64/files", |
252 | params={"path": "/etc/init/mounted-dev.conf"}, stream=True) |
253 | @@ -321,7 +364,7 @@ |
254 | files_api.post.assert_any_call( |
255 | params={"path": "/etc/systemd/system/snapd.service.d/no-cdn.conf"}, |
256 | data=b"[Service]\nEnvironment=SNAPPY_STORE_NO_CDN=1\n", |
257 | - headers={"X-LXD-uid": 0, "X-LXD-gid": 0, "X-LXD-mode": "0644"}) |
258 | + headers={"X-LXD-uid": "0", "X-LXD-gid": "0", "X-LXD-mode": "0644"}) |
259 | container.start.assert_called_once_with(wait=True) |
260 | self.assertEqual(LXD_RUNNING, container.status_code) |
261 | |
262 | @@ -340,6 +383,7 @@ |
263 | client.profiles.get.side_effect = FakeLXDAPIException |
264 | container = client.containers.create.return_value |
265 | client.containers.get.return_value = container |
266 | + client.host_info = {"environment": {"driver_version": "2.0"}} |
267 | container.start.side_effect = ( |
268 | lambda wait=False: setattr(container, "status_code", LXD_RUNNING)) |
269 | files_api = container.api.files |
270 | @@ -360,7 +404,7 @@ |
271 | data=( |
272 | fallback_hosts + |
273 | "\n127.0.1.1\texample.buildd example\n").encode("UTF-8"), |
274 | - headers={"X-LXD-uid": 0, "X-LXD-gid": 0, "X-LXD-mode": "0644"}) |
275 | + headers={"X-LXD-uid": "0", "X-LXD-gid": "0", "X-LXD-mode": "0644"}) |
276 | |
277 | def test_start_with_mounted_dev_conf(self): |
278 | fs_fixture = self.useFixture(FakeFilesystem()) |
279 | @@ -375,6 +419,7 @@ |
280 | self.useFixture(MockPatch("pylxd.Client")) |
281 | client = pylxd.Client() |
282 | client.profiles.get.side_effect = FakeLXDAPIException |
283 | + client.host_info = {"environment": {"driver_version": "2.0"}} |
284 | container = client.containers.create.return_value |
285 | client.containers.get.return_value = container |
286 | container.start.side_effect = ( |
287 | @@ -406,7 +451,7 @@ |
288 | : # /sbin/MAKEDEV std fd ppp tun |
289 | end script |
290 | """).encode("UTF-8"), |
291 | - headers={"X-LXD-uid": 0, "X-LXD-gid": 0, "X-LXD-mode": "0644"}) |
292 | + headers={"X-LXD-uid": "0", "X-LXD-gid": "0", "X-LXD-mode": "0644"}) |
293 | |
294 | def test_run(self): |
295 | processes_fixture = self.useFixture(FakeProcesses()) |
296 | @@ -456,7 +501,7 @@ |
297 | container.api.files.post.assert_called_once_with( |
298 | params={"path": target_path}, |
299 | data=b"hello\n", |
300 | - headers={"X-LXD-uid": 0, "X-LXD-gid": 0, "X-LXD-mode": "0644"}) |
301 | + headers={"X-LXD-uid": "0", "X-LXD-gid": "0", "X-LXD-mode": "0644"}) |
302 | |
303 | def test_copy_in_error(self): |
304 | source_dir = self.useFixture(TempDir()).path |
Thanks for working on this!
As well as the inline comments I've left, I'm pretty sure that this is going to need changes to the test suite.