Merge lp:~mpontillo/maas/fix-curtin-custom-driver-preseed--bug-1667426 into lp:~maas-committers/maas/trunk

Proposed by Mike Pontillo
Status: Merged
Approved by: Mike Pontillo
Approved revision: no longer in the source branch.
Merged at revision: 5756
Proposed branch: lp:~mpontillo/maas/fix-curtin-custom-driver-preseed--bug-1667426
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 108 lines (+65/-2)
2 files modified
contrib/preseeds_v2/curtin_userdata (+16/-2)
src/maasserver/tests/test_preseed.py (+49/-0)
To merge this branch: bzr merge lp:~mpontillo/maas/fix-curtin-custom-driver-preseed--bug-1667426
Reviewer Review Type Date Requested Status
Lee Trager (community) Approve
Review via email: mp+318168@code.launchpad.net

Commit message

Fix curtin config rendering for third-party drivers.

Description of the change

It seems that third-party driver functionality in MAAS has gone unused since the move to MAAS 2.x. We have a bug leftover from the Python 2 -> Python 3 conversion which caused the (binary format) APT keys in drivers.yaml to fail to be rendered.

This branch also makes the YAML template more robust in the following ways:

 - Gracefully handle missing keys by leaving commands out of the YAML rather than raising a difficult-to-debug exception during deployment.

 - Nodes will no longer fail to deploy if the kernel module specified in drivers.yaml fails to be inserted. If the deployment succeeds anyway, this is something that will either be automatically corrected post-deployment (because a DKMS package was installed), OR would likely be a known issue with the driver that can be corrected by the user post-deployment. So this has been changed from a failure condition to a warning. (As a side effect, this allows custom drivers which do not require a kernel module to be used, but this branch does not add tests for that.)

 - If keys are missing from drivers.yaml, preseed generation should no longer crash and time out deployment with no visible error. The deployment will simply proceed without the missing keys. (As a side effect, this should allow the third-party driver feature to install custom packages that do not necessarily need a custom repository to work, but this branch does not add tests for that.)

To post a comment you must log in.
Revision history for this message
Lee Trager (ltrager) wrote :

LGTM!

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

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

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

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Hm. Launchpad bug? Diff seems stale. Trying the Needs Review -> Work in Progress -> Needs Review transition again...

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Oh. Just now noticed this; it WAS a Launchpad bug.

Fault 380: 'An unexpected error has occurred while updating a Launchpad branch. Please report a Launchpad bug and quote: OOPS-05b5986d0373f49ba74c975b35393199.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'contrib/preseeds_v2/curtin_userdata'
2--- contrib/preseeds_v2/curtin_userdata 2016-12-07 09:25:19 +0000
3+++ contrib/preseeds_v2/curtin_userdata 2017-02-24 03:57:27 +0000
4@@ -6,21 +6,35 @@
5 {{endfor}}
6 {{if third_party_drivers and driver}}
7 early_commands:
8- {{py: key_string = ''.join(['\\x%x' % x for x in map(ord, driver['key_binary'])])}}
9+ {{py: key_string = ''.join(['\\x%x' % x for x in driver['key_binary']])}}
10+ {{if driver['key_binary'] and driver['repository'] and driver['package']}}
11 driver_00_get_key: /bin/echo -en '{{key_string}}' > /tmp/maas-{{driver['package']}}.gpg
12 driver_01_add_key: ["apt-key", "add", "/tmp/maas-{{driver['package']}}.gpg"]
13+ {{endif}}
14+ {{if driver['repository']}}
15 driver_02_add: ["add-apt-repository", "-y", "deb {{driver['repository']}} {{node.get_distro_series()}} main"]
16+ {{endif}}
17+ {{if driver['package']}}
18 driver_03_update_install: ["sh", "-c", "apt-get update --quiet && apt-get --assume-yes install {{driver['package']}}"]
19- driver_04_load: ["sh", "-c", "depmod && modprobe {{driver['module']}}"]
20+ {{endif}}
21+ {{if driver['module']}}
22+ driver_04_load: ["sh", "-c", "depmod && modprobe {{driver['module']}} || echo 'Warning: Failed to load module: {{driver['module']}}'"]
23+ {{endif}}
24 {{endif}}
25 late_commands:
26 maas: [wget, '--no-proxy', {{node_disable_pxe_url|escape.json}}, '--post-data', {{node_disable_pxe_data|escape.json}}, '-O', '/dev/null']
27 {{if third_party_drivers and driver}}
28+ {{if driver['key_binary'] and driver['repository'] and driver['package']}}
29 driver_00_key_get: curtin in-target -- sh -c "/bin/echo -en '{{key_string}}' > /tmp/maas-{{driver['package']}}.gpg"
30 driver_02_key_add: ["curtin", "in-target", "--", "apt-key", "add", "/tmp/maas-{{driver['package']}}.gpg"]
31+ {{endif}}
32+ {{if driver['repository']}}
33 driver_03_add: ["curtin", "in-target", "--", "add-apt-repository", "-y", "deb {{driver['repository']}} {{node.get_distro_series()}} main"]
34+ {{endif}}
35 driver_04_update_install: ["curtin", "in-target", "--", "apt-get", "update", "--quiet"]
36+ {{if driver['package']}}
37 driver_05_install: ["curtin", "in-target", "--", "apt-get", "-y", "install", "{{driver['package']}}"]
38+ {{endif}}
39 driver_06_depmod: ["curtin", "in-target", "--", "depmod"]
40 driver_07_update_initramfs: ["curtin", "in-target", "--", "update-initramfs", "-u"]
41 {{endif}}
42
43=== modified file 'src/maasserver/tests/test_preseed.py'
44--- src/maasserver/tests/test_preseed.py 2017-01-28 00:51:47 +0000
45+++ src/maasserver/tests/test_preseed.py 2017-02-24 03:57:27 +0000
46@@ -77,6 +77,7 @@
47 MAASServerTestCase,
48 MAASTransactionServerTestCase,
49 )
50+from maasserver.third_party_drivers import DriversConfig
51 from maasserver.utils import absolute_reverse
52 from maasserver.utils.curtin import curtin_supports_webhook_events
53 from maastesting.matchers import (
54@@ -850,6 +851,54 @@
55 self.assertThat(mock_supports_storage, MockCalledOnceWith())
56
57
58+class TestRenderCurtinUserdataWithThirdPartyDrivers(
59+ PreseedRPCMixin, BootImageHelperMixin, MAASServerTestCase):
60+ """Ensures curtin configs for all third-party drivers can be rendered."""
61+
62+ # Try rendering each driver in drivers.yaml.
63+ scenarios = [
64+ (driver['comment'], {'driver': driver})
65+ for driver in DriversConfig.load_from_cache()['drivers']
66+ ]
67+
68+ def test_render_curtin_preseed_with_third_party_driver(self):
69+ node = factory.make_Node_with_Interface_on_Subnet(
70+ primary_rack=self.rpc_rack_controller)
71+ Config.objects.set_config(
72+ 'enable_third_party_drivers', True)
73+ self.configure_get_boot_images_for_node(node, 'xinstall')
74+ get_third_party_driver = self.patch(
75+ preseed_module, "get_third_party_driver")
76+ get_third_party_driver.return_value = self.driver
77+ curtin_config_text = get_curtin_config(node)
78+ config = yaml.safe_load(curtin_config_text)
79+ self.assertThat(
80+ config['early_commands'], Contains('driver_00_get_key'))
81+ self.assertThat(
82+ config['early_commands'], Contains('driver_01_add_key'))
83+ self.assertThat(
84+ config['early_commands'], Contains('driver_02_add'))
85+ self.assertThat(
86+ config['early_commands'], Contains('driver_03_update_install'))
87+ self.assertThat(
88+ config['early_commands'], Contains('driver_04_load'))
89+ self.assertThat(
90+ config['late_commands'], Contains('driver_00_key_get'))
91+ self.assertThat(
92+ config['late_commands'], Contains('driver_02_key_add'))
93+ self.assertThat(
94+ config['late_commands'], Contains('driver_03_add'))
95+ self.assertThat(
96+ config['late_commands'], Contains('driver_04_update_install'))
97+ self.assertThat(
98+ config['late_commands'], Contains('driver_05_install'))
99+ self.assertThat(
100+ config['late_commands'], Contains('driver_06_depmod'))
101+ self.assertThat(
102+ config['late_commands'],
103+ Contains('driver_07_update_initramfs'))
104+
105+
106 class TestGetCurtinUserDataOS(
107 PreseedRPCMixin, BootImageHelperMixin, MAASServerTestCase):
108 """Tests for `get_curtin_userdata` using os specific scenarios."""