diff --git a/config/main.py b/config/main.py index ed2f131298..ace8643b99 100644 --- a/config/main.py +++ b/config/main.py @@ -93,6 +93,18 @@ def _abort_if_false(ctx, param, value): if not value: ctx.abort() +def _restart_services(): + run_command("service interfaces-config restart", display_cmd=True) + run_command("service ntp-config restart", display_cmd=True) + run_command("service rsyslog-config restart", display_cmd=True) + run_command("service swss restart", display_cmd=True) + run_command("service bgp restart", display_cmd=True) + run_command("service teamd restart", display_cmd=True) + run_command("service pmon restart", display_cmd=True) + run_command("service lldp restart", display_cmd=True) + run_command("service snmp restart", display_cmd=True) + run_command("service dhcp_relay restart", display_cmd=True) + # This is our main entrypoint - the main 'config' command @click.group() def cli(): @@ -131,6 +143,12 @@ def reload(filename): command = "{} -j {} --write-to-db".format(SONIC_CFGGEN_PATH, filename) run_command(command, display_cmd=True) client.set(config_db.INIT_INDICATOR, True) + command = "{} -j {} -v \"DEVICE_METADATA['localhost']['hostname']\"".format(SONIC_CFGGEN_PATH, filename) + p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + p.wait() + hostname = p.communicate()[0].strip() + _change_hostname(hostname) + _restart_services() @cli.command() @click.option('-y', '--yes', is_flag=True, callback=_abort_if_false, @@ -177,16 +195,7 @@ def load_minigraph(): hostname = p.communicate()[0].strip() _change_hostname(hostname) #FIXME: After config DB daemon is implemented, we'll no longer need to restart every service. - run_command("service interfaces-config restart", display_cmd=True) - run_command("service ntp-config restart", display_cmd=True) - run_command("service rsyslog-config restart", display_cmd=True) - run_command("service swss restart", display_cmd=True) - run_command("service bgp restart", display_cmd=True) - run_command("service teamd restart", display_cmd=True) - run_command("service pmon restart", display_cmd=True) - run_command("service lldp restart", display_cmd=True) - run_command("service snmp restart", display_cmd=True) - run_command("service dhcp_relay restart", display_cmd=True) + _restart_services() print "Please note setting loaded from minigraph will be lost after system reboot. To preserve setting, run `config save`." # # 'bgp' group diff --git a/pfcwd/main.py b/pfcwd/main.py index 2f54ef0b3a..288b10e0ad 100644 --- a/pfcwd/main.py +++ b/pfcwd/main.py @@ -3,6 +3,7 @@ import click import swsssdk from tabulate import tabulate +from natsort import natsorted STATS_DESCRIPTION = [ ('STORM DETECTED CNT', 'PFC_WD_QUEUE_STATS_DEADLOCK_DETECTED'), @@ -17,7 +18,14 @@ ('RX PACKETS LAST DROP', 'PFC_WD_QUEUE_STATS_RX_DROPPED_PACKETS_LAST') ] +CONFIG_DESCRIPTION = [ + ('ACTION', 'action', 'drop'), + ('DETECTION TIME', 'detection_time', 'N/A'), + ('RESTORATION TIME', 'restoration_time', 'infinite') +] + STATS_HEADER = ('QUEUE',) + zip(*STATS_DESCRIPTION)[0] +CONFIG_HEADER = ('PORT',) + zip(*CONFIG_DESCRIPTION)[0] # Main entrypoint @click.group() @@ -26,13 +34,22 @@ def cli(): def get_all_queues(db): queue_names = db.get_all(db.COUNTERS_DB, 'COUNTERS_QUEUE_NAME_MAP') - return sorted(queue_names.keys()) + return natsorted(queue_names.keys()) + +def get_all_ports(db): + port_names = db.get_all(db.COUNTERS_DB, 'COUNTERS_PORT_NAME_MAP') + return natsorted(port_names.keys()) + +# Show commands +@cli.group() +def show(): + """ Show PFC Watchdog information""" # Show stats -@cli.command() +@show.command() @click.argument('queues', nargs = -1) def stats(queues): - """ Show PFC WD stats per queue """ + """ Show PFC Watchdog stats per queue """ db = swsssdk.SonicV2Connector(host='127.0.0.1') db.connect(db.COUNTERS_DB) table = [] @@ -49,10 +66,89 @@ def stats(queues): for stat in STATS_DESCRIPTION: line = stats.get(stat[1], '0') stats_list.append(line) - #click.echo("Queue ID " + queue) table.append([queue] + stats_list) - print(tabulate(table, STATS_HEADER, stralign='right', numalign='right', tablefmt='simple')) + click.echo(tabulate(table, STATS_HEADER, stralign='right', numalign='right', tablefmt='simple')) + +# Show stats +@show.command() +@click.argument('ports', nargs = -1) +def config(ports): + """ Show PFC Watchdog configuration """ + configdb = swsssdk.ConfigDBConnector() + configdb.connect() + countersdb = swsssdk.SonicV2Connector(host='127.0.0.1') + countersdb.connect(countersdb.COUNTERS_DB) + table = [] + + all_ports = get_all_ports(countersdb) + + if len(ports) == 0: + ports = all_ports + + for port in ports: + config_list = [] + config_entry = configdb.get_entry('PFC_WD_TABLE', port) + if config_entry is None or config_entry == {}: + continue + for config in CONFIG_DESCRIPTION: + line = config_entry.get(config[1], config[2]) + config_list.append(line) + table.append([port] + config_list) + + click.echo(tabulate(table, CONFIG_HEADER, stralign='right', numalign='right', tablefmt='simple')) + +# Start WD +@cli.command() +@click.option('--action', '-a', type=click.Choice(['drop', 'forward', 'alert'])) +@click.option('--restoration-time', '-r', type=click.IntRange(100, 5000)) +@click.argument('ports', nargs = -1) +@click.argument('detection-time', type=click.IntRange(100, 60000)) +def start(action, restoration_time, ports, detection_time): + """ Start PFC watchdog on port(s) """ + configdb = swsssdk.ConfigDBConnector() + configdb.connect() + countersdb = swsssdk.SonicV2Connector(host='127.0.0.1') + countersdb.connect(countersdb.COUNTERS_DB) + + all_ports = get_all_ports(countersdb) + + if len(ports) == 0: + ports = all_ports + + pfcwd_info = { + 'detection_time': detection_time, + } + if action is not None: + pfcwd_info['action'] = action + if restoration_time is not None: + pfcwd_info['restoration_time'] = restoration_time + + for port in ports: + if port not in all_ports: + continue + configdb.set_entry("PFC_WD_TABLE", port, None) + configdb.set_entry("PFC_WD_TABLE", port, pfcwd_info) + +# Stop WD +@cli.command() +@click.argument('ports', nargs = -1) +def stop(ports): + """ Stop PFC watchdog on port(s) """ + configdb = swsssdk.ConfigDBConnector() + configdb.connect() + countersdb = swsssdk.SonicV2Connector(host='127.0.0.1') + countersdb.connect(countersdb.COUNTERS_DB) + + all_ports = get_all_ports(countersdb) + + if len(ports) == 0: + ports = all_ports + + for port in ports: + if port not in all_ports: + continue + configdb.set_entry("PFC_WD_TABLE", port, None) if __name__ == '__main__': cli()