Merge branch 'coretk' into coretk-validation

This commit is contained in:
Huy Pham 2019-12-10 09:58:54 -08:00
commit 2292001e17
13 changed files with 346 additions and 235 deletions

View file

@ -6,7 +6,6 @@ import logging
import os
import time
from pathlib import Path
from tkinter import messagebox
import grpc
@ -14,6 +13,7 @@ from core.api.grpc import client, core_pb2
from coretk import appconfig
from coretk.dialogs.mobilityplayer import MobilityPlayer
from coretk.dialogs.sessions import SessionsDialog
from coretk.errors import show_grpc_error
from coretk.graph import tags
from coretk.graph.shape import AnnotationData, Shape
from coretk.graph.shapeutils import ShapeType
@ -196,6 +196,7 @@ class CoreClient:
self.reset()
# get session data
try:
response = self.client.get_session(self.session_id)
session = response.session
self.state = session.state
@ -235,7 +236,9 @@ class CoreClient:
if _id >= 1000:
interface = _id % 1000
node_id = int(_id / 1000)
self.set_emane_model_config(node_id, config.model, config.config, interface)
self.set_emane_model_config(
node_id, config.model, config.config, interface
)
# save and retrieve data, needed for session nodes
for node in session.nodes:
@ -267,7 +270,9 @@ class CoreClient:
# store links as created links
for link in session.links:
self.created_links.add(tuple(sorted([link.node_one_id, link.node_two_id])))
self.created_links.add(
tuple(sorted([link.node_one_id, link.node_two_id]))
)
# draw session
self.app.canvas.reset_and_redraw(session)
@ -275,6 +280,8 @@ class CoreClient:
# get metadata
response = self.client.get_session_metadata(self.session_id)
self.parse_metadata(response.config)
except grpc.RpcError as e:
show_grpc_error(e)
# update ui to represent current state
if self.is_runtime():
@ -353,6 +360,7 @@ class CoreClient:
:return: nothing
"""
try:
response = self.client.create_session()
logging.info("created session: %s", response)
location_config = self.app.guiconfig["location"]
@ -366,12 +374,17 @@ class CoreClient:
scale=location_config["scale"],
)
self.join_session(response.session_id, query_location=False)
except grpc.RpcError as e:
show_grpc_error(e)
def delete_session(self, session_id=None):
if session_id is None:
session_id = self.session_id
try:
response = self.client.delete_session(session_id)
logging.info("Deleted session result: %s", response)
logging.info("deleted session result: %s", response)
except grpc.RpcError as e:
show_grpc_error(e)
def set_up(self):
"""
@ -403,21 +416,15 @@ class CoreClient:
x.node_type: set(x.services) for x in response.defaults
}
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.UNAVAILABLE:
messagebox.showerror("Server Error", "CORE Daemon Unavailable")
else:
messagebox.showerror("GRPC Error", e.details())
show_grpc_error(e)
self.app.close()
def get_session_state(self):
response = self.client.get_session(self.session_id)
logging.info("get session: %s", response)
return response.session.state
def edit_node(self, node_id, x, y):
position = core_pb2.Position(x=x, y=y)
try:
self.client.edit_node(self.session_id, node_id, position, source="gui")
except grpc.RpcError as e:
show_grpc_error(e)
def start_session(self):
nodes = [x.core_node for x in self.canvas_nodes.values()]
@ -436,6 +443,7 @@ class CoreClient:
emane_config = None
start = time.perf_counter()
try:
response = self.client.start_session(
self.session_id,
nodes,
@ -451,24 +459,35 @@ class CoreClient:
)
self.set_metadata()
process_time = time.perf_counter() - start
logging.debug("start session(%s), result: %s", self.session_id, response.result)
logging.debug(
"start session(%s), result: %s", self.session_id, response.result
)
self.app.statusbar.start_session_callback(process_time)
# display mobility players
for node_id, config in self.mobility_configs.items():
canvas_node = self.canvas_nodes[node_id]
mobility_player = MobilityPlayer(self.app, self.app, canvas_node, config)
mobility_player = MobilityPlayer(
self.app, self.app, canvas_node, config
)
mobility_player.show()
self.mobility_players[node_id] = mobility_player
except grpc.RpcError as e:
show_grpc_error(e)
def stop_session(self, session_id=None):
if not session_id:
session_id = self.session_id
start = time.perf_counter()
try:
response = self.client.stop_session(session_id)
logging.debug(
"stopped session(%s), result: %s", session_id, response.result
)
process_time = time.perf_counter() - start
self.app.statusbar.stop_session_callback(process_time)
logging.debug("stopped session(%s), result: %s", session_id, response.result)
except grpc.RpcError as e:
show_grpc_error(e)
def set_metadata(self):
# create canvas data
@ -492,9 +511,12 @@ class CoreClient:
logging.info("set session metadata: %s", response)
def launch_terminal(self, node_id):
try:
response = self.client.get_node_terminal(self.session_id, node_id)
logging.info("get terminal %s", response.terminal)
os.system(f"xterm -e {response.terminal} &")
except grpc.RpcError as e:
show_grpc_error(e)
def save_xml(self, file_path):
"""
@ -503,9 +525,11 @@ class CoreClient:
:param str file_path: file path that user pick
:return: nothing
"""
try:
response = self.client.save_xml(self.session_id, file_path)
logging.info("saved xml(%s): %s", file_path, response)
self.client.events(self.session_id, self.handle_events)
except grpc.RpcError as e:
show_grpc_error(e)
def open_xml(self, file_path):
"""
@ -514,9 +538,12 @@ class CoreClient:
:param str file_path: file to open
:return: session id
"""
try:
response = self.client.open_xml(file_path)
logging.debug("open xml: %s", response)
self.join_session(response.session_id)
except grpc.RpcError as e:
show_grpc_error(e)
def get_node_service(self, node_id, service_name):
response = self.client.get_node_service(self.session_id, node_id, service_name)
@ -553,7 +580,7 @@ class CoreClient:
"""
node_protos = [x.core_node for x in self.canvas_nodes.values()]
link_protos = list(self.links.values())
if self.get_session_state() != core_pb2.SessionState.DEFINITION:
if self.state != core_pb2.SessionState.DEFINITION:
self.client.set_session_state(
self.session_id, core_pb2.SessionState.DEFINITION
)
@ -590,7 +617,7 @@ class CoreClient:
:return: nothing
"""
logging.debug("Close grpc")
logging.debug("close grpc")
self.client.close()
def next_node_id(self):

View file

@ -6,7 +6,10 @@ import tkinter as tk
import webbrowser
from tkinter import ttk
import grpc
from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error
from coretk.images import ImageEnum, Images
from coretk.widgets import ConfigFrame
@ -52,9 +55,13 @@ class EmaneModelDialog(Dialog):
self.model = f"emane_{model}"
self.interface = interface
self.config_frame = None
try:
self.config = self.app.core.get_emane_model_config(
self.node.id, self.model, self.interface
)
except grpc.RpcError as e:
show_grpc_error(e)
self.destroy()
self.draw()
def draw(self):

View file

@ -3,7 +3,10 @@ mobility configuration
"""
from tkinter import ttk
import grpc
from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error
from coretk.widgets import ConfigFrame
PAD = 5
@ -20,7 +23,11 @@ class MobilityConfigDialog(Dialog):
self.canvas_node = canvas_node
self.node = canvas_node.core_node
self.config_frame = None
try:
self.config = self.app.core.get_mobility_config(self.node.id)
except grpc.RpcError as e:
show_grpc_error(e)
self.destroy()
self.draw()
def draw(self):

View file

@ -1,8 +1,11 @@
import tkinter as tk
from tkinter import ttk
import grpc
from core.api.grpc.core_pb2 import MobilityAction
from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error
from coretk.images import ImageEnum, Images
PAD = 5
@ -50,6 +53,7 @@ class MobilityPlayerDialog(Dialog):
super().__init__(
master, app, f"{canvas_node.core_node.name} Mobility Player", modal=False
)
self.geometry("")
self.canvas_node = canvas_node
self.node = canvas_node.core_node
self.config = config
@ -123,20 +127,29 @@ class MobilityPlayerDialog(Dialog):
def click_play(self):
self.set_play()
session_id = self.app.core.session_id
try:
self.app.core.client.mobility_action(
session_id, self.node.id, MobilityAction.START
)
except grpc.RpcError as e:
show_grpc_error(e)
def click_pause(self):
self.set_pause()
session_id = self.app.core.session_id
try:
self.app.core.client.mobility_action(
session_id, self.node.id, MobilityAction.PAUSE
)
except grpc.RpcError as e:
show_grpc_error(e)
def click_stop(self):
self.set_stop()
session_id = self.app.core.session_id
try:
self.app.core.client.mobility_action(
session_id, self.node.id, MobilityAction.STOP
)
except grpc.RpcError as e:
show_grpc_error(e)

View file

@ -3,8 +3,11 @@ import logging
import tkinter as tk
from tkinter import ttk
import grpc
from core.api.grpc import core_pb2
from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error
from coretk.images import ImageEnum, Images
from coretk.widgets import CodeText, ListboxScroll
@ -47,9 +50,9 @@ class ServiceConfiguration(Dialog):
self.draw()
def load(self):
try:
# create nodes and links in definition state for getting and setting service file
self.app.core.create_nodes_and_links()
service_configs = self.app.core.service_configs
if (
self.node_id in service_configs
@ -72,7 +75,9 @@ class ServiceConfiguration(Dialog):
self.validation_mode = service_config.validation_mode
self.validation_time = service_config.validation_timer
self.original_service_files = {
x: self.app.core.get_node_service_file(self.node_id, self.service_name, x)
x: self.app.core.get_node_service_file(
self.node_id, self.service_name, x
)
for x in self.filenames
}
self.temp_service_files = {
@ -85,6 +90,8 @@ class ServiceConfiguration(Dialog):
):
for file, data in file_configs[self.node_id][self.service_name].items():
self.temp_service_files[file] = data
except grpc.RpcError as e:
show_grpc_error(e)
def draw(self):
# self.columnconfigure(1, weight=1)
@ -366,6 +373,7 @@ class ServiceConfiguration(Dialog):
startup_commands = self.startup_commands_listbox.get(0, "end")
shutdown_commands = self.shutdown_commands_listbox.get(0, "end")
validate_commands = self.validate_commands_listbox.get(0, "end")
try:
config = self.core.set_node_service(
self.node_id,
self.service_name,
@ -390,6 +398,8 @@ class ServiceConfiguration(Dialog):
self.app.core.set_node_service_file(
self.node_id, self.service_name, file, self.temp_service_files[file]
)
except grpc.RpcError as e:
show_grpc_error(e)
self.destroy()
def display_service_file_data(self, event):

View file

@ -1,7 +1,10 @@
import logging
from tkinter import ttk
import grpc
from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error
from coretk.widgets import ConfigFrame
PAD_X = 2
@ -12,17 +15,23 @@ class SessionOptionsDialog(Dialog):
def __init__(self, master, app):
super().__init__(master, app, "Session Options", modal=True)
self.config_frame = None
self.config = self.get_config()
self.draw()
def get_config(self):
try:
session_id = self.app.core.session_id
response = self.app.core.client.get_session_options(session_id)
return response.config
except grpc.RpcError as e:
show_grpc_error(e)
self.destroy()
def draw(self):
self.top.columnconfigure(0, weight=1)
self.top.rowconfigure(0, weight=1)
session_id = self.app.core.session_id
response = self.app.core.client.get_session_options(session_id)
logging.info("session options: %s", response)
self.config_frame = ConfigFrame(self.top, self.app, config=response.config)
self.config_frame = ConfigFrame(self.top, self.app, config=self.config)
self.config_frame.draw_config()
self.config_frame.grid(sticky="nsew")
@ -37,7 +46,10 @@ class SessionOptionsDialog(Dialog):
def save(self):
config = self.config_frame.parse_config()
try:
session_id = self.app.core.session_id
response = self.app.core.client.set_session_options(session_id, config)
logging.info("saved session config: %s", response)
except grpc.RpcError as e:
show_grpc_error(e)
self.destroy()

View file

@ -3,8 +3,11 @@ import threading
import tkinter as tk
from tkinter import ttk
import grpc
from core.api.grpc import core_pb2
from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error
from coretk.images import ImageEnum, Images
@ -14,8 +17,18 @@ class SessionsDialog(Dialog):
self.selected = False
self.selected_id = None
self.tree = None
self.sessions = self.get_sessions()
self.draw()
def get_sessions(self):
try:
response = self.app.core.client.get_sessions()
logging.info("sessions: %s", response)
return response.sessions
except grpc.RpcError as e:
show_grpc_error(e)
self.destroy()
def draw(self):
self.top.columnconfigure(0, weight=1)
self.draw_description()
@ -48,9 +61,7 @@ class SessionsDialog(Dialog):
self.tree.column("nodes", stretch=tk.YES)
self.tree.heading("nodes", text="Node Count")
response = self.app.core.client.get_sessions()
logging.info("sessions: %s", response)
for index, session in enumerate(response.sessions):
for index, session in enumerate(self.sessions):
state_name = core_pb2.SessionState.Enum.Name(session.state)
self.tree.insert(
"",

View file

@ -4,7 +4,10 @@ wlan configuration
from tkinter import ttk
import grpc
from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error
from coretk.widgets import ConfigFrame
PAD = 5
@ -18,7 +21,11 @@ class WlanConfigDialog(Dialog):
self.canvas_node = canvas_node
self.node = canvas_node.core_node
self.config_frame = None
try:
self.config = self.app.core.get_wlan_config(self.node.id)
except grpc.RpcError as e:
show_grpc_error(e)
self.destroy()
self.draw()
def draw(self):

8
coretk/coretk/errors.py Normal file
View file

@ -0,0 +1,8 @@
from tkinter import messagebox
def show_grpc_error(e):
title = [x.capitalize() for x in e.code().name.lower().split("_")]
title = " ".join(title)
title = f"GRPC {title}"
messagebox.showerror(title, e.details())

View file

@ -2,11 +2,14 @@ import logging
import tkinter as tk
from tkinter import font
import grpc
from core.api.grpc.core_pb2 import NodeType
from coretk.dialogs.emaneconfig import EmaneConfigDialog
from coretk.dialogs.mobilityconfig import MobilityConfigDialog
from coretk.dialogs.nodeconfig import NodeConfigDialog
from coretk.dialogs.wlanconfig import WlanConfigDialog
from coretk.errors import show_grpc_error
from coretk.graph import tags
from coretk.graph.enums import GraphMode
from coretk.graph.tooltip import CanvasTooltip
@ -138,8 +141,11 @@ class CanvasNode:
if self.app.core.is_runtime() and self.app.core.observer:
self.tooltip.text.set("waiting...")
self.tooltip.on_enter(event)
try:
output = self.app.core.run(self.core_node.id)
self.tooltip.text.set(output)
except grpc.RpcError as e:
show_grpc_error(e)
def on_leave(self, event):
self.tooltip.on_leave(event)

View file

@ -10,7 +10,6 @@ from tkinter import filedialog, messagebox
import grpc
from core.api.grpc import core_pb2
from coretk.appconfig import XML_PATH
from coretk.dialogs.about import AboutDialog
from coretk.dialogs.canvasbackground import CanvasBackgroundDialog
@ -52,12 +51,7 @@ class MenuAction:
"menuaction.py: clean_nodes_links_and_set_configuration() Exiting the program"
)
try:
state = self.app.core.get_session_state()
if (
state == core_pb2.SessionState.SHUTDOWN
or state == core_pb2.SessionState.DEFINITION
):
if not self.app.core.is_runtime():
self.app.core.delete_session()
if quitapp:
self.app.quit()
@ -73,7 +67,7 @@ class MenuAction:
elif quitapp:
self.app.quit()
except grpc.RpcError:
logging.error("error getting session state")
logging.exception("error deleting session")
if quitapp:
self.app.quit()

View file

@ -195,24 +195,29 @@ In order to be able to do use the Bird Internet Routing Protocol, you must modif
### FRRouting
FRRouting is a routing software package that provides TCP/IP based routing services with routing protocols support such as BGP, RIP, OSPF, IS-IS and more. FRR also supports special BGP Route Reflector and Route Server behavior. In addition to traditional IPv4 routing protocols, FRR also supports IPv6 routing protocols. With an SNMP daemon that supports the AgentX protocol, FRR provides routing protocol MIB read-only access (SNMP Support).
FRR currently supports the following protocols:
* BGP
FRR (as of v7.2) currently supports the following protocols:
* BGPv4
* OSPFv2
* OSPFv3
* RIPv1
* RIPv2
* RIPng
* RIPv1/v2/ng
* IS-IS
* PIM-SM/MSDP
* PIM-SM/MSDP/BSM(AutoRP)
* LDP
* BFD
* Babel
* PBR
* OpenFabric
* VRRPv2/v3
* EIGRP (alpha)
* NHRP (alpha)
#### FRRouting Package Install
Ubuntu 19.10 and later
```shell
sudo apt update && sudo apt install frr
```
Ubuntu 16.04 and Ubuntu 18.04
```shell
sudo apt install curl
curl -s https://deb.frrouting.org/frr/keys.asc | sudo apt-key add -
@ -220,6 +225,10 @@ FRRVER="frr-stable"
echo deb https://deb.frrouting.org/frr $(lsb_release -s -c) $FRRVER | sudo tee -a /etc/apt/sources.list.d/frr.list
sudo apt update && sudo apt install frr frr-pythontools
```
Fedora 31
```shell
sudo dnf update && sudo dnf install frr
```
#### FRRouting Source Code Install
Building FRR from source is the best way to ensure you have the latest features and bug fixes. Details for each supported platform, including dependency package listings, permissions, and other gotchas, are in the developers documentation.

View file

@ -35,7 +35,7 @@ corestart() {
echo "$NAME already started"
else
echo "starting $NAME"
sudo $CMD 2>&1 >> "$LOG" &
$CMD 2>&1 >> "$LOG" &
fi
echo $! > "$PIDFILE"