Merge ~xnox/cloud-init:master into cloud-init:master

Proposed by Dimitri John Ledkov on 2017-04-20
Status: Merged
Merged at revision: df4ca453520342a0541ab9202305858bf39d4f48
Proposed branch: ~xnox/cloud-init:master
Merge into: cloud-init:master
Diff against target: 91 lines (+34/-3)
2 files modified
cloudinit/net/__init__.py (+7/-0)
tests/unittests/test_net.py (+27/-3)
Reviewer Review Type Date Requested Status
Scott Moser 2017-04-20 Approve on 2017-04-21
Server Team CI bot continuous-integration Approve on 2017-04-20
Ryan Harper 2017-04-20 Pending
Review via email: mp+322828@code.launchpad.net

Commit message

net: kernel lies about vlans not stealing mac addresses, when they do

Introduce is_vlan function and call that when building dictionary of
interfaces by mac address.

LP: #1682871

To post a comment you must log in.

FAILED: Continuous integration, rev:9cff0a5689846ebb92219efbed3f7f8d7748dd06
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~xnox/cloud-init/+git/cloud-init/+merge/322828/+edit-commit-message

https://jenkins.ubuntu.com/server/job/cloud-init-ci/257/
Executed test runs:
    SUCCESS: https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-amd64/257
    SUCCESS: https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-arm64/257
    SUCCESS: https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-ppc64el/257
    SUCCESS: https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-s390x/257
    SUCCESS: https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=vm-i386/257

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/257/rebuild

review: Needs Fixing (continuous-integration)
Dimitri John Ledkov (xnox) wrote :

I did pass all the tests, and have set the commit message now.
I am unable to retrigger jenkins =(

Scott Moser (smoser) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
2index 346be5d..a072a8d 100644
3--- a/cloudinit/net/__init__.py
4+++ b/cloudinit/net/__init__.py
5@@ -86,6 +86,11 @@ def is_bridge(devname):
6 return os.path.exists(sys_dev_path(devname, "bridge"))
7
8
9+def is_vlan(devname):
10+ uevent = str(read_sys_net_safe(devname, "uevent"))
11+ return 'DEVTYPE=vlan' in uevent.splitlines()
12+
13+
14 def is_connected(devname):
15 # is_connected isn't really as simple as that. 2 is
16 # 'physically connected'. 3 is 'not connected'. but a wlan interface will
17@@ -393,6 +398,8 @@ def get_interfaces_by_mac():
18 continue
19 if is_bridge(name):
20 continue
21+ if is_vlan(name):
22+ continue
23 mac = get_interface_mac(name)
24 # some devices may not have a mac (tun0)
25 if not mac:
26diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
27index 9cc5e4a..89e7536 100644
28--- a/tests/unittests/test_net.py
29+++ b/tests/unittests/test_net.py
30@@ -1463,13 +1463,16 @@ class TestNetRenderers(CiTestCase):
31
32 class TestGetInterfacesByMac(CiTestCase):
33 _data = {'devices': ['enp0s1', 'enp0s2', 'bond1', 'bridge1',
34- 'bridge1-nic', 'tun0'],
35+ 'bridge1-nic', 'tun0', 'bond1.101'],
36 'bonds': ['bond1'],
37 'bridges': ['bridge1'],
38- 'own_macs': ['enp0s1', 'enp0s2', 'bridge1-nic', 'bridge1'],
39+ 'vlans': ['bond1.101'],
40+ 'own_macs': ['enp0s1', 'enp0s2', 'bridge1-nic', 'bridge1',
41+ 'bond1.101'],
42 'macs': {'enp0s1': 'aa:aa:aa:aa:aa:01',
43 'enp0s2': 'aa:aa:aa:aa:aa:02',
44 'bond1': 'aa:aa:aa:aa:aa:01',
45+ 'bond1.101': 'aa:aa:aa:aa:aa:01',
46 'bridge1': 'aa:aa:aa:aa:aa:03',
47 'bridge1-nic': 'aa:aa:aa:aa:aa:03',
48 'tun0': None}}
49@@ -1484,13 +1487,16 @@ class TestGetInterfacesByMac(CiTestCase):
50 def _se_is_bridge(self, name):
51 return name in self.data['bridges']
52
53+ def _se_is_vlan(self, name):
54+ return name in self.data['vlans']
55+
56 def _se_interface_has_own_mac(self, name):
57 return name in self.data['own_macs']
58
59 def _mock_setup(self):
60 self.data = copy.deepcopy(self._data)
61 mocks = ('get_devicelist', 'get_interface_mac', 'is_bridge',
62- 'interface_has_own_mac')
63+ 'interface_has_own_mac', 'is_vlan')
64 self.mocks = {}
65 for n in mocks:
66 m = mock.patch('cloudinit.net.' + n,
67@@ -1536,6 +1542,24 @@ class TestGetInterfacesByMac(CiTestCase):
68 mock.call('b1')],
69 any_order=True)
70
71+ def test_excludes_vlans(self):
72+ self._mock_setup()
73+ # add a device 'b1', make all return they have their "own mac",
74+ # set everything other than 'b1' to be a vlan.
75+ # then expect b1 is the only thing left.
76+ self.data['macs']['b1'] = 'aa:aa:aa:aa:aa:b1'
77+ self.data['devices'].append('b1')
78+ self.data['bonds'] = []
79+ self.data['bridges'] = []
80+ self.data['own_macs'] = self.data['devices']
81+ self.data['vlans'] = [f for f in self.data['devices'] if f != "b1"]
82+ ret = net.get_interfaces_by_mac()
83+ self.assertEqual({'aa:aa:aa:aa:aa:b1': 'b1'}, ret)
84+ self.mocks['is_vlan'].assert_has_calls(
85+ [mock.call('bridge1'), mock.call('enp0s1'), mock.call('bond1'),
86+ mock.call('b1')],
87+ any_order=True)
88+
89
90 def _gzip_data(data):
91 with io.BytesIO() as iobuf:

Subscribers

People subscribed via source and target branches