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 <phora...@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 <phora...@redhat.com> _______________________________________________ vdsm-patches mailing list vdsm-patches@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches