Merge pull request #355 from coreemu/coretk-fix

Coretk fix
This commit is contained in:
bharnden 2020-01-20 21:18:38 -08:00 committed by GitHub
commit daea312162
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 63 additions and 26 deletions

View file

@ -38,6 +38,17 @@ OBSERVERS = {
"IPSec policies": "setkey -DP", "IPSec policies": "setkey -DP",
} }
DEFAULT_TERMS = {
"xterm": "xterm -e",
"aterm": "aterm -e",
"eterm": "eterm -e",
"rxvt": "rxvt -e",
"konsole": "konsole -e",
"lxterminal": "lxterminal -e",
"xfce4-terminal": "xfce4-terminal -x",
"gnome-terminal": "gnome-terminal --window--",
}
class CoreServer: class CoreServer:
def __init__(self, name: str, address: str, port: int): def __init__(self, name: str, address: str, port: int):
@ -110,6 +121,8 @@ class CoreClient:
self.emane_config = None self.emane_config = None
self.service_configs.clear() self.service_configs.clear()
self.file_configs.clear() self.file_configs.clear()
for mobility_player in self.mobility_players.values():
mobility_player.handle_close()
self.mobility_players.clear() self.mobility_players.clear()
# clear streams # clear streams
if self.handling_throughputs: if self.handling_throughputs:
@ -300,6 +313,7 @@ class CoreClient:
# 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: except grpc.RpcError as e:
self.app.after(0, show_grpc_error, e) self.app.after(0, show_grpc_error, e)
@ -396,7 +410,7 @@ class CoreClient:
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 result: %s", 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) self.app.after(0, show_grpc_error, e)
@ -527,6 +541,9 @@ class CoreClient:
try: try:
terminal = self.app.guiconfig["preferences"]["terminal"] terminal = self.app.guiconfig["preferences"]["terminal"]
response = self.client.get_node_terminal(self.session_id, node_id) response = self.client.get_node_terminal(self.session_id, node_id)
output = os.popen(f"echo {terminal}").read()[:-1]
if output in DEFAULT_TERMS:
terminal = DEFAULT_TERMS[output]
cmd = f'{terminal} "{response.terminal}" &' cmd = f'{terminal} "{response.terminal}" &'
logging.info("launching terminal %s", cmd) logging.info("launching terminal %s", cmd)
os.system(cmd) os.system(cmd)
@ -669,6 +686,8 @@ class CoreClient:
config = {x: self.emane_config[x].value for x in self.emane_config} config = {x: self.emane_config[x].value for x in self.emane_config}
self.client.set_emane_config(self.session_id, config) self.client.set_emane_config(self.session_id, config)
self.set_metadata()
def close(self): def close(self):
""" """
Clean ups when done using grpc Clean ups when done using grpc

View file

@ -215,3 +215,7 @@ class SessionsDialog(Dialog):
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()
selections = self.tree.get_children()
if selections:
self.tree.focus(selections[0])
self.tree.selection_set(selections[0])

View file

@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Any, Tuple
from core.gui import themes from core.gui import themes
from core.gui.dialogs.linkconfig import LinkConfigurationDialog from core.gui.dialogs.linkconfig import LinkConfigurationDialog
from core.gui.graph import tags from core.gui.graph import tags
from core.gui.nodeutils import NodeUtils from core.gui.nodeutils import EdgeUtils, NodeUtils
if TYPE_CHECKING: if TYPE_CHECKING:
from core.gui.graph.graph import CanvasGraph from core.gui.graph.graph import CanvasGraph
@ -160,7 +160,7 @@ class CanvasEdge:
def complete(self, dst: int): def complete(self, dst: int):
self.dst = dst self.dst = dst
self.token = tuple(sorted((self.src, self.dst))) self.token = EdgeUtils.get_token(self.src, self.dst)
x, y = self.canvas.coords(self.dst) x, y = self.canvas.coords(self.dst)
x1, y1, _, _ = self.canvas.coords(self.id) x1, y1, _, _ = self.canvas.coords(self.id)
self.canvas.coords(self.id, x1, y1, x, y) self.canvas.coords(self.id, x1, y1, x, y)

View file

@ -5,7 +5,6 @@ from typing import TYPE_CHECKING, List, Tuple
from PIL import Image, ImageTk from PIL import Image, ImageTk
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from core.gui import nodeutils
from core.gui.dialogs.shapemod import ShapeDialog from core.gui.dialogs.shapemod import ShapeDialog
from core.gui.graph import tags from core.gui.graph import tags
from core.gui.graph.edges import CanvasEdge, CanvasWirelessEdge from core.gui.graph.edges import CanvasEdge, CanvasWirelessEdge
@ -13,8 +12,7 @@ from core.gui.graph.enums import GraphMode, ScaleOption
from core.gui.graph.node import CanvasNode from core.gui.graph.node import CanvasNode
from core.gui.graph.shape import Shape from core.gui.graph.shape import Shape
from core.gui.graph.shapeutils import ShapeType, is_draw_shape, is_marker from core.gui.graph.shapeutils import ShapeType, is_draw_shape, is_marker
from core.gui.images import Images from core.gui.nodeutils import EdgeUtils, NodeUtils
from core.gui.nodeutils import NodeUtils
if TYPE_CHECKING: if TYPE_CHECKING:
from core.gui.app import Application from core.gui.app import Application
@ -192,7 +190,7 @@ class CanvasGraph(tk.Canvas):
""" """
add a wireless edge between 2 canvas nodes add a wireless edge between 2 canvas nodes
""" """
token = tuple(sorted((src.id, dst.id))) token = EdgeUtils.get_token(src.id, dst.id)
x1, y1 = self.coords(src.id) x1, y1 = self.coords(src.id)
x2, y2 = self.coords(dst.id) x2, y2 = self.coords(dst.id)
position = (x1, y1, x2, y2) position = (x1, y1, x2, y2)
@ -204,7 +202,7 @@ class CanvasGraph(tk.Canvas):
self.tag_raise(dst.id) self.tag_raise(dst.id)
def delete_wireless_edge(self, src: CanvasNode, dst: CanvasNode): def delete_wireless_edge(self, src: CanvasNode, dst: CanvasNode):
token = tuple(sorted((src.id, dst.id))) token = EdgeUtils.get_token(src.id, dst.id)
edge = self.wireless_edges.pop(token) edge = self.wireless_edges.pop(token)
edge.delete() edge.delete()
src.wireless_edges.remove(edge) src.wireless_edges.remove(edge)
@ -219,16 +217,7 @@ class CanvasGraph(tk.Canvas):
# peer to peer node is not drawn on the GUI # peer to peer node is not drawn on the GUI
if NodeUtils.is_ignore_node(core_node.type): if NodeUtils.is_ignore_node(core_node.type):
continue continue
image = NodeUtils.node_image(core_node)
# draw nodes on the canvas
logging.info("drawing core node: %s", core_node)
image = NodeUtils.node_icon(core_node.type, core_node.model)
if core_node.icon:
try:
image = Images.create(core_node.icon, nodeutils.ICON_SIZE)
except OSError:
logging.error("invalid icon: %s", core_node.icon)
x = core_node.position.x x = core_node.position.x
y = core_node.position.y y = core_node.position.y
node = CanvasNode(self.master, x, y, core_node, image) node = CanvasNode(self.master, x, y, core_node, image)
@ -242,7 +231,7 @@ class CanvasGraph(tk.Canvas):
node_one = canvas_node_one.core_node node_one = canvas_node_one.core_node
canvas_node_two = self.core.canvas_nodes[link.node_two_id] canvas_node_two = self.core.canvas_nodes[link.node_two_id]
node_two = canvas_node_two.core_node node_two = canvas_node_two.core_node
token = tuple(sorted((canvas_node_one.id, canvas_node_two.id))) token = EdgeUtils.get_token(canvas_node_one.id, canvas_node_two.id)
if link.type == core_pb2.LinkType.WIRELESS: if link.type == core_pb2.LinkType.WIRELESS:
self.add_wireless_edge(canvas_node_one, canvas_node_two) self.add_wireless_edge(canvas_node_one, canvas_node_two)
@ -266,8 +255,10 @@ class CanvasGraph(tk.Canvas):
self.core.links[edge.token] = edge self.core.links[edge.token] = edge
if link.HasField("interface_one"): if link.HasField("interface_one"):
canvas_node_one.interfaces.append(link.interface_one) canvas_node_one.interfaces.append(link.interface_one)
edge.src_interface = link.interface_one
if link.HasField("interface_two"): if link.HasField("interface_two"):
canvas_node_two.interfaces.append(link.interface_two) canvas_node_two.interfaces.append(link.interface_two)
edge.dst_interface = link.interface_two
elif link.options.unidirectional: elif link.options.unidirectional:
edge = self.edges[token] edge = self.edges[token]
edge.asymmetric_link = link edge.asymmetric_link = link
@ -385,7 +376,7 @@ class CanvasGraph(tk.Canvas):
return return
# ignore repeated edges # ignore repeated edges
token = tuple(sorted((edge.src, self.selected))) token = EdgeUtils.get_token(edge.src, self.selected)
if token in self.edges: if token in self.edges:
edge.delete() edge.delete()
return return
@ -883,7 +874,7 @@ class CanvasGraph(tk.Canvas):
dest_node_copy = self.nodes[copy_map[edge.token[1]]] dest_node_copy = self.nodes[copy_map[edge.token[1]]]
self.create_edge(source_node_copy, dest_node_copy) self.create_edge(source_node_copy, dest_node_copy)
copy_edge = self.edges[ copy_edge = self.edges[
tuple(sorted([source_node_copy.id, dest_node_copy.id])) EdgeUtils.get_token(source_node_copy.id, dest_node_copy.id)
] ]
copy_link = copy_edge.link copy_link = copy_edge.link
options = edge.link.options options = edge.link.options

View file

@ -32,10 +32,10 @@ class MenuAction:
self.app = app self.app = app
self.canvas = app.canvas self.canvas = app.canvas
def cleanup_old_session(self): def cleanup_old_session(self, session_id):
logging.info("cleaning up old session") logging.info("cleaning up old session")
self.app.core.stop_session() self.app.core.stop_session()
self.app.core.delete_session() self.app.core.delete_session(session_id)
def prompt_save_running_session(self, quitapp: bool = False): def prompt_save_running_session(self, quitapp: bool = False):
""" """
@ -49,7 +49,12 @@ class MenuAction:
callback = None callback = None
if quitapp: if quitapp:
callback = self.app.quit callback = self.app.quit
task = BackgroundTask(self.app, self.cleanup_old_session, callback) task = BackgroundTask(
self.app,
self.cleanup_old_session,
callback,
(self.app.core.session_id,),
)
task.start() task.start()
elif quitapp: elif quitapp:
self.app.quit() self.app.quit()

View file

@ -1,10 +1,12 @@
from typing import TYPE_CHECKING, Optional, Set import logging
from typing import TYPE_CHECKING, Optional, Set, Tuple
from core.api.grpc.core_pb2 import NodeType from core.api.grpc.core_pb2 import NodeType
from core.gui.images import ImageEnum, Images from core.gui.images import ImageEnum, Images
if TYPE_CHECKING: if TYPE_CHECKING:
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from PIL import ImageTk
ICON_SIZE = 48 ICON_SIZE = 48
ANTENNA_SIZE = 32 ANTENNA_SIZE = 32
@ -89,11 +91,21 @@ class NodeUtils:
return node_type in cls.RJ45_NODES return node_type in cls.RJ45_NODES
@classmethod @classmethod
def node_icon(cls, node_type: NodeType, model: str) -> bool: def node_icon(cls, node_type: NodeType, model: str) -> "ImageTk.PhotoImage":
if model == "": if model == "":
model = None model = None
return cls.NODE_ICONS[(node_type, model)] return cls.NODE_ICONS[(node_type, model)]
@classmethod
def node_image(cls, core_node: "core_pb2.Node") -> "ImageTk.PhotoImage":
image = cls.node_icon(core_node.type, core_node.model)
if core_node.icon:
try:
image = Images.create(core_node.icon, ICON_SIZE)
except OSError:
logging.error("invalid icon: %s", core_node.icon)
return image
@classmethod @classmethod
def setup(cls): def setup(cls):
nodes = [ nodes = [
@ -123,3 +135,9 @@ class NodeUtils:
cls.NETWORK_NODES.append(node_draw) cls.NETWORK_NODES.append(node_draw)
cls.NODE_ICONS[(node_type, None)] = node_draw.image cls.NODE_ICONS[(node_type, None)] = node_draw.image
cls.ANTENNA_ICON = Images.get(ImageEnum.ANTENNA, ANTENNA_SIZE) cls.ANTENNA_ICON = Images.get(ImageEnum.ANTENNA, ANTENNA_SIZE)
class EdgeUtils:
@classmethod
def get_token(cls, src: int, dst: int) -> Tuple[int, ...]:
return tuple(sorted([src, dst]))