Merge ~enolfc/cloud-init:bug-1716397 into cloud-init:master

Proposed by Enol Fernández
Status: Work in progress
Proposed branch: ~enolfc/cloud-init:bug-1716397
Merge into: cloud-init:master
Diff against target: 198 lines (+101/-11)
2 files modified
cloudinit/sources/DataSourceOpenNebula.py (+24/-7)
tests/unittests/test_datasource/test_opennebula.py (+77/-4)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
cloud-init Commiters Pending
Review via email: mp+330518@code.launchpad.net

Commit message

OpenNebula: support network configuration with persistent named devices.

OpenNebula network configuration is provided in context with device
identifiers in the form ETH[0-9]. That assumes that the host can "know"
the name of the device in the guest, which is unreliable at best and
completely broken when predictable names are used.

The change here now utilizes context variables named ETH<N>_MAC that
provide the mac address for the 'ETH<N>' device.

LP: #1716397

Description of the change

To post a comment you must log in.
Revision history for this message
Enol Fernández (enolfc) wrote :

Tests are broken, will submit new commits soon

Revision history for this message
Scott Moser (smoser) wrote :

Thank you for your contribution to cloud-init. Contributions to
cloud-init require the developer to have signed the Canonical Contributors
Agreement [1]. Your launchpad id is not currently listed as a member of
the contributor-agreement-canonical group [2].

Membership in that group is currently managed by a manual process, so it
is possible that you have followed the process but were not added to the
group. If you have already signed the contributor agreement, please
simply say so here.

For more information on contribution see the hacking documentation in
cloud-init [3].

--
[1] https://www.ubuntu.com/legal/contributors
[2] https://launchpad.net/~contributor-agreement-canonical/+members
[3] http://cloudinit.readthedocs.io/en/latest/topics/hacking.html

Revision history for this message
Scott Moser (smoser) wrote :

is _MAC expected present in all OpenNebula releases ? or is that something only provided in newer releases ? It'd be good to comment about when it was present.

Thanks for raising this and helping out.

Revision history for this message
Enol Fernández (enolfc) wrote :

The first reference I could find to this is in OpenNebula 4.4:
http://docs.opennebula.org/4.4/user/virtual_machine_setup/cong.html#network-configuration

I can include a fallback if the _MAC is not available.

On 11 September 2017 at 17:11, Scott Moser <email address hidden> wrote:

> is _MAC expected present in all OpenNebula releases ? or is that something
> only provided in newer releases ? It'd be good to comment about when it
> was present.
>
> Thanks for raising this and helping out.
>
> --
> https://code.launchpad.net/~enolfc/cloud-init/+git/cloud-
> init/+merge/330518
> You are the owner of ~enolfc/cloud-init:bug-1716397.
>

--
Enol Fernández | Cloud Technologist | EGI Foundation
<email address hidden>

Revision history for this message
Scott Moser (smoser) wrote :

For my own reference, 4.4 was Dec 2013
 https://opennebula.org/software/release/

so that is "pretty old".

Revision history for this message
Enol Fernández (enolfc) wrote :

Hi,

I'm asking my company to sign the agreement. Once that's done, I should get
back to you to add me to the group?

Enol

On 11 September 2017 at 17:11, Scott Moser <email address hidden> wrote:

> Thank you for your contribution to cloud-init. Contributions to
> cloud-init require the developer to have signed the Canonical Contributors
> Agreement [1]. Your launchpad id is not currently listed as a member of
> the contributor-agreement-canonical group [2].
>
> Membership in that group is currently managed by a manual process, so it
> is possible that you have followed the process but were not added to the
> group. If you have already signed the contributor agreement, please
> simply say so here.
>
> For more information on contribution see the hacking documentation in
> cloud-init [3].
>
> --
> [1] https://www.ubuntu.com/legal/contributors
> [2] https://launchpad.net/~contributor-agreement-canonical/+members
> [3] http://cloudinit.readthedocs.io/en/latest/topics/hacking.html
>
> --
> https://code.launchpad.net/~enolfc/cloud-init/+git/cloud-
> init/+merge/330518
> You are the owner of ~enolfc/cloud-init:bug-1716397.
>

--
Enol Fernández | Cloud Technologist | EGI Foundation
<email address hidden>

Revision history for this message
Scott Moser (smoser) wrote :

Yes, please let me know when you or your company has signed. Unfortunately
there is some manual process still around, so as soon as that's done I'll
accept your code but you might not show in the group right away.
Thanks

On Wed, Sep 13, 2017 at 10:04 AM, Enol Fernández <email address hidden>
wrote:

> Hi,
>
> I'm asking my company to sign the agreement. Once that's done, I should get
> back to you to add me to the group?
>
> Enol
>
> On 11 September 2017 at 17:11, Scott Moser <email address hidden> wrote:
>
> > Thank you for your contribution to cloud-init. Contributions to
> > cloud-init require the developer to have signed the Canonical
> Contributors
> > Agreement [1]. Your launchpad id is not currently listed as a member of
> > the contributor-agreement-canonical group [2].
> >
> > Membership in that group is currently managed by a manual process, so it
> > is possible that you have followed the process but were not added to the
> > group. If you have already signed the contributor agreement, please
> > simply say so here.
> >
> > For more information on contribution see the hacking documentation in
> > cloud-init [3].
> >
> > --
> > [1] https://www.ubuntu.com/legal/contributors
> > [2] https://launchpad.net/~contributor-agreement-canonical/+members
> > [3] http://cloudinit.readthedocs.io/en/latest/topics/hacking.html
> >
> > --
> > https://code.launchpad.net/~enolfc/cloud-init/+git/cloud-
> > init/+merge/330518
> > You are the owner of ~enolfc/cloud-init:bug-1716397.
> >
>
>
>
> --
> Enol Fernández | Cloud Technologist | EGI Foundation
> <email address hidden>
>
> https://code.launchpad.net/~enolfc/cloud-init/+git/cloud-
> init/+merge/330518
> You are subscribed to branch cloud-init:master.
>

Revision history for this message
Server Team CI bot (server-team-bot) wrote :

FAILED: Continuous integration, rev:1e704904ffb283afddd87c05616f3967b896699d
https://jenkins.ubuntu.com/server/job/cloud-init-ci/289/
Executed test runs:
    SUCCESS: Checkout
    FAILED: Unit & Style Tests

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:0f71ba25af6a754337ed700f0c55dde1b14679b0
https://jenkins.ubuntu.com/server/job/cloud-init-ci/319/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    SUCCESS: MAAS Compatability Testing
    IN_PROGRESS: Declarative: Post Actions

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

review: Approve (continuous-integration)
Revision history for this message
Scott Moser (smoser) wrote :

Enol,
I'm sorry to bother you, but did you get anywhere on the CLA ?

Thanks,
Scott

Revision history for this message
Enol Fernández (enolfc) wrote :

Hi Scott,

I did not get a reply back yet. Will ping again.

E.

On 21 September 2017 at 02:15, Scott Moser <email address hidden> wrote:

> Enol,
> I'm sorry to bother you, but did you get anywhere on the CLA ?
>
> Thanks,
> Scott
> --
> https://code.launchpad.net/~enolfc/cloud-init/+git/cloud-
> init/+merge/330518
> You are the owner of ~enolfc/cloud-init:bug-1716397.
>

--
Enol Fernández | Cloud Technologist | EGI Foundation
<email address hidden>

Revision history for this message
Scott Moser (smoser) wrote :

Enol,

Just as housekeeping I'm going to put this into 'work in progress'.
Please feel free to comment and move it back.

Please feel free to ping me in email or in irc if you have any questions.

Thanks for your contribution.

Scott

Unmerged commits

0f71ba2... by Enol Fernández

OpenNebula: support network configuration with persistent named devices

OpenNebula network configuration is provided in context with device
identifiers in the form ETH[0-9]. That assumes that the host can "know"
the name of the device in the guest, which is unreliable at best and
completely broken when predictable names are used.

The change here now utilizes context variables named ETH<N>_MAC that
provide the mac address for the 'ETH<N>' device.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/sources/DataSourceOpenNebula.py b/cloudinit/sources/DataSourceOpenNebula.py
2index 5fdac19..2d2a6d0 100644
3--- a/cloudinit/sources/DataSourceOpenNebula.py
4+++ b/cloudinit/sources/DataSourceOpenNebula.py
5@@ -19,6 +19,7 @@ import string
6
7 from cloudinit import log as logging
8 from cloudinit import net
9+from cloudinit.net import eni
10 from cloudinit import sources
11 from cloudinit import util
12
13@@ -86,7 +87,7 @@ class DataSourceOpenNebula(sources.DataSource):
14 return False
15
16 self.seed = seed
17- self.network_eni = results.get("network_config")
18+ self.network_eni = results.get("network-interfaces")
19 self.metadata = md
20 self.userdata_raw = results.get('userdata')
21 return True
22@@ -99,6 +100,12 @@ class DataSourceOpenNebula(sources.DataSource):
23 resolve_ip = False
24 return sources.DataSource.get_hostname(self, fqdn, resolve_ip)
25
26+ @property
27+ def network_config(self):
28+ if self.network_eni:
29+ return eni.convert_eni_data(self.network_eni)
30+ return None
31+
32
33 class NonContextDiskDir(Exception):
34 pass
35@@ -161,6 +168,13 @@ class OpenNebulaNetwork(object):
36 else:
37 return None
38
39+ def mac2dev(self, mac, dev=''):
40+ for k in self.context:
41+ m = re.match(r'(ETH\d+)_MAC$', k)
42+ if self.context[k] == mac:
43+ return m.groups()[0]
44+ return dev
45+
46 def gen_conf(self):
47 global_dns = []
48 if 'DNS' in self.context:
49@@ -174,22 +188,25 @@ class OpenNebulaNetwork(object):
50 for mac, dev in self.ifaces.items():
51 ip_components = self.mac2ip(mac)
52
53+ one_dev = self.mac2dev(mac, dev)
54+
55 conf.append('auto ' + dev)
56 conf.append('iface ' + dev + ' inet static')
57- conf.append(' address ' + self.get_ip(dev, ip_components))
58- conf.append(' network ' + self.get_network(dev, ip_components))
59- conf.append(' netmask ' + self.get_mask(dev))
60+ conf.append(' address ' + self.get_ip(one_dev, ip_components))
61+ conf.append(' network ' + self.get_network(one_dev,
62+ ip_components))
63+ conf.append(' netmask ' + self.get_mask(one_dev))
64
65- gateway = self.get_gateway(dev)
66+ gateway = self.get_gateway(one_dev)
67 if gateway:
68 conf.append(' gateway ' + gateway)
69
70- domain = self.get_domain(dev)
71+ domain = self.get_domain(one_dev)
72 if domain:
73 conf.append(' dns-search ' + domain)
74
75 # add global DNS servers to all interfaces
76- dns = self.get_dns(dev)
77+ dns = self.get_dns(one_dev)
78 if global_dns or dns:
79 all_dns = global_dns
80 if dns:
81diff --git a/tests/unittests/test_datasource/test_opennebula.py b/tests/unittests/test_datasource/test_opennebula.py
82index e7d5569..765c195 100644
83--- a/tests/unittests/test_datasource/test_opennebula.py
84+++ b/tests/unittests/test_datasource/test_opennebula.py
85@@ -235,7 +235,8 @@ class TestOpenNebulaDataSource(TestCase):
86
87 class TestOpenNebulaNetwork(unittest.TestCase):
88
89- system_nics = {'02:00:0a:12:01:01': 'eth0'}
90+ eth0_system_nics = {'02:00:0a:12:01:01': 'eth0'}
91+ ens0_system_nics = {'02:00:0a:12:01:01': 'ens0'}
92
93 def test_lo(self):
94 net = ds.OpenNebulaNetwork(context={}, system_nics_by_mac={})
95@@ -244,9 +245,25 @@ auto lo
96 iface lo inet loopback
97 ''')
98
99+ def test_dev2mac_eth0(self):
100+ context = {
101+ 'ETH0_MAC': '02:00:0a:12:01:01'
102+ }
103+
104+ net = ds.OpenNebulaNetwork(context,
105+ system_nics_by_mac=self.eth0_system_nics)
106+ one_dev = net.mac2dev('02:00:0a:12:01:01')
107+ self.assertEqual(one_dev, 'ETH0')
108+
109+ def test_dev2mac_default(self):
110+ net = ds.OpenNebulaNetwork({},
111+ system_nics_by_mac=self.eth0_system_nics)
112+ one_dev = net.mac2dev('02:00:0a:12:01:01', 'FOO')
113+ self.assertEqual(one_dev, 'FOO')
114+
115 @mock.patch(DS_PATH + ".get_physical_nics_by_mac")
116 def test_eth0(self, m_get_phys_by_mac):
117- m_get_phys_by_mac.return_value = self.system_nics
118+ m_get_phys_by_mac.return_value = self.eth0_system_nics
119 net = ds.OpenNebulaNetwork({})
120 self.assertEqual(net.gen_conf(), u'''\
121 auto lo
122@@ -259,6 +276,61 @@ iface eth0 inet static
123 netmask 255.255.255.0
124 ''')
125
126+ def test_no_eth_system_nic(self):
127+ context = {
128+ 'DNS': '1.2.3.8',
129+ 'ETH0_IP': '1.2.3.4',
130+ 'ETH0_NETWORK': '1.2.3.0',
131+ 'ETH0_MASK': '255.255.0.0',
132+ 'ETH0_GATEWAY': '1.2.3.5',
133+ 'ETH0_DOMAIN': 'example.com',
134+ 'ETH0_DNS': '1.2.3.6 1.2.3.7',
135+ 'ETH0_MAC': '02:00:0a:12:01:01'
136+ }
137+
138+ net = ds.OpenNebulaNetwork(context,
139+ system_nics_by_mac=self.ens0_system_nics)
140+ self.assertEqual(net.gen_conf(), u'''\
141+auto lo
142+iface lo inet loopback
143+
144+auto ens0
145+iface ens0 inet static
146+ address 1.2.3.4
147+ network 1.2.3.0
148+ netmask 255.255.0.0
149+ gateway 1.2.3.5
150+ dns-search example.com
151+ dns-nameservers 1.2.3.8 1.2.3.6 1.2.3.7
152+''')
153+
154+ def test_eth0_override_no_mac(self):
155+ context = {
156+ 'DNS': '1.2.3.8',
157+ 'ETH0_IP': '1.2.3.4',
158+ 'ETH0_NETWORK': '1.2.3.0',
159+ 'ETH0_MASK': '255.255.0.0',
160+ 'ETH0_GATEWAY': '1.2.3.5',
161+ 'ETH0_DOMAIN': 'example.com',
162+ 'ETH0_DNS': '1.2.3.6 1.2.3.7',
163+ }
164+
165+ net = ds.OpenNebulaNetwork(context,
166+ system_nics_by_mac=self.eth0_system_nics)
167+ self.assertEqual(net.gen_conf(), u'''\
168+auto lo
169+iface lo inet loopback
170+
171+auto eth0
172+iface eth0 inet static
173+ address 1.2.3.4
174+ network 1.2.3.0
175+ netmask 255.255.0.0
176+ gateway 1.2.3.5
177+ dns-search example.com
178+ dns-nameservers 1.2.3.8 1.2.3.6 1.2.3.7
179+''')
180+
181 def test_eth0_override(self):
182 context = {
183 'DNS': '1.2.3.8',
184@@ -267,11 +339,12 @@ iface eth0 inet static
185 'ETH0_MASK': '255.255.0.0',
186 'ETH0_GATEWAY': '1.2.3.5',
187 'ETH0_DOMAIN': 'example.com',
188- 'ETH0_DNS': '1.2.3.6 1.2.3.7'
189+ 'ETH0_DNS': '1.2.3.6 1.2.3.7',
190+ 'ETH0_MAC': '02:00:0a:12:01:01'
191 }
192
193 net = ds.OpenNebulaNetwork(context,
194- system_nics_by_mac=self.system_nics)
195+ system_nics_by_mac=self.eth0_system_nics)
196 self.assertEqual(net.gen_conf(), u'''\
197 auto lo
198 iface lo inet loopback

Subscribers

People subscribed via source and target branches