Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add show reboot-history #1154

Closed
wants to merge 82 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
e5e19ab
initial commit
sujinmkang Oct 9, 2020
60085a7
group the reboot cause show command
sujinmkang Oct 9, 2020
e1244a5
[setup.py] Pin external runtime dependencies at known working version…
jleveque Oct 9, 2020
c4b2b6c
group the reboot-cause history with reboot-cause
sujinmkang Oct 10, 2020
561d133
[README.md] Add instructions for setting up a build/test environment …
jleveque Oct 11, 2020
a71c72b
[show] Add 'show' CLI for system-health feature (#971)
shlomibitton Oct 12, 2020
b6af9f4
Fix expected neighbor when multiple ports connect to same neighbor (#…
lguohan Oct 13, 2020
3a7457c
[celestica] consutil to support customize tty device name (#1155)
sandycelestica Oct 13, 2020
d8977fe
read last reboot-cause from symlink file
sujinmkang Oct 13, 2020
9531e41
rename
sujinmkang Oct 13, 2020
fcd8647
lgtm
sujinmkang Oct 13, 2020
e66777b
fix test
sujinmkang Oct 13, 2020
29a7e78
fix ut
sujinmkang Oct 13, 2020
89b189c
ut
sujinmkang Oct 14, 2020
4659ee2
ut2
sujinmkang Oct 14, 2020
059cdca
Fix exception for ipaddress in python2 (#1164)
bingwang-ms Oct 14, 2020
a733df5
[watermarkstat] Add unit tests for watermarkstat show commands (#1157)
neethajohn Oct 14, 2020
e51d44f
[consutil] Fix issue where the show line command crash if no ttyUSB e…
Blueve Oct 15, 2020
c382d89
[config/console] Support update console configuration related command…
Blueve Oct 15, 2020
574726f
rename last reboot cause file and fix ut
sujinmkang Oct 15, 2020
28c23f0
review comments & fix ut
sujinmkang Oct 15, 2020
984ef40
ut fix
sujinmkang Oct 15, 2020
4220356
review comments
sujinmkang Oct 15, 2020
3b62af0
show/main.py
sujinmkang Oct 15, 2020
b96fb6b
remove redundant
sujinmkang Oct 16, 2020
c395e14
Modify fast-reboot script to use BGP service script to stop bgp servi…
vaibhavhd Oct 19, 2020
510d0ad
[consutil] Add brief option to show line command (#1176)
Blueve Oct 20, 2020
59a511d
[config/show] Add CLI support for proxy arp (#1168)
theasianpianist Oct 20, 2020
13bd06b
Fixes the issue with show interface counters and for pfc and queue co…
abdosi Oct 20, 2020
5c12ffd
review comments
sujinmkang Oct 21, 2020
ca92e36
[counterpoll] Disable Counter Poll When Entering Fast Reboot (#1174)
tahmed-dev Oct 21, 2020
f08d628
type
sujinmkang Oct 22, 2020
0c3a97f
Remove stdeb.cfg; no longer used now that we build as wheel (#1182)
jleveque Oct 23, 2020
5651b17
fix unit test
sujinmkang Oct 23, 2020
a060cf9
review comments
sujinmkang Oct 23, 2020
00a2570
fdbshow and nbrshow use SonicV2Connector with decode_responses=True, …
qiluo-msft Oct 24, 2020
f14bbe5
[CLI][show][platform] Added ASIC count in the output. (#1185)
smaheshm Oct 26, 2020
dfc73ac
review comments
sujinmkang Oct 26, 2020
e889212
[fwutil]: Set min log priority to INFO. (#1191)
nazariig Oct 26, 2020
987c433
^^
sujinmkang Oct 26, 2020
63c6733
Add license file, remove third-party licenses file (#1192)
jleveque Oct 27, 2020
1753f22
[show] remove 'device2interface_dict' in show interface neighbor expe…
lolyu Oct 27, 2020
f645a38
unit test coverage
sujinmkang Oct 27, 2020
d7e372b
fix expected_output
sujinmkang Oct 27, 2020
615c3b4
unit test
sujinmkang Oct 27, 2020
baeeed9
mock read file
sujinmkang Oct 28, 2020
2f33931
ut
sujinmkang Oct 28, 2020
2decd0c
ut
sujinmkang Oct 28, 2020
8af9aee
Show FG_NHG CLI Commands Added (#1056)
kktheballer Oct 29, 2020
ef5f212
[sfputil] Display 'N/A' for non-SFP ports (#1078)
PJHsieh Nov 2, 2020
b4a0ebe
fix unittest
sujinmkang Nov 2, 2020
9011750
Merge branch 'reboot-history' of https://github.com/sujinmkang/sonic-…
sujinmkang Nov 2, 2020
6d0452b
initial commit
sujinmkang Oct 9, 2020
b4075f6
group the reboot cause show command
sujinmkang Oct 9, 2020
8359c7b
group the reboot-cause history with reboot-cause
sujinmkang Oct 10, 2020
6f838c1
read last reboot-cause from symlink file
sujinmkang Oct 13, 2020
ac52429
rename
sujinmkang Oct 13, 2020
cc4f4e9
lgtm
sujinmkang Oct 13, 2020
b645c24
fix test
sujinmkang Oct 13, 2020
e9fb1fc
fix ut
sujinmkang Oct 13, 2020
c61191d
ut
sujinmkang Oct 14, 2020
b7a634c
ut2
sujinmkang Oct 14, 2020
6dce6ed
rename last reboot cause file and fix ut
sujinmkang Oct 15, 2020
c6f02ec
review comments & fix ut
sujinmkang Oct 15, 2020
17516c5
ut fix
sujinmkang Oct 15, 2020
81d0736
review comments
sujinmkang Oct 15, 2020
df9cfcf
show/main.py
sujinmkang Oct 15, 2020
cd282e9
remove redundant
sujinmkang Oct 16, 2020
e6b55ae
review comments
sujinmkang Oct 21, 2020
ac2eba5
type
sujinmkang Oct 22, 2020
b927ab7
fix unit test
sujinmkang Oct 23, 2020
212274d
review comments
sujinmkang Oct 23, 2020
f452276
review comments
sujinmkang Oct 26, 2020
2e8fad6
^^
sujinmkang Oct 26, 2020
fd2629f
unit test coverage
sujinmkang Oct 27, 2020
b59df08
fix expected_output
sujinmkang Oct 27, 2020
7d20f97
unit test
sujinmkang Oct 27, 2020
08817ad
mock read file
sujinmkang Oct 28, 2020
b18f0c4
ut
sujinmkang Oct 28, 2020
9489bb8
ut
sujinmkang Oct 28, 2020
517c2c5
fix unittest
sujinmkang Nov 2, 2020
02eb1c7
Merge branch 'reboot-history' of https://github.com/sujinmkang/sonic-…
sujinmkang Nov 3, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright 2016-2020 Microsoft, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,44 @@ This repository produces two packages, as follows:

A Python wheel package, containing all the Python source code for the command-line utilities

#### Setting up a build/test environment

The sonic-utilities package depends on a number of other packages, many of which are available via PyPI, but some are part of the SONiC codebase. When building/testing the package, setuptools/pip will attempt to install the packages available from PyPI. However, you will need to manually build and install the SONiC dependencies before attempting to build or test the package.

Currently, this list of dependencies is as follows:


- libyang_1.0.73_amd64.deb
- libyang-cpp_1.0.73_amd64.deb
- python2-yang_1.0.73_amd64.deb
- python3-yang_1.0.73_amd64.deb
- redis_dump_load-1.1-py2-none-any.whl
- swsssdk-2.0.1-py2-none-any.whl
- sonic_py_common-1.0-py2-none-any.whl
- sonic_config_engine-1.0-py2-none-any.whl
- sonic_yang_mgmt-1.0-py2-none-any.whl
- sonic_yang_models-1.0-py3-none-any.whl


A convenient alternative is to let the SONiC build system configure a build enviroment for you. This can be done by cloning the [sonic-buildimage](https://github.com/Azure/sonic-buildimage) repo, building the sonic-utilities package inside the Debian Buster slave container, and staying inside the container once the build finishes. During the build process, the SONiC build system will build and install all the necessary dependencies inside the container. After following the instructions to clone and initialize the sonic-buildimage repo, this can be done as follows:

1. Configure the build environment for an ASIC type (any type will do, here we use `generic`)
```
make configure PLATFORM=generic
```

2. Build the sonic-utilities Python wheel package inside the Buster slave container, and tell the build system to keep the container alive when finished
```
make NOJESSIE=1 NOSTRETCH=1 KEEP_SLAVE_ON=yes target/python-wheels/sonic_utilities-1.2-py2-none-any.whl
```

3. When the build finishes, your prompt will change to indicate you are inside the slave container. Change into the `src/sonic-utilities/` directory
```
user@911799f161a0:/sonic$ cd src/sonic-utilities/
```

4. You can now make changes to the sonic-utilities source and build the package or run unit tests with the commands below. When finished, you can exit the container by calling `exit`.

#### To build

```
Expand Down
30 changes: 0 additions & 30 deletions ThirdPartyLicenses.txt

This file was deleted.

88 changes: 87 additions & 1 deletion config/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,92 @@ def remove_console_setting(db, linenum):
ctx = click.get_current_context()
ctx.fail("Trying to delete console port setting, which is not present.")

#
# 'console remote_device' group ('config console remote_device ...')
#
@console.command('remote_device')
@clicommon.pass_db
@click.argument('linenum', metavar='<line_number>', required=True, type=click.IntRange(0, 65535))
@click.argument('devicename', metavar='<device_name>', required=False)
def upate_console_remote_device_name(db, linenum, devicename):
"""Update remote device name for a console line"""
config_db = db.cfgdb
ctx = click.get_current_context()

table = "CONSOLE_PORT"
dataKey = 'remote_device'

data = config_db.get_entry(table, linenum)
if data:
if dataKey in data and devicename == data[dataKey]:
# do nothing if the device name is same with existing configurtion
return
elif not devicename:
# remove configuration key from console setting if user not give a remote device name
data.pop(dataKey, None)
config_db.mod_entry(table, linenum, data)
elif isExistingSameDevice(config_db, devicename, table):
ctx.fail("Given device name {} has been used. Please enter a valid device name or remove the existing one !!".format(devicename))
else:
data[dataKey] = devicename
config_db.mod_entry(table, linenum, data)
else:
ctx.fail("Trying to update console port setting, which is not present.")

#
# 'console baud' group ('config console baud ...')
#
@console.command('baud')
@clicommon.pass_db
@click.argument('linenum', metavar='<line_number>', required=True, type=click.IntRange(0, 65535))
@click.argument('baud', metavar='<baud>', required=True, type=click.INT)
def update_console_baud(db, linenum, baud):
"""Update baud for a console line"""
config_db = db.cfgdb
ctx = click.get_current_context()

table = "CONSOLE_PORT"
dataKey = 'baud_rate'

data = config_db.get_entry(table, linenum)
if data:
baud = str(baud)
if dataKey in data and baud == data[dataKey]:
# do nothing if the baud is same with existing configurtion
return
else:
data[dataKey] = baud
config_db.mod_entry(table, linenum, data)
else:
ctx.fail("Trying to update console port setting, which is not present.")

#
# 'console flow_control' group ('config console flow_control ...')
#
@console.command('flow_control')
@clicommon.pass_db
@click.argument('mode', metavar='<mode>', required=True, type=click.Choice(["enable", "disable"]))
@click.argument('linenum', metavar='<line_number>', required=True, type=click.IntRange(0, 65535))
def update_console_flow_control(db, mode, linenum):
"""Update flow control setting for a console line"""
config_db = db.cfgdb
ctx = click.get_current_context()

table = "CONSOLE_PORT"
dataKey = 'flow_control'

innerMode = "1" if mode == "enable" else "0"

data = config_db.get_entry(table, linenum)
if data:
if dataKey in data and innerMode == data[dataKey]:
# do nothing if the flow control setting is same with existing configurtion
return
else:
data[dataKey] = innerMode
config_db.mod_entry(table, linenum, data)
else:
ctx.fail("Trying to update console port setting, which is not present.")

def isExistingSameDevice(config_db, deviceName, table):
"""Check if the given device name is conflict with existing device"""
Expand All @@ -73,4 +159,4 @@ def isExistingSameDevice(config_db, deviceName, table):
if "remote_device" in values and deviceName == values["remote_device"]:
return True

return False
return False
39 changes: 38 additions & 1 deletion config/vlan.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import click

import utilities_common.cli as clicommon

from time import sleep
from .utils import log

#
Expand Down Expand Up @@ -50,6 +51,42 @@ def del_vlan(db, vid):
db.cfgdb.set_entry('VLAN_MEMBER', k, None)
db.cfgdb.set_entry('VLAN', 'Vlan{}'.format(vid), None)

def restart_ndppd():
verify_swss_running_cmd = "docker container inspect -f '{{.State.Status}}' swss"
docker_exec_cmd = "docker exec -it swss {}"
ndppd_config_gen_cmd = "sonic-cfggen -d -t /usr/share/sonic/templates/ndppd.conf.j2,/etc/ndppd.conf"
ndppd_restart_cmd = "supervisorctl restart ndppd"

output = clicommon.run_command(verify_swss_running_cmd, return_cmd=True)

if output and output.strip() != "running":
click.echo(click.style('SWSS container is not running, changes will take effect the next time the SWSS container starts', fg='red'),)
return

clicommon.run_command(docker_exec_cmd.format(ndppd_config_gen_cmd), display_cmd=True)
sleep(3)
clicommon.run_command(docker_exec_cmd.format(ndppd_restart_cmd), display_cmd=True)


@vlan.command('proxy_arp')
@click.argument('vid', metavar='<vid>', required=True, type=int)
@click.argument('mode', metavar='<mode>', required=True, type=click.Choice(["enabled", "disabled"]))
@clicommon.pass_db
def config_proxy_arp(db, vid, mode):
"""Configure proxy ARP for a VLAN"""

log.log_info("'setting proxy ARP to {} for Vlan{}".format(mode, vid))

ctx = click.get_current_context()

vlan = 'Vlan{}'.format(vid)

if not clicommon.is_valid_vlan_interface(db.cfgdb, vlan):
ctx.fail("Interface {} does not exist".format(vlan))

db.cfgdb.set_entry('VLAN_INTERFACE', vlan, {"proxy_arp": mode})
click.echo('Proxy ARP setting saved to ConfigDB')
restart_ndppd()
#
# 'member' group ('config vlan member ...')
#
Expand Down
47 changes: 30 additions & 17 deletions consutil/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import re
import subprocess
import sys
import os
from swsssdk import ConfigDBConnector
from sonic_py_common import device_info
except ImportError as e:
raise ImportError("%s - required module not found" % str(e))

Expand All @@ -27,6 +29,8 @@
FLOW_KEY = "flow_control"
DEFAULT_BAUD = "9600"

FILENAME = "udevprefix.conf"

# QUIET == True => picocom will not output any messages, and pexpect will wait for console
# switch login or command line to let user interact with shell
# Downside: if console switch output ever does not match DEV_READY_MSG, program will think connection failed
Expand All @@ -37,19 +41,27 @@
DEV_READY_MSG = r"([Ll]ogin:|[Pp]assword:|[$>#])" # login prompt or command line prompt
TIMEOUT_SEC = 0.2

# runs command, exit if stderr is written to, returns stdout otherwise
# input: cmd (str), output: output of cmd (str)
def run_command(cmd):
platform_path, _ = device_info.get_paths_to_platform_and_hwsku_dirs()
PLUGIN_PATH = "/".join([platform_path, "plugins", FILENAME])

if os.path.exists(PLUGIN_PATH):
fp = open(PLUGIN_PATH, 'r')
line = fp.readlines()
DEVICE_PREFIX = "/dev/" + line[0]

# runs command, exit if stderr is written to and abort argument is ture, returns stdout, stderr otherwise
# input: cmd (str, bool), output: output of cmd (str) and error of cmd (str) if abort is not true
def run_command(cmd, abort=True):
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
output = proc.stdout.read()
error = proc.stderr.read()
if error != "":
if abort and error != "":
click.echo("Command resulted in error: {}".format(error))
sys.exit(ERR_CMD)
return output
return output if abort else (output, error)

# returns a list of all lines
def getAllLines():
def getAllLines(brief=False):
config_db = ConfigDBConnector()
config_db.connect()

Expand All @@ -61,16 +73,17 @@ def getAllLines():
line[LINE_KEY] = k
lines.append(line)

# Querying device directory to get all available console ports
cmd = "ls " + DEVICE_PREFIX + "*"
output = run_command(cmd)
availableTtys = output.split('\n')
availableTtys = list(filter(lambda dev: re.match(DEVICE_PREFIX + r"\d+", dev) != None, availableTtys))
for tty in availableTtys:
k = tty[len(DEVICE_PREFIX):]
if k not in keys:
line = { LINE_KEY: k }
lines.append(line)
# Querying device directory to get all available console ports
if not brief:
cmd = "ls " + DEVICE_PREFIX + "*"
output, _ = run_command(cmd, abort=False)
availableTtys = output.split('\n')
availableTtys = list(filter(lambda dev: re.match(DEVICE_PREFIX + r"\d+", dev) != None, availableTtys))
for tty in availableTtys:
k = tty[len(DEVICE_PREFIX):]
if k not in keys:
line = { LINE_KEY: k }
lines.append(line)
return lines

# returns a dictionary of busy lines and their info
Expand Down Expand Up @@ -119,4 +132,4 @@ def getLine(target, deviceBool=False):
lineNumber = line[LINE_KEY]
targetLine = line

return targetLine if lineNumber else None
return targetLine if lineNumber else None
9 changes: 5 additions & 4 deletions consutil/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ def consutil():

# 'show' subcommand
@consutil.command()
def show():
"""Show all lines and their info"""
lines = getAllLines()
@click.option('--brief', '-b', metavar='<brief_mode>', required=False, is_flag=True)
def show(brief):
"""Show all lines and their info include available ttyUSB devices unless specified brief mode"""
lines = getAllLines(brief)
busyLines = getBusyLines()

# sort lines for table rendering
Expand Down Expand Up @@ -59,7 +60,7 @@ def clear(target):
"""Clear preexisting connection to line"""
targetLine = getLine(target)
if not targetLine:
click.echo("Target [{}] does not exist".format(linenum))
click.echo("Target [{}] does not exist".format(target))
sys.exit(ERR_DEV)
lineNumber = targetLine[LINE_KEY]

Expand Down
35 changes: 35 additions & 0 deletions counterpoll/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#! /usr/bin/python -u

import click
import json
import swsssdk
from tabulate import tabulate

Expand Down Expand Up @@ -234,3 +235,37 @@ def show():

click.echo(tabulate(data, headers=header, tablefmt="simple", missingval=""))

def _update_config_db(status, filename):
""" Update counter configuration in config_db file """
with open(filename) as config_db_file:
config_db = json.load(config_db_file)

write_config_db = False
if "FLEX_COUNTER_TABLE" in config_db:
for counter, counter_config in config_db["FLEX_COUNTER_TABLE"].items():
if "FLEX_COUNTER_STATUS" in counter_config and \
counter_config["FLEX_COUNTER_STATUS"] is not status:
counter_config["FLEX_COUNTER_STATUS"] = status
write_config_db = True

if write_config_db:
with open(filename, 'w') as config_db_file:
json.dump(config_db, config_db_file, indent=4)

# Working on Config DB
@cli.group()
def config_db():
""" Config DB counter commands """

@config_db.command()
@click.argument("filename", default="/etc/sonic/config_db.json", type=click.Path(exists=True))
def enable(filename):
""" Enable counter configuration in config_db file """
_update_config_db("enable", filename)

@config_db.command()
@click.argument("filename", default="/etc/sonic/config_db.json", type=click.Path(exists=True))
def disable(filename):
""" Disable counter configuration in config_db file """
_update_config_db("disable", filename)

Loading