fix merge conflict

This commit is contained in:
Huy Pham 2020-02-12 14:16:17 -08:00
commit 9cd756f2dc
18 changed files with 126 additions and 56 deletions

View file

@ -335,7 +335,7 @@ class CoreClient:
self.parse_metadata(response.config) self.parse_metadata(response.config)
except grpc.RpcError as e: except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e) self.app.after(0, show_grpc_error, e, self.app, self.app)
# update ui to represent current state # update ui to represent current state
self.app.after(0, self.app.joined_session_update) self.app.after(0, self.app.joined_session_update)
@ -423,16 +423,20 @@ class CoreClient:
) )
self.join_session(response.session_id, query_location=False) self.join_session(response.session_id, query_location=False)
except grpc.RpcError as e: except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e) self.app.after(0, show_grpc_error, e, self.app, self.app)
def delete_session(self, session_id: int = None): def delete_session(self, session_id: int = None, parent_frame=None):
if session_id is None: if session_id is None:
session_id = self.session_id session_id = self.session_id
try: try:
response = self.client.delete_session(session_id) response = self.client.delete_session(session_id)
logging.info("deleted session(%s), Result: %s", session_id, response) logging.info("deleted session(%s), Result: %s", session_id, response)
except grpc.RpcError as e: except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e) # use the right master widget so the error dialog displays right on top of it
master = self.app
if parent_frame:
master = parent_frame
self.app.after(0, show_grpc_error, e, master, self.app)
def set_up(self): def set_up(self):
""" """
@ -468,7 +472,7 @@ 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:
self.app.after(0, show_grpc_error, e) self.app.after(0, show_grpc_error, e, self.app, self.app)
self.app.close() self.app.close()
def edit_node(self, core_node: core_pb2.Node): def edit_node(self, core_node: core_pb2.Node):
@ -477,7 +481,7 @@ class CoreClient:
self.session_id, core_node.id, core_node.position, source=GUI_SOURCE self.session_id, core_node.id, core_node.position, source=GUI_SOURCE
) )
except grpc.RpcError as e: except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e) self.app.after(0, show_grpc_error, e, self.app, self.app)
def start_session(self) -> core_pb2.StartSessionResponse: def start_session(self) -> core_pb2.StartSessionResponse:
nodes = [x.core_node for x in self.canvas_nodes.values()] nodes = [x.core_node for x in self.canvas_nodes.values()]
@ -521,7 +525,7 @@ class CoreClient:
if response.result: if response.result:
self.set_metadata() self.set_metadata()
except grpc.RpcError as e: except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e) self.app.after(0, show_grpc_error, e, self.app, self.app)
return response return response
def stop_session(self, session_id: int = None) -> core_pb2.StartSessionResponse: def stop_session(self, session_id: int = None) -> core_pb2.StartSessionResponse:
@ -532,7 +536,7 @@ class CoreClient:
response = self.client.stop_session(session_id) response = self.client.stop_session(session_id)
logging.info("stopped session(%s), result: %s", session_id, response) logging.info("stopped session(%s), result: %s", session_id, response)
except grpc.RpcError as e: except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e) self.app.after(0, show_grpc_error, e, self.app, self.app)
return response return response
def show_mobility_players(self): def show_mobility_players(self):
@ -577,7 +581,7 @@ class CoreClient:
logging.info("launching terminal %s", cmd) logging.info("launching terminal %s", cmd)
os.system(cmd) os.system(cmd)
except grpc.RpcError as e: except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e) self.app.after(0, show_grpc_error, e, self.app, self.app)
def save_xml(self, file_path: str): def save_xml(self, file_path: str):
""" """
@ -590,7 +594,7 @@ class CoreClient:
response = self.client.save_xml(self.session_id, file_path) response = self.client.save_xml(self.session_id, file_path)
logging.info("saved xml file %s, result: %s", file_path, response) logging.info("saved xml file %s, result: %s", file_path, response)
except grpc.RpcError as e: except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e) self.app.after(0, show_grpc_error, e, self.app, self.app)
def open_xml(self, file_path: str): def open_xml(self, file_path: str):
""" """
@ -601,7 +605,7 @@ class CoreClient:
logging.info("open xml file %s, response: %s", file_path, response) logging.info("open xml file %s, response: %s", file_path, response)
self.join_session(response.session_id) self.join_session(response.session_id)
except grpc.RpcError as e: except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e) self.app.after(0, show_grpc_error, e, self.app, self.app)
def get_node_service( def get_node_service(
self, node_id: int, service_name: str self, node_id: int, service_name: str

Binary file not shown.

After

(image error) Size: 2.2 KiB

View file

@ -65,8 +65,13 @@ class ConfigServiceConfigDialog(Dialog):
self.config_frame = None self.config_frame = None
self.default_config = None self.default_config = None
self.config = None self.config = None
self.has_error = False
self.load() self.load()
self.draw()
if not self.has_error:
self.draw()
def load(self): def load(self):
try: try:
@ -106,7 +111,8 @@ class ConfigServiceConfigDialog(Dialog):
self.modified_files.add(file) self.modified_files.add(file)
self.temp_service_files[file] = data self.temp_service_files[file] = data
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) self.has_error = True
show_grpc_error(e, self.app, self.app)
def draw(self): def draw(self):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)
@ -327,7 +333,7 @@ class ConfigServiceConfigDialog(Dialog):
all_current = current_listbox.get(0, tk.END) all_current = current_listbox.get(0, tk.END)
current_listbox.itemconfig(all_current.index(self.service_name), bg="green") current_listbox.itemconfig(all_current.index(self.service_name), bg="green")
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) show_grpc_error(e, self.top, self.app)
self.destroy() self.destroy()
def handle_template_changed(self, event: tk.Event): def handle_template_changed(self, event: tk.Event):

View file

@ -65,14 +65,16 @@ 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.has_error = False
try: try:
self.config = self.app.core.get_emane_model_config( self.config = self.app.core.get_emane_model_config(
self.node.id, self.model, self.interface self.node.id, self.model, self.interface
) )
self.draw()
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) show_grpc_error(e, self.app, self.app)
self.has_error = True
self.destroy() self.destroy()
self.draw()
def draw(self): def draw(self):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)
@ -225,7 +227,8 @@ class EmaneConfigDialog(Dialog):
dialog = EmaneModelDialog( dialog = EmaneModelDialog(
self, self.app, self.canvas_node.core_node, model_name self, self.app, self.canvas_node.core_node, model_name
) )
dialog.show() if not dialog.has_error:
dialog.show()
def emane_model_change(self, event: tk.Event): def emane_model_change(self, event: tk.Event):
""" """

View file

@ -29,12 +29,14 @@ 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.has_error = False
try: try:
self.config = self.app.core.get_mobility_config(self.node.id) self.config = self.app.core.get_mobility_config(self.node.id)
self.draw()
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) self.has_error = True
show_grpc_error(e, self.app, self.app)
self.destroy() self.destroy()
self.draw()
def draw(self): def draw(self):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)

View file

@ -153,7 +153,7 @@ class MobilityPlayerDialog(Dialog):
session_id, self.node.id, MobilityAction.START session_id, self.node.id, MobilityAction.START
) )
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) show_grpc_error(e, self.top, self.app)
def click_pause(self): def click_pause(self):
self.set_pause() self.set_pause()
@ -163,7 +163,7 @@ class MobilityPlayerDialog(Dialog):
session_id, self.node.id, MobilityAction.PAUSE session_id, self.node.id, MobilityAction.PAUSE
) )
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) show_grpc_error(e, self.top, self.app)
def click_stop(self): def click_stop(self):
self.set_stop() self.set_stop()
@ -173,4 +173,4 @@ class MobilityPlayerDialog(Dialog):
session_id, self.node.id, MobilityAction.STOP session_id, self.node.id, MobilityAction.STOP
) )
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) show_grpc_error(e, self.top, self.app)

View file

@ -124,7 +124,8 @@ class NodeConfigServiceDialog(Dialog):
service_name=self.current.listbox.get(current_selection[0]), service_name=self.current.listbox.get(current_selection[0]),
node_id=self.node_id, node_id=self.node_id,
) )
dialog.show() if not dialog.has_error:
dialog.show()
else: else:
messagebox.showinfo( messagebox.showinfo(
"Node service configuration", "Select a service to configure" "Node service configuration", "Select a service to configure"

View file

@ -140,7 +140,12 @@ class NodeServiceDialog(Dialog):
service_name=self.current.listbox.get(current_selection[0]), service_name=self.current.listbox.get(current_selection[0]),
node_id=self.node_id, node_id=self.node_id,
) )
dialog.show()
# if error occurred when creating ServiceConfigDialog, don't show the dialog
if not dialog.has_error:
dialog.show()
else:
dialog.destroy()
else: else:
messagebox.showinfo( messagebox.showinfo(
"Node service configuration", "Select a service to configure" "Node service configuration", "Select a service to configure"

View file

@ -64,10 +64,14 @@ class ServiceConfigDialog(Dialog):
self.original_service_files = {} self.original_service_files = {}
self.temp_service_files = {} self.temp_service_files = {}
self.modified_files = set() self.modified_files = set()
self.load()
self.draw()
def load(self): self.has_error = False
self.load()
if not self.has_error:
self.draw()
def load(self) -> bool:
try: try:
self.app.core.create_nodes_and_links() self.app.core.create_nodes_and_links()
default_config = self.app.core.get_node_service( default_config = self.app.core.get_node_service(
@ -109,7 +113,8 @@ class ServiceConfigDialog(Dialog):
for file, data in file_configs[self.node_id][self.service_name].items(): for file, data in file_configs[self.node_id][self.service_name].items():
self.temp_service_files[file] = data self.temp_service_files[file] = data
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) self.has_error = True
show_grpc_error(e, self.master, self.app)
def draw(self): def draw(self):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)
@ -444,7 +449,7 @@ class ServiceConfigDialog(Dialog):
all_current = current_listbox.get(0, tk.END) all_current = current_listbox.get(0, tk.END)
current_listbox.itemconfig(all_current.index(self.service_name), bg="green") current_listbox.itemconfig(all_current.index(self.service_name), bg="green")
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) show_grpc_error(e, self.top, self.app)
self.destroy() self.destroy()
def display_service_file_data(self, event: tk.Event): def display_service_file_data(self, event: tk.Event):

View file

@ -17,8 +17,10 @@ class SessionOptionsDialog(Dialog):
def __init__(self, master: "Application", app: "Application"): def __init__(self, master: "Application", app: "Application"):
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.has_error = False
self.config = self.get_config() self.config = self.get_config()
self.draw() if not self.has_error:
self.draw()
def get_config(self): def get_config(self):
try: try:
@ -26,7 +28,8 @@ class SessionOptionsDialog(Dialog):
response = self.app.core.client.get_session_options(session_id) response = self.app.core.client.get_session_options(session_id)
return response.config return response.config
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) self.has_error = True
show_grpc_error(e, self.app, self.app)
self.destroy() self.destroy()
def draw(self): def draw(self):
@ -53,5 +56,5 @@ class SessionOptionsDialog(Dialog):
response = self.app.core.client.set_session_options(session_id, config) response = self.app.core.client.set_session_options(session_id, config)
logging.info("saved session config: %s", response) logging.info("saved session config: %s", response)
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) show_grpc_error(e, self.top, self.app)
self.destroy() self.destroy()

View file

@ -25,8 +25,10 @@ class SessionsDialog(Dialog):
self.selected = False self.selected = False
self.selected_id = None self.selected_id = None
self.tree = None self.tree = None
self.has_error = False
self.sessions = self.get_sessions() self.sessions = self.get_sessions()
self.draw() if not self.has_error:
self.draw()
def get_sessions(self) -> Iterable[core_pb2.SessionSummary]: def get_sessions(self) -> Iterable[core_pb2.SessionSummary]:
try: try:
@ -34,7 +36,8 @@ class SessionsDialog(Dialog):
logging.info("sessions: %s", response) logging.info("sessions: %s", response)
return response.sessions return response.sessions
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) show_grpc_error(e, self.app, self.app)
self.has_error = True
self.destroy() self.destroy()
def draw(self): def draw(self):
@ -211,7 +214,7 @@ class SessionsDialog(Dialog):
item = self.tree.selection() item = self.tree.selection()
if item: if item:
sid = int(self.tree.item(item, "text")) sid = int(self.tree.item(item, "text"))
self.app.core.delete_session(sid) self.app.core.delete_session(sid, self.top)
self.tree.delete(item[0]) self.tree.delete(item[0])
if sid == self.app.core.session_id: if sid == self.app.core.session_id:
self.click_new() self.click_new()

View file

@ -27,12 +27,14 @@ 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.has_error = False
try: try:
self.config = self.app.core.get_wlan_config(self.node.id) self.config = self.app.core.get_wlan_config(self.node.id)
self.draw()
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) show_grpc_error(e, self.app, self.app)
self.has_error = True
self.destroy() self.destroy()
self.draw()
def draw(self): def draw(self):
self.top.columnconfigure(0, weight=1) self.top.columnconfigure(0, weight=1)

View file

@ -1,12 +1,38 @@
from tkinter import messagebox from tkinter import ttk
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from core.gui.dialogs.dialog import Dialog
from core.gui.images import ImageEnum, Images
from core.gui.widgets import CodeText
if TYPE_CHECKING: if TYPE_CHECKING:
import grpc import grpc
from core.gui.app import Application
def show_grpc_error(e: "grpc.RpcError"): class ErrorDialog(Dialog):
def __init__(self, master, app: "Application", title: str, details: str):
super().__init__(master, app, title, modal=True)
self.error_message = None
self.details = details
self.draw()
def draw(self):
self.top.columnconfigure(0, weight=1)
self.top.rowconfigure(0, weight=1)
image = Images.get(ImageEnum.ERROR, 36)
label = ttk.Label(self.top, image=image)
label.image = image
label.grid(row=0, column=0)
self.error_message = CodeText(self.top)
self.error_message.text.insert("1.0", self.details)
self.error_message.text.config(state="disabled")
self.error_message.grid(row=1, column=0, sticky="nsew")
def show_grpc_error(e: "grpc.RpcError", master, app: "Application"):
title = [x.capitalize() for x in e.code().name.lower().split("_")] title = [x.capitalize() for x in e.code().name.lower().split("_")]
title = " ".join(title) title = " ".join(title)
title = f"GRPC {title}" title = f"GRPC {title}"
messagebox.showerror(title, e.details()) dialog = ErrorDialog(master, app, title, e.details())
dialog.show()

View file

@ -163,7 +163,7 @@ class CanvasNode:
output = self.app.core.run(self.core_node.id) output = self.app.core.run(self.core_node.id)
self.tooltip.text.set(output) self.tooltip.text.set(output)
except grpc.RpcError as e: except grpc.RpcError as e:
show_grpc_error(e) show_grpc_error(e, self.app, self.app)
def on_leave(self, event: tk.Event): def on_leave(self, event: tk.Event):
self.tooltip.on_leave(event) self.tooltip.on_leave(event)
@ -238,12 +238,14 @@ class CanvasNode:
def show_wlan_config(self): def show_wlan_config(self):
self.canvas.context = None self.canvas.context = None
dialog = WlanConfigDialog(self.app, self.app, self) dialog = WlanConfigDialog(self.app, self.app, self)
dialog.show() if not dialog.has_error:
dialog.show()
def show_mobility_config(self): def show_mobility_config(self):
self.canvas.context = None self.canvas.context = None
dialog = MobilityConfigDialog(self.app, self.app, self) dialog = MobilityConfigDialog(self.app, self.app, self)
dialog.show() if not dialog.has_error:
dialog.show()
def show_mobility_player(self): def show_mobility_player(self):
self.canvas.context = None self.canvas.context = None

View file

@ -89,3 +89,4 @@ class ImageEnum(Enum):
DELETE = "delete" DELETE = "delete"
SHUTDOWN = "shutdown" SHUTDOWN = "shutdown"
CANCEL = "cancel" CANCEL = "cancel"
ERROR = "error"

View file

@ -9,6 +9,8 @@ import webbrowser
from tkinter import filedialog, messagebox from tkinter import filedialog, messagebox
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import grpc
from core.gui.appconfig import XMLS_PATH from core.gui.appconfig import XMLS_PATH
from core.gui.dialogs.about import AboutDialog from core.gui.dialogs.about import AboutDialog
from core.gui.dialogs.canvassizeandscale import SizeAndScaleDialog from core.gui.dialogs.canvassizeandscale import SizeAndScaleDialog
@ -34,12 +36,18 @@ class MenuAction:
self.app = app self.app = app
self.canvas = app.canvas self.canvas = app.canvas
def cleanup_old_session(self, session_id): def cleanup_old_session(self, session_id: int):
response = self.app.core.stop_session() try:
self.app.core.delete_session(session_id) res = self.app.core.client.get_session(session_id)
logging.info( logging.debug("retrieve session(%s), %s", session_id, res)
"Stop session(%s) and delete it, result: %s", session_id, response.result stop_response = self.app.core.stop_session()
) logging.debug("stop session(%s), result: %s", session_id, stop_response)
delete_response = self.app.core.delete_session(session_id)
logging.debug(
"deleted session(%s), result: %s", session_id, delete_response
)
except grpc.RpcError:
logging.debug("session is not alive")
def prompt_save_running_session(self, quitapp: bool = False): def prompt_save_running_session(self, quitapp: bool = False):
""" """
@ -125,7 +133,8 @@ class MenuAction:
def session_options(self): def session_options(self):
logging.debug("Click options") logging.debug("Click options")
dialog = SessionOptionsDialog(self.app, self.app) dialog = SessionOptionsDialog(self.app, self.app)
dialog.show() if not dialog.has_error:
dialog.show()
def session_change_sessions(self): def session_change_sessions(self):
logging.debug("Click change sessions") logging.debug("Click change sessions")

View file

@ -3,7 +3,7 @@ import time
import tkinter as tk import tkinter as tk
from enum import Enum from enum import Enum
from functools import partial from functools import partial
from tkinter import messagebox, ttk from tkinter import ttk
from typing import TYPE_CHECKING, Callable from typing import TYPE_CHECKING, Callable
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
@ -302,9 +302,6 @@ class Toolbar(ttk.Frame):
self.set_runtime() self.set_runtime()
self.app.core.set_metadata() self.app.core.set_metadata()
self.app.core.show_mobility_players() self.app.core.show_mobility_players()
else:
message = "\n".join(response.exceptions)
messagebox.showerror("Start Error", message)
def set_runtime(self): def set_runtime(self):
self.runtime_frame.tkraise() self.runtime_frame.tkraise()
@ -490,8 +487,6 @@ class Toolbar(ttk.Frame):
message = f"Stopped in {total:.3f} seconds" message = f"Stopped in {total:.3f} seconds"
self.app.statusbar.set_status(message) self.app.statusbar.set_status(message)
self.app.canvas.stopped_session() self.app.canvas.stopped_session()
if not response.result:
messagebox.showerror("Stop Error", "Errors stopping session")
def update_annotation( def update_annotation(
self, image: "ImageTk.PhotoImage", shape_type: ShapeType, image_enum self, image: "ImageTk.PhotoImage", shape_type: ShapeType, image_enum

View file

@ -208,6 +208,9 @@ bootfrr()
fi fi
bootdaemon "zebra" bootdaemon "zebra"
if grep -q "^ip route " $FRR_CONF; then
bootdaemon "staticd"
fi
for r in rip ripng ospf6 ospf bgp babel; do for r in rip ripng ospf6 ospf bgp babel; do
if grep -q "^router \\<${r}\\>" $FRR_CONF; then if grep -q "^router \\<${r}\\>" $FRR_CONF; then
bootdaemon "${r}d" bootdaemon "${r}d"