sonic-net / sonic-py-swsssdk Goto Github PK
View Code? Open in Web Editor NEWPython SONiC switch state service sdk
License: Other
Python SONiC switch state service sdk
License: Other
Sonic counts on DBInterface code here to set notify-keyspace-events as AKE for each db. This is done through calling sonic-db-cli in postStart() from database.sh.
It worked well as long as we start redis server from docker-database container for all dbs. Now we start to support sonic voq chassis and have a separate container, docker-database-chassis, to start all chassis dbs in new redis server instance. The chassis container starts before database container, as a result, sonic-db-cli PING
wont work for it since not all dbs are available at that time.
The solution is to enhance sonic-db-cli to ping dbs from a given redis server instance, something like this: sonic-db-cl PING -i redis-chassis
root@sonic:~# python3
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
import swsssdk
db = swsssdk.ConfigDBConnector()
db.connect()
cfg = db.get_config()
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python3.5/dist-packages/swsssdk-2.0.1-py3.5.egg/swsssdk/configdb.py", line 284, in get_config
(table_name, row) = key.split(self.TABLE_NAME_SEPARATOR, 1)
TypeError: a bytes-like object is required, not 'str'
FIX:
Current code:
for key in keys:
try:
(table_name, row) = key.split(self.TABLE_NAME_SEPARATOR, 1)
Proposed code change:
for key in keys:
if PY3K:
key = key.decode('utf-8')
try:
(table_name, row) = key.split(self.TABLE_NAME_SEPARATOR, 1)
From: [email protected] [mailto:[email protected]] On Behalf Of Haiyang Zheng
Sent: Wednesday, October 25, 2017 7:02 PM
To: sonicproject [email protected]
Subject: Re: [SONiC] configdb.py unable to get tables with NULL Value
Thanks Taoyu for the quick reply.
sonic-cfggen -d -v NTP_SERVER also works for me.
However, I'm trying to using the config db python sdk, which return {} for the NTP_SERVER without my change.
admin@OCPSCH01040HHLF:~$ sonic-cfggen -d -v NTP_SERVER
{'10.34.14.107': {}}
admin@OCPSCH01040HHLF:~$ sudo sw config ntp -i 10.34.14.123 -s 10.34.14.107
{}
admin@OCPSCH01040HHLF:~$ cat /usr/lib/python2.7/dist-packages/switch/switch.py
@click.command()
@click.option('-i','--src-ip', required=True, help="Set the source ip")
@click.option('-s','--server-list', required=True, help="Set the server list with , as delimiter, e.g. Server1,Server2,...")
def ntp(src_ip, server_list):
"""Set the ntp src_ip and server_list"""
config_db = ConfigDBConnector()
config_db.connect()
data = config_db.get_table('NTP_SERVER')
print data ==> this is returning {}
for key in data:
print "NTP_SERVER key: "+key
set_config_db_entry('NTP_SERVER', key, None)
Sometimes, sonic-mgmt need check values in redis db by calling "sonic-db-cli $DB HGETALL $KEY". And it would be great if the output of such command can be parsed to a python dictionary easily.
However, sonic-db-cli now return raw string for hgetall comamnd. For example:
admin@r-leopard-01:~$ sonic-db-cli CONFIG_DB HGETALL "TELEMETRY|gnmi"
{'client_auth': 'false', 'log_level': '2', 'port': '50051'}
Python json module cannot parse such string to a dictionary:
{'client_auth': 'false', 'log_level': '2', 'port': '50051'}
I would suggest to change the following code in sonic-db-cli from:
if resp is None:
print()
elif isinstance(resp, list):
print("\n".join(resp))
else:
print(resp)
to
if resp is None:
print()
elif isinstance(resp, list):
print("\n".join(resp))
elif isinstance(resp, dict):
json.dumps(resp)
else:
print(resp)
Any thought?
Is SONiC v1 support no longer needed/working?
If created SonicV2Connector object with wrong password and try connecting to a database like following:
sonic_db=swsssdk.SonicV2Connector(password="wrong_password")
sonic_db.connect("COUNTERS_DB")
swsssdk infinitely logging following warning messages and application is blocked forever, In case of wrong password a specific exception should be raised and function interface.py->_persistent_connect() should return immediately rather than retrying infinitely.
[2022-09-13 16:37:21,960][WARNING][swsssdk] Connecting to DB '2 COUNTERS_DB' failed, will retry in 10s
related issue - https://github.com/STORDIS/monsoon/issues/7
I need to remove the key of table entry from config db, but class ConfigDBConnector have no method to do it.
Hi All,
I have the following function to add an IP interface to SONiC. After calling this function I can see the newly created entry using redis-cli but look like new configuration hasn't been applied to HW.
I couldn't find the new interface with "ifconfig", "show interface summary" and ping commands
What else do we need to do here to notify the syncd service to write changes to ASIC?
Thanks,
def add_ip_inf(self, infName, ipAddr, mask):
db = swsssdk.ConfigDBConnector()
db.connect()
fullAddr = "{}/{}".format(ipAddr, mask)
# Add IP interface
try:
if infName.startswith("Ethernet"):
resp = db.set_entry("INTERFACE", (infName, fullAddr), {"NULL": "NULL"})
elif infName.startswith("PortChannel"):
resp = db.set_entry("PORTCHANNEL_INTERFACE", (infName, fullAddr), {"NULL": "NULL"})
elif infName.startswith("Vlan"):
resp = db.set_entry("VLAN_INTERFACE", (infName, fullAddr), {"NULL": "NULL"})
status = True
except Exception as e:
status = False
resp = str(e)
return status
when I run my python codefiles, this code line "from swsssdk import ConfigDBConnector" report error:
ImportError: No module named swsssdk
how can I run sonic python code file normally ?please give some help.thanks
Based on the description in https://redis.io/topics/notifications:
"
Because Redis Pub/Sub is fire and forget currently there is no way to use this feature if your application demands reliable notification of events, that is, if your Pub/Sub client disconnects, and reconnects later, all the events delivered during the time the client was disconnected are lost.
"
It looks to me there is possibility the INIT_INDICATOR is set between client.get() and pubsub.psubscribe(pattern), the notification might get missed and pubsub.listen() will be blocked there, unless client buffers all notification from the moment of client.pubsub()
def __wait_for_db_init(self):
client = self.redis_clients[self.CONFIG_DB]
pubsub = client.pubsub()
initialized = client.get(self.INIT_INDICATOR)
if not initialized:
pattern = "__keyspace@{}__:{}".format(self.db_map[self.CONFIG_DB]['db'], self.INIT_INDICATOR)
pubsub.psubscribe(pattern)
for item in pubsub.listen():
lldp-syncd generate LLDP_ENTRY_TABLE and sync to redis one field after one.
this may cause the snmp agent with below syslog from time to time, because snmp agent update may interleaving the hset operations.
i suggest the py-swsssdk support hmset command, and lldp-syncd use this interface to avoid the syslog.
Jul 16 18:16:42.268005 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Error updating remote mgmt addr: b'lldp_rem_time_mark' Jul 16 19:04:20.220476 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark' Jul 16 21:45:27.373210 dut-testbed-225 WARNING snmp#snmp-subagent message repeated 4 times: [ [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark'] Jul 16 21:45:27.373210 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Error updating remote mgmt addr: b'lldp_rem_time_mark' Jul 16 21:49:50.834105 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark' Jul 17 03:55:51.676539 dut-testbed-225 WARNING snmp#snmp-subagent message repeated 11 times: [ [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark'] Jul 17 03:55:51.676835 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Error updating remote mgmt addr: b'lldp_rem_time_mark' Jul 17 04:19:30.444283 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark' Jul 17 06:46:16.750943 dut-testbed-225 WARNING snmp#snmp-subagent message repeated 4 times: [ [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark'] Jul 17 06:46:16.751034 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Error updating remote mgmt addr: b'lldp_rem_time_mark' Jul 17 06:48:38.603073 dut-testbed-225 WARNING snmp#snmp-subagent [sonic_ax_impl] WARNING: Exception when updating lldpRemTable: b'lldp_rem_time_mark'
root@sonic:/home/admin# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
root@sonic:/home/admin#
2 Now try to initiate a connection with retry option. A py exception is observed.
root@sonic:/home/admin# cat test.py
#!/usr/bin/env python2.7
from swsssdk import SonicV2Connector
state_db = SonicV2Connector(host='17.0.0.1')
state_db.connect(state_db.STATE_DB,True)
root@sonic:/home/admin#
root@sonic:/home/admin# ./test.py
Traceback (most recent call last):
File "./test.py", line 5, in
state_db.connect(state_db.STATE_DB,True)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 255, in connect
super(SonicV2Connector, self).connect(db_id, retry_on)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/interface.py", line 169, in connect
self._persistent_connect(db_id)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/interface.py", line 198, in _persistent_connect
self.close(db_id)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 258, in close
db_id = self.get_dbid(db_name)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 277, in get_dbid
return SonicDBConfig.get_dbid(db_name, self.namespace)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 215, in get_dbid
SonicDBConfig.db_name_validation(db_name, namespace)
File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 143, in db_name_validation
raise RuntimeError(msg)
RuntimeError: 6 is not a valid database name in configuration file
root@sonic:/home/admin#
Hi all,
I think it's good to add opcode for notification in configdb.py to verify the difference between these:
"AAA": null
"AAA": {}
So I want to contribute a PR with this patch as bellow, but I have no access for push and merge PR? How to deal with this?
commit f547f9c02347e7b42962278005bcba973892a18b
Author: sam <[email protected]>
Date: Tue Nov 27 11:31:27 2018 +0800
add opcode in redis notification
diff --git a/src/swsssdk/configdb.py b/src/swsssdk/configdb.py
index e255979..87cad6e 100644
--- a/src/swsssdk/configdb.py
+++ b/src/swsssdk/configdb.py
@@ -76,10 +76,10 @@ class ConfigDBConnector(SonicV2Connector):
if self.handlers.has_key(table):
self.handlers.pop(table)
- def __fire(self, table, key, data):
+ def __fire(self, table, key, data, op_str='add'):
if self.handlers.has_key(table):
handler = self.handlers[table]
- handler(table, key, data)
+ handler(table, key, data, op_str)
def listen(self):
"""Start listen Redis keyspace events and will trigger corresponding handlers when content of a table changes.
@@ -94,7 +94,11 @@ class ConfigDBConnector(SonicV2Connector):
if self.handlers.has_key(table):
client = self.redis_clients[self.CONFIG_DB]
data = self.__raw_to_typed(client.hgetall(key))
- self.__fire(table, row, data)
+ op = client.keys(key)
+ op_str = 'add'
+ if len(op) == 0:
+ op_str = 'del'
+ self.__fire(table, row, data, op_str)
except ValueError:
pass #Ignore non table-formated redis entries
Similar to portTable ConfigDone, it will be good for py swsssdk to be consistent with existing c++ swss-common library to use hset instead of set for CONFIG_DB_INITIALIZED.
The flag is to be checked by all app modules which need access to configDB. Using redis operation which is not supported by c++ swss-common library causes unnecessary extra work in c++ modules.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.