Merge lp:~mpontillo/maas/fix-long-bridge-names--bug-1672327 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: 5999
Proposed branch: lp:~mpontillo/maas/fix-long-bridge-names--bug-1672327
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 116 lines (+48/-7)
2 files modified
src/maasserver/models/interface.py (+19/-3)
src/maasserver/models/tests/test_interface.py (+29/-4)
To merge this branch: bzr merge lp:~mpontillo/maas/fix-long-bridge-names--bug-1672327
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+322797@code.launchpad.net

Commit message

When creating a bridge name, keep the name under 16 characters.

Uses the same algorithm as proposed for Juju in https://github.com/juju/juju/pull/7204.

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Looks good.

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (33.1 KiB)

The attempt to merge lp:~mpontillo/maas/fix-long-bridge-names--bug-1672327 into lp:maas failed. Below is the output from the failed tests.

Get:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
Hit:2 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial InRelease
Get:3 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
Get:4 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-backports InRelease [102 kB]
Fetched 306 kB in 0s (393 kB/s)
Reading package lists...
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
    --no-install-recommends install apache2 archdetect-deb authbind avahi-utils bash bind9 bind9utils build-essential bzr bzr-builddeb chromium-browser chromium-chromedriver curl daemontools debhelper dh-apport dh-systemd distro-info dnsutils firefox freeipmi-tools git gjs ipython isc-dhcp-common isc-dhcp-server libjs-angularjs libjs-jquery libjs-jquery-hotkeys libjs-yui3-full libjs-yui3-min libnss-wrapper libpq-dev make nodejs-legacy npm postgresql psmisc pxelinux python3-all python3-apt python3-attr python3-bson python3-convoy python3-crochet python3-cssselect python3-curtin python3-dev python3-distro-info python3-django python3-django-nose python3-django-piston3 python3-dnspython python3-docutils python3-formencode python3-hivex python3-httplib2 python3-jinja2 python3-jsonschema python3-lxml python3-netaddr python3-netifaces python3-novaclient python3-oauth python3-oauthlib python3-openssl python3-paramiko python3-petname python3-pexpect python3-psycopg2 python3-pyinotify python3-pyparsing python3-pyvmomi python3-requests python3-seamicroclient python3-setuptools python3-simplestreams python3-sphinx python3-tempita python3-twisted python3-txtftp python3-tz python3-yaml python3-zope.interface python-bson python-crochet python-django python-django-piston python-djorm-ext-pgarray python-formencode python-lxml python-netaddr python-netifaces python-pocket-lint python-psycopg2 python-simplejson python-tempita python-twisted python-yaml socat syslinux-common tgt ubuntu-cloudimage-keyring wget xvfb
Reading package lists...
Building dependency tree...
Reading state information...
authbind is already the newest version (2.1.1+nmu1).
avahi-utils is already the newest version (0.6.32~rc+dfsg-1ubuntu2).
build-essential is already the newest version (12.1ubuntu2).
debhelper is already the newest version (9.20160115ubuntu3).
distro-info is already the newest version (0.14build1).
git is already the newest version (1:2.7.4-0ubuntu1).
libjs-angularjs is already the newest version (1.2.28-1ubuntu2).
libjs-jquery is already the newest version (1.11.3+dfsg-4).
libjs-yui3-full is already the newest version (3.5.1-1ubuntu3).
libjs-yui3-min is already the newest version (3.5.1-1ubuntu3).
make is already the newest version (4.1-6).
postgresql is already the newest version (9.5+173).
psmisc is already the newest version (22.21-2.1build1).
pxelinux is already the newest version (3:6.03+dfsg-11ubuntu1).
python-formencode is already the newest version (1.3.0-0ubuntu5).
python-lxml is already the newest version (3.5.0-1build1).
python-netaddr is already the newest version (0.7.18-1...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/maasserver/models/interface.py'
--- src/maasserver/models/interface.py 2017-04-17 14:11:28 +0000
+++ src/maasserver/models/interface.py 2017-04-20 03:18:37 +0000
@@ -13,6 +13,7 @@
13 ]13 ]
1414
15from collections import OrderedDict15from collections import OrderedDict
16from zlib import crc32
1617
17from django.contrib.postgres.fields import ArrayField18from django.contrib.postgres.fields import ArrayField
18from django.core.exceptions import (19from django.core.exceptions import (
@@ -1182,6 +1183,21 @@
1182 auto_ip.save()1183 auto_ip.save()
1183 return subnet, auto_ip1184 return subnet, auto_ip
11841185
1186 def get_default_bridge_name(self):
1187 """Returns the default name for a bridge created on this interface."""
1188 # This is a fix for bug #1672327, consistent with Juju's idea of what
1189 # the bridge name should be.
1190 ifname = self.get_name().encode('utf-8')
1191 name = b"br-%s" % ifname
1192 if len(name) > 15:
1193 name = b"b-%s" % ifname
1194 if ifname[:2] == b'en':
1195 name = b"b-%s" % ifname[2:]
1196 if len(name) > 15:
1197 ifname_hash = (b"%06x" % (crc32(ifname) & 0xffffffff))[-6:]
1198 name = b"b-%s-%s" % (ifname_hash, ifname[len(ifname) - 6:])
1199 return name.decode('utf-8')
1200
1185 def create_acquired_bridge(self, bridge_stp=None, bridge_fd=None):1201 def create_acquired_bridge(self, bridge_stp=None, bridge_fd=None):
1186 """Create an acquired bridge on top of this interface.1202 """Create an acquired bridge on top of this interface.
11871203
@@ -1200,10 +1216,10 @@
1200 }1216 }
1201 if 'mtu' in self.params:1217 if 'mtu' in self.params:
1202 params['mtu'] = self.params['mtu']1218 params['mtu'] = self.params['mtu']
1219 name = self.get_default_bridge_name()
1203 bridge = BridgeInterface(1220 bridge = BridgeInterface(
1204 name="br-%s" % self.get_name(), node=self.node,1221 name=name, node=self.node, mac_address=self.mac_address,
1205 mac_address=self.mac_address, vlan=self.vlan,1222 vlan=self.vlan, enabled=True, acquired=True, params=params)
1206 enabled=True, acquired=True, params=params)
1207 bridge.save()1223 bridge.save()
1208 # The order in which the creating and linkage between child and parent1224 # The order in which the creating and linkage between child and parent
1209 # is important. The IP addresses must first be moved from this1225 # is important. The IP addresses must first be moved from this
12101226
=== modified file 'src/maasserver/models/tests/test_interface.py'
--- src/maasserver/models/tests/test_interface.py 2017-03-29 21:13:51 +0000
+++ src/maasserver/models/tests/test_interface.py 2017-04-20 03:18:37 +0000
@@ -1409,7 +1409,7 @@
1409 parent.save()1409 parent.save()
1410 bridge = parent.create_acquired_bridge()1410 bridge = parent.create_acquired_bridge()
1411 self.assertThat(bridge, MatchesStructure(1411 self.assertThat(bridge, MatchesStructure(
1412 name=Equals("br-%s" % parent.get_name()),1412 name=Equals("%s" % parent.get_default_bridge_name()),
1413 mac_address=Equals(parent.mac_address),1413 mac_address=Equals(parent.mac_address),
1414 node=Equals(parent.node),1414 node=Equals(parent.node),
1415 vlan=Equals(parent.vlan),1415 vlan=Equals(parent.vlan),
@@ -2986,7 +2986,7 @@
2986 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)2986 parent = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
2987 bridge = parent.create_acquired_bridge()2987 bridge = parent.create_acquired_bridge()
2988 self.assertThat(bridge, MatchesStructure(2988 self.assertThat(bridge, MatchesStructure(
2989 name=Equals("br-%s" % parent.get_name()),2989 name=Equals("%s" % parent.get_default_bridge_name()),
2990 mac_address=Equals(parent.mac_address),2990 mac_address=Equals(parent.mac_address),
2991 node=Equals(parent.node),2991 node=Equals(parent.node),
2992 vlan=Equals(parent.vlan),2992 vlan=Equals(parent.vlan),
@@ -3007,7 +3007,7 @@
3007 bridge = parent.create_acquired_bridge(3007 bridge = parent.create_acquired_bridge(
3008 bridge_stp=bridge_stp, bridge_fd=bridge_fd)3008 bridge_stp=bridge_stp, bridge_fd=bridge_fd)
3009 self.assertThat(bridge, MatchesStructure(3009 self.assertThat(bridge, MatchesStructure(
3010 name=Equals("br-%s" % parent.get_name()),3010 name=Equals("%s" % parent.get_default_bridge_name()),
3011 mac_address=Equals(parent.mac_address),3011 mac_address=Equals(parent.mac_address),
3012 node=Equals(parent.node),3012 node=Equals(parent.node),
3013 vlan=Equals(parent.vlan),3013 vlan=Equals(parent.vlan),
@@ -3029,7 +3029,7 @@
3029 alloc_type=IPADDRESS_TYPE.STICKY, interface=parent)3029 alloc_type=IPADDRESS_TYPE.STICKY, interface=parent)
3030 bridge = parent.create_acquired_bridge()3030 bridge = parent.create_acquired_bridge()
3031 self.assertThat(bridge, MatchesStructure(3031 self.assertThat(bridge, MatchesStructure(
3032 name=Equals("br-%s" % parent.get_name()),3032 name=Equals("%s" % parent.get_default_bridge_name()),
3033 mac_address=Equals(parent.mac_address),3033 mac_address=Equals(parent.mac_address),
3034 node=Equals(parent.node),3034 node=Equals(parent.node),
3035 vlan=Equals(parent.vlan),3035 vlan=Equals(parent.vlan),
@@ -3179,3 +3179,28 @@
3179 "Automatically created VLAN (observed by %s)." % (3179 "Automatically created VLAN (observed by %s)." % (
3180 iface.get_log_string()),3180 iface.get_log_string()),
3181 new_vlan.description)3181 new_vlan.description)
3182
3183
3184class TestInterfaceGetDefaultBridgeName(MAASServerTestCase):
3185
3186 # Normally we would use scenarios for this, but this was copied and
3187 # pasted from Juju code in bridgepolicy_test.go.
3188 expected_bridge_names = {
3189 "eno0": "br-eno0",
3190 "twelvechars0": "br-twelvechars0",
3191 "thirteenchars": "b-thirteenchars",
3192 "enfourteenchar": "b-fourteenchar",
3193 "enfifteenchars0": "b-fifteenchars0",
3194 "fourteenchars1": "b-5590a4-chars1",
3195 "fifteenchars.12": "b-7e0acf-ars.12",
3196 "zeros0526193032": "b-000000-193032",
3197 "enx00e07cc81e1d": "b-x00e07cc81e1d",
3198 }
3199
3200 def test__returns_expected_bridge_names_consistent_with_juju(self):
3201 interface = factory.make_Interface()
3202 for ifname, expected_bridge_name in self.expected_bridge_names.items():
3203 interface.name = ifname
3204 self.assertThat(
3205 interface.get_default_bridge_name(),
3206 Equals(expected_bridge_name))