Merge lp:~jtv/maas/net-udev-rules into lp:~maas-committers/maas/trunk

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 3097
Proposed branch: lp:~jtv/maas/net-udev-rules
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 106 lines (+77/-0)
2 files modified
src/maasserver/networking_preseed.py (+62/-0)
src/maasserver/tests/test_networking_preseed.py (+15/-0)
To merge this branch: bzr merge lp:~jtv/maas/net-udev-rules
Reviewer Review Type Date Requested Status
Raphaël Badin (community) Approve
Review via email: mp+236054@code.launchpad.net

Commit message

Generate udev rules file, server-side, for installation on a node.

Part of the work to generate a node's full networking configuration on the server, so Curtin can install it, with IPv6 optionally enabled and IPv4 optionally disabled.

Description of the change

This was largely just copied over from the node-side script that we currently install and run on a node to set up its networking. That script will go away once this new approach works.

Jeroen

To post a comment you must log in.
Revision history for this message
Raphaël Badin (rvb) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/networking_preseed.py'
2--- src/maasserver/networking_preseed.py 2014-09-25 19:38:57 +0000
3+++ src/maasserver/networking_preseed.py 2014-09-26 04:10:25 +0000
4@@ -29,6 +29,7 @@
5 ]
6
7 from collections import defaultdict
8+from textwrap import dedent
9
10 from lxml import etree
11 from maasserver.dns.zonegenerator import get_dns_server_address
12@@ -369,3 +370,64 @@
13 compose_debian_network_interfaces_ipv6_stanza(
14 interface, static_ipv6, gateway))
15 return '%s\n' % '\n\n'.join(stanzas)
16+
17+
18+def compose_udev_equality(key, value):
19+ """Return a udev comparison clause, like `ACTION=="add"`."""
20+ assert key == key.upper()
21+ return '%s=="%s"' % (key, value)
22+
23+
24+def compose_udev_attr_equality(attribute, value):
25+ """Return a udev attribute comparison clause, like `ATTR{type}=="1"`."""
26+ assert attribute == attribute.lower()
27+ return 'ATTR{%s}=="%s"' % (attribute, value)
28+
29+
30+def compose_udev_setting(key, value):
31+ """Return a udev assignment clause, like `NAME="eth0"`."""
32+ assert key == key.upper()
33+ return '%s="%s"' % (key, value)
34+
35+
36+def compose_udev_rule(interface, mac):
37+ """Return a udev rule to set the name of network interface with `mac`.
38+
39+ The rule ends up as a single line looking something like:
40+
41+ SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*",
42+ ATTR{address}="ff:ee:dd:cc:bb:aa", NAME="eth0"
43+
44+ (Note the difference between `=` and `==`: they both occur.)
45+ """
46+ rule = ', '.join([
47+ compose_udev_equality('SUBSYSTEM', 'net'),
48+ compose_udev_equality('ACTION', 'add'),
49+ compose_udev_equality('DRIVERS', '?*'),
50+ compose_udev_attr_equality('address', mac),
51+ compose_udev_setting('NAME', interface),
52+ ])
53+ return '%s\n' % rule
54+
55+
56+def compose_linux_udev_rules_file(interfaces):
57+ """Return text for a udev persistent-net rules file.
58+
59+ These rules assign fixed names to network interfaces. They ensure that
60+ the same network interface cards come up with the same interface names on
61+ every boot. Otherwise, the kernel may assign interface names in different
62+ orders on every boot, and so network interfaces can "switch identities"
63+ every other time the machine reboots.
64+
65+ :param interfaces: List of tuples of interface name and MAC address.
66+ :return: Text to write into a udev rules file.
67+ """
68+ rules = [
69+ compose_udev_rule(interface, mac)
70+ for interface, mac in interfaces
71+ ]
72+ return dedent("""\
73+ # MAAS-assigned network interface names.
74+ %s
75+ # End of MAAS-assigned network interface names.
76+ """) % '\n\n'.join(rules)
77
78=== modified file 'src/maasserver/tests/test_networking_preseed.py'
79--- src/maasserver/tests/test_networking_preseed.py 2014-09-25 19:38:57 +0000
80+++ src/maasserver/tests/test_networking_preseed.py 2014-09-26 04:10:25 +0000
81@@ -31,6 +31,7 @@
82 compose_debian_network_interfaces_file,
83 compose_debian_network_interfaces_ipv4_stanza,
84 compose_debian_network_interfaces_ipv6_stanza,
85+ compose_linux_udev_rules_file,
86 extract_mac_string,
87 extract_network_interfaces,
88 generate_dns_server_entry,
89@@ -916,3 +917,17 @@
90 interfaces_file = compose_debian_network_interfaces_file(node)
91 self.assertIn('auto %s' % interface, interfaces_file)
92 self.assertEqual(1, interfaces_file.count('auto %s' % interface))
93+
94+
95+class TestComposeLinuxUdevRulesFile(MAASServerTestCase):
96+
97+ def test__generates_udev_rule(self):
98+ interface = factory.make_name('eth')
99+ mac = factory.make_mac_address()
100+ expected_rule = (
101+ '\nSUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
102+ 'ATTR{address}=="%(mac)s", NAME="%(interface)s"\n'
103+ ) % {'mac': mac, 'interface': interface}
104+ self.assertIn(
105+ expected_rule,
106+ compose_linux_udev_rules_file([(interface, mac)]))