From 858e771efd8f040a18c7e222e4dd971536afe145 Mon Sep 17 00:00:00 2001 From: Blake Harnden <32446120+bharnden@users.noreply.github.com> Date: Tue, 28 Jul 2020 21:49:34 -0700 Subject: [PATCH] pygui: fixes for copying links/asymmetric links, fixes for configuring asymmetric links, fixed issues adding nodes/links and editing links from gui due to not being able to identify same source changes --- daemon/core/gui/coreclient.py | 56 +++++++++++++++++++------ daemon/core/gui/dialogs/linkconfig.py | 37 ++++------------- daemon/core/gui/graph/graph.py | 59 ++++++++++++++++++--------- 3 files changed, 91 insertions(+), 61 deletions(-) diff --git a/daemon/core/gui/coreclient.py b/daemon/core/gui/coreclient.py index 6129031a..9fe8130a 100644 --- a/daemon/core/gui/coreclient.py +++ b/daemon/core/gui/coreclient.py @@ -474,21 +474,22 @@ class CoreClient: self.ifaces_manager.reset_mac() nodes = [x.to_proto() for x in self.session.nodes.values()] links = [] - for link in self.session.links: + asymmetric_links = [] + for edge in self.links.values(): + link = edge.link if link.iface1 and not link.iface1.mac: link.iface1.mac = self.ifaces_manager.next_mac() if link.iface2 and not link.iface2.mac: link.iface2.mac = self.ifaces_manager.next_mac() links.append(link.to_proto()) + if edge.asymmetric_link: + asymmetric_links.append(edge.asymmetric_link.to_proto()) wlan_configs = self.get_wlan_configs_proto() mobility_configs = self.get_mobility_configs_proto() emane_model_configs = self.get_emane_model_configs_proto() hooks = [x.to_proto() for x in self.session.hooks.values()] service_configs = self.get_service_configs_proto() file_configs = self.get_service_file_configs_proto() - asymmetric_links = [ - x.asymmetric_link for x in self.links.values() if x.asymmetric_link - ] config_service_configs = self.get_config_service_configs_proto() emane_config = to_dict(self.session.emane_config) result = False @@ -686,17 +687,32 @@ class CoreClient: for node in self.session.nodes.values(): response = self.client.add_node(self.session.id, node.to_proto()) logging.debug("created node: %s", response) - for link in self.session.links: - link_proto = link.to_proto() + asymmetric_links = [] + for edge in self.links.values(): + link = edge.link response = self.client.add_link( self.session.id, - link_proto.node1_id, - link_proto.node2_id, - link_proto.iface1, - link_proto.iface2, - link_proto.options, + link.node1_id, + link.node2_id, + link.iface1, + link.iface2, + link.options, + source=GUI_SOURCE, ) logging.debug("created link: %s", response) + if edge.asymmetric_link: + asymmetric_links.append(edge.asymmetric_link) + for link in asymmetric_links: + response = self.client.add_link( + self.session.id, + link.node1_id, + link.node2_id, + link.iface1, + link.iface2, + link.options, + source=GUI_SOURCE, + ) + logging.debug("created asymmetric link: %s", response) def send_data(self) -> None: """ @@ -892,8 +908,7 @@ class CoreClient: ) edge.set_link(link) self.links[edge.token] = edge - self.session.links.append(link) - logging.info("Add link between %s and %s", src_node.name, dst_node.name) + logging.info("added link between %s and %s", src_node.name, dst_node.name) def get_wlan_configs_proto(self) -> List[wlan_pb2.WlanConfig]: configs = [] @@ -1039,3 +1054,18 @@ class CoreClient: logging.info("execute python script %s", response) if response.session_id != -1: self.join_session(response.session_id) + + def edit_link(self, link: Link) -> None: + iface1_id = link.iface1.id if link.iface1 else None + iface2_id = link.iface2.id if link.iface2 else None + response = self.client.edit_link( + self.session.id, + link.node1_id, + link.node2_id, + link.options.to_proto(), + iface1_id, + iface2_id, + source=GUI_SOURCE, + ) + if not response.result: + logging.error("error editing link: %s", link) diff --git a/daemon/core/gui/dialogs/linkconfig.py b/daemon/core/gui/dialogs/linkconfig.py index 2a91da30..914bad1e 100644 --- a/daemon/core/gui/dialogs/linkconfig.py +++ b/daemon/core/gui/dialogs/linkconfig.py @@ -228,21 +228,15 @@ class LinkConfigurationDialog(Dialog): bandwidth=bandwidth, jitter=jitter, delay=delay, dup=duplicate, loss=loss ) link.options = options - - iface1_id = None - if link.iface1: - iface1_id = link.iface1.id - iface2_id = None - if link.iface2: - iface2_id = link.iface2.id - + iface1_id = link.iface1.id if link.iface1 else None + iface2_id = link.iface2.id if link.iface2 else None if not self.is_symmetric: link.options.unidirectional = True asym_iface1 = None - if iface1_id: + if iface1_id is not None: asym_iface1 = Interface(id=iface1_id) asym_iface2 = None - if iface2_id: + if iface2_id is not None: asym_iface2 = Interface(id=iface2_id) down_bandwidth = get_int(self.down_bandwidth) down_jitter = get_int(self.down_jitter) @@ -260,8 +254,8 @@ class LinkConfigurationDialog(Dialog): self.edge.asymmetric_link = Link( node1_id=link.node2_id, node2_id=link.node1_id, - iface1=asym_iface1, - iface2=asym_iface2, + iface1=asym_iface2, + iface2=asym_iface1, options=options, ) else: @@ -269,24 +263,9 @@ class LinkConfigurationDialog(Dialog): self.edge.asymmetric_link = None if self.app.core.is_runtime() and link.options: - session_id = self.app.core.session.id - self.app.core.client.edit_link( - session_id, - link.node1_id, - link.node2_id, - link.options, - iface1_id, - iface2_id, - ) + self.app.core.edit_link(link) if self.edge.asymmetric_link: - self.app.core.client.edit_link( - session_id, - link.node2_id, - link.node1_id, - self.edge.asymmetric_link.options, - iface1_id, - iface2_id, - ) + self.app.core.edit_link(self.edge.asymmetric_link) # update edge label self.edge.draw_link_options() diff --git a/daemon/core/gui/graph/graph.py b/daemon/core/gui/graph/graph.py index 69ae87cc..bb762bb8 100644 --- a/daemon/core/gui/graph/graph.py +++ b/daemon/core/gui/graph/graph.py @@ -262,7 +262,7 @@ class CanvasGraph(tk.Canvas): edge = self.edges.get(token) if not edge: return - edge.link.options.CopyFrom(link.options) + edge.link.options = deepcopy(link.options) def add_wireless_edge(self, src: CanvasNode, dst: CanvasNode, link: Link) -> None: network_id = link.network_id if link.network_id else None @@ -924,7 +924,8 @@ class CanvasGraph(tk.Canvas): # maps original node canvas id to copy node canvas id copy_map = {} # the edges that will be copy over - to_copy_edges = [] + to_copy_edges = set() + to_copy_ids = {x.id for x in self.to_copy} for canvas_node in self.to_copy: core_node = canvas_node.core_node actual_x = core_node.position.x + 50 @@ -954,15 +955,39 @@ class CanvasGraph(tk.Canvas): self.nodes[node.id] = node self.core.set_canvas_node(copy, node) for edge in canvas_node.edges: - if edge.src not in self.to_copy or edge.dst not in self.to_copy: + if edge.src not in to_copy_ids or edge.dst not in to_copy_ids: if canvas_node.id == edge.src: dst_node = self.nodes[edge.dst] self.create_edge(node, dst_node) + token = create_edge_token(node.id, dst_node.id) elif canvas_node.id == edge.dst: src_node = self.nodes[edge.src] self.create_edge(src_node, node) + token = create_edge_token(src_node.id, node.id) + copy_edge = self.edges[token] + copy_link = copy_edge.link + iface1_id = copy_link.iface1.id if copy_link.iface1 else None + iface2_id = copy_link.iface2.id if copy_link.iface2 else None + options = edge.link.options + if options: + copy_edge.link.options = deepcopy(options) + if options and options.unidirectional: + asym_iface1 = None + if iface1_id is not None: + asym_iface1 = Interface(id=iface1_id) + asym_iface2 = None + if iface2_id is not None: + asym_iface2 = Interface(id=iface2_id) + copy_edge.asymmetric_link = Link( + node1_id=copy_link.node2_id, + node2_id=copy_link.node1_id, + iface1=asym_iface2, + iface2=asym_iface1, + options=deepcopy(edge.asymmetric_link.options), + ) + copy_edge.redraw() else: - to_copy_edges.append(edge) + to_copy_edges.add(edge) # copy link and link config for edge in to_copy_edges: @@ -974,30 +999,26 @@ class CanvasGraph(tk.Canvas): token = create_edge_token(src_node_copy.id, dst_node_copy.id) copy_edge = self.edges[token] copy_link = copy_edge.link + iface1_id = copy_link.iface1.id if copy_link.iface1 else None + iface2_id = copy_link.iface2.id if copy_link.iface2 else None options = edge.link.options - copy_link.options = deepcopy(options) - iface1_id = None - if copy_link.iface1: - iface1_id = copy_link.iface1.id - iface2_id = None - if copy_link.iface2: - iface2_id = copy_link.iface2.id - if not options.unidirectional: - copy_edge.asymmetric_link = None - else: + if options: + copy_link.options = deepcopy(options) + if options and options.unidirectional: asym_iface1 = None - if iface1_id: + if iface1_id is not None: asym_iface1 = Interface(id=iface1_id) asym_iface2 = None - if iface2_id: + if iface2_id is not None: asym_iface2 = Interface(id=iface2_id) copy_edge.asymmetric_link = Link( node1_id=copy_link.node2_id, node2_id=copy_link.node1_id, - iface1=asym_iface1, - iface2=asym_iface2, - options=edge.asymmetric_link.options, + iface1=asym_iface2, + iface2=asym_iface1, + options=deepcopy(edge.asymmetric_link.options), ) + copy_edge.redraw() self.itemconfig( copy_edge.id, width=self.itemcget(edge.id, "width"),