pygui updated node service configurations to be self contained and copyable
This commit is contained in:
parent
85b4a81f8a
commit
d7ebb90329
6 changed files with 57 additions and 77 deletions
|
@ -91,9 +91,7 @@ class CoreClient:
|
|||
self.links = {}
|
||||
self.hooks = {}
|
||||
self.emane_config = None
|
||||
self.service_configs = {}
|
||||
self.config_service_configs = {}
|
||||
self.file_configs = {}
|
||||
self.mobility_players = {}
|
||||
self.handling_throughputs = None
|
||||
self.handling_events = None
|
||||
|
@ -126,8 +124,6 @@ class CoreClient:
|
|||
self.links.clear()
|
||||
self.hooks.clear()
|
||||
self.emane_config = None
|
||||
self.service_configs.clear()
|
||||
self.file_configs.clear()
|
||||
self.modified_service_nodes.clear()
|
||||
for mobility_player in self.mobility_players.values():
|
||||
mobility_player.handle_close()
|
||||
|
@ -332,13 +328,14 @@ class CoreClient:
|
|||
# get service configurations
|
||||
response = self.client.get_node_service_configs(self.session_id)
|
||||
for config in response.configs:
|
||||
service_configs = self.service_configs.setdefault(config.node_id, {})
|
||||
service_configs[config.service] = config.data
|
||||
canvas_node = self.canvas_nodes[config.node_id]
|
||||
canvas_node.service_configs[config.service] = config.data
|
||||
logging.debug("service file configs: %s", config.files)
|
||||
for file_name in config.files:
|
||||
file_configs = self.file_configs.setdefault(config.node_id, {})
|
||||
files = file_configs.setdefault(config.service, {})
|
||||
data = config.files[file_name]
|
||||
files = canvas_node.service_file_configs.setdefault(
|
||||
config.service, {}
|
||||
)
|
||||
files[file_name] = data
|
||||
|
||||
# get config service configurations
|
||||
|
@ -953,8 +950,13 @@ class CoreClient:
|
|||
|
||||
def get_service_configs_proto(self) -> List[ServiceConfig]:
|
||||
configs = []
|
||||
for node_id, services in self.service_configs.items():
|
||||
for name, config in services.items():
|
||||
for canvas_node in self.canvas_nodes.values():
|
||||
if not NodeUtils.is_container_node(canvas_node.core_node.type):
|
||||
continue
|
||||
if not canvas_node.service_configs:
|
||||
continue
|
||||
node_id = canvas_node.core_node.id
|
||||
for name, config in canvas_node.service_configs.items():
|
||||
config_proto = ServiceConfig(
|
||||
node_id=node_id,
|
||||
service=name,
|
||||
|
@ -969,9 +971,14 @@ class CoreClient:
|
|||
|
||||
def get_service_file_configs_proto(self) -> List[ServiceFileConfig]:
|
||||
configs = []
|
||||
for (node_id, file_configs) in self.file_configs.items():
|
||||
for service, file_config in file_configs.items():
|
||||
for file, data in file_config.items():
|
||||
for canvas_node in self.canvas_nodes.values():
|
||||
if not NodeUtils.is_container_node(canvas_node.core_node.type):
|
||||
continue
|
||||
if not canvas_node.service_file_configs:
|
||||
continue
|
||||
node_id = canvas_node.core_node.id
|
||||
for service, file_configs in canvas_node.service_file_configs.items():
|
||||
for file, data in file_configs.items():
|
||||
config_proto = ServiceFileConfig(
|
||||
node_id=node_id, service=service, file=file, data=data
|
||||
)
|
||||
|
@ -1036,27 +1043,6 @@ class CoreClient:
|
|||
)
|
||||
return dict(config)
|
||||
|
||||
def copy_node_service(self, _from: int, _to: int):
|
||||
services = self.canvas_nodes[_from].core_node.services
|
||||
self.canvas_nodes[_to].core_node.services[:] = services
|
||||
logging.debug("copying node %s service to node %s", _from, _to)
|
||||
|
||||
def copy_node_config(self, src_node: core_pb2.Node, dst_id: int):
|
||||
node_type = src_node.type
|
||||
if node_type == core_pb2.NodeType.DEFAULT:
|
||||
services = src_node.services
|
||||
dst_node = self.canvas_nodes[dst_id]
|
||||
dst_node.core_node.services[:] = services
|
||||
config = self.service_configs.get(src_node.id)
|
||||
if config:
|
||||
self.service_configs[dst_id] = config
|
||||
file_configs = self.file_configs.get(src_node.id)
|
||||
if file_configs:
|
||||
for key, value in file_configs.items():
|
||||
if dst_id not in self.file_configs:
|
||||
self.file_configs[dst_id] = {}
|
||||
self.file_configs[dst_id][key] = value
|
||||
|
||||
def service_been_modified(self, node_id: int) -> bool:
|
||||
return node_id in self.modified_service_nodes
|
||||
|
||||
|
|
|
@ -135,10 +135,11 @@ class NodeServiceDialog(Dialog):
|
|||
current_selection = self.current.listbox.curselection()
|
||||
if len(current_selection):
|
||||
dialog = ServiceConfigDialog(
|
||||
master=self,
|
||||
app=self.app,
|
||||
service_name=self.current.listbox.get(current_selection[0]),
|
||||
node_id=self.node_id,
|
||||
self,
|
||||
self.app,
|
||||
self.current.listbox.get(current_selection[0]),
|
||||
self.canvas_node,
|
||||
self.node_id,
|
||||
)
|
||||
|
||||
# if error occurred when creating ServiceConfigDialog, don't show the dialog
|
||||
|
@ -182,14 +183,6 @@ class NodeServiceDialog(Dialog):
|
|||
return
|
||||
|
||||
def is_custom_service(self, service: str) -> bool:
|
||||
service_configs = self.app.core.service_configs
|
||||
file_configs = self.app.core.file_configs
|
||||
if self.node_id in service_configs and service in service_configs[self.node_id]:
|
||||
return True
|
||||
if (
|
||||
self.node_id in file_configs
|
||||
and service in file_configs[self.node_id]
|
||||
and file_configs[self.node_id][service]
|
||||
):
|
||||
return True
|
||||
return False
|
||||
has_service_config = service in self.canvas_node.service_configs
|
||||
has_file_config = service in self.canvas_node.service_file_configs
|
||||
return has_service_config or has_file_config
|
||||
|
|
|
@ -16,22 +16,26 @@ from core.gui.widgets import CodeText, ListboxScroll
|
|||
|
||||
if TYPE_CHECKING:
|
||||
from core.gui.app import Application
|
||||
from core.gui.graph.node import CanvasNode
|
||||
|
||||
|
||||
class ServiceConfigDialog(Dialog):
|
||||
def __init__(
|
||||
self, master: Any, app: "Application", service_name: str, node_id: int
|
||||
self,
|
||||
master: Any,
|
||||
app: "Application",
|
||||
service_name: str,
|
||||
canvas_node: "CanvasNode",
|
||||
node_id: int,
|
||||
):
|
||||
title = f"{service_name} Service"
|
||||
super().__init__(master, app, title, modal=True)
|
||||
self.master = master
|
||||
self.app = app
|
||||
self.core = app.core
|
||||
self.canvas_node = canvas_node
|
||||
self.node_id = node_id
|
||||
self.service_name = service_name
|
||||
self.service_configs = app.core.service_configs
|
||||
self.file_configs = app.core.file_configs
|
||||
|
||||
self.radiovar = tk.IntVar()
|
||||
self.radiovar.set(2)
|
||||
self.metadata = ""
|
||||
|
@ -54,7 +58,6 @@ class ServiceConfigDialog(Dialog):
|
|||
ImageEnum.DOCUMENTNEW, int(16 * app.app_scale)
|
||||
)
|
||||
self.editdelete_img = Images.get(ImageEnum.EDITDELETE, int(16 * app.app_scale))
|
||||
|
||||
self.notebook = None
|
||||
self.metadata_entry = None
|
||||
self.filename_combobox = None
|
||||
|
@ -70,9 +73,7 @@ class ServiceConfigDialog(Dialog):
|
|||
self.default_config = None
|
||||
self.temp_service_files = {}
|
||||
self.modified_files = set()
|
||||
|
||||
self.has_error = False
|
||||
|
||||
self.load()
|
||||
if not self.has_error:
|
||||
self.draw()
|
||||
|
@ -87,8 +88,8 @@ class ServiceConfigDialog(Dialog):
|
|||
self.default_validate = default_config.validate[:]
|
||||
self.default_shutdown = default_config.shutdown[:]
|
||||
self.default_directories = default_config.dirs[:]
|
||||
custom_service_config = self.service_configs.get(self.node_id, {}).get(
|
||||
self.service_name, None
|
||||
custom_service_config = self.canvas_node.service_configs.get(
|
||||
self.service_name
|
||||
)
|
||||
self.default_config = default_config
|
||||
service_config = (
|
||||
|
@ -111,10 +112,11 @@ class ServiceConfigDialog(Dialog):
|
|||
for x in default_config.configs
|
||||
}
|
||||
self.temp_service_files = dict(self.original_service_files)
|
||||
file_config = self.file_configs.get(self.node_id, {}).get(
|
||||
|
||||
file_configs = self.canvas_node.service_file_configs.get(
|
||||
self.service_name, {}
|
||||
)
|
||||
for file, data in file_config.items():
|
||||
for file, data in file_configs.items():
|
||||
self.temp_service_files[file] = data
|
||||
except grpc.RpcError as e:
|
||||
self.has_error = True
|
||||
|
@ -449,7 +451,7 @@ class ServiceConfigDialog(Dialog):
|
|||
and not self.has_new_files()
|
||||
and not self.is_custom_directory()
|
||||
):
|
||||
self.service_configs.get(self.node_id, {}).pop(self.service_name, None)
|
||||
self.canvas_node.service_configs.pop(self.service_name, None)
|
||||
self.current_service_color("")
|
||||
self.destroy()
|
||||
return
|
||||
|
@ -470,17 +472,13 @@ class ServiceConfigDialog(Dialog):
|
|||
validations=validate,
|
||||
shutdowns=shutdown,
|
||||
)
|
||||
if self.node_id not in self.service_configs:
|
||||
self.service_configs[self.node_id] = {}
|
||||
self.service_configs[self.node_id][self.service_name] = config
|
||||
self.canvas_node.service_configs[self.service_name] = config
|
||||
for file in self.modified_files:
|
||||
if self.node_id not in self.file_configs:
|
||||
self.file_configs[self.node_id] = {}
|
||||
if self.service_name not in self.file_configs[self.node_id]:
|
||||
self.file_configs[self.node_id][self.service_name] = {}
|
||||
self.file_configs[self.node_id][self.service_name][
|
||||
file
|
||||
] = self.temp_service_files[file]
|
||||
file_configs = self.canvas_node.service_file_configs.setdefault(
|
||||
self.service_name, {}
|
||||
)
|
||||
file_configs[file] = self.temp_service_files[file]
|
||||
# TODO: check if this is really needed
|
||||
self.app.core.set_node_service_file(
|
||||
self.node_id, self.service_name, file, self.temp_service_files[file]
|
||||
)
|
||||
|
@ -526,8 +524,9 @@ class ServiceConfigDialog(Dialog):
|
|||
clears out any custom configuration permanently
|
||||
"""
|
||||
# clear coreclient data
|
||||
self.service_configs.get(self.node_id, {}).pop(self.service_name, None)
|
||||
self.file_configs.get(self.node_id, {}).pop(self.service_name, None)
|
||||
self.canvas_node.service_configs.pop(self.service_name, None)
|
||||
file_configs = self.canvas_node.service_file_configs.pop(self.service_name, {})
|
||||
file_configs.pop(self.service_name, None)
|
||||
self.temp_service_files = dict(self.original_service_files)
|
||||
self.modified_files.clear()
|
||||
|
||||
|
|
|
@ -352,7 +352,6 @@ class CanvasGraph(tk.Canvas):
|
|||
"""
|
||||
Convert window coordinate to canvas coordinate
|
||||
"""
|
||||
logging.info("event type: %s", type(event))
|
||||
x = self.canvasx(event.x)
|
||||
y = self.canvasy(event.y)
|
||||
return x, y
|
||||
|
@ -924,10 +923,13 @@ class CanvasGraph(tk.Canvas):
|
|||
)
|
||||
node = CanvasNode(self.master, scaled_x, scaled_y, copy, canvas_node.image)
|
||||
|
||||
# copy configurations
|
||||
# copy configurations and services
|
||||
node.core_node.services[:] = canvas_node.core_node.services
|
||||
node.emane_model_configs = deepcopy(canvas_node.emane_model_configs)
|
||||
node.wlan_config = deepcopy(canvas_node.wlan_config)
|
||||
node.mobility_config = deepcopy(canvas_node.mobility_config)
|
||||
node.service_configs = deepcopy(canvas_node.service_configs)
|
||||
node.service_file_configs = deepcopy(canvas_node.service_file_configs)
|
||||
|
||||
# add new node to modified_service_nodes set if that set contains the
|
||||
# to_copy node
|
||||
|
@ -937,7 +939,6 @@ class CanvasGraph(tk.Canvas):
|
|||
copy_map[canvas_node.id] = node.id
|
||||
self.core.canvas_nodes[copy.id] = node
|
||||
self.nodes[node.id] = node
|
||||
self.core.copy_node_config(core_node, copy.id)
|
||||
for edge in canvas_node.edges:
|
||||
if edge.src not in self.to_copy or edge.dst not in self.to_copy:
|
||||
if canvas_node.id == edge.src:
|
||||
|
|
|
@ -62,6 +62,8 @@ class CanvasNode:
|
|||
self.emane_model_configs = {}
|
||||
self.wlan_config = {}
|
||||
self.mobility_config = {}
|
||||
self.service_configs = {}
|
||||
self.service_file_configs = {}
|
||||
self.setup_bindings()
|
||||
|
||||
def setup_bindings(self):
|
||||
|
|
|
@ -347,7 +347,6 @@ class Menubar(tk.Menu):
|
|||
for i in range(self.edit_menu.index(tk.END) + 1):
|
||||
try:
|
||||
label = self.edit_menu.entrycget(i, "label")
|
||||
logging.info("menu label: %s", label)
|
||||
if label not in labels:
|
||||
continue
|
||||
state = tk.DISABLED if is_runtime else tk.NORMAL
|
||||
|
|
Loading…
Reference in a new issue