Change in vdsm[master]: net: native ovs [2]: split ovs and legacy networks

phoracek at redhat.com phoracek at redhat.com
Sun Mar 27 14:45:58 UTC 2016


Petr Horáček has uploaded a new change for review.

Change subject: net: native ovs [2]: split ovs and legacy networks
......................................................................

net: native ovs [2]: split ovs and legacy networks

Implement ovs/legacy split function.

Change-Id: Ib78057445c38da542450b4ab8d79ea049a9c17f1
Bug-Url: https://bugzilla.redhat.com/1195208
Signed-off-by: Petr Horáček <phoracek at redhat.com>
---
M lib/vdsm/netinfo/bonding.py
M lib/vdsm/network/ovs/Makefile.am
M lib/vdsm/network/ovs/switch.py
A lib/vdsm/network/ovs/utils.py
M lib/vdsm/utils.py
M tests/network/netinfo_test.py
A tests/network/ovs_test.py
M tests/utilsTests.py
M vdsm.spec.in
9 files changed, 161 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/09/55309/1

diff --git a/lib/vdsm/netinfo/bonding.py b/lib/vdsm/netinfo/bonding.py
index 4046db5..22edbd0 100644
--- a/lib/vdsm/netinfo/bonding.py
+++ b/lib/vdsm/netinfo/bonding.py
@@ -288,3 +288,24 @@
             raise
 
     return _bond_opts_read_elements(opt_path)
+
+
+def parse_bond_options(options, keep_custom=False):
+    """
+    Parse bonding options string into dictionary, if keep_custom is set to
+    True, custom option will not be recursive parsed.
+    >>> get_bond_options('mode=4 custom=foo=yes,bar=no')
+    {'custom': {'bar': 'no', 'foo': 'yes'}, 'mode': '4'}
+    """
+    def _string_to_dict(str, div):
+        if options == '':
+            return {}
+        return dict(option.split('=', 1)
+                    for option in str.strip(div).split(div))
+    if options:
+        d_options = _string_to_dict(options, ' ')
+        if d_options.get('custom') and not keep_custom:
+            d_options['custom'] = _string_to_dict(d_options['custom'], ',')
+        return d_options
+    else:
+        return {}
diff --git a/lib/vdsm/network/ovs/Makefile.am b/lib/vdsm/network/ovs/Makefile.am
index b061e0c..b369ad0 100644
--- a/lib/vdsm/network/ovs/Makefile.am
+++ b/lib/vdsm/network/ovs/Makefile.am
@@ -24,4 +24,5 @@
 dist_vdsmnetworkovs_PYTHON = \
 	__init__.py \
 	switch.py \
+	utils.py \
 	$(NULL)
diff --git a/lib/vdsm/network/ovs/switch.py b/lib/vdsm/network/ovs/switch.py
index ee1f1fc..d959572 100644
--- a/lib/vdsm/network/ovs/switch.py
+++ b/lib/vdsm/network/ovs/switch.py
@@ -20,13 +20,15 @@
 
 from contextlib import contextmanager
 
+from . import utils
+
 
 def is_ovs_net(attrs):
-    pass
+    return utils.is_ovs_net(attrs)
 
 
 def is_ovs_bond(attrs):
-    pass
+    return utils.is_ovs_bond(attrs)
 
 
 def validate_network_setup(nets, bonds):
diff --git a/lib/vdsm/network/ovs/utils.py b/lib/vdsm/network/ovs/utils.py
new file mode 100644
index 0000000..d488e61
--- /dev/null
+++ b/lib/vdsm/network/ovs/utils.py
@@ -0,0 +1,39 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+from __future__ import absolute_import
+
+from vdsm.netinfo.bonding import parse_bond_options
+from vdsm.utils import rget
+
+
+def is_ovs_net(attrs):
+    return get_bool(rget(attrs, ('custom', 'ovs')))
+
+
+def is_ovs_bond(attrs):
+    bond_options = parse_bond_options(attrs.get('options', ''))
+    ovs_bond = get_bool(rget(bond_options, ('custom', 'ovs')))
+    return ovs_bond
+
+
+def get_bool(input):
+    if input in (1, '1', True, 'True', 'true', 'Yes', 'yes', 'on'):
+        return True
+    else:
+        return False
diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index 843a54f..7dd2279 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -928,3 +928,16 @@
         yield
     except exceptions:
         pass
+
+
+def rget(dict, keys, default=None):
+    """Recursive dictionary.get()
+
+    >>> rget({'a': {'b': 'hello'}}, ('a', 'b'))
+    'hello'
+    """
+    if dict is None:
+        return default
+    elif len(keys) == 0:
+        return dict
+    return rget(dict.get(keys[0]), keys[1:], default)
diff --git a/tests/network/netinfo_test.py b/tests/network/netinfo_test.py
index c8395dd..19d6588 100644
--- a/tests/network/netinfo_test.py
+++ b/tests/network/netinfo_test.py
@@ -392,6 +392,16 @@
     def _cidr_form(self, ip_addr, prefix_length):
         return '{}/{}'.format(ip_addr, prefix_length)
 
+    def test_parse_bond_options(self):
+        self.assertEqual(
+            bonding.get_bond_options('mode=4 custom=foo=yes,bar=no',
+                                     keep_custom=True),
+            {'custom': 'foo=yes,bar=no', 'mode': '4'})
+        self.assertEqual(
+            bonding.get_bond_options('mode=4 custom=foo=yes,bar=no',
+                                     keep_custom=False),
+            {'custom': {'bar': 'no', 'foo': 'yes'}, 'mode': '4'})
+
 
 @attr(type='integration')
 class TestIPv6Addresses(TestCaseBase):
diff --git a/tests/network/ovs_test.py b/tests/network/ovs_test.py
new file mode 100644
index 0000000..76870c1
--- /dev/null
+++ b/tests/network/ovs_test.py
@@ -0,0 +1,64 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+from __future__ import absolute_import
+
+from vdsm.network.ovs import utils as ovs_utils
+
+from testlib import VdsmTestCase as TestCaseBase
+
+
+class UtilsTests(TestCaseBase):
+
+    def test_is_ovs_net(self):
+        self.assertTrue(
+            ovs_utils.is_ovs_net({'custom': {'ovs': True}}))
+        self.assertTrue(
+            ovs_utils.is_ovs_net({'custom': {'ovs': 1}}))
+        self.assertTrue(
+            ovs_utils.is_ovs_net({'custom': {'ovs': 'yes', 'foo': False}}))
+
+        self.assertFalse(
+            ovs_utils.is_ovs_net({'custom': {'ovs': False}}))
+        self.assertFalse(
+            ovs_utils.is_ovs_net({'custom': {'ovs': 'bleh'}}))
+        self.assertFalse(
+            ovs_utils.is_ovs_net({'custom': {'foo': 'bar'}}))
+        self.assertFalse(
+            ovs_utils.is_ovs_net({'nic': 'dummy'}))
+
+    def test_is_ovs_bond(self):
+        self.assertTrue(
+            ovs_utils.is_ovs_bond({'options': 'custom=ovs=True'}))
+        self.assertTrue(
+            ovs_utils.is_ovs_bond({'options': 'custom=foo=bar,ovs=True'}))
+        self.assertTrue(
+            ovs_utils.is_ovs_bond({'options': 'custom=ovs=1'}))
+        self.assertTrue(
+            ovs_utils.is_ovs_bond({'options': 'mode=4 custom=ovs=True'}))
+
+        self.assertFalse(
+            ovs_utils.is_ovs_bond({'options': 'custom=ovs=False'}))
+        self.assertFalse(
+            ovs_utils.is_ovs_bond({'options': 'custom=ovs=0'}))
+        self.assertFalse(
+            ovs_utils.is_ovs_bond({'options': 'custom=ovs=bleh'}))
+        self.assertFalse(
+            ovs_utils.is_ovs_bond({'options': 'custom=foo=bleh'}))
+        self.assertFalse(
+            ovs_utils.is_ovs_bond({'nics': ['foo', 'bar']}))
diff --git a/tests/utilsTests.py b/tests/utilsTests.py
index 9679202..fb39141 100644
--- a/tests/utilsTests.py
+++ b/tests/utilsTests.py
@@ -358,6 +358,14 @@
             with utils.suppress(OSError, AttributeError):
                 raise RuntimeError()
 
+    def test_rget(self):
+        self.assertEqual(
+            utils.rget({'a': {'b': 'hello'}}, ('a', 'b')),
+            'hello')
+        self.assertEqual(
+            utils.rget({'a': {'b': 'hello'}}, ('a', 'c'), default='bye'),
+            'bye')
+
 
 class AsyncProcessOperationTests(TestCaseBase):
     def _echo(self, text):
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 299e7b9..d1a053f 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1140,6 +1140,7 @@
 %{python_sitelib}/%{vdsm_name}/network/legacy_switch.py*
 %{python_sitelib}/%{vdsm_name}/network/ovs/__init__.py*
 %{python_sitelib}/%{vdsm_name}/network/ovs/switch.py*
+%{python_sitelib}/%{vdsm_name}/network/ovs/utils.py*
 %{python_sitelib}/%{vdsm_name}/network/models.py*
 %{python_sitelib}/%{vdsm_name}/network/netswitch.py*
 %{python_sitelib}/%{vdsm_name}/network/sourceroute.py*


-- 
To view, visit https://gerrit.ovirt.org/55309
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib78057445c38da542450b4ab8d79ea049a9c17f1
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Petr Horáček <phoracek at redhat.com>


More information about the vdsm-patches mailing list