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 os
import time import time
from pathlib import Path from pathlib import Path
from tkinter import messagebox
import grpc import grpc
@ -14,6 +13,7 @@ from core.api.grpc import client, core_pb2
from coretk import appconfig from coretk import appconfig
from coretk.dialogs.mobilityplayer import MobilityPlayer from coretk.dialogs.mobilityplayer import MobilityPlayer
from coretk.dialogs.sessions import SessionsDialog from coretk.dialogs.sessions import SessionsDialog
from coretk.errors import show_grpc_error
from coretk.graph import tags from coretk.graph import tags
from coretk.graph.shape import AnnotationData, Shape from coretk.graph.shape import AnnotationData, Shape
from coretk.graph.shapeutils import ShapeType from coretk.graph.shapeutils import ShapeType
@ -196,85 +196,92 @@ class CoreClient:
self.reset() self.reset()
# get session data # get session data
response = self.client.get_session(self.session_id) try:
session = response.session response = self.client.get_session(self.session_id)
self.state = session.state session = response.session
self.client.events(self.session_id, self.handle_events) self.state = session.state
self.client.throughputs(self.handle_throughputs) self.client.events(self.session_id, self.handle_events)
self.client.throughputs(self.handle_throughputs)
# get location # get location
if query_location: if query_location:
response = self.client.get_session_location(self.session_id) response = self.client.get_session_location(self.session_id)
self.location = response.location self.location = response.location
# get emane models # get emane models
response = self.client.get_emane_models(self.session_id) response = self.client.get_emane_models(self.session_id)
self.emane_models = response.models self.emane_models = response.models
# get hooks # get hooks
response = self.client.get_hooks(self.session_id) response = self.client.get_hooks(self.session_id)
for hook in response.hooks: for hook in response.hooks:
self.hooks[hook.file] = hook self.hooks[hook.file] = hook
# get mobility configs # get mobility configs
response = self.client.get_mobility_configs(self.session_id) response = self.client.get_mobility_configs(self.session_id)
for node_id in response.configs: for node_id in response.configs:
node_config = response.configs[node_id].config node_config = response.configs[node_id].config
self.mobility_configs[node_id] = node_config self.mobility_configs[node_id] = node_config
# get emane config # get emane config
response = self.client.get_emane_config(self.session_id) response = self.client.get_emane_config(self.session_id)
self.emane_config = response.config self.emane_config = response.config
# get emane model config # get emane model config
response = self.client.get_emane_model_configs(self.session_id) response = self.client.get_emane_model_configs(self.session_id)
for _id in response.configs: for _id in response.configs:
config = response.configs[_id] config = response.configs[_id]
interface = None interface = None
node_id = _id node_id = _id
if _id >= 1000: if _id >= 1000:
interface = _id % 1000 interface = _id % 1000
node_id = int(_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 # save and retrieve data, needed for session nodes
for node in session.nodes: for node in session.nodes:
# get node service config and file config # get node service config and file config
self.created_nodes.add(node.id) self.created_nodes.add(node.id)
# get wlan configs for wlan nodes # get wlan configs for wlan nodes
if node.type == core_pb2.NodeType.WIRELESS_LAN: if node.type == core_pb2.NodeType.WIRELESS_LAN:
response = self.client.get_wlan_config(self.session_id, node.id) response = self.client.get_wlan_config(self.session_id, node.id)
self.wlan_configs[node.id] = response.config self.wlan_configs[node.id] = response.config
# retrieve service configurations data for default nodes # retrieve service configurations data for default nodes
elif node.type == core_pb2.NodeType.DEFAULT: elif node.type == core_pb2.NodeType.DEFAULT:
for service in node.services: for service in node.services:
response = self.client.get_node_service( response = self.client.get_node_service(
self.session_id, node.id, service self.session_id, node.id, service
)
if node.id not in self.service_configs:
self.service_configs[node.id] = {}
self.service_configs[node.id][service] = response.service
for file in response.service.configs:
response = self.client.get_node_service_file(
self.session_id, node.id, service, file
) )
if node.id not in self.file_configs: if node.id not in self.service_configs:
self.file_configs[node.id] = {} self.service_configs[node.id] = {}
if service not in self.file_configs[node.id]: self.service_configs[node.id][service] = response.service
self.file_configs[node.id][service] = {} for file in response.service.configs:
self.file_configs[node.id][service][file] = response.data response = self.client.get_node_service_file(
self.session_id, node.id, service, file
)
if node.id not in self.file_configs:
self.file_configs[node.id] = {}
if service not in self.file_configs[node.id]:
self.file_configs[node.id][service] = {}
self.file_configs[node.id][service][file] = response.data
# store links as created links # store links as created links
for link in session.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 # draw session
self.app.canvas.reset_and_redraw(session) self.app.canvas.reset_and_redraw(session)
# get metadata # get metadata
response = self.client.get_session_metadata(self.session_id) response = self.client.get_session_metadata(self.session_id)
self.parse_metadata(response.config) self.parse_metadata(response.config)
except grpc.RpcError as e:
show_grpc_error(e)
# update ui to represent current state # update ui to represent current state
if self.is_runtime(): if self.is_runtime():
@ -353,25 +360,31 @@ class CoreClient:
:return: nothing :return: nothing
""" """
response = self.client.create_session() try:
logging.info("created session: %s", response) response = self.client.create_session()
location_config = self.app.guiconfig["location"] logging.info("created session: %s", response)
self.location = core_pb2.SessionLocation( location_config = self.app.guiconfig["location"]
x=location_config["x"], self.location = core_pb2.SessionLocation(
y=location_config["y"], x=location_config["x"],
z=location_config["z"], y=location_config["y"],
lat=location_config["lat"], z=location_config["z"],
lon=location_config["lon"], lat=location_config["lat"],
alt=location_config["alt"], lon=location_config["lon"],
scale=location_config["scale"], alt=location_config["alt"],
) scale=location_config["scale"],
self.join_session(response.session_id, query_location=False) )
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): def delete_session(self, session_id=None):
if session_id is None: if session_id is None:
session_id = self.session_id session_id = self.session_id
response = self.client.delete_session(session_id) try:
logging.info("Deleted session result: %s", response) response = self.client.delete_session(session_id)
logging.info("deleted session result: %s", response)
except grpc.RpcError as e:
show_grpc_error(e)
def set_up(self): def set_up(self):
""" """
@ -403,21 +416,15 @@ class CoreClient:
x.node_type: set(x.services) for x in response.defaults x.node_type: set(x.services) for x in response.defaults
} }
except grpc.RpcError as e: except grpc.RpcError as e:
if e.code() == grpc.StatusCode.UNAVAILABLE: show_grpc_error(e)
messagebox.showerror("Server Error", "CORE Daemon Unavailable")
else:
messagebox.showerror("GRPC Error", e.details())
self.app.close() 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): def edit_node(self, node_id, x, y):
position = core_pb2.Position(x=x, y=y) position = core_pb2.Position(x=x, y=y)
self.client.edit_node(self.session_id, node_id, position, source="gui") 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): def start_session(self):
nodes = [x.core_node for x in self.canvas_nodes.values()] nodes = [x.core_node for x in self.canvas_nodes.values()]
@ -436,39 +443,51 @@ class CoreClient:
emane_config = None emane_config = None
start = time.perf_counter() start = time.perf_counter()
response = self.client.start_session( try:
self.session_id, response = self.client.start_session(
nodes, self.session_id,
links, nodes,
self.location, links,
hooks, self.location,
emane_config, hooks,
emane_model_configs, emane_config,
wlan_configs, emane_model_configs,
mobility_configs, wlan_configs,
service_configs, mobility_configs,
file_configs, service_configs,
) file_configs,
self.set_metadata() )
process_time = time.perf_counter() - start self.set_metadata()
logging.debug("start session(%s), result: %s", self.session_id, response.result) process_time = time.perf_counter() - start
self.app.statusbar.start_session_callback(process_time) logging.debug(
"start session(%s), result: %s", self.session_id, response.result
)
self.app.statusbar.start_session_callback(process_time)
# display mobility players # display mobility players
for node_id, config in self.mobility_configs.items(): for node_id, config in self.mobility_configs.items():
canvas_node = self.canvas_nodes[node_id] canvas_node = self.canvas_nodes[node_id]
mobility_player = MobilityPlayer(self.app, self.app, canvas_node, config) mobility_player = MobilityPlayer(
mobility_player.show() self.app, self.app, canvas_node, config
self.mobility_players[node_id] = mobility_player )
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): def stop_session(self, session_id=None):
if not session_id: if not session_id:
session_id = self.session_id session_id = self.session_id
start = time.perf_counter() start = time.perf_counter()
response = self.client.stop_session(session_id) try:
process_time = time.perf_counter() - start response = self.client.stop_session(session_id)
self.app.statusbar.stop_session_callback(process_time) logging.debug(
logging.debug("stopped session(%s), result: %s", session_id, response.result) "stopped session(%s), result: %s", session_id, response.result
)
process_time = time.perf_counter() - start
self.app.statusbar.stop_session_callback(process_time)
except grpc.RpcError as e:
show_grpc_error(e)
def set_metadata(self): def set_metadata(self):
# create canvas data # create canvas data
@ -492,9 +511,12 @@ class CoreClient:
logging.info("set session metadata: %s", response) logging.info("set session metadata: %s", response)
def launch_terminal(self, node_id): def launch_terminal(self, node_id):
response = self.client.get_node_terminal(self.session_id, node_id) try:
logging.info("get terminal %s", response.terminal) response = self.client.get_node_terminal(self.session_id, node_id)
os.system(f"xterm -e {response.terminal} &") 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): def save_xml(self, file_path):
""" """
@ -503,9 +525,11 @@ class CoreClient:
:param str file_path: file path that user pick :param str file_path: file path that user pick
:return: nothing :return: nothing
""" """
response = self.client.save_xml(self.session_id, file_path) try:
logging.info("saved xml(%s): %s", file_path, response) response = self.client.save_xml(self.session_id, file_path)
self.client.events(self.session_id, self.handle_events) logging.info("saved xml(%s): %s", file_path, response)
except grpc.RpcError as e:
show_grpc_error(e)
def open_xml(self, file_path): def open_xml(self, file_path):
""" """
@ -514,9 +538,12 @@ class CoreClient:
:param str file_path: file to open :param str file_path: file to open
:return: session id :return: session id
""" """
response = self.client.open_xml(file_path) try:
logging.debug("open xml: %s", response) response = self.client.open_xml(file_path)
self.join_session(response.session_id) 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): def get_node_service(self, node_id, service_name):
response = self.client.get_node_service(self.session_id, 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()] node_protos = [x.core_node for x in self.canvas_nodes.values()]
link_protos = list(self.links.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.client.set_session_state(
self.session_id, core_pb2.SessionState.DEFINITION self.session_id, core_pb2.SessionState.DEFINITION
) )
@ -590,7 +617,7 @@ class CoreClient:
:return: nothing :return: nothing
""" """
logging.debug("Close grpc") logging.debug("close grpc")
self.client.close() self.client.close()
def next_node_id(self): def next_node_id(self):

View file

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

View file

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

View file

@ -1,8 +1,11 @@
import tkinter as tk import tkinter as tk
from tkinter import ttk from tkinter import ttk
import grpc
from core.api.grpc.core_pb2 import MobilityAction from core.api.grpc.core_pb2 import MobilityAction
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error
from coretk.images import ImageEnum, Images from coretk.images import ImageEnum, Images
PAD = 5 PAD = 5
@ -50,6 +53,7 @@ class MobilityPlayerDialog(Dialog):
super().__init__( super().__init__(
master, app, f"{canvas_node.core_node.name} Mobility Player", modal=False master, app, f"{canvas_node.core_node.name} Mobility Player", modal=False
) )
self.geometry("")
self.canvas_node = canvas_node self.canvas_node = canvas_node
self.node = canvas_node.core_node self.node = canvas_node.core_node
self.config = config self.config = config
@ -123,20 +127,29 @@ class MobilityPlayerDialog(Dialog):
def click_play(self): def click_play(self):
self.set_play() self.set_play()
session_id = self.app.core.session_id session_id = self.app.core.session_id
self.app.core.client.mobility_action( try:
session_id, self.node.id, MobilityAction.START 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): def click_pause(self):
self.set_pause() self.set_pause()
session_id = self.app.core.session_id session_id = self.app.core.session_id
self.app.core.client.mobility_action( try:
session_id, self.node.id, MobilityAction.PAUSE 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): def click_stop(self):
self.set_stop() self.set_stop()
session_id = self.app.core.session_id session_id = self.app.core.session_id
self.app.core.client.mobility_action( try:
session_id, self.node.id, MobilityAction.STOP 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 import tkinter as tk
from tkinter import ttk from tkinter import ttk
import grpc
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error
from coretk.images import ImageEnum, Images from coretk.images import ImageEnum, Images
from coretk.widgets import CodeText, ListboxScroll from coretk.widgets import CodeText, ListboxScroll
@ -47,44 +50,48 @@ class ServiceConfiguration(Dialog):
self.draw() self.draw()
def load(self): def load(self):
# create nodes and links in definition state for getting and setting service file try:
self.app.core.create_nodes_and_links() # 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 service_configs = self.app.core.service_configs
if ( if (
self.node_id in service_configs self.node_id in service_configs
and self.service_name in service_configs[self.node_id] and self.service_name in service_configs[self.node_id]
): ):
service_config = self.app.core.service_configs[self.node_id][ service_config = self.app.core.service_configs[self.node_id][
self.service_name self.service_name
] ]
else: else:
service_config = self.app.core.get_node_service( service_config = self.app.core.get_node_service(
self.node_id, self.service_name self.node_id, self.service_name
) )
self.dependencies = [x for x in service_config.dependencies] self.dependencies = [x for x in service_config.dependencies]
self.executables = [x for x in service_config.executables] self.executables = [x for x in service_config.executables]
self.metadata = service_config.meta self.metadata = service_config.meta
self.filenames = [x for x in service_config.configs] self.filenames = [x for x in service_config.configs]
self.startup_commands = [x for x in service_config.startup] self.startup_commands = [x for x in service_config.startup]
self.validation_commands = [x for x in service_config.validate] self.validation_commands = [x for x in service_config.validate]
self.shutdown_commands = [x for x in service_config.shutdown] self.shutdown_commands = [x for x in service_config.shutdown]
self.validation_mode = service_config.validation_mode self.validation_mode = service_config.validation_mode
self.validation_time = service_config.validation_timer self.validation_time = service_config.validation_timer
self.original_service_files = { 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(
for x in self.filenames self.node_id, self.service_name, x
} )
self.temp_service_files = { for x in self.filenames
x: self.original_service_files[x] for x in self.original_service_files }
} self.temp_service_files = {
file_configs = self.app.core.file_configs x: self.original_service_files[x] for x in self.original_service_files
if ( }
self.node_id in file_configs file_configs = self.app.core.file_configs
and self.service_name in file_configs[self.node_id] if (
): self.node_id in file_configs
for file, data in file_configs[self.node_id][self.service_name].items(): and self.service_name in file_configs[self.node_id]
self.temp_service_files[file] = data ):
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): def draw(self):
# self.columnconfigure(1, weight=1) # self.columnconfigure(1, weight=1)
@ -366,30 +373,33 @@ class ServiceConfiguration(Dialog):
startup_commands = self.startup_commands_listbox.get(0, "end") startup_commands = self.startup_commands_listbox.get(0, "end")
shutdown_commands = self.shutdown_commands_listbox.get(0, "end") shutdown_commands = self.shutdown_commands_listbox.get(0, "end")
validate_commands = self.validate_commands_listbox.get(0, "end") validate_commands = self.validate_commands_listbox.get(0, "end")
config = self.core.set_node_service( try:
self.node_id, config = self.core.set_node_service(
self.service_name, self.node_id,
startup_commands, self.service_name,
validate_commands, startup_commands,
shutdown_commands, validate_commands,
) shutdown_commands,
if self.node_id not in service_configs:
service_configs[self.node_id] = {}
if self.service_name not in service_configs[self.node_id]:
self.app.core.service_configs[self.node_id][self.service_name] = config
for file in self.modified_files:
file_configs = self.app.core.file_configs
if self.node_id not in file_configs:
file_configs[self.node_id] = {}
if self.service_name not in file_configs[self.node_id]:
file_configs[self.node_id][self.service_name] = {}
file_configs[self.node_id][self.service_name][
file
] = self.temp_service_files[file]
self.app.core.set_node_service_file(
self.node_id, self.service_name, file, self.temp_service_files[file]
) )
if self.node_id not in service_configs:
service_configs[self.node_id] = {}
if self.service_name not in service_configs[self.node_id]:
self.app.core.service_configs[self.node_id][self.service_name] = config
for file in self.modified_files:
file_configs = self.app.core.file_configs
if self.node_id not in file_configs:
file_configs[self.node_id] = {}
if self.service_name not in file_configs[self.node_id]:
file_configs[self.node_id][self.service_name] = {}
file_configs[self.node_id][self.service_name][
file
] = self.temp_service_files[file]
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() self.destroy()
def display_service_file_data(self, event): def display_service_file_data(self, event):

View file

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

View file

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

View file

@ -4,7 +4,10 @@ wlan configuration
from tkinter import ttk from tkinter import ttk
import grpc
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.errors import show_grpc_error
from coretk.widgets import ConfigFrame from coretk.widgets import ConfigFrame
PAD = 5 PAD = 5
@ -18,7 +21,11 @@ class WlanConfigDialog(Dialog):
self.canvas_node = canvas_node self.canvas_node = canvas_node
self.node = canvas_node.core_node self.node = canvas_node.core_node
self.config_frame = None self.config_frame = None
self.config = self.app.core.get_wlan_config(self.node.id) 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() self.draw()
def draw(self): 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 import tkinter as tk
from tkinter import font from tkinter import font
import grpc
from core.api.grpc.core_pb2 import NodeType from core.api.grpc.core_pb2 import NodeType
from coretk.dialogs.emaneconfig import EmaneConfigDialog from coretk.dialogs.emaneconfig import EmaneConfigDialog
from coretk.dialogs.mobilityconfig import MobilityConfigDialog from coretk.dialogs.mobilityconfig import MobilityConfigDialog
from coretk.dialogs.nodeconfig import NodeConfigDialog from coretk.dialogs.nodeconfig import NodeConfigDialog
from coretk.dialogs.wlanconfig import WlanConfigDialog from coretk.dialogs.wlanconfig import WlanConfigDialog
from coretk.errors import show_grpc_error
from coretk.graph import tags from coretk.graph import tags
from coretk.graph.enums import GraphMode from coretk.graph.enums import GraphMode
from coretk.graph.tooltip import CanvasTooltip from coretk.graph.tooltip import CanvasTooltip
@ -138,8 +141,11 @@ class CanvasNode:
if self.app.core.is_runtime() and self.app.core.observer: if self.app.core.is_runtime() and self.app.core.observer:
self.tooltip.text.set("waiting...") self.tooltip.text.set("waiting...")
self.tooltip.on_enter(event) self.tooltip.on_enter(event)
output = self.app.core.run(self.core_node.id) try:
self.tooltip.text.set(output) 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): def on_leave(self, event):
self.tooltip.on_leave(event) self.tooltip.on_leave(event)

View file

@ -10,7 +10,6 @@ from tkinter import filedialog, messagebox
import grpc import grpc
from core.api.grpc import core_pb2
from coretk.appconfig import XML_PATH from coretk.appconfig import XML_PATH
from coretk.dialogs.about import AboutDialog from coretk.dialogs.about import AboutDialog
from coretk.dialogs.canvasbackground import CanvasBackgroundDialog from coretk.dialogs.canvasbackground import CanvasBackgroundDialog
@ -52,12 +51,7 @@ class MenuAction:
"menuaction.py: clean_nodes_links_and_set_configuration() Exiting the program" "menuaction.py: clean_nodes_links_and_set_configuration() Exiting the program"
) )
try: try:
state = self.app.core.get_session_state() if not self.app.core.is_runtime():
if (
state == core_pb2.SessionState.SHUTDOWN
or state == core_pb2.SessionState.DEFINITION
):
self.app.core.delete_session() self.app.core.delete_session()
if quitapp: if quitapp:
self.app.quit() self.app.quit()
@ -73,7 +67,7 @@ class MenuAction:
elif quitapp: elif quitapp:
self.app.quit() self.app.quit()
except grpc.RpcError: except grpc.RpcError:
logging.error("error getting session state") logging.exception("error deleting session")
if quitapp: if quitapp:
self.app.quit() 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
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). 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: FRR (as of v7.2) currently supports the following protocols:
* BGP * BGPv4
* OSPFv2 * OSPFv2
* OSPFv3 * OSPFv3
* RIPv1 * RIPv1/v2/ng
* RIPv2
* RIPng
* IS-IS * IS-IS
* PIM-SM/MSDP * PIM-SM/MSDP/BSM(AutoRP)
* LDP * LDP
* BFD * BFD
* Babel * Babel
* PBR * PBR
* OpenFabric * OpenFabric
* VRRPv2/v3
* EIGRP (alpha) * EIGRP (alpha)
* NHRP (alpha) * NHRP (alpha)
#### FRRouting Package Install #### FRRouting Package Install
Ubuntu 19.10 and later
```shell
sudo apt update && sudo apt install frr
```
Ubuntu 16.04 and Ubuntu 18.04
```shell ```shell
sudo apt install curl sudo apt install curl
curl -s https://deb.frrouting.org/frr/keys.asc | sudo apt-key add - 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 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 sudo apt update && sudo apt install frr frr-pythontools
``` ```
Fedora 31
```shell
sudo dnf update && sudo dnf install frr
```
#### FRRouting Source Code Install #### 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. 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" echo "$NAME already started"
else else
echo "starting $NAME" echo "starting $NAME"
sudo $CMD 2>&1 >> "$LOG" & $CMD 2>&1 >> "$LOG" &
fi fi
echo $! > "$PIDFILE" echo $! > "$PIDFILE"