[PATCH] (v2) Add support for network team devices (#1003591)

Vratislav Podzimek vpodzime at redhat.com
Wed Nov 13 13:12:15 UTC 2013


On Tue, 2013-11-12 at 14:33 +0100, Radek Vykydal wrote:
> ---
>  pykickstart/commands/network.py | 74 +++++++++++++++++++++++++++++++++++++++++
>  pykickstart/handlers/control.py |  8 ++---
>  tests/commands/network.py       | 73 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 151 insertions(+), 4 deletions(-)
>  create mode 100644 tests/commands/network.py
> 
> diff --git a/pykickstart/commands/network.py b/pykickstart/commands/network.py
> index 6f50ac1..1412dc7 100644
> --- a/pykickstart/commands/network.py
> +++ b/pykickstart/commands/network.py
> @@ -193,6 +193,31 @@ class F19_NetworkData(F16_NetworkData):
>  
>          return retval
>  
> +class F20_NetworkData(F19_NetworkData):
> +    removedKeywords = F19_NetworkData.removedKeywords
> +    removedAttrs = F19_NetworkData.removedAttrs
> +
> +    def __init__(self, *args, **kwargs):
> +        F19_NetworkData.__init__(self, *args, **kwargs)
> +        self.teamslaves = kwargs.get("teamslaves", [])
> +        self.teamconfig = kwargs.get("teamconfig", "")
> +
> +    def _getArgsAsStr(self):
> +        retval = F19_NetworkData._getArgsAsStr(self)
> +
> +        # see the tests for format description
> +        if self.teamslaves:
> +            slavecfgs = []
> +            for slave, config in self.teamslaves:
> +                if config:
> +                    config = "'" + config + "'"
> +                slavecfgs.append(slave+config)
> +            slavecfgs = ",".join(slavecfgs).replace('"', r'\"')
> +            retval += " --teamslaves=\"%s\"" % slavecfgs
You can use ' --teamslaves="%s"' here and there making strings better
readable.

> +        if self.teamconfig:
> +            retval += " --teamconfig=\"%s\"" % self.teamconfig.replace('"', r'\"')
> +        return retval
> +
>  class RHEL4_NetworkData(FC3_NetworkData):
>      removedKeywords = FC3_NetworkData.removedKeywords
>      removedAttrs = FC3_NetworkData.removedAttrs
> @@ -384,6 +409,55 @@ class F19_Network(F18_Network):
>                  default="")
>          return op
>  
> +class F20_Network(F19_Network):
> +
> +    def _getParser(self):
> +        # see the tests for teamslaves option
> +        def teamslaves_cb(option, opt_str, value, parser):
> +            # value is of: "<DEV1>['<JSON_CONFIG1>'],<DEV2>['<JSON_CONFIG2>'],..."
> +            # for example: "eth1,eth2'{"prio": 100}',eth3"
> +            teamslaves = []
> +            if value:
> +                # Although slaves, having optional config, are separated by ","
> +                # first extract json configs because they can contain the ","
> +                parts = value.split("'")
> +                # parts == ['eth1,eth2', '{"prio": 100}', ',eth3']
> +                # ensure the list has even number of items for further zipping,
> +                # for odd number of items
> +                if len(parts) % 2 == 1:
> +                    # if the list ends with an empty string which must be a leftover
> +                    # from splitting string not ending with device eg
> +                    # "eth1,eth2'{"prio":100"}'"
> +                    if not parts[-1]:
> +                        # just remove it
> +                        parts = parts[:-1]
> +                    # if not (our example), add empty config for the last device
> +                    else:
> +                        parts.append('')
> +                        # parts == ['eth1,eth2', '{"prio": 100}', ',eth3', '']
> +                # zip devices with its configs
                                      ^^ their configs

> +                it = iter(parts)
> +                for devs, cfg in zip(it,it):
> +                    # first loop:
> +                    # devs == "eth1,eth2", cfg == '{"prio": 100}'
> +                    devs = devs.strip(',').split(',')
> +                    # devs == ["eth1", "eth2"]
> +                    # initialize config of all devs but the last one to empty
> +                    for d in devs[:-1]:
> +                        teamslaves.append((d, ''))
> +                    # teamslaves == [("eth1", '')]
> +                    # and set config of the last device
> +                    teamslaves.append((devs[-1], cfg))
> +                    # teamslaves == [('eth1', ''), ('eth2', '{"prio": 100}']
> +            parser.values.teamslaves = teamslaves
> +
> +        op = F19_Network._getParser(self)
> +        op.add_option("--teamslaves", dest="teamslaves", action="callback",
> +                callback=teamslaves_cb, nargs=1, type="string")
> +        op.add_option("--teamconfig", dest="teamconfig", action="store",
> +                default="")
> +        return op
> +
>  class RHEL4_Network(FC3_Network):
>      removedKeywords = FC3_Network.removedKeywords
>      removedAttrs = FC3_Network.removedAttrs
> diff --git a/pykickstart/handlers/control.py b/pykickstart/handlers/control.py
> index 0139f9a..2566c89 100644
> --- a/pykickstart/handlers/control.py
> +++ b/pykickstart/handlers/control.py
> @@ -1058,7 +1058,7 @@ commandMap = {
>          "mediacheck": mediacheck.FC4_MediaCheck,
>          "method": method.F19_Method,
>          "multipath": multipath.FC6_MultiPath,
> -        "network": network.F19_Network,
> +        "network": network.F20_Network,
>          "nfs": nfs.FC6_NFS,
>          "part": partition.F20_Partition,
>          "partition": partition.F20_Partition,
> @@ -1347,7 +1347,7 @@ commandMap = {
>          "mediacheck": mediacheck.FC4_MediaCheck,
>          "method": method.F19_Method,
>          "multipath": multipath.FC6_MultiPath,
> -        "network": network.F19_Network,
> +        "network": network.F20_Network,
>          "nfs": nfs.FC6_NFS,
>          "part": partition.F18_Partition,
>          "partition": partition.F18_Partition,
> @@ -1655,7 +1655,7 @@ dataMap = {
>          "IscsiData": iscsi.F17_IscsiData,
>          "LogVolData": logvol.F20_LogVolData,
>          "MultiPathData": multipath.FC6_MultiPathData,
> -        "NetworkData": network.F19_NetworkData,
> +        "NetworkData": network.F20_NetworkData,
>          "PartData": partition.F18_PartData,
>          "RaidData": raid.F18_RaidData,
>          "RepoData": repo.F15_RepoData,
> @@ -1724,7 +1724,7 @@ dataMap = {
>          "IscsiData": iscsi.F17_IscsiData,
>          "LogVolData": logvol.F18_LogVolData,
>          "MultiPathData": multipath.FC6_MultiPathData,
> -        "NetworkData": network.F19_NetworkData,
> +        "NetworkData": network.F20_NetworkData,
>          "PartData": partition.F18_PartData,
>          "RaidData": raid.F18_RaidData,
>          "RepoData": repo.F15_RepoData,
> diff --git a/tests/commands/network.py b/tests/commands/network.py
> new file mode 100644
> index 0000000..9643c74
> --- /dev/null
> +++ b/tests/commands/network.py
> @@ -0,0 +1,73 @@
> +#
> +# Radek Vykydal <rvykydal at redhat.com>
> +#
> +# Copyright 2013 Red Hat, Inc.
> +#
> +# This copyrighted material is made available to anyone wishing to use, modify,
> +# copy, or redistribute it subject to the terms and conditions of the GNU
> +# General Public License v.2.  This program is distributed in the hope that it
> +# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
> +# implied warranties 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.  Any Red Hat
> +# trademarks that are incorporated in the source code or documentation are not
> +# subject to the GNU General Public License and may only be used or replicated
> +# with the express permission of Red Hat, Inc.
> +#
> +import unittest
> +from tests.baseclass import *
> +
> +from pykickstart.errors import *
> +from pykickstart.commands.network import *
> +
> +class F20_TestCase(CommandTest):
> +    command = "network"
> +
> +    def runTest(self):
> +
> +        # team device
> +
> +        cmd = "network --device team0 --bootproto static --ip=10.34.102.222 --netmask=255.255.255.0 --gateway=10.34.102.254 --nameserver=10.34.39.2 --teamslaves=\"p3p1'{\\\"prio\\\": -10, \\\"sticky\\\": true}',p3p2'{\\\"prio\\\": 100}'\" --teamconfig=\"{\\\"runner\\\": {\\\"name\\\": \\\"activebackup\\\"}}\" --activate"
Would be nice to use r'string' strings to avoid escaping backslashes and
double quotes.

Apart from these three minor comments this looks godo to me.

-- 
Vratislav Podzimek

Anaconda Rider | Red Hat, Inc. | Brno - Czech Republic



More information about the anaconda-patches mailing list