Skip to content

Commit

Permalink
resouce: ethernetport: convert to asyncio
Browse files Browse the repository at this point in the history
Follow the sync API deprecation and use an internal asyncio loop if no
external loop can be retrieved.

Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
  • Loading branch information
Emantor committed Sep 25, 2024
1 parent 77c503a commit 612455d
Showing 1 changed file with 26 additions and 19 deletions.
45 changes: 26 additions & 19 deletions labgrid/resource/ethernetport.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,27 @@ class SNMPSwitch:
"""SNMPSwitch describes a switch accessible over SNMP. This class
implements functions to query ports and the forwarding database."""
hostname = attr.ib(validator=attr.validators.instance_of(str))
loop = attr.ib()

def __attrs_post_init__(self):
import pysnmp.hlapi.v3arch.asyncio as hlapi

self.logger = logging.getLogger(f"{self}")
self.ports = {}
self.fdb = {}
self.macs_by_port = {}
self.transport = self.loop.run_until_complete(hlapi.UdpTransportTarget.create((self.hostname, 161)))
self._autodetect()

def _autodetect(self):
from pysnmp import hlapi
import pysnmp.hlapi.v3arch.asyncio as hlapi

for (errorIndication, errorStatus, _, varBindTable) in hlapi.getCmd(
for (errorIndication, errorStatus, _, varBindTable) in self.loop.run_until_complete(hlapi.getCmd(
hlapi.SnmpEngine(),
hlapi.CommunityData('public'),
hlapi.UdpTransportTarget((self.hostname, 161)),
self.transport,
hlapi.ContextData(),
hlapi.ObjectType(hlapi.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))):
hlapi.ObjectType(hlapi.ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)))):
if errorIndication:
raise Exception(f"snmp error {errorIndication}")
elif errorStatus:
Expand All @@ -51,7 +55,7 @@ def _get_ports(self):
Returns:
Dict[Dict[]]: ports and their values
"""
from pysnmp import hlapi
import pysnmp.hlapi.v3arch.asyncio as hlapi

variables = [
(hlapi.ObjectType(hlapi.ObjectIdentity('IF-MIB', 'ifIndex')), 'index'),
Expand All @@ -64,14 +68,14 @@ def _get_ports(self):
]
ports = {}

for (errorIndication, errorStatus, _, varBindTable) in hlapi.bulkCmd(
for (errorIndication, errorStatus, _, varBindTable) in self.loop.run_until_complete(hlapi.bulkCmd(
hlapi.SnmpEngine(),
hlapi.CommunityData('public'),
hlapi.UdpTransportTarget((self.hostname, 161)),
self.transport,
hlapi.ContextData(),
0, 20,
*[x[0] for x in variables],
lexicographicMode=False):
lexicographicMode=False)):
if errorIndication:
raise Exception(f"snmp error {errorIndication}")
elif errorStatus:
Expand All @@ -93,18 +97,18 @@ def _get_fdb_dot1d(self):
Returns:
Dict[List[str]]: ports and their values
"""
from pysnmp import hlapi
import pysnmp.hlapi.v3arch.asyncio as hlapi

ports = {}

for (errorIndication, errorStatus, _, varBindTable) in hlapi.bulkCmd(
for (errorIndication, errorStatus, _, varBindTable) in self.loop.run_until_complete(hlapi.bulkCmd(
hlapi.SnmpEngine(),
hlapi.CommunityData('public'),
hlapi.UdpTransportTarget((self.hostname, 161)),
self.transport,
hlapi.ContextData(),
0, 50,
hlapi.ObjectType(hlapi.ObjectIdentity('BRIDGE-MIB', 'dot1dTpFdbPort')),
lexicographicMode=False):
lexicographicMode=False)):
if errorIndication:
raise Exception(f"snmp error {errorIndication}")
elif errorStatus:
Expand All @@ -126,18 +130,18 @@ def _get_fdb_dot1q(self):
Returns:
Dict[List[str]]: ports and their values
"""
from pysnmp import hlapi
import pysnmp.hlapi.v3arch.asyncio as hlapi

ports = {}

for (errorIndication, errorStatus, _, varBindTable) in hlapi.bulkCmd(
for (errorIndication, errorStatus, _, varBindTable) in self.loop.run_until_complete(hlapi.bulkCmd(
hlapi.SnmpEngine(),
hlapi.CommunityData('public'),
hlapi.UdpTransportTarget((self.hostname, 161)),
self.transport,
hlapi.ContextData(),
0, 50,
hlapi.ObjectType(hlapi.ObjectIdentity('Q-BRIDGE-MIB', 'dot1qTpFdbPort')),
lexicographicMode=False):
lexicographicMode=False)):
if errorIndication:
raise Exception(f"snmp error {errorIndication}")
elif errorStatus:
Expand Down Expand Up @@ -177,6 +181,9 @@ def update(self):
self.logger.debug("updating macs by port")
self._update_macs()

def deactivate(self):
self.loop.close()


@attr.s
class EthernetPortManager(ResourceManager):
Expand Down Expand Up @@ -223,14 +230,16 @@ async def poll_neighbour(self):

await asyncio.sleep(1.0)

self.loop = asyncio.get_event_loop()

async def poll_switches(self):
current = set(resource.switch for resource in self.resources)
removed = set(self.switches) - current
new = current - set(self.switches)
for switch in removed:
del self.switches[switch]
for switch in new:
self.switches[switch] = SNMPSwitch(switch)
self.switches[switch] = SNMPSwitch(switch, self.loop)
for switch in current:
self.switches[switch].update()
await asyncio.sleep(1.0)
Expand All @@ -248,7 +257,6 @@ async def poll(self, handler):
import traceback
traceback.print_exc(file=sys.stderr)

self.loop = asyncio.get_event_loop()
self.poll_tasks.append(self.loop.create_task(poll(self, poll_neighbour)))
self.poll_tasks.append(self.loop.create_task(poll(self, poll_switches)))

Expand Down Expand Up @@ -309,7 +317,6 @@ def poll(self):
resource.extra = extra
self.logger.debug("new information for %s: %s", resource, extra)


@target_factory.reg_resource
@attr.s
class SNMPEthernetPort(ManagedResource):
Expand Down

0 comments on commit 612455d

Please sign in to comment.