From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mogw0735.ocn.ad.jp (mogw0735.ocn.ad.jp [153.149.232.36]) by dpdk.org (Postfix) with ESMTP id 869A95F0F for ; Tue, 6 Mar 2018 11:51:25 +0100 (CET) Received: from mf-smf-ucb020c3 (mf-smf-ucb020c3.ocn.ad.jp [153.153.66.135]) by mogw0735.ocn.ad.jp (Postfix) with ESMTP id E722B1280237; Tue, 6 Mar 2018 19:51:23 +0900 (JST) Received: from ntt.pod01.mv-mta-ucb027 ([153.149.142.101]) by mf-smf-ucb020c3 with ESMTP id tABnejrUBQ0QOtABnetdgP; Tue, 06 Mar 2018 19:51:23 +0900 Received: from smtp.ocn.ne.jp ([153.149.227.165]) by ntt.pod01.mv-mta-ucb027 with id JarP1x00F3akymp01arPp4; Tue, 06 Mar 2018 10:51:23 +0000 Received: from localhost.localdomain (sp1-66-103-93.msc.spmode.ne.jp [1.66.103.93]) by smtp.ocn.ne.jp (Postfix) with ESMTPA; Tue, 6 Mar 2018 19:51:23 +0900 (JST) From: ogawa.yasufumi@lab.ntt.co.jp To: ferruh.yigit@intel.com, spp@dpdk.org Cc: Yasufumi Ogawa Date: Tue, 6 Mar 2018 19:50:51 +0900 Message-Id: <20180306105055.65210-10-ogawa.yasufumi@lab.ntt.co.jp> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20180306105055.65210-1-ogawa.yasufumi@lab.ntt.co.jp> References: <20180306105055.65210-1-ogawa.yasufumi@lab.ntt.co.jp> Subject: [spp] [PATCH 09/13] controller: add do_topo to shell.py 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: Tue, 06 Mar 2018 10:51:25 -0000 From: Yasufumi Ogawa 'topo' is an experimental command for SPP controller to outptu topology of network configuration. It enables to display a graphical image of network configuration on terminal, or browser for which websocket server is running with. 'topo' command supports four types of output. For multiple output support, it uses graphviz, imagemagick and other external tools. * terminal (but very few terminals supporting to display images) * browser (websocket server is required) * image file (jpg, png, bmp) * text (dot, json, yaml) Here is a list of required tools for 'topo'. Notice that SPP controller and 'topo' command support MacOS on a remote host. * graphviz * imagemagick * libsixel-bin (for Ubuntu) and terminal app supporting img2sixel * iTerm2 and imgcat (for MacOS) For terminal, only few terminal applications are supported. You can use mlterm or xterm for which 'img2sixel' supports on linux or iTerm on MacOS. If you use iTerm2, you have to get a shell script 'imgcat' from [1] and save it as 'spp/src/controller/3rd_party/imgcat.sh'. [1] https://iterm2.com/documentation-images.html For browser support, you are required to install websocket libraries and use 'spp_ws' tool. 'spp_ws' is not released yet, but soon. There are some example usecases. (1) Display on terminal or browser. spp > topo term spp > topo http (2) Output to a file. spp > topo myconfig.jpg spp > topo myconfig dot This update is only for 'shell.py' and requires a module file 'topo.py' in which methods for 'topo' command are implemented. Signed-off-by: Yasufumi Ogawa --- src/controller/shell.py | 85 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/src/controller/shell.py b/src/controller/shell.py index c5ef82d..8a0580a 100644 --- a/src/controller/shell.py +++ b/src/controller/shell.py @@ -7,6 +7,7 @@ from shell_lib import common import spp_common from spp_common import logger import subprocess +import topo class Shell(cmd.Cmd, object): @@ -481,7 +482,89 @@ class Shell(cmd.Cmd, object): from pprint import pprint if args == '': pprint(vars(self)) - pprint(self.__class__.__name__) + + def do_topo(self, args): + """Output network topology + + Support four types of output. + * terminal (but very few terminals supporting to display images) + * browser (websocket server is required) + * image file (jpg, png, bmp) + * text (dot, json, yaml) + + spp > topo term # terminal + spp > topo http # browser + spp > topo network_conf.jpg # image + spp > topo network_conf.dot # text + """ + + if len(spp_common.SECONDARY_LIST) == 0: + message = "secondary not exist" + print(message) + self.response(self.CMD_NOTREADY, message) + else: + tp = topo.Topo( + spp_common.SECONDARY_LIST, + spp_common.MAIN2SEC, + spp_common.SEC2MAIN) + args_ary = args.split() + if len(args_ary) == 0: + print("Usage: topo dst [ftype]") + return False + elif (args_ary[0] == "term") or (args_ary[0] == "http"): + res_ary = tp.show(args_ary[0]) + elif len(args_ary) == 1: + ftype = args_ary[0].split(".")[-1] + res_ary = tp.output(args_ary[0], ftype) + elif len(args_ary) == 2: + res_ary = tp.output(args_ary[0], args_ary[1]) + else: + print("Usage: topo dst [ftype]") + return False + self.response(self.CMD_OK, json.dumps(res_ary)) + + def complete_topo(self, text, line, begidx, endidx): + """Complete topo command + + If no token given, return 'term' and 'http'. + On the other hand, complete 'term' or 'http' if token starts + from it, or complete file name if is one of supported formats. + """ + + terms = ['term', 'http'] + # Supported formats + img_exts = ['jpg', 'png', 'bmp'] + txt_exts = ['dot', 'yml', 'js'] + + # Number of given tokens is expected as two. First one is + # 'topo'. If it is three or more, this methods returns nothing. + tokens = re.sub(r"\s+", " ", line).split(' ') + if (len(tokens) == 2): + if (text == ''): + completions = terms + else: + completions = [] + # Check if 2nd token is a part of terms. + for t in terms: + if t.startswith(tokens[1]): + completions.append(t) + # Not a part of terms, so check for completion for + # output file name. + if len(completions) == 0: + if tokens[1].endswith('.'): + completions = img_exts + txt_exts + elif ('.' in tokens[1]): + fname = tokens[1].split('.')[0] + token = tokens[1].split('.')[-1] + for ext in img_exts: + if ext.startswith(token): + completions.append(fname + '.' + ext) + for ext in txt_exts: + if ext.startswith(token): + completions.append(fname + '.' + ext) + return completions + else: # do nothing for three or more tokens + pass def do_load_cmd(self, args): """Load command plugin -- 2.13.1