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,85 +196,92 @@ class CoreClient:
self.reset()
# get session data
response = self.client.get_session(self.session_id)
session = response.session
self.state = session.state
self.client.events(self.session_id, self.handle_events)
self.client.throughputs(self.handle_throughputs)
try:
response = self.client.get_session(self.session_id)
session = response.session
self.state = session.state
self.client.events(self.session_id, self.handle_events)
self.client.throughputs(self.handle_throughputs)
# get location
if query_location:
response = self.client.get_session_location(self.session_id)
self.location = response.location
# get location
if query_location:
response = self.client.get_session_location(self.session_id)
self.location = response.location
# get emane models
response = self.client.get_emane_models(self.session_id)
self.emane_models = response.models
# get emane models
response = self.client.get_emane_models(self.session_id)
self.emane_models = response.models
# get hooks
response = self.client.get_hooks(self.session_id)
for hook in response.hooks:
self.hooks[hook.file] = hook
# get hooks
response = self.client.get_hooks(self.session_id)
for hook in response.hooks:
self.hooks[hook.file] = hook
# get mobility configs
response = self.client.get_mobility_configs(self.session_id)
for node_id in response.configs:
node_config = response.configs[node_id].config
self.mobility_configs[node_id] = node_config
# get mobility configs
response = self.client.get_mobility_configs(self.session_id)
for node_id in response.configs:
node_config = response.configs[node_id].config
self.mobility_configs[node_id] = node_config
# get emane config
response = self.client.get_emane_config(self.session_id)
self.emane_config = response.config
# get emane config
response = self.client.get_emane_config(self.session_id)
self.emane_config = response.config
# get emane model config
response = self.client.get_emane_model_configs(self.session_id)
for _id in response.configs:
config = response.configs[_id]
interface = None
node_id = _id
if _id >= 1000:
interface = _id % 1000
node_id = int(_id / 1000)
self.set_emane_model_config(node_id, config.model, config.config, interface)
# get emane model config
response = self.client.get_emane_model_configs(self.session_id)
for _id in response.configs:
config = response.configs[_id]
interface = None
node_id = _id
if _id >= 1000:
interface = _id % 1000
node_id = int(_id / 1000)
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:
# get node service config and file config
self.created_nodes.add(node.id)
# save and retrieve data, needed for session nodes
for node in session.nodes:
# get node service config and file config
self.created_nodes.add(node.id)
# get wlan configs for wlan nodes
if node.type == core_pb2.NodeType.WIRELESS_LAN:
response = self.client.get_wlan_config(self.session_id, node.id)
self.wlan_configs[node.id] = response.config
# retrieve service configurations data for default nodes
elif node.type == core_pb2.NodeType.DEFAULT:
for service in node.services:
response = self.client.get_node_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
# get wlan configs for wlan nodes
if node.type == core_pb2.NodeType.WIRELESS_LAN:
response = self.client.get_wlan_config(self.session_id, node.id)
self.wlan_configs[node.id] = response.config
# retrieve service configurations data for default nodes
elif node.type == core_pb2.NodeType.DEFAULT:
for service in node.services:
response = self.client.get_node_service(
self.session_id, node.id, service
)
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
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:
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
for link in session.links:
self.created_links.add(tuple(sorted([link.node_one_id, link.node_two_id])))
# store links as created links
for link in session.links:
self.created_links.add(
tuple(sorted([link.node_one_id, link.node_two_id]))
)
# draw session
self.app.canvas.reset_and_redraw(session)
# draw session
self.app.canvas.reset_and_redraw(session)
# get metadata
response = self.client.get_session_metadata(self.session_id)
self.parse_metadata(response.config)
# 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,25 +360,31 @@ class CoreClient:
:return: nothing
"""
response = self.client.create_session()
logging.info("created session: %s", response)
location_config = self.app.guiconfig["location"]
self.location = core_pb2.SessionLocation(
x=location_config["x"],
y=location_config["y"],
z=location_config["z"],
lat=location_config["lat"],
lon=location_config["lon"],
alt=location_config["alt"],
scale=location_config["scale"],
)
self.join_session(response.session_id, query_location=False)
try:
response = self.client.create_session()
logging.info("created session: %s", response)
location_config = self.app.guiconfig["location"]
self.location = core_pb2.SessionLocation(
x=location_config["x"],
y=location_config["y"],
z=location_config["z"],
lat=location_config["lat"],
lon=location_config["lon"],
alt=location_config["alt"],
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
response = self.client.delete_session(session_id)
logging.info("Deleted session result: %s", response)
try:
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):
"""
@ -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)
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):
nodes = [x.core_node for x in self.canvas_nodes.values()]
@ -436,39 +443,51 @@ class CoreClient:
emane_config = None
start = time.perf_counter()
response = self.client.start_session(
self.session_id,
nodes,
links,
self.location,
hooks,
emane_config,
emane_model_configs,
wlan_configs,
mobility_configs,
service_configs,
file_configs,
)
self.set_metadata()
process_time = time.perf_counter() - start
logging.debug("start session(%s), result: %s", self.session_id, response.result)
self.app.statusbar.start_session_callback(process_time)
try:
response = self.client.start_session(
self.session_id,
nodes,
links,
self.location,
hooks,
emane_config,
emane_model_configs,
wlan_configs,
mobility_configs,
service_configs,
file_configs,
)
self.set_metadata()
process_time = time.perf_counter() - start
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.show()
self.mobility_players[node_id] = mobility_player
# 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.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()
response = self.client.stop_session(session_id)
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)
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)
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):
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} &")
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
"""
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)
try:
response = self.client.save_xml(self.session_id, file_path)
logging.info("saved xml(%s): %s", file_path, response)
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
"""
response = self.client.open_xml(file_path)
logging.debug("open xml: %s", response)
self.join_session(response.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
self.config = self.app.core.get_emane_model_config(
self.node.id, self.model, self.interface
)
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
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()
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
self.app.core.client.mobility_action(
session_id, self.node.id, MobilityAction.START
)
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
self.app.core.client.mobility_action(
session_id, self.node.id, MobilityAction.PAUSE
)
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
self.app.core.client.mobility_action(
session_id, self.node.id, MobilityAction.STOP
)
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,44 +50,48 @@ class ServiceConfiguration(Dialog):
self.draw()
def load(self):
# 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
and self.service_name in service_configs[self.node_id]
):
service_config = self.app.core.service_configs[self.node_id][
self.service_name
]
else:
service_config = self.app.core.get_node_service(
self.node_id, self.service_name
)
self.dependencies = [x for x in service_config.dependencies]
self.executables = [x for x in service_config.executables]
self.metadata = service_config.meta
self.filenames = [x for x in service_config.configs]
self.startup_commands = [x for x in service_config.startup]
self.validation_commands = [x for x in service_config.validate]
self.shutdown_commands = [x for x in service_config.shutdown]
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)
for x in self.filenames
}
self.temp_service_files = {
x: self.original_service_files[x] for x in self.original_service_files
}
file_configs = self.app.core.file_configs
if (
self.node_id in file_configs
and self.service_name in file_configs[self.node_id]
):
for file, data in file_configs[self.node_id][self.service_name].items():
self.temp_service_files[file] = data
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
and self.service_name in service_configs[self.node_id]
):
service_config = self.app.core.service_configs[self.node_id][
self.service_name
]
else:
service_config = self.app.core.get_node_service(
self.node_id, self.service_name
)
self.dependencies = [x for x in service_config.dependencies]
self.executables = [x for x in service_config.executables]
self.metadata = service_config.meta
self.filenames = [x for x in service_config.configs]
self.startup_commands = [x for x in service_config.startup]
self.validation_commands = [x for x in service_config.validate]
self.shutdown_commands = [x for x in service_config.shutdown]
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
)
for x in self.filenames
}
self.temp_service_files = {
x: self.original_service_files[x] for x in self.original_service_files
}
file_configs = self.app.core.file_configs
if (
self.node_id in file_configs
and self.service_name in file_configs[self.node_id]
):
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,30 +373,33 @@ 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")
config = self.core.set_node_service(
self.node_id,
self.service_name,
startup_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]
try:
config = self.core.set_node_service(
self.node_id,
self.service_name,
startup_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]
)
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()
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)
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
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()
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)
output = self.app.core.run(self.core_node.id)
self.tooltip.text.set(output)
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"