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
=== modified file 'src/maasserver/networking_preseed.py'
--- src/maasserver/networking_preseed.py 2014-09-25 19:38:57 +0000
+++ src/maasserver/networking_preseed.py 2014-09-26 04:10:25 +0000
@@ -29,6 +29,7 @@
29 ]29 ]
3030
31from collections import defaultdict31from collections import defaultdict
32from textwrap import dedent
3233
33from lxml import etree34from lxml import etree
34from maasserver.dns.zonegenerator import get_dns_server_address35from maasserver.dns.zonegenerator import get_dns_server_address
@@ -369,3 +370,64 @@
369 compose_debian_network_interfaces_ipv6_stanza(370 compose_debian_network_interfaces_ipv6_stanza(
370 interface, static_ipv6, gateway))371 interface, static_ipv6, gateway))
371 return '%s\n' % '\n\n'.join(stanzas)372 return '%s\n' % '\n\n'.join(stanzas)
373
374
375def compose_udev_equality(key, value):
376 """Return a udev comparison clause, like `ACTION=="add"`."""
377 assert key == key.upper()
378 return '%s=="%s"' % (key, value)
379
380
381def compose_udev_attr_equality(attribute, value):
382 """Return a udev attribute comparison clause, like `ATTR{type}=="1"`."""
383 assert attribute == attribute.lower()
384 return 'ATTR{%s}=="%s"' % (attribute, value)
385
386
387def compose_udev_setting(key, value):
388 """Return a udev assignment clause, like `NAME="eth0"`."""
389 assert key == key.upper()
390 return '%s="%s"' % (key, value)
391
392
393def compose_udev_rule(interface, mac):
394 """Return a udev rule to set the name of network interface with `mac`.
395
396 The rule ends up as a single line looking something like:
397
398 SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*",
399 ATTR{address}="ff:ee:dd:cc:bb:aa", NAME="eth0"
400
401 (Note the difference between `=` and `==`: they both occur.)
402 """
403 rule = ', '.join([
404 compose_udev_equality('SUBSYSTEM', 'net'),
405 compose_udev_equality('ACTION', 'add'),
406 compose_udev_equality('DRIVERS', '?*'),
407 compose_udev_attr_equality('address', mac),
408 compose_udev_setting('NAME', interface),
409 ])
410 return '%s\n' % rule
411
412
413def compose_linux_udev_rules_file(interfaces):
414 """Return text for a udev persistent-net rules file.
415
416 These rules assign fixed names to network interfaces. They ensure that
417 the same network interface cards come up with the same interface names on
418 every boot. Otherwise, the kernel may assign interface names in different
419 orders on every boot, and so network interfaces can "switch identities"
420 every other time the machine reboots.
421
422 :param interfaces: List of tuples of interface name and MAC address.
423 :return: Text to write into a udev rules file.
424 """
425 rules = [
426 compose_udev_rule(interface, mac)
427 for interface, mac in interfaces
428 ]
429 return dedent("""\
430 # MAAS-assigned network interface names.
431 %s
432 # End of MAAS-assigned network interface names.
433 """) % '\n\n'.join(rules)
372434
=== modified file 'src/maasserver/tests/test_networking_preseed.py'
--- src/maasserver/tests/test_networking_preseed.py 2014-09-25 19:38:57 +0000
+++ src/maasserver/tests/test_networking_preseed.py 2014-09-26 04:10:25 +0000
@@ -31,6 +31,7 @@
31 compose_debian_network_interfaces_file,31 compose_debian_network_interfaces_file,
32 compose_debian_network_interfaces_ipv4_stanza,32 compose_debian_network_interfaces_ipv4_stanza,
33 compose_debian_network_interfaces_ipv6_stanza,33 compose_debian_network_interfaces_ipv6_stanza,
34 compose_linux_udev_rules_file,
34 extract_mac_string,35 extract_mac_string,
35 extract_network_interfaces,36 extract_network_interfaces,
36 generate_dns_server_entry,37 generate_dns_server_entry,
@@ -916,3 +917,17 @@
916 interfaces_file = compose_debian_network_interfaces_file(node)917 interfaces_file = compose_debian_network_interfaces_file(node)
917 self.assertIn('auto %s' % interface, interfaces_file)918 self.assertIn('auto %s' % interface, interfaces_file)
918 self.assertEqual(1, interfaces_file.count('auto %s' % interface))919 self.assertEqual(1, interfaces_file.count('auto %s' % interface))
920
921
922class TestComposeLinuxUdevRulesFile(MAASServerTestCase):
923
924 def test__generates_udev_rule(self):
925 interface = factory.make_name('eth')
926 mac = factory.make_mac_address()
927 expected_rule = (
928 '\nSUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
929 'ATTR{address}=="%(mac)s", NAME="%(interface)s"\n'
930 ) % {'mac': mac, 'interface': interface}
931 self.assertIn(
932 expected_rule,
933 compose_linux_udev_rules_file([(interface, mac)]))