Merge ~ack/maas:set-snap-proxy into maas:master

Proposed by Alberto Donato
Status: Merged
Approved by: Alberto Donato
Approved revision: 16ab34cae3475d4eb1679c14e77ee3079e7c425c
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~ack/maas:set-snap-proxy
Merge into: maas:master
Diff against target: 519 lines (+164/-102)
5 files modified
src/maasserver/compose_preseed.py (+16/-0)
src/maasserver/tests/test_compose_preseed.py (+26/-4)
src/metadataserver/tests/test_api.py (+8/-7)
src/metadataserver/tests/test_vendor_data.py (+100/-79)
src/metadataserver/vendor_data.py (+14/-12)
Reviewer Review Type Date Requested Status
MAAS Lander Needs Fixing
Adam Collard (community) Approve
Review via email: mp+399926@code.launchpad.net

Commit message

set proxy for snapd when deploying machines

To post a comment you must log in.
Revision history for this message
Adam Collard (adam-collard) wrote :

LGTM

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b set-snap-proxy lp:~ack/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/9581/console
COMMIT: cf111960ea305da946360e126763d6af153cdb28

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

There was an error fetching revisions from git servers. Please try again in a few minutes. If the problem persists, contact Launchpad support.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/compose_preseed.py b/src/maasserver/compose_preseed.py
2index 37dffec..fb6ac65 100644
3--- a/src/maasserver/compose_preseed.py
4+++ b/src/maasserver/compose_preseed.py
5@@ -303,6 +303,20 @@ def get_cloud_init_reporting(request, node, token):
6 }
7
8
9+def get_snap_config(request, node):
10+ """Return the cloud-init snap configuration."""
11+ proxy = get_apt_proxy(request, node.get_boot_rack_controller(), node)
12+ if not proxy:
13+ return {}
14+ return {
15+ "snap": {
16+ "commands": [
17+ f'snap set system proxy.http="{proxy}" proxy.https="{proxy}"',
18+ ],
19+ },
20+ }
21+
22+
23 def get_rsyslog_host_port(request, node):
24 """Return the rsyslog host and port to use."""
25 configs = Config.objects.get_configs(["remote_syslog", "maas_syslog_port"])
26@@ -509,6 +523,8 @@ def _compose_cloud_init_preseed(
27 cloud_config.update(
28 get_archive_config(request, node, preserve_sources=False)
29 )
30+ # Add snaps configuration
31+ cloud_config.update(get_snap_config(request, node))
32
33 enable_ssh = (
34 node.status in {NODE_STATUS.COMMISSIONING, NODE_STATUS.TESTING}
35diff --git a/src/maasserver/tests/test_compose_preseed.py b/src/maasserver/tests/test_compose_preseed.py
36index 3f8369b..a7e634b 100644
37--- a/src/maasserver/tests/test_compose_preseed.py
38+++ b/src/maasserver/tests/test_compose_preseed.py
39@@ -1,9 +1,6 @@
40-# Copyright 2012-2019 Canonical Ltd. This software is licensed under the
41+# Copyright 2012-2021 Canonical Ltd. This software is licensed under the
42 # GNU Affero General Public License version 3 (see the file LICENSE).
43
44-"""Tests for `maasserver.compose_preseed`."""
45-
46-
47 import random
48
49 from django.urls import reverse
50@@ -473,6 +470,14 @@ class TestComposePreseed(MAASServerTestCase):
51 }
52 ),
53 )
54+ self.assertEqual(
55+ config["snap"],
56+ {
57+ "commands": [
58+ f'snap set system proxy.http="{apt_proxy}" proxy.https="{apt_proxy}"',
59+ ],
60+ },
61+ )
62
63 def test_compose_preseed_for_commissioning_node_skips_apt_proxy(self):
64 # Disable boot source cache signals.
65@@ -524,6 +529,14 @@ class TestComposePreseed(MAASServerTestCase):
66 )
67 self.assertThat(preseed["rsyslog"]["remotes"], KeysEqual("maas"))
68 self.assertAptConfig(preseed, apt_proxy)
69+ self.assertEqual(
70+ preseed["snap"],
71+ {
72+ "commands": [
73+ f'snap set system proxy.http="{apt_proxy}" proxy.https="{apt_proxy}"',
74+ ],
75+ },
76+ )
77
78 def test_compose_preseed_for_commissioning_node_has_header(self):
79 rack_controller = factory.make_RackController()
80@@ -870,6 +883,14 @@ class TestComposePreseed(MAASServerTestCase):
81 preseed["datasource"]["MAAS"]["metadata_url"],
82 )
83 self.assertAptConfig(preseed, expected_apt_proxy)
84+ self.assertEqual(
85+ preseed["snap"],
86+ {
87+ "commands": [
88+ f'snap set system proxy.http="{expected_apt_proxy}" proxy.https="{expected_apt_proxy}"',
89+ ],
90+ },
91+ )
92
93 def test_compose_preseed_with_curtin_installer_skips_apt_proxy(self):
94 # Disable boot source cache signals.
95@@ -890,6 +911,7 @@ class TestComposePreseed(MAASServerTestCase):
96 )
97
98 self.assertNotIn("proxy", preseed["apt"])
99+ self.assertNotIn("snap", preseed)
100
101 # LP: #1743966 - Test for archive key work around
102 def test_compose_preseed_for_curtin_and_trusty_aptsources(self):
103diff --git a/src/metadataserver/tests/test_api.py b/src/metadataserver/tests/test_api.py
104index 36a599e..50d25a5 100644
105--- a/src/metadataserver/tests/test_api.py
106+++ b/src/metadataserver/tests/test_api.py
107@@ -28,7 +28,6 @@ from testtools.matchers import (
108 ContainsAll,
109 ContainsDict,
110 Equals,
111- KeysEqual,
112 StartsWith,
113 )
114 import yaml
115@@ -981,9 +980,9 @@ class TestMetadataCommon(MAASServerTestCase):
116 content = yaml.safe_load(response.content)
117 self.assertThat(response, HasStatusCode(http.client.OK))
118 self.assertThat(content, LooksLikeCloudInit)
119- self.assertThat(
120+ self.assertCountEqual(
121 yaml.safe_load(content["cloud-init"]),
122- KeysEqual("system_info", "runcmd"),
123+ ["runcmd", "snap", "system_info"],
124 )
125
126 def test_vendor_data_node_without_def_user_includes_no_system_info(self):
127@@ -998,8 +997,9 @@ class TestMetadataCommon(MAASServerTestCase):
128 content = yaml.safe_load(response.content)
129 self.assertThat(response, HasStatusCode(http.client.OK))
130 self.assertThat(content, LooksLikeCloudInit)
131- self.assertThat(
132- yaml.safe_load(content["cloud-init"]), KeysEqual("runcmd")
133+ self.assertCountEqual(
134+ yaml.safe_load(content["cloud-init"]),
135+ ["runcmd", "snap"],
136 )
137
138 def test_vendor_data_for_node_without_owner_includes_no_system_info(self):
139@@ -1010,8 +1010,9 @@ class TestMetadataCommon(MAASServerTestCase):
140 content = yaml.safe_load(response.content)
141 self.assertThat(response, HasStatusCode(http.client.OK))
142 self.assertThat(content, LooksLikeCloudInit)
143- self.assertThat(
144- yaml.safe_load(content["cloud-init"]), KeysEqual("runcmd")
145+ self.assertCountEqual(
146+ yaml.safe_load(content["cloud-init"]),
147+ ["runcmd", "snap"],
148 )
149
150 def test_vendor_data_calls_through_to_get_vendor_data(self):
151diff --git a/src/metadataserver/tests/test_vendor_data.py b/src/metadataserver/tests/test_vendor_data.py
152index 3b5e328..36fc86b 100644
153--- a/src/metadataserver/tests/test_vendor_data.py
154+++ b/src/metadataserver/tests/test_vendor_data.py
155@@ -32,6 +32,7 @@ from metadataserver.vendor_data import (
156 generate_ephemeral_deployment_network_configuration,
157 generate_ntp_configuration,
158 generate_rack_controller_configuration,
159+ generate_snap_configuration,
160 generate_system_info,
161 get_vendor_data,
162 )
163@@ -116,6 +117,30 @@ class TestGenerateSystemInfo(MAASServerTestCase):
164 )
165
166
167+class TestGenerateSnapConfiguration(MAASServerTestCase):
168+ def test_no_proxy(self):
169+ node = factory.make_Node()
170+ config = generate_snap_configuration(node, None)
171+ self.assertEqual(list(config), [])
172+
173+ def test_proxy(self):
174+ node = factory.make_Node()
175+ config = generate_snap_configuration(node, "http://proxy.example.com/")
176+ self.assertEqual(
177+ list(config),
178+ [
179+ (
180+ "snap",
181+ {
182+ "commands": [
183+ 'snap set system proxy.http="http://proxy.example.com/" proxy.https="http://proxy.example.com/"'
184+ ],
185+ },
186+ ),
187+ ],
188+ )
189+
190+
191 class TestGenerateNTPConfiguration(MAASServerTestCase):
192 """Tests for `generate_ntp_configuration`."""
193
194@@ -203,84 +228,84 @@ class TestGenerateRackControllerConfiguration(MAASServerTestCase):
195
196 def test_yields_nothing_when_node_is_not_netboot_disabled(self):
197 configuration = generate_rack_controller_configuration(
198- node=factory.make_Node(osystem="ubuntu"),
199- proxy="http://proxy.example.com/",
200+ node=factory.make_Node(osystem="ubuntu")
201 )
202- self.assertThat(dict(configuration), Equals({}))
203+ self.assertEqual(list(configuration), [])
204
205 def test_yields_nothing_when_node_is_not_ubuntu(self):
206 tag = factory.make_Tag(name="switch")
207 node = factory.make_Node(osystem="centos", netboot=False)
208 node.tags.add(tag)
209- configuration = generate_rack_controller_configuration(
210- node, proxy="http://proxy.example.com/"
211- )
212- self.assertThat(dict(configuration), Equals({}))
213+ configuration = generate_rack_controller_configuration(node)
214+ self.assertEqual(list(configuration), [])
215
216 def test_yields_configuration_with_ubuntu(self):
217 tag = factory.make_Tag(name="wedge100")
218 node = factory.make_Node(osystem="ubuntu", netboot=False)
219 node.tags.add(tag)
220- configuration = generate_rack_controller_configuration(
221- node, proxy="http://proxy.example.com/"
222- )
223+ configuration = generate_rack_controller_configuration(node)
224 secret = "1234"
225 Config.objects.set_config("rpc_shared_secret", secret)
226 channel = version.get_maas_version_track_channel()
227 maas_url = "http://%s:5240/MAAS" % get_maas_facing_server_host(
228 node.get_boot_rack_controller()
229 )
230- cmd = "/bin/snap/maas init --mode rack"
231-
232- self.assertThat(
233- dict(configuration),
234- KeysEqual(
235- {
236- "runcmd": [
237- f"snap install maas --channel={channel}",
238- "%s --maas-url %s --secret %s"
239- % (cmd, maas_url, secret),
240- ]
241- }
242- ),
243+ self.assertEqual(
244+ list(configuration),
245+ [
246+ (
247+ "runcmd",
248+ [
249+ ["snap", "install", "maas", f"--channel={channel}"],
250+ [
251+ "/snap/bin/maas",
252+ "init",
253+ "rack",
254+ "--maas-url",
255+ maas_url,
256+ "--secret",
257+ secret,
258+ ],
259+ ],
260+ ),
261+ ],
262 )
263
264 def test_yields_nothing_when_machine_install_rackd_false(self):
265 node = factory.make_Node(osystem="ubuntu", netboot=False)
266 node.install_rackd = False
267- configuration = generate_rack_controller_configuration(
268- node, proxy="http://proxy.example.com/"
269- )
270- self.assertThat(dict(configuration), Equals({}))
271+ configuration = generate_rack_controller_configuration(node)
272+ self.assertEqual(list(configuration), [])
273
274 def test_yields_configuration_when_machine_install_rackd_true(self):
275 node = factory.make_Node(osystem="ubuntu", netboot=False)
276 node.install_rackd = True
277- proxy = "http://proxy.example.com/"
278- configuration = generate_rack_controller_configuration(
279- node, proxy=proxy
280- )
281+ configuration = generate_rack_controller_configuration(node)
282 secret = "1234"
283 Config.objects.set_config("rpc_shared_secret", secret)
284 channel = version.get_maas_version_track_channel()
285 maas_url = "http://%s:5240/MAAS" % get_maas_facing_server_host(
286 node.get_boot_rack_controller()
287 )
288- cmd = "/bin/snap/maas init --mode rack"
289-
290- self.assertThat(
291- dict(configuration),
292- KeysEqual(
293- {
294- "runcmd": [
295- "snap set system proxy.http=%s proxy.https=%s"
296- % (proxy, proxy),
297- f"snap install maas --channel={channel}",
298- "%s --maas-url %s --secret %s"
299- % (cmd, maas_url, secret),
300- ]
301- }
302- ),
303+ self.assertEqual(
304+ list(configuration),
305+ [
306+ (
307+ "runcmd",
308+ [
309+ ["snap", "install", "maas", f"--channel={channel}"],
310+ [
311+ "/snap/bin/maas",
312+ "init",
313+ "rack",
314+ "--maas-url",
315+ maas_url,
316+ "--secret",
317+ secret,
318+ ],
319+ ],
320+ ),
321+ ],
322 )
323
324 def test_yields_configuration_when_machine_install_kvm_true(self):
325@@ -415,7 +440,7 @@ class TestGenerateVcenterConfiguration(MAASServerTestCase):
326 )
327 config = get_vendor_data(node, None)
328 self.assertThat(mock_get_configs, MockNotCalled())
329- self.assertDictEqual({}, config)
330+ self.assertNotIn(config, "write_files")
331
332 def test_returns_nothing_if_no_values_set(self):
333 node = factory.make_Node(
334@@ -425,7 +450,7 @@ class TestGenerateVcenterConfiguration(MAASServerTestCase):
335 )
336 node.nodemetadata_set.create(key="vcenter_registration", value="True")
337 config = get_vendor_data(node, None)
338- self.assertDictEqual({}, config)
339+ self.assertNotIn(config, "write_files")
340
341 def test_returns_vcenter_yaml(self):
342 node = factory.make_Node(
343@@ -435,24 +460,22 @@ class TestGenerateVcenterConfiguration(MAASServerTestCase):
344 )
345 node.nodemetadata_set.create(key="vcenter_registration", value="True")
346 vcenter = {
347+ "vcenter_datacenter": factory.make_name("vcenter_datacenter"),
348 "vcenter_server": factory.make_name("vcenter_server"),
349- "vcenter_username": factory.make_name("vcenter_username"),
350 "vcenter_password": factory.make_name("vcenter_password"),
351- "vcenter_datacenter": factory.make_name("vcenter_datacenter"),
352+ "vcenter_username": factory.make_name("vcenter_username"),
353 }
354 for key, value in vcenter.items():
355 Config.objects.set_config(key, value)
356 config = get_vendor_data(node, None)
357- self.assertDictEqual(
358- {
359- "write_files": [
360- {
361- "content": yaml.safe_dump(vcenter),
362- "path": "/altbootbank/maas/vcenter.yaml",
363- }
364- ]
365- },
366- config,
367+ self.assertEqual(
368+ config["write_files"],
369+ [
370+ {
371+ "content": yaml.safe_dump(vcenter),
372+ "path": "/altbootbank/maas/vcenter.yaml",
373+ },
374+ ],
375 )
376
377 def test_returns_vcenter_yaml_if_rbac_admin(self):
378@@ -466,24 +489,22 @@ class TestGenerateVcenterConfiguration(MAASServerTestCase):
379 rbac.store.add_pool(node.pool)
380 rbac.store.allow(node.owner.username, node.pool, "admin-machines")
381 vcenter = {
382+ "vcenter_datacenter": factory.make_name("vcenter_datacenter"),
383 "vcenter_server": factory.make_name("vcenter_server"),
384- "vcenter_username": factory.make_name("vcenter_username"),
385 "vcenter_password": factory.make_name("vcenter_password"),
386- "vcenter_datacenter": factory.make_name("vcenter_datacenter"),
387+ "vcenter_username": factory.make_name("vcenter_username"),
388 }
389 for key, value in vcenter.items():
390 Config.objects.set_config(key, value)
391 config = get_vendor_data(node, None)
392- self.assertDictEqual(
393- {
394- "write_files": [
395- {
396- "content": yaml.safe_dump(vcenter),
397- "path": "/altbootbank/maas/vcenter.yaml",
398- }
399- ]
400- },
401- config,
402+ self.assertEqual(
403+ config["write_files"],
404+ [
405+ {
406+ "content": yaml.safe_dump(vcenter),
407+ "path": "/altbootbank/maas/vcenter.yaml",
408+ },
409+ ],
410 )
411
412 def test_returns_nothing_if_rbac_user(self):
413@@ -497,23 +518,23 @@ class TestGenerateVcenterConfiguration(MAASServerTestCase):
414 rbac.store.add_pool(node.pool)
415 rbac.store.allow(node.owner.username, node.pool, "deploy-machines")
416 vcenter = {
417+ "vcenter_datacenter": factory.make_name("vcenter_datacenter"),
418+ "vcenter_password": factory.make_name("vcenter_password"),
419 "vcenter_server": factory.make_name("vcenter_server"),
420 "vcenter_username": factory.make_name("vcenter_username"),
421- "vcenter_password": factory.make_name("vcenter_password"),
422- "vcenter_datacenter": factory.make_name("vcenter_datacenter"),
423 }
424 for key, value in vcenter.items():
425 Config.objects.set_config(key, value)
426 config = get_vendor_data(node, None)
427- self.assertDictEqual({}, config)
428+ self.assertNotIn(config, "write_files")
429
430 def test_returns_nothing_if_no_user(self):
431 node = factory.make_Node(status=NODE_STATUS.DEPLOYING, osystem="esxi")
432- for i in ["server", "username", "password", "datacenter"]:
433+ for i in ["datacenter", "password", "server", "username"]:
434 key = "vcenter_%s" % i
435 Config.objects.set_config(key, factory.make_name(key))
436 config = get_vendor_data(node, None)
437- self.assertDictEqual({}, config)
438+ self.assertNotIn(config, "write_files")
439
440 def test_returns_nothing_if_user(self):
441 node = factory.make_Node(
442@@ -525,7 +546,7 @@ class TestGenerateVcenterConfiguration(MAASServerTestCase):
443 key = "vcenter_%s" % i
444 Config.objects.set_config(key, factory.make_name(key))
445 config = get_vendor_data(node, None)
446- self.assertDictEqual({}, config)
447+ self.assertNotIn(config, "write_files")
448
449 def test_returns_nothing_if_vcenter_registration_not_set(self):
450 node = factory.make_Node(
451@@ -537,4 +558,4 @@ class TestGenerateVcenterConfiguration(MAASServerTestCase):
452 key = "vcenter_%s" % i
453 Config.objects.set_config(key, factory.make_name(key))
454 config = get_vendor_data(node, None)
455- self.assertDictEqual({}, config)
456+ self.assertNotIn(config, "write_files")
457diff --git a/src/metadataserver/vendor_data.py b/src/metadataserver/vendor_data.py
458index 4da5c8c..b914df5 100644
459--- a/src/metadataserver/vendor_data.py
460+++ b/src/metadataserver/vendor_data.py
461@@ -28,8 +28,9 @@ def get_vendor_data(node, proxy):
462 return dict(
463 chain(
464 generate_system_info(node),
465+ generate_snap_configuration(node, proxy),
466 generate_ntp_configuration(node),
467- generate_rack_controller_configuration(node, proxy),
468+ generate_rack_controller_configuration(node),
469 generate_kvm_pod_configuration(node),
470 generate_ephemeral_netplan_lock_removal(node),
471 generate_ephemeral_deployment_network_configuration(node),
472@@ -49,6 +50,17 @@ def generate_system_info(node):
473 }
474
475
476+def generate_snap_configuration(node, proxy):
477+ """Generate cloud-init configuration for snapd."""
478+ if not proxy:
479+ return
480+ yield "snap", {
481+ "commands": [
482+ f'snap set system proxy.http="{proxy}" proxy.https="{proxy}"',
483+ ],
484+ }
485+
486+
487 def generate_ntp_configuration(node):
488 """Generate cloud-init configuration for NTP servers.
489
490@@ -76,7 +88,7 @@ def generate_ntp_configuration(node):
491 yield "ntp", {"servers": servers, "pools": pools}
492
493
494-def generate_rack_controller_configuration(node, proxy):
495+def generate_rack_controller_configuration(node):
496 """Generate cloud-init configuration to install the rack controller."""
497
498 # FIXME: For now, we are using a tag ('switch') to deploy the rack
499@@ -103,20 +115,10 @@ def generate_rack_controller_configuration(node, proxy):
500 secret = Config.objects.get_config("rpc_shared_secret")
501 source = get_maas_version_track_channel()
502 yield "runcmd", [
503- [
504- "snap",
505- "set",
506- "system",
507- f"proxy.http={proxy}",
508- f"proxy.https={proxy}",
509- ],
510 ["snap", "install", "maas", f"--channel={source}"],
511- ["systemctl", "restart", "snapd"],
512- ["export", "PATH=$PATH"],
513 [
514 "/snap/bin/maas",
515 "init",
516- "--mode",
517 "rack",
518 "--maas-url",
519 maas_url,

Subscribers

People subscribed via source and target branches