[spp] [PATCH 1/5] controller: add config command
ogawa.yasufumi at lab.ntt.co.jp
ogawa.yasufumi at lab.ntt.co.jp
Mon Feb 4 04:11:57 CET 2019
From: Yasufumi Ogawa <ogawa.yasufumi at lab.ntt.co.jp>
`config` command is for managing default configurations of SPP CLI.
For example, you can change default command prompt `spp > ` to another
one.
List of all of configurations is referred with `config`, or list of
started with `p` is referred with `config p`.
# show all configs
spp > config
- topo_size: "60%" # Percentage or ratio of topo
- prompt: "spp > " # Command prompt
...
# only started with `p`
spp > config p
- prompt: "spp > " # Command prompt
To change configuration, specify key and its value.
# set prompt
Set prompt: "$ spp "
$ spp
Signed-off-by: Yasufumi Ogawa <ogawa.yasufumi at lab.ntt.co.jp>
---
src/controller/commands/pri.py | 14 ++++--
src/controller/shell.py | 103 ++++++++++++++++++++++++++++++++++++++---
2 files changed, 105 insertions(+), 12 deletions(-)
diff --git a/src/controller/commands/pri.py b/src/controller/commands/pri.py
index b9f1234..b03524b 100644
--- a/src/controller/commands/pri.py
+++ b/src/controller/commands/pri.py
@@ -141,7 +141,7 @@ class SppPrimary(object):
rports['id'], rports['rx'], rports['tx'],
rports['rx_drop'], rports['tx_drop']))
- def complete(self, text, line, begidx, endidx):
+ def complete(self, text, line, begidx, endidx, cli_config, template):
"""Completion for primary process commands.
Called from complete_pri() to complete primary command.
@@ -150,8 +150,12 @@ class SppPrimary(object):
candidates = []
tokens = line.split(' ')
- base_core = 1 # shared among secondaries
- mytemplate = "-l {},{} -m 512 -- {} {} -s {}"
+ template = template.replace('__MEM__', cli_config['sec_mem']['val'])
+ template = template.replace('__BASE_LCORE__', cli_config['sec_base_lcore']['val'])
+ if cli_config['sec_vhost_cli']['val']:
+ template = template.replace('__VHOST_CLI__', '--vhost-client')
+ else:
+ template = template.replace('__VHOST_CLI__', '')
if tokens[0].endswith(';'):
@@ -195,8 +199,8 @@ class SppPrimary(object):
elif ptype == 'pcap': # at least two cores
rest_core = '{}-{}'.format(int(sid), int(sid)+1)
- candidates = [mytemplate.format(
- base_core, rest_core, opt_sid, sid, server_addr)]
+ candidates = [template.format(
+ rest_core, opt_sid, sid, server_addr)]
if not text:
completions = candidates
diff --git a/src/controller/shell.py b/src/controller/shell.py
index e68ac63..8cf10e6 100644
--- a/src/controller/shell.py
+++ b/src/controller/shell.py
@@ -23,17 +23,43 @@ import subprocess
class Shell(cmd.Cmd, object):
"""SPP command prompt."""
- recorded_file = None
+ # Default config, but changed via `config` command
+ cli_config = {
+ 'prompt': {
+ 'val': 'spp > ', 'desc': 'Command prompt'},
+ 'topo_size': {
+ 'val': '60%', 'desc': 'Percentage or ratio of topo'},
+ 'sec_mem': {
+ 'val':'-m 512', 'desc': 'Mem size'},
+ 'sec_base_lcore': {
+ 'val': '1', 'desc': 'Shared lcore among secondaryes'},
+ 'sec_vf_nof_lcores': {
+ 'val': '3', 'desc': 'Number of lcores for vf workers'},
+ 'sec_vhost_cli': {
+ 'val': '', 'desc': 'Vhost client mode'},
+ }
+
+ # Setup template of `pri; launch`
+ template = "-l __BASE_LCORE__,{} "
+ template = template + "__MEM__ "
+ template = template + "-- "
+ template = template + "{} {} " # '-n 1' or '--client-id 1'
+ template = template + "-s {} " # '-s 192.168.1.100:6666'
+ template = template + "__VHOST_CLI__"
+
hist_file = os.path.expanduser('~/.spp_history')
+ PLUGIN_DIR = 'plugins'
# Commands not included in history
HIST_EXCEPT = ['bye', 'exit', 'history', 'redo']
+ # Shell settings which are reserved vars of Cmd class.
+ # `intro` is to be shown as a welcome message.
intro = 'Welcome to the SPP CLI. Type `help` or `?` to list commands.\n'
- prompt = 'spp > '
+ prompt = cli_config['prompt']['val'] # command prompt
- PLUGIN_DIR = 'plugins'
- topo_size = '60%'
+ # Recipe file to be recorded with `record` command
+ recorded_file = None
# setup history file
if os.path.exists(hist_file):
@@ -47,7 +73,8 @@ class Shell(cmd.Cmd, object):
self.spp_ctl_cli = spp_cli_objs[0]
self.use_cache = use_cache
self.init_spp_procs()
- self.spp_topo = topo.SppTopo(self.spp_ctl_cli, {}, self.topo_size)
+ self.spp_topo = topo.SppTopo(
+ self.spp_ctl_cli, {}, self.cli_config['topo_size']['val'])
common.set_current_server_addr(
self.spp_ctl_cli.ip_addr, self.spp_ctl_cli.port)
@@ -249,7 +276,7 @@ class Shell(cmd.Cmd, object):
"""Close record file"""
if self.recorded_file:
- print("closing file")
+ print("Closing file")
self.recorded_file.close()
self.recorded_file = None
@@ -331,7 +358,8 @@ class Shell(cmd.Cmd, object):
"""Completion for primary process commands."""
line = re.sub(r'\s+', " ", line)
- return self.primary.complete(text, line, begidx, endidx)
+ return self.primary.complete(text, line, begidx, endidx,
+ self.cli_config, self.template)
def do_nfv(self, cmd):
"""Send a command to spp_nfv specified with ID.
@@ -618,6 +646,67 @@ class Shell(cmd.Cmd, object):
def complete_playback(self, text, line, begidx, endidx):
return common.compl_common(text, line)
+ def do_config(self, args):
+ """Show or update config.
+
+ # show list of config
+ spp > config
+
+ # set prompt to "$ spp "
+ spp > config prompt "$ spp "
+ """
+
+ tokens = args.strip().split(' ')
+ if len(tokens) == 1:
+ key = tokens[0]
+ if key == '':
+ for k,v in self.cli_config.items():
+ print('- {}: "{}"\t# {}'.format(k, v['val'], v['desc']))
+ elif key in self.cli_config.keys():
+ print('- {}: "{}"\t# {}'.format(
+ key, self.cli_config[key]['val'],
+ self.cli_config[key]['desc']))
+ else:
+ res = {}
+ for k, v in self.cli_config.items():
+ if k.startswith(key):
+ res[k] = {'val': v['val'], 'desc': v['desc']}
+ for k, v in res.items():
+ print('- {}: "{}"\t# {}'.format(k, v['val'], v['desc']))
+
+ elif len(tokens) > 1:
+ key = tokens[0]
+ if key in self.cli_config.keys():
+ for s in ['"', "'"]:
+ args = args.replace(s, '')
+
+ # TODO(yasufum) add validation for given value
+ self.cli_config[key]['val'] = args[(len(key) + 1):]
+ print('Set {}: "{}"'.format(key, self.cli_config[key]['val']))
+
+ # Command prompt should be updated immediately
+ if key == 'prompt':
+ self.prompt = self.cli_config['prompt']['val']
+
+ def complete_config(self, text, line, begidx, endidx):
+ candidates = []
+ tokens = line.strip().split(' ')
+
+ if len(tokens) == 1:
+ candidates = self.cli_config.keys()
+ elif len(tokens) == 2:
+ if text:
+ candidates = self.cli_config.keys()
+
+ if not text:
+ completions = candidates
+ else:
+ logger.debug(candidates)
+ completions = [p for p in candidates
+ if p.startswith(text)
+ ]
+ return completions
+
def do_pwd(self, args):
"""Show corrent directory.
--
2.7.4
More information about the spp
mailing list