[VOL-1036] Initial implementation of device lifecycle management
Change-Id: I5aa58fdcbcd852f6f5eef35d48f25f76e20c0418
diff --git a/adapters/ponsim_olt/ponsim_olt.py b/adapters/ponsim_olt/ponsim_olt.py
index 5e096b4..95bafaa 100644
--- a/adapters/ponsim_olt/ponsim_olt.py
+++ b/adapters/ponsim_olt/ponsim_olt.py
@@ -25,7 +25,7 @@
import structlog
from scapy.layers.l2 import Ether, Dot1Q
from twisted.internet import reactor
-from twisted.internet.defer import inlineCallbacks
+from twisted.internet.defer import inlineCallbacks, returnValue
from grpc._channel import _Rendezvous
from adapters.common.frameio.frameio import BpfProgramFilter, hexify
@@ -245,11 +245,10 @@
self.log.info('grpc-channel-closed')
+ @inlineCallbacks
def _get_nni_port(self):
- ports = self.adapter_agent.get_ports(self.device_id, Port.ETHERNET_NNI)
- if ports:
- # For now, we use on one NNI port
- return ports[0]
+ ports = yield self.adapter_agent.get_ports(self.device_id, Port.ETHERNET_NNI)
+ returnValue(ports)
@inlineCallbacks
def activate(self, device):
@@ -272,7 +271,8 @@
device.vendor = 'ponsim'
device.model = 'n/a'
device.serial_number = device.host_and_port
- device.connect_status = ConnectStatus.REACHABLE
+ device.mac_address = "AA:BB:CC:DD:EE:FF"
+ # device.connect_status = ConnectStatus.REACHABLE
yield self.adapter_agent.device_update(device)
# Now set the initial PM configuration for this device
@@ -288,7 +288,7 @@
port_no=info.nni_port,
label='NNI facing Ethernet port',
type=Port.ETHERNET_NNI,
- admin_state=AdminState.ENABLED,
+ # admin_state=AdminState.ENABLED,
oper_status=OperStatus.ACTIVE
)
self.nni_port = nni_port
@@ -297,10 +297,11 @@
port_no=1,
label='PON port',
type=Port.PON_OLT,
- admin_state=AdminState.ENABLED,
+ # admin_state=AdminState.ENABLED,
oper_status=OperStatus.ACTIVE
))
- yield self.adapter_agent.device_state_update(device.id, oper_status=OperStatus.ACTIVE)
+
+ yield self.adapter_agent.device_state_update(device.id, connect_status=ConnectStatus.REACHABLE, oper_status=OperStatus.ACTIVE)
# register ONUS
self.log.info('onu-found', onus=info.onus, len=len(info.onus))
@@ -319,7 +320,7 @@
# TODO
# Start collecting stats from the device after a brief pause
- # self.start_kpi_collection(device.id)
+ self.start_kpi_collection(device.id)
except Exception as e:
log.exception("Exception-activating", e=e)
@@ -577,138 +578,69 @@
log.info('self-test-device', device=device.id)
raise NotImplementedError()
+
+ @inlineCallbacks
def disable(self):
self.log.info('disabling', device_id=self.device_id)
self.stop_kpi_collection()
- # Get the latest device reference
- device = self.adapter_agent.get_device(self.device_id)
-
- # Update the operational status to UNKNOWN
- device.oper_status = OperStatus.UNKNOWN
- device.connect_status = ConnectStatus.UNREACHABLE
- self.adapter_agent.device_update(device)
-
- # Remove the logical device
- logical_device = self.adapter_agent.get_logical_device(
- self.logical_device_id)
- self.adapter_agent.delete_logical_device(logical_device)
-
- # Disable all child devices first
- self.adapter_agent.update_child_devices_state(self.device_id,
- admin_state=AdminState.DISABLED)
-
- # Remove the peer references from this device
- self.adapter_agent.delete_all_peer_references(self.device_id)
-
- # Set all ports to disabled
- self.adapter_agent.disable_all_ports(self.device_id)
+ # Update the operational status to UNKNOWN and connection status to UNREACHABLE
+ yield self.adapter_agent.device_state_update(self.device_id, oper_status=OperStatus.UNKNOWN, connect_status=ConnectStatus.UNREACHABLE)
self.close_channel()
self.log.info('disabled-grpc-channel')
- # Update the logice device mapping
- if self.logical_device_id in \
- self.adapter.logical_device_id_to_root_device_id:
- del self.adapter.logical_device_id_to_root_device_id[
- self.logical_device_id]
-
# TODO:
# 1) Remove all flows from the device
# 2) Remove the device from ponsim
- self.log.info('disabled', device_id=device.id)
+ self.log.info('disabled', device_id=self.device_id)
+ @inlineCallbacks
def reenable(self):
self.log.info('re-enabling', device_id=self.device_id)
- # Get the latest device reference
- device = self.adapter_agent.get_device(self.device_id)
-
# Set the ofp_port_no and nni_port in case we bypassed the reconcile
# process if the device was in DISABLED state on voltha restart
if not self.ofp_port_no and not self.nni_port:
- stub = ponsim_pb2.PonSimStub(self.get_channel())
+ yield self.get_channel()
+ stub = ponsim_pb2.PonSimStub(self.channel)
info = stub.GetDeviceInfo(Empty())
log.info('got-info', info=info)
self.ofp_port_no = info.nni_port
- self.nni_port = self._get_nni_port()
+ ports = yield self._get_nni_port()
+ # For ponsim, we are using only 1 NNI port
+ if ports.items:
+ self.nni_port = ports.items[0]
- # Update the connect status to REACHABLE
- device.connect_status = ConnectStatus.REACHABLE
- self.adapter_agent.device_update(device)
+ # Update the state of the NNI port
+ yield self.adapter_agent.port_state_update(self.device_id,
+ port_type=Port.ETHERNET_NNI,
+ port_no=self.ofp_port_no,
+ oper_status=OperStatus.ACTIVE)
- # Set all ports to enabled
- self.adapter_agent.enable_all_ports(self.device_id)
+ # Update the state of the PON port
+ yield self.adapter_agent.port_state_update(self.device_id,
+ port_type=Port.PON_OLT,
+ port_no=1,
+ oper_status=OperStatus.ACTIVE)
- ld = LogicalDevice(
- # not setting id and datapth_id will let the adapter agent pick id
- desc=ofp_desc(
- hw_desc='simulated pon',
- sw_desc='simulated pon',
- serial_num=uuid4().hex,
- dp_desc='n/a'
- ),
- switch_features=ofp_switch_features(
- n_buffers=256, # TODO fake for now
- n_tables=2, # TODO ditto
- capabilities=( # TODO and ditto
- OFPC_FLOW_STATS
- | OFPC_TABLE_STATS
- | OFPC_PORT_STATS
- | OFPC_GROUP_STATS
- )
- ),
- root_device_id=device.id
- )
- mac_address = "AA:BB:CC:DD:EE:FF"
- ld_initialized = self.adapter_agent.create_logical_device(ld,
- dpid=mac_address)
- cap = OFPPF_1GB_FD | OFPPF_FIBER
- self.adapter_agent.add_logical_port(ld_initialized.id, LogicalPort(
- id='nni',
- ofp_port=ofp_port(
- port_no=self.ofp_port_no,
- hw_addr=mac_str_to_tuple(
- '00:00:00:00:00:%02x' % self.ofp_port_no),
- name='nni',
- config=0,
- state=OFPPS_LIVE,
- curr=cap,
- advertised=cap,
- peer=cap,
- curr_speed=OFPPF_1GB_FD,
- max_speed=OFPPF_1GB_FD
- ),
- device_id=device.id,
- device_port_no=self.nni_port.port_no,
- root_port=True
- ))
+ # Set the operational state of the device to ACTIVE and connect status to REACHABLE
+ yield self.adapter_agent.device_state_update(self.device_id,
+ connect_status=ConnectStatus.REACHABLE,
+ oper_status=OperStatus.ACTIVE)
- device = self.adapter_agent.get_device(device.id)
- device.parent_id = ld_initialized.id
- device.oper_status = OperStatus.ACTIVE
- self.adapter_agent.device_update(device)
- self.logical_device_id = ld_initialized.id
+ # TODO: establish frame grpc-stream
+ # yield reactor.callInThread(self.rcv_grpc)
- # Reenable all child devices
- self.adapter_agent.update_child_devices_state(device.id,
- admin_state=AdminState.ENABLED)
+ self.start_kpi_collection(self.device_id)
- # establish frame grpc-stream
- reactor.callInThread(self.rcv_grpc)
-
- self.start_kpi_collection(device.id)
-
- self.log.info('re-enabled', device_id=device.id)
+ self.log.info('re-enabled', device_id=self.device_id)
def delete(self):
self.log.info('deleting', device_id=self.device_id)
- # Remove all child devices
- self.adapter_agent.delete_all_child_devices(self.device_id)
-
self.close_channel()
self.log.info('disabled-grpc-channel')
@@ -725,7 +657,7 @@
try:
# Step 1: gather metrics from device
port_metrics = \
- self.pm_metrics.collect_port_metrics(self.get_channel())
+ self.pm_metrics.collect_port_metrics(self.channel)
# Step 2: prepare the KpiEvent for submission
# we can time-stamp them here (or could use time derived from OLT