From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from tama50.ecl.ntt.co.jp (tama50.ecl.ntt.co.jp [129.60.39.147]) by dpdk.org (Postfix) with ESMTP id 869DB5B2E for ; Thu, 18 Oct 2018 13:25:36 +0200 (CEST) Received: from vc2.ecl.ntt.co.jp (vc2.ecl.ntt.co.jp [129.60.86.154]) by tama50.ecl.ntt.co.jp (8.13.8/8.13.8) with ESMTP id w9IBPZcX020290; Thu, 18 Oct 2018 20:25:35 +0900 Received: from vc2.ecl.ntt.co.jp (localhost [127.0.0.1]) by vc2.ecl.ntt.co.jp (Postfix) with ESMTP id 39702639489; Thu, 18 Oct 2018 20:25:35 +0900 (JST) Received: from localhost.localdomain (unknown [129.60.13.51]) by vc2.ecl.ntt.co.jp (Postfix) with ESMTP id 1A31063947C; Thu, 18 Oct 2018 20:25:35 +0900 (JST) From: ogawa.yasufumi@lab.ntt.co.jp To: spp@dpdk.org, ferruh.yigit@intel.com, ogawa.yasufumi@lab.ntt.co.jp Date: Thu, 18 Oct 2018 20:25:14 +0900 Message-Id: <20181018112518.77556-6-ogawa.yasufumi@lab.ntt.co.jp> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20181018112518.77556-1-ogawa.yasufumi@lab.ntt.co.jp> References: <20181018112518.77556-1-ogawa.yasufumi@lab.ntt.co.jp> X-TM-AS-MML: disable Subject: [spp] [PATCH 5/9] controller: move pri command to SppPrimary X-BeenThere: spp@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Soft Patch Panel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Oct 2018 11:25:37 -0000 From: Yasufumi Ogawa 'spp.py' includes many methods and vals for supporting several commands. Some of them are global and others are command's local. It would be hard to maintain if more commands are added to 'spp.py'. SppPrimary defines 'pri' command and its completion as in a separated module. It is intended to be used from Shell, which is derived from 'cmd.Cmd'. Signed-off-by: Yasufumi Ogawa --- src/controller/commands/__init__.py | 0 src/controller/commands/pri.py | 123 ++++++++++++++++++++++++++++++++++++ src/controller/shell.py | 108 ++----------------------------- 3 files changed, 129 insertions(+), 102 deletions(-) create mode 100644 src/controller/commands/__init__.py create mode 100644 src/controller/commands/pri.py diff --git a/src/controller/commands/__init__.py b/src/controller/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/controller/commands/pri.py b/src/controller/commands/pri.py new file mode 100644 index 0000000..b51138d --- /dev/null +++ b/src/controller/commands/pri.py @@ -0,0 +1,123 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2018 Nippon Telegraph and Telephone Corporation + + +class SppPrimary(object): + """Exec SPP primary command. + + SppPrimary class is intended to be used in Shell class as a delegator + for running 'pri' command. + + 'self.command()' is called from do_pri() and 'self.complete()' is called + from complete_pri() of both of which is defined in Shell. + """ + + # All of primary commands used for validation and completion. + PRI_CMDS = ['status', 'exit', 'clear'] + + def __init__(self, spp_ctl_cli): + self.spp_ctl_cli = spp_ctl_cli + + def run(self, cmd): + """Called from do_pri() to Send command to primary process.""" + + if not (cmd in self.PRI_CMDS): + print("Invalid pri command: '%s'" % cmd) + return None + + if cmd == 'status': + res = self.spp_ctl_cli.get('primary/status') + if res is not None: + if res.status_code == 200: + self.print_status(res.json()) + elif res.status_code in self.rest_common_error_codes: + # Print default error message + pass + else: + print('Error: unknown response.') + + elif cmd == 'clear': + res = self.spp_ctl_cli.delete('primary/status') + if res is not None: + if res.status_code == 204: + print('Clear port statistics.') + elif res.status_code in self.rest_common_error_codes: + pass + else: + print('Error: unknown response.') + + elif cmd == 'exit': + print('"pri; exit" is deprecated.') + + else: + print('Invalid pri command!') + + def print_status(self, json_obj): + """Parse SPP primary's status and print. + + Primary returns the status as JSON format, but it is just a little + long. + + { + "phy_ports": [ + { + "eth": "56:48:4f:12:34:00", + "id": 0, + "rx": 78932932, + "tx": 78932931, + "tx_drop": 1, + } + ... + ], + "ring_ports": [ + { + "id": 0, + "rx": 89283, + "rx_drop": 0, + "tx": 89283, + "tx_drop": 0 + }, + ... + ] + } + + It is formatted to be simple and more understandable. + + Physical Ports: + ID rx tx tx_drop mac_addr + 0 78932932 78932931 1 56:48:4f:53:54:00 + Ring Ports: + ID rx tx rx_drop rx_drop + 0 89283 89283 0 0 + ... + """ + + if 'phy_ports' in json_obj: + print('Physical Ports:') + print(' ID rx tx tx_drop mac_addr') + for pports in json_obj['phy_ports']: + print(' %2d %10d %10d %10d %s' % ( + pports['id'], pports['rx'], pports['tx'], + pports['tx_drop'], pports['eth'])) + + if 'ring_ports' in json_obj: + print('Ring Ports:') + print(' ID rx tx rx_drop rx_drop') + for rports in json_obj['ring_ports']: + print(' %2d %10d %10d %10d %10d' % ( + rports['id'], rports['rx'], rports['tx'], + rports['rx_drop'], rports['tx_drop'])) + + def complete(self, text, line, begidx, endidx): + """Completion for primary process commands. + + Called from complete_pri() to complete primary command. + """ + + if not text: + completions = self.PRI_CMDS[:] + else: + completions = [p for p in self.PRI_CMDS + if p.startswith(text) + ] + return completions diff --git a/src/controller/shell.py b/src/controller/shell.py index f1c9ccd..9834df0 100644 --- a/src/controller/shell.py +++ b/src/controller/shell.py @@ -1,10 +1,10 @@ -#!/usr/bin/env python # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2015-2016 Intel Corporation from __future__ import absolute_import import cmd +from .commands import pri import os import re import readline @@ -27,7 +27,6 @@ class Shell(cmd.Cmd, object): PORT_TYPES = ['phy', 'ring', 'vhost', 'pcap', 'nullpmd'] - PRI_CMDS = ['status', 'exit', 'clear'] SEC_CMDS = ['status', 'exit', 'forward', 'stop', 'add', 'patch', 'del'] SEC_SUBCMDS = ['vhost', 'ring', 'pcap', 'nullpmd'] BYE_CMDS = ['sec', 'all'] @@ -49,6 +48,7 @@ class Shell(cmd.Cmd, object): def __init__(self, spp_ctl_cli): cmd.Cmd.__init__(self) self.spp_ctl_cli = spp_ctl_cli + self.spp_primary = pri.SppPrimary(self.spp_ctl_cli) def default(self, line): """Define defualt behaviour. @@ -131,62 +131,6 @@ class Shell(cmd.Cmd, object): else: print('Error: unknown response.') - def print_pri_status(self, json_obj): - """Parse SPP primary's status and print. - - Primary returns the status as JSON format, but it is just a little - long. - - { - "phy_ports": [ - { - "eth": "56:48:4f:12:34:00", - "id": 0, - "rx": 78932932, - "tx": 78932931, - "tx_drop": 1, - } - ... - ], - "ring_ports": [ - { - "id": 0, - "rx": 89283, - "rx_drop": 0, - "tx": 89283, - "tx_drop": 0 - }, - ... - ] - } - - It is formatted to be simple and more understandable. - - Physical Ports: - ID rx tx tx_drop mac_addr - 0 78932932 78932931 1 56:48:4f:53:54:00 - Ring Ports: - ID rx tx rx_drop rx_drop - 0 89283 89283 0 0 - ... - """ - - if 'phy_ports' in json_obj: - print('Physical Ports:') - print(' ID rx tx tx_drop mac_addr') - for pports in json_obj['phy_ports']: - print(' %2d %10d %10d %10d %s' % ( - pports['id'], pports['rx'], pports['tx'], - pports['tx_drop'], pports['eth'])) - - if 'ring_ports' in json_obj: - print('Ring Ports:') - print(' ID rx tx rx_drop rx_drop') - for rports in json_obj['ring_ports']: - print(' %2d %10d %10d %10d %10d' % ( - rports['id'], rports['rx'], rports['tx'], - rports['rx_drop'], rports['tx_drop'])) - def print_sec_status(self, json_obj): """Parse and print message from SPP secondary. @@ -218,35 +162,6 @@ class Shell(cmd.Cmd, object): else: print(' - %s -> %s' % (port, dst)) - def command_primary(self, command): - """Send command to primary process""" - - if command == 'status': - res = self.spp_ctl_cli.get('primary/status') - if res is not None: - if res.status_code == 200: - self.print_pri_status(res.json()) - elif res.status_code in self.rest_common_error_codes: - pass - else: - print('Error: unknown response.') - - elif command == 'clear': - res = self.spp_ctl_cli.delete('primary/status') - if res is not None: - if res.status_code == 204: - print('Clear port statistics.') - elif res.status_code in self.rest_common_error_codes: - pass - else: - print('Error: unknown response.') - - elif command == 'exit': - print('"pri; exit" is deprecated.') - - else: - print('Invalid pri command!') - def command_secondary(self, sec_id, command): """Send command to secondary process.""" @@ -442,23 +357,12 @@ class Shell(cmd.Cmd, object): if logger is not None: logger.info("Receive pri command: '%s'" % command) - if command and (command in self.PRI_CMDS): - self.command_primary(command) - else: - message = "Invalid pri command: '%s'" % command - print(message) + self.spp_primary.run(command) def complete_pri(self, text, line, begidx, endidx): - """Completion for primary process commands""" + """Completion for primary process commands.""" - if not text: - completions = self.PRI_CMDS[:] - else: - completions = [p - for p in self.PRI_CMDS - if p.startswith(text) - ] - return completions + return self.spp_primary.complete(text, line, begidx, endidx) def do_sec(self, arg): """Send a command to secondary process specified with ID. @@ -666,7 +570,7 @@ class Shell(cmd.Cmd, object): print('Closing secondary ...') self.close_all_secondary() print('Closing primary ...') - self.command_primary('exit') + self.spp_primary.run('exit') elif cmds[0] == '': print('Thank you for using Soft Patch Panel') self.close() -- 2.13.1