From: ogawa.yasufumi@lab.ntt.co.jp
To: ferruh.yigit@intel.com, spp@dpdk.org, ogawa.yasufumi@lab.ntt.co.jp
Subject: [spp] [PATCH 1/5] controller: change sec command to nfv
Date: Wed, 12 Dec 2018 11:03:11 +0900 [thread overview]
Message-ID: <1544580195-9242-2-git-send-email-ogawa.yasufumi@lab.ntt.co.jp> (raw)
In-Reply-To: <1544580195-9242-1-git-send-email-ogawa.yasufumi@lab.ntt.co.jp>
From: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
This update is to change `sec` command to `nfv` and correct completion
of patch sub command. Completion of `patch` command should not show
ports already used, and should not show dst port after `reset`.
Signed-off-by: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
---
src/controller/commands/bye.py | 8 +-
src/controller/commands/nfv.py | 314 +++++++++++++++++++++++++++++++++++++++++
src/controller/commands/sec.py | 202 --------------------------
src/controller/shell.py | 80 +++++++----
4 files changed, 372 insertions(+), 232 deletions(-)
create mode 100644 src/controller/commands/nfv.py
delete mode 100644 src/controller/commands/sec.py
diff --git a/src/controller/commands/bye.py b/src/controller/commands/bye.py
index 3ffc259..dfbd048 100644
--- a/src/controller/commands/bye.py
+++ b/src/controller/commands/bye.py
@@ -14,10 +14,10 @@ class SppBye(object):
BYE_CMDS = ['sec', 'all']
- def __init__(self, spp_ctl_cli, spp_primary, spp_secondary):
+ def __init__(self, spp_ctl_cli, spp_primary, spp_nfvs):
self.spp_ctl_cli = spp_ctl_cli
self.spp_primary = spp_primary
- self.spp_secondary = spp_secondary
+ self.spp_nfvs = spp_nfvs
def run(self, args, sec_ids):
@@ -44,5 +44,5 @@ class SppBye(object):
def close_all_secondary(self, sec_ids):
"""Terminate all secondary processes."""
- for i in sec_ids:
- self.spp_secondary.run(i, 'exit')
+ for i, nfv in self.spp_nfvs.items():
+ nfv.run(i, 'exit')
diff --git a/src/controller/commands/nfv.py b/src/controller/commands/nfv.py
new file mode 100644
index 0000000..9af4449
--- /dev/null
+++ b/src/controller/commands/nfv.py
@@ -0,0 +1,314 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Nippon Telegraph and Telephone Corporation
+
+from .. import spp_common
+
+
+class SppNfv(object):
+ """Exec spp_nfv command.
+
+ SppNfv lass is intended to be used in Shell class as a delegator for
+ running 'nfv' command.
+
+ 'self.command()' is called from do_nfv() and 'self.complete()' is called
+ from complete_nfv() of both of which is defined in Shell.
+ """
+
+ # All of commands and sub-commands used for validation and completion.
+ NFV_CMDS = ['status', 'exit', 'forward', 'stop', 'add', 'patch', 'del']
+
+ def __init__(self, spp_ctl_cli, sec_id, use_cache=False):
+ self.spp_ctl_cli = spp_ctl_cli
+ self.sec_id = sec_id
+ self.ports = [] # registered ports
+ self.patchs = []
+
+ # Call REST API each time of completion if it is True.
+ self.use_cache = use_cache
+
+ def run(self, cmdline):
+ """Called from do_nfv() to Send command to secondary process."""
+
+ cmd = cmdline.split(' ')[0]
+ params = cmdline.split(' ')[1:]
+
+ if cmd == 'status':
+ res = self.spp_ctl_cli.get('nfvs/%d' % self.sec_id)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 200:
+ self.print_nfv_status(res.json())
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ elif cmd == 'add':
+ if self.use_cache is True:
+ self.ports.append(params[0])
+
+ req_params = {'action': 'add', 'port': params[0]}
+
+ res = self.spp_ctl_cli.put('nfvs/%d/ports' %
+ self.sec_id, req_params)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ print('Add %s.' % params[0])
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ elif cmd == 'del':
+ if self.use_cache is True:
+ if params[0] in self.ports:
+ self.ports.remove(params[0])
+
+ req_params = {'action': 'del', 'port': params[0]}
+ res = self.spp_ctl_cli.put('nfvs/%d/ports' %
+ self.sec_id, req_params)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ print('Delete %s.' % params[0])
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ elif cmd == 'forward' or cmd == 'stop':
+ if cmd == 'forward':
+ req_params = {'action': 'start'}
+ elif cmd == 'stop':
+ req_params = {'action': 'stop'}
+ else:
+ print('Unknown command. "forward" or "stop"?')
+
+ res = self.spp_ctl_cli.put('nfvs/%d/forward' %
+ self.sec_id, req_params)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ if cmd == 'forward':
+ print('Start forwarding.')
+ else:
+ print('Stop forwarding.')
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ elif cmd == 'patch':
+ if params[0] == 'reset':
+ res = self.spp_ctl_cli.delete('nfvs/%d/patches' % self.sec_id)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ print('Clear all of patches.')
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+ else:
+ req_params = {'src': params[0], 'dst': params[1]}
+ res = self.spp_ctl_cli.put(
+ 'nfvs/%d/patches' % self.sec_id, req_params)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ print('Patch ports (%s -> %s).' % (
+ params[0], params[1]))
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ elif cmd == 'exit':
+ res = self.spp_ctl_cli.delete('nfvs/%d' % self.sec_id)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 204:
+ print('Exit nfv %d' % self.sec_id)
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ else:
+ print('Invalid command "%s".' % cmd)
+
+ def print_nfv_status(self, json_obj):
+ """Parse and print message from SPP secondary.
+
+ Print status received from secondary.
+
+ spp > nfv 1;status
+ - status: idling
+ - ports:
+ - phy:0 -> ring:0
+ - phy:1
+
+ The format of the received message is JSON and ended with
+ series of null character "\x00".
+
+ {"client-id":1,...,"patches":[{"src":"phy:0"...},...]}'\x00..
+ """
+
+ nfv_attr = json_obj
+ print('- status: %s' % nfv_attr['status'])
+ print('- ports:')
+ for port in nfv_attr['ports']:
+ dst = None
+ for patch in nfv_attr['patches']:
+ if patch['src'] == port:
+ dst = patch['dst']
+
+ if dst is None:
+ print(' - %s' % port)
+ else:
+ print(' - %s -> %s' % (port, dst))
+
+ def get_registered_ports(self):
+ res = self.spp_ctl_cli.get('nfvs/%d' % self.sec_id)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 200:
+ return res.json()['ports']
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ def get_registered_patches(self):
+ res = self.spp_ctl_cli.get('nfvs/%d' % self.sec_id)
+ if res is not None:
+ error_codes = self.spp_ctl_cli.rest_common_error_codes
+ if res.status_code == 200:
+ return res.json()['patches']
+ elif res.status_code in error_codes:
+ pass
+ else:
+ print('Error: unknown response.')
+
+ def complete(self, sec_ids, text, line, begidx, endidx):
+ """Completion for spp_nfv commands.
+
+ Called from complete_nfv() to complete secondary command.
+ """
+
+ try:
+ completions = []
+ tokens = line.split(';')
+
+ if len(tokens) == 2:
+ sub_tokens = tokens[1].split(' ')
+
+ if len(sub_tokens) == 1:
+ if not (sub_tokens[0] in self.NFV_CMDS):
+ completions = self._compl_first_tokens(sub_tokens[0])
+
+ else:
+ if sub_tokens[0] in ['status', 'exit', 'forward', 'stop']:
+ if len(sub_tokens) < 2:
+ if sub_tokens[0].startswith(sub_tokens[1]):
+ completions = [sub_tokens[0]]
+
+ elif sub_tokens[0] == 'add':
+ completions = self._compl_add(sub_tokens)
+
+ elif sub_tokens[0] == 'del':
+ completions = self._compl_del(sub_tokens)
+
+ elif sub_tokens[0] == 'patch':
+ completions = self._compl_patch(sub_tokens)
+
+ return completions
+
+ except Exception as e:
+ print(e)
+
+ def _compl_first_tokens(self, token):
+ res = []
+ for kw in self.NFV_CMDS:
+ if kw.startswith(token):
+ res.append(kw)
+ return res
+
+ def _compl_add(self, sub_tokens):
+ if len(sub_tokens) < 3:
+ res = []
+
+ port_types = spp_common.PORT_TYPES[:]
+ port_types.remove('phy')
+
+ for kw in port_types:
+ if kw.startswith(sub_tokens[1]):
+ res.append(kw + ':')
+ return res
+
+ def _compl_del(self, sub_tokens):
+ if len(sub_tokens) < 3:
+ res = []
+
+ if self.use_cache is False:
+ self.ports = self.get_registered_ports()
+
+ for kw in self.ports:
+ if kw.startswith(sub_tokens[1]):
+ if ':' in sub_tokens[1]: # exp, 'ring:' or 'ring:0'
+ res.append(kw.split(':')[1])
+ else:
+ res.append(kw)
+
+ for p in res:
+ if p.startswith('phy:'):
+ res.remove(p)
+
+ return res
+
+ def _compl_patch(self, sub_tokens):
+ # Patch command consists of three tokens max, for instance,
+ # `nfv 1; patch phy:0 ring:1`.
+ if len(sub_tokens) < 4:
+ res = []
+
+ if self.use_cache is False:
+ self.ports = self.get_registered_ports()
+ self.patches = self.get_registered_patches()
+
+ # Get patched ports of src and dst to be used for completion.
+ src_ports = []
+ dst_ports = []
+ for pt in self.patches:
+ src_ports.append(pt['src'])
+ dst_ports.append(pt['dst'])
+
+ # Remove patched ports from candidates.
+ target_idx = len(sub_tokens) - 1 # target is src or dst
+ tmp_ports = self.ports[:] # candidates
+ if target_idx == 1: # find src port
+ # If some of ports are patched, `reset` should be included.
+ if self.patches != []:
+ tmp_ports.append('reset')
+ for pt in src_ports:
+ tmp_ports.remove(pt) # remove patched ports
+ else: # find dst port
+ # If `reset` is given, no need to show dst ports.
+ if sub_tokens[target_idx - 1] == 'reset':
+ tmp_ports = []
+ else:
+ for pt in dst_ports:
+ tmp_ports.remove(pt)
+
+ # Return candidates.
+ for kw in tmp_ports:
+ if kw.startswith(sub_tokens[target_idx]):
+ # Completion does not work correctly if `:` is included in
+ # tokens. Required to create keyword only after `:`.
+ if ':' in sub_tokens[target_idx]: # 'ring:' or 'ring:0'
+ res.append(kw.split(':')[1]) # add only after `:`
+ else:
+ res.append(kw)
+
+ return res
diff --git a/src/controller/commands/sec.py b/src/controller/commands/sec.py
deleted file mode 100644
index ec1da58..0000000
--- a/src/controller/commands/sec.py
+++ /dev/null
@@ -1,202 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2018 Nippon Telegraph and Telephone Corporation
-
-
-class SppSecondary(object):
- """Exec SPP secondary command.
-
- SppSecondaryclass is intended to be used in Shell class as a delegator
- for running 'sec' command.
-
- 'self.command()' is called from do_sec() and 'self.complete()' is called
- from complete_sec() of both of which is defined in Shell.
- """
-
- # All of commands and sub-commands used for validation and completion.
- SEC_CMDS = ['status', 'exit', 'forward', 'stop', 'add', 'patch', 'del']
- SEC_SUBCMDS = ['vhost', 'ring', 'pcap', 'nullpmd']
-
- def __init__(self, spp_ctl_cli):
- self.spp_ctl_cli = spp_ctl_cli
-
- def run(self, sec_id, cmdline):
- """Called from do_sec() to Send command to secondary process."""
-
- cmd = cmdline.split(' ')[0]
- params = cmdline.split(' ')[1:]
-
- if cmd == 'status':
- res = self.spp_ctl_cli.get('nfvs/%d' % sec_id)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 200:
- self.print_sec_status(res.json())
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
-
- elif cmd == 'add':
- req_params = {'action': 'add', 'port': params[0]}
- res = self.spp_ctl_cli.put('nfvs/%d/ports' % sec_id, req_params)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- print('Add %s.' % params[0])
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
-
- elif cmd == 'del':
- req_params = {'action': 'del', 'port': params[0]}
- res = self.spp_ctl_cli.put('nfvs/%d/ports' % sec_id, req_params)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- print('Delete %s.' % params[0])
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
-
- elif cmd == 'forward' or cmd == 'stop':
- if cmd == 'forward':
- req_params = {'action': 'start'}
- elif cmd == 'stop':
- req_params = {'action': 'stop'}
- else:
- print('Unknown command. "forward" or "stop"?')
-
- res = self.spp_ctl_cli.put('nfvs/%d/forward' % sec_id, req_params)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- if cmd == 'forward':
- print('Start forwarding.')
- else:
- print('Stop forwarding.')
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
-
- elif cmd == 'patch':
- if params[0] == 'reset':
- res = self.spp_ctl_cli.delete('nfvs/%d/patches' % sec_id)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- print('Clear all of patches.')
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
- else:
- req_params = {'src': params[0], 'dst': params[1]}
- res = self.spp_ctl_cli.put(
- 'nfvs/%d/patches' % sec_id, req_params)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- print('Patch ports (%s -> %s).' % (
- params[0], params[1]))
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
-
- elif cmd == 'exit':
- res = self.spp_ctl_cli.delete('nfvs/%d' % sec_id)
- if res is not None:
- error_codes = self.spp_ctl_cli.rest_common_error_codes
- if res.status_code == 204:
- print('Exit sec %d' % sec_id)
- elif res.status_code in error_codes:
- pass
- else:
- print('Error: unknown response.')
-
- else:
- print('Invalid command "%s".' % cmd)
-
- def print_sec_status(self, json_obj):
- """Parse and print message from SPP secondary.
-
- Print status received from secondary.
-
- spp > sec 1;status
- - status: idling
- - ports:
- - phy:0 -> ring:0
- - phy:1
-
- The format of the received message is JSON and ended with
- series of null character "\x00".
-
- {"client-id":1,...,"patches":[{"src":"phy:0"...},...]}'\x00..
- """
-
- sec_attr = json_obj
- print('- status: %s' % sec_attr['status'])
- print('- ports:')
- for port in sec_attr['ports']:
- dst = None
- for patch in sec_attr['patches']:
- if patch['src'] == port:
- dst = patch['dst']
-
- if dst is None:
- print(' - %s' % port)
- else:
- print(' - %s -> %s' % (port, dst))
-
- def complete(self, sec_ids, text, line, begidx, endidx):
- """Completion for secondary process commands.
-
- Called from complete_sec() to complete secondary command.
- """
-
- try:
- cleaned_line = line
-
- if len(cleaned_line.split()) == 1:
- completions = [str(i)+";" for i in sec_ids]
- elif len(cleaned_line.split()) == 2:
- if not (";" in cleaned_line):
- tmplist = [str(i) for i in sec_ids]
- completions = [p+";"
- for p in tmplist
- if p.startswith(text)
- ]
- elif cleaned_line[-1] == ";":
- completions = self.SEC_CMDS[:]
- else:
- seccmd = cleaned_line.split(";")[1]
- if cleaned_line[-1] != " ":
- completions = [p
- for p in self.SEC_CMDS
- if p.startswith(seccmd)
- ]
- elif ("add" in seccmd) or ("del" in seccmd):
- completions = self.SEC_SUBCMDS[:]
- else:
- completions = []
- elif len(cleaned_line.split()) == 3:
- subcmd = cleaned_line.split()[-1]
- if ("add" == subcmd) or ("del" == subcmd):
- completions = self.SEC_SUBCMDS[:]
- else:
- if cleaned_line[-1] == " ":
- completions = []
- else:
- completions = [p
- for p in self.SEC_SUBCMDS
- if p.startswith(subcmd)
- ]
- else:
- completions = []
- return completions
- except Exception as e:
- print(len(cleaned_line.split()))
- print(e)
diff --git a/src/controller/shell.py b/src/controller/shell.py
index 84d4e2f..eafc5de 100644
--- a/src/controller/shell.py
+++ b/src/controller/shell.py
@@ -6,7 +6,7 @@ from __future__ import absolute_import
import cmd
from .commands import bye
from .commands import pri
-from .commands import sec
+from .commands import nfv
from .commands import topo
from .commands import vf
from .commands import mirror
@@ -42,7 +42,10 @@ class Shell(cmd.Cmd, object):
cmd.Cmd.__init__(self)
self.spp_ctl_cli = spp_ctl_cli
self.spp_primary = pri.SppPrimary(self.spp_ctl_cli)
- self.spp_secondary = sec.SppSecondary(self.spp_ctl_cli)
+
+ self.spp_nfvs = {}
+ for sec_id in self.get_sec_ids('nfv'):
+ self.spp_nfvs[sec_id] = nfv.SppNfv(self.spp_ctl_cli, sec_id)
self.spp_vfs = {}
for sec_id in self.get_sec_ids('vf'):
@@ -55,7 +58,7 @@ class Shell(cmd.Cmd, object):
self.spp_topo = topo.SppTopo(self.spp_ctl_cli, {}, self.topo_size)
self.spp_bye = bye.SppBye(self.spp_ctl_cli, self.spp_primary,
- self.spp_secondary)
+ self.spp_nfvs)
def default(self, line):
"""Define defualt behaviour.
@@ -141,7 +144,8 @@ class Shell(cmd.Cmd, object):
cnt = 1
for pt in ['nfv', 'vf', 'mirror']:
for obj in sec_obj[pt]:
- print(' %d: %s:%s' % (cnt, obj['type'], obj['client-id']))
+ print(' %d: %s:%s' %
+ (cnt, obj['type'], obj['client-id']))
cnt += 1
elif res.status_code in self.spp_ctl_cli.rest_common_error_codes:
pass
@@ -264,20 +268,19 @@ class Shell(cmd.Cmd, object):
return self.spp_primary.complete(text, line, begidx, endidx)
- def do_sec(self, cmd):
- """Send a command to secondary process specified with ID.
+ def do_nfv(self, cmd):
+ """Send a command to spp_nfv specified with ID.
- SPP secondary process is specified with secondary ID and takes
- sub commands.
+ Spp_nfv is specified with secondary ID and takes sub commands.
- spp > sec 1; status
- spp > sec 1; add ring:0
- spp > sec 1; patch phy:0 ring:0
+ spp > nfv 1; status
+ spp > nfv 1; add ring:0
+ spp > nfv 1; patch phy:0 ring:0
You can refer all of sub commands by pressing TAB after
- 'sec 1;'.
+ 'nfv 1;'.
- spp > sec 1; # press TAB
+ spp > nfv 1; # press TAB
add del exit forward patch status stop
"""
@@ -287,21 +290,44 @@ class Shell(cmd.Cmd, object):
if len(cmds) < 2:
print("Required an ID and ';' before the command.")
elif str.isdigit(cmds[0]):
- sec_id = int(cmds[0])
- if self.check_sec_cmds(cmds[1]):
- self.spp_secondary.run(sec_id, cmds[1])
- else:
- print("Invalid sec command")
+ self.spp_nfvs[int(cmds[0])].run(cmds[1])
else:
- print(cmds[0])
- print("first %s" % cmds[1])
+ print('Invalid command: %s' % tmparg)
- def complete_sec(self, text, line, begidx, endidx):
- """Completion for secondary process commands"""
+ def complete_nfv(self, text, line, begidx, endidx):
+ """Completion for nfv command"""
line = self.clean_cmd(line)
- return self.spp_secondary.complete(
- self.get_sec_ids('nfv'), text, line, begidx, endidx)
+
+ tokens = line.split(';')
+ if len(tokens) == 1:
+ # Add SppNfv of sec_id if it is not exist
+ sec_ids = self.get_sec_ids('nfv')
+ for idx in sec_ids:
+ if self.spp_nfvs[idx] is None:
+ self.spp_nfvs[idx] = nfv.SppNfv(self.spp_ctl_cli, idx)
+
+ if len(line.split()) == 1:
+ res = [str(i)+';' for i in sec_ids]
+ else:
+ if not (';' in line):
+ res = [str(i)+';'
+ for i in sec_ids
+ if (str(i)+';').startswith(text)]
+ return res
+ elif len(tokens) == 2:
+ first_tokens = tokens[0].split(' ') # 'nfv 1' => ['nfv', '1']
+ if len(first_tokens) == 2:
+ idx = int(first_tokens[1])
+
+ # Add SppVf of sec_id if it is not exist
+ if self.spp_nfvs[idx] is None:
+ self.spp_nfvs[idx] = nfv.SppNfv(self.spp_ctl_cli, idx)
+
+ res = self.spp_nfvs[idx].complete(self.get_sec_ids('nfv'),
+ text, line, begidx, endidx)
+ # logger.info(res)
+ return res
def do_vf(self, cmd):
"""Send a command to spp_vf.
@@ -451,7 +477,8 @@ class Shell(cmd.Cmd, object):
sec_ids = self.get_sec_ids('mirror')
for idx in sec_ids:
if self.spp_mirrors[idx] is None:
- self.spp_mirrors[idx] = mirror.SppMirror(self.spp_ctl_cli, idx)
+ self.spp_mirrors[idx] = mirror.SppMirror(
+ self.spp_ctl_cli, idx)
if len(line.split()) == 1:
res = [str(i)+';' for i in sec_ids]
@@ -469,7 +496,8 @@ class Shell(cmd.Cmd, object):
# Add SppMirror of sec_id if it is not exist
if self.spp_mirrors[idx] is None:
- self.spp_mirrors[idx] = mirror.SppMirror(self.spp_ctl_cli, idx)
+ self.spp_mirrors[idx] = mirror.SppMirror(
+ self.spp_ctl_cli, idx)
return self.spp_mirrors[idx].complete(
self.get_sec_ids('mirror'), text, line, begidx, endidx)
--
2.7.4
next prev parent reply other threads:[~2018-12-12 2:05 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-12 2:03 [spp] [PATCH 0/5] update SPP CLI ogawa.yasufumi
2018-12-12 2:03 ` ogawa.yasufumi [this message]
2018-12-12 2:03 ` [spp] [PATCH 2/5] controller: change to exclude used port from del ogawa.yasufumi
2018-12-12 2:03 ` [spp] [PATCH 3/5] controller: add checking for add and del cmds ogawa.yasufumi
2018-12-12 2:03 ` [spp] [PATCH 4/5] controller: refactor SppNfv class ogawa.yasufumi
2018-12-12 2:03 ` [spp] [PATCH 5/5] controller: update SppBye class ogawa.yasufumi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1544580195-9242-2-git-send-email-ogawa.yasufumi@lab.ntt.co.jp \
--to=ogawa.yasufumi@lab.ntt.co.jp \
--cc=ferruh.yigit@intel.com \
--cc=spp@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).