From e71321f6d6d75529d9e74602daa071742bd35b50 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Mon, 20 Jul 2020 18:19:13 -0700 Subject: [PATCH 1/4] show interface portchannel support for Multi ASIC Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- scripts/teamshow | 44 +++++++++++++++++++++++++++++++------------- show/main.py | 10 ++++++++-- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/scripts/teamshow b/scripts/teamshow index e38bf5affc..42ebd9a9dd 100755 --- a/scripts/teamshow +++ b/scripts/teamshow @@ -26,6 +26,13 @@ import subprocess import sys from tabulate import tabulate from natsort import natsorted +from utilities_common.multi_asic import MultiAsic +from utilities_common.multi_asic import run_on_all_asics +from utilities_common.multi_asic import multi_asic_args + +from sonic_device_util import get_npu_id_from_name +from utilities_common.multi_asic import multi_asic_args +from utilities_common.multi_asic import PORT_CHANNEL_OBJ PORT_CHANNEL_APPL_TABLE_PREFIX = "LAG_TABLE:" PORT_CHANNEL_CFG_TABLE_PREFIX = "PORTCHANNEL|" @@ -35,24 +42,31 @@ PORT_CHANNEL_MEMBER_APPL_TABLE_PREFIX = "LAG_MEMBER_TABLE:" PORT_CHANNEL_MEMBER_STATUS_FIELD = "status" class Teamshow(object): - def __init__(self): + def __init__(self,display_option, namespace_option): self.teams = [] self.teamsraw = {} self.summary = {} self.err = None - # setup db connection - self.db = swsssdk.SonicV2Connector(host="127.0.0.1") - self.db.connect(self.db.APPL_DB) - self.db.connect(self.db.CONFIG_DB) + self.db = None + self.multi_asic = MultiAsic(display_option, namespace_option) + + @run_on_all_asics + def get_teams_info(self): + self.get_portchannel_names() + self.get_teamdctl() + self.get_teamshow_result() def get_portchannel_names(self): """ Get the portchannel names from database. """ + self.teams = [] team_keys = self.db.keys(self.db.CONFIG_DB, PORT_CHANNEL_CFG_TABLE_PREFIX+"*") - if team_keys is None: - return - self.teams = [key[len(PORT_CHANNEL_CFG_TABLE_PREFIX):] for key in team_keys] + for key in team_keys: + team_name = key[len(PORT_CHANNEL_CFG_TABLE_PREFIX):] + if self.multi_asic.skip_display(PORT_CHANNEL_OBJ, team_name) is True: + continue + self.teams.append(team_name) def get_portchannel_status(self, port_channel_name): """ @@ -77,7 +91,7 @@ class Teamshow(object): Command: 'teamdctl state dump'. """ for team in self.teams: - teamdctl_cmd = 'teamdctl ' + team + ' state dump' + teamdctl_cmd = "sudo docker exec -it teamd{} teamdctl {} state dump".format(get_npu_id_from_name(self.multi_asic.current_namespace), team) p = subprocess.Popen(teamdctl_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) (output, err) = p.communicate() rc = p.wait() @@ -144,11 +158,15 @@ def main(): if os.geteuid() != 0: exit("This utility must be run as root") + parser = multi_asic_args() + args = parser.parse_args() + + display_option = args.display + namespace_option = args.namespace + try: - team = Teamshow() - team.get_portchannel_names() - team.get_teamdctl() - team.get_teamshow_result() + team = Teamshow(display_option, namespace_option) + team.get_teams_info() team.display_summary() except Exception as e: sys.exit(e.message) diff --git a/show/main.py b/show/main.py index b670596466..e440ece196 100755 --- a/show/main.py +++ b/show/main.py @@ -19,6 +19,7 @@ from swsssdk import ConfigDBConnector from swsssdk import SonicV2Connector from portconfig import get_child_ports +from utilities_common.multi_asic import multi_asic_click_options import mlnx @@ -1116,10 +1117,15 @@ def rif(interface, period, verbose): # 'portchannel' subcommand ("show interfaces portchannel") @interfaces.command() +@multi_asic_click_options @click.option('--verbose', is_flag=True, help="Enable verbose output") -def portchannel(verbose): +def portchannel(namespace, display, verbose): """Show PortChannel information""" - cmd = "sudo teamshow" + + namespace_option = "" if namespace is None else " -n {}".format(namespace) + + cmd = "sudo teamshow -d {} {}".format(display, namespace_option) + run_command(cmd, display_cmd=verbose) # From 194b619a5813e0c6a9804e16c94f658f414d6a41 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Thu, 30 Jul 2020 14:15:03 -0700 Subject: [PATCH 2/4] Minor change to use the new library Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- scripts/teamshow | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/scripts/teamshow b/scripts/teamshow index 42ebd9a9dd..bad28663eb 100755 --- a/scripts/teamshow +++ b/scripts/teamshow @@ -21,17 +21,16 @@ import json import os -import swsssdk import subprocess import sys + from tabulate import tabulate from natsort import natsorted + +from sonic_py_common.multi_asic_device_info import get_asic_id_from_name from utilities_common.multi_asic import MultiAsic from utilities_common.multi_asic import run_on_all_asics from utilities_common.multi_asic import multi_asic_args - -from sonic_device_util import get_npu_id_from_name -from utilities_common.multi_asic import multi_asic_args from utilities_common.multi_asic import PORT_CHANNEL_OBJ PORT_CHANNEL_APPL_TABLE_PREFIX = "LAG_TABLE:" @@ -91,7 +90,7 @@ class Teamshow(object): Command: 'teamdctl state dump'. """ for team in self.teams: - teamdctl_cmd = "sudo docker exec -it teamd{} teamdctl {} state dump".format(get_npu_id_from_name(self.multi_asic.current_namespace), team) + teamdctl_cmd = "sudo docker exec -it teamd{} teamdctl {} state dump".format(get_asic_id_from_name(self.multi_asic.current_namespace), team) p = subprocess.Popen(teamdctl_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) (output, err) = p.communicate() rc = p.wait() From a942c4bb70052ebf7be1b364b57144140727ed1a Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Tue, 18 Aug 2020 06:06:02 -0700 Subject: [PATCH 3/4] refactor to latest chnages Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- show/interfaces/portchannel.py | 60 ++++++++++++---------------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/show/interfaces/portchannel.py b/show/interfaces/portchannel.py index 1bc6df7465..ae14d1a34c 100644 --- a/show/interfaces/portchannel.py +++ b/show/interfaces/portchannel.py @@ -1,9 +1,13 @@ -import click -from tabulate import tabulate -from natsort import natsorted +import os +import sys +import click import utilities_common.cli as clicommon +from natsort import natsorted +from tabulate import tabulate +import utilities_common.multi_asic as multi_asic_util +from utilities_common.constants import PORT_CHANNEL_OBJ """ Script to show LAG and LAG member status in a summary view @@ -24,20 +28,6 @@ """ -import json -import os -import subprocess -import sys - -from tabulate import tabulate -from natsort import natsorted - -from sonic_py_common.multi_asic_device_info import get_asic_id_from_name -from utilities_common.multi_asic import MultiAsic -from utilities_common.multi_asic import run_on_all_asics -from utilities_common.multi_asic import multi_asic_args -from utilities_common.multi_asic import PORT_CHANNEL_OBJ - PORT_CHANNEL_APPL_TABLE_PREFIX = "LAG_TABLE:" PORT_CHANNEL_CFG_TABLE_PREFIX = "PORTCHANNEL|" PORT_CHANNEL_STATE_TABLE_PREFIX = "LAG_TABLE|" @@ -48,15 +38,15 @@ PORT_CHANNEL_MEMBER_STATUS_FIELD = "status" class Teamshow(object): - def __init__(self,display_option, namespace_option): + def __init__(self, namespace_option, display_option): self.teams = [] self.teamsraw = {} self.summary = {} self.err = None self.db = None - self.multi_asic = MultiAsic(display_option, namespace_option) + self.multi_asic = multi_asic_util.MultiAsic(display_option, namespace_option) - @run_on_all_asics + @multi_asic_util.run_on_multi_asic def get_teams_info(self): self.get_portchannel_names() self.get_teamdctl() @@ -143,7 +133,7 @@ def get_teamshow_result(self): pstate = self.db.get_all(self.db.STATE_DB, PORT_CHANNEL_MEMBER_STATE_TABLE_PREFIX+team+'|'+port) selected = True if pstate['runner.aggregator.selected'] == "true" else False if clicommon.get_interface_naming_mode() == "alias": - alias = clicommon.InterfaceAliasConverter(self.db2).name_to_alias(port) + alias = clicommon.InterfaceAliasConverter().name_to_alias(port) info["ports"] += alias + "(" else: info["ports"] += port + "(" @@ -167,22 +157,12 @@ def display_summary(self): output.append([team_id, 'PortChannel'+team_id, self.summary[team_id]['protocol'], self.summary[team_id]['ports']]) print tabulate(output, header) -def main(): - if os.geteuid() != 0: - exit("This utility must be run as root") - - parser = multi_asic_args() - args = parser.parse_args() - - display_option = args.display - namespace_option = args.namespace - - try: - team = Teamshow(display_option, namespace_option) - team.get_teams_info() - team.display_summary() - except Exception as e: - sys.exit(e.message) - -if __name__ == "__main__": - main() +# 'portchannel' subcommand ("show interfaces portchannel") +@click.command() +@multi_asic_util.multi_asic_click_options +@click.option('--verbose', is_flag=True, help="Enable verbose output") +def portchannel(namespace, display, verbose): + """Show PortChannel information""" + team = Teamshow(namespace, display) + team.get_teams_info() + team.display_summary() \ No newline at end of file From 0eaaa72158b8bda8430de232fe647d0166b50c7f Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Fri, 21 Aug 2020 09:08:59 -0700 Subject: [PATCH 4/4] Address review comments Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- show/interfaces/portchannel.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/show/interfaces/portchannel.py b/show/interfaces/portchannel.py index ae14d1a34c..ea027fa928 100644 --- a/show/interfaces/portchannel.py +++ b/show/interfaces/portchannel.py @@ -58,6 +58,8 @@ def get_portchannel_names(self): """ self.teams = [] team_keys = self.db.keys(self.db.CONFIG_DB, PORT_CHANNEL_CFG_TABLE_PREFIX+"*") + if team_keys is None: + return for key in team_keys: team_name = key[len(PORT_CHANNEL_CFG_TABLE_PREFIX):] if self.multi_asic.skip_display(PORT_CHANNEL_OBJ, team_name) is True: @@ -155,7 +157,7 @@ def display_summary(self): output = [] for team_id in natsorted(self.summary): output.append([team_id, 'PortChannel'+team_id, self.summary[team_id]['protocol'], self.summary[team_id]['ports']]) - print tabulate(output, header) + print(tabulate(output, header)) # 'portchannel' subcommand ("show interfaces portchannel") @click.command()