← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~smoser/cloud-init:open-nebula-no-ip into cloud-init:master

 

Scott Moser has proposed merging ~smoser/cloud-init:open-nebula-no-ip into cloud-init:master.

Requested reviews:
  cloud init development team (cloud-init-dev)

For more details, see:
https://code.launchpad.net/~smoser/cloud-init/+git/cloud-init/+merge/307200
-- 
Your team cloud init development team is requested to review the proposed merge of ~smoser/cloud-init:open-nebula-no-ip into cloud-init:master.
diff --git a/cloudinit/sources/DataSourceOpenNebula.py b/cloudinit/sources/DataSourceOpenNebula.py
index 635a836..ba5f3f9 100644
--- a/cloudinit/sources/DataSourceOpenNebula.py
+++ b/cloudinit/sources/DataSourceOpenNebula.py
@@ -30,6 +30,7 @@ import re
 import string
 
 from cloudinit import log as logging
+from cloudinit import net
 from cloudinit import sources
 from cloudinit import util
 
@@ -120,17 +121,11 @@ class BrokenContextDiskDir(Exception):
 
 
 class OpenNebulaNetwork(object):
-    REG_DEV_MAC = re.compile(
-        r'^\d+: (eth\d+):.*?link\/ether (..:..:..:..:..:..) ?',
-        re.MULTILINE | re.DOTALL)
-
-    def __init__(self, ip, context):
-        self.ip = ip
+    def __init__(self, context, system_nics_by_mac=None):
         self.context = context
-        self.ifaces = self.get_ifaces()
-
-    def get_ifaces(self):
-        return self.REG_DEV_MAC.findall(self.ip)
+        if system_nics_by_mac is None:
+            system_nics_by_mac = get_physical_nics_by_mac()
+        self.ifaces = system_nics_by_mac
 
     def mac2ip(self, mac):
         components = mac.split(':')[2:]
@@ -188,9 +183,7 @@ class OpenNebulaNetwork(object):
         conf.append('iface lo inet loopback')
         conf.append('')
 
-        for i in self.ifaces:
-            dev = i[0]
-            mac = i[1]
+        for mac, dev in self.ifaces.items():
             ip_components = self.mac2ip(mac)
 
             conf.append('auto ' + dev)
@@ -405,16 +398,19 @@ def read_context_disk_dir(source_dir, asuser=None):
     # generate static /etc/network/interfaces
     # only if there are any required context variables
     # http://opennebula.org/documentation:rel3.8:cong#network_configuration
-    for k in context:
-        if re.match(r'^ETH\d+_IP$', k):
-            (out, _) = util.subp(['ip', 'link'])
-            net = OpenNebulaNetwork(out, context)
-            results['network-interfaces'] = net.gen_conf()
-            break
+    ipaddr_keys = [k for k in context if re.match(r'^ETH\d+_IP$', k)]
+    if ipaddr_keys:
+        onet = OpenNebulaNetwork(context)
+        results['network-interfaces'] = onet.gen_conf()
 
     return results
 
 
+def get_physical_nics_by_mac():
+    devs = net.get_interfaces_by_mac()
+    return dict([(m, n) for m, n in devs.items() if net.is_physical(n)])
+
+
 # Legacy: Must be present in case we load an old pkl object
 DataSourceOpenNebulaNet = DataSourceOpenNebula
 
diff --git a/tests/unittests/test_datasource/test_opennebula.py b/tests/unittests/test_datasource/test_opennebula.py
index d796f03..339d8a4 100644
--- a/tests/unittests/test_datasource/test_opennebula.py
+++ b/tests/unittests/test_datasource/test_opennebula.py
@@ -1,7 +1,7 @@
 from cloudinit import helpers
 from cloudinit.sources import DataSourceOpenNebula as ds
 from cloudinit import util
-from ..helpers import TestCase, populate_dir
+from ..helpers import mock, populate_dir, TestCase
 
 import os
 import pwd
@@ -31,12 +31,7 @@ SSH_KEY = 'ssh-rsa AAAAB3NzaC1....sIkJhq8wdX+4I3A4cYbYP ubuntu@server-460-%i'
 HOSTNAME = 'foo.example.com'
 PUBLIC_IP = '10.0.0.3'
 
-CMD_IP_OUT = '''\
-1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
-    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
-2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
-    link/ether 02:00:0a:12:01:01 brd ff:ff:ff:ff:ff:ff
-'''
+DS_PATH = "cloudinit.sources.DataSourceOpenNebula"
 
 
 class TestOpenNebulaDataSource(TestCase):
@@ -233,18 +228,19 @@ class TestOpenNebulaDataSource(TestCase):
 
 class TestOpenNebulaNetwork(unittest.TestCase):
 
-    def setUp(self):
-        super(TestOpenNebulaNetwork, self).setUp()
+    macs = {'02:00:0a:12:01:01': 'eth0'}
 
     def test_lo(self):
-        net = ds.OpenNebulaNetwork('', {})
+        net = ds.OpenNebulaNetwork(context={}, system_nics_by_mac={})
         self.assertEqual(net.gen_conf(), u'''\
 auto lo
 iface lo inet loopback
 ''')
 
-    def test_eth0(self):
-        net = ds.OpenNebulaNetwork(CMD_IP_OUT, {})
+    @mock.patch(DS_PATH + ".get_physical_nics_by_mac")
+    def test_eth0(self, m_get_phys_by_mac):
+        m_get_phys_by_mac.return_value = self.macs
+        net = ds.OpenNebulaNetwork({})
         self.assertEqual(net.gen_conf(), u'''\
 auto lo
 iface lo inet loopback
@@ -267,7 +263,7 @@ iface eth0 inet static
             'ETH0_DNS': '1.2.3.6 1.2.3.7'
         }
 
-        net = ds.OpenNebulaNetwork(CMD_IP_OUT, context)
+        net = ds.OpenNebulaNetwork(context, system_nics_by_mac=self.macs)
         self.assertEqual(net.gen_conf(), u'''\
 auto lo
 iface lo inet loopback

Follow ups