pygui updated config services to be associated with nodes directly and copyable

This commit is contained in:
Blake Harnden 2020-04-21 11:13:41 -07:00
parent d7ebb90329
commit b04da98f44
5 changed files with 49 additions and 38 deletions

View file

@ -91,7 +91,6 @@ class CoreClient:
self.links = {} self.links = {}
self.hooks = {} self.hooks = {}
self.emane_config = None self.emane_config = None
self.config_service_configs = {}
self.mobility_players = {} self.mobility_players = {}
self.handling_throughputs = None self.handling_throughputs = None
self.handling_events = None self.handling_events = None
@ -341,10 +340,10 @@ class CoreClient:
# get config service configurations # get config service configurations
response = self.client.get_node_config_service_configs(self.session_id) response = self.client.get_node_config_service_configs(self.session_id)
for config in response.configs: for config in response.configs:
node_configs = self.config_service_configs.setdefault( canvas_node = self.canvas_nodes[config.node_id]
config.node_id, {} service_config = canvas_node.config_service_configs.setdefault(
config.name, {}
) )
service_config = node_configs.setdefault(config.name, {})
if config.templates: if config.templates:
service_config["templates"] = config.templates service_config["templates"] = config.templates
if config.config: if config.config:
@ -989,8 +988,13 @@ class CoreClient:
self self
) -> List[configservices_pb2.ConfigServiceConfig]: ) -> List[configservices_pb2.ConfigServiceConfig]:
config_service_protos = [] config_service_protos = []
for node_id, node_config in self.config_service_configs.items(): for canvas_node in self.canvas_nodes.values():
for name, service_config in node_config.items(): if not NodeUtils.is_container_node(canvas_node.core_node.type):
continue
if not canvas_node.config_service_configs:
continue
node_id = canvas_node.core_node.id
for name, service_config in canvas_node.config_service_configs.items():
config = service_config.get("config", {}) config = service_config.get("config", {})
config_proto = configservices_pb2.ConfigServiceConfig( config_proto = configservices_pb2.ConfigServiceConfig(
node_id=node_id, node_id=node_id,

View file

@ -16,21 +16,26 @@ from core.gui.widgets import CodeText, ConfigFrame, ListboxScroll
if TYPE_CHECKING: if TYPE_CHECKING:
from core.gui.app import Application from core.gui.app import Application
from core.gui.graph.node import CanvasNode
class ConfigServiceConfigDialog(Dialog): class ConfigServiceConfigDialog(Dialog):
def __init__( 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} Config Service" title = f"{service_name} Config Service"
super().__init__(master, app, title, modal=True) super().__init__(master, app, title, modal=True)
self.master = master self.master = master
self.app = app self.app = app
self.core = app.core self.core = app.core
self.canvas_node = canvas_node
self.node_id = node_id self.node_id = node_id
self.service_name = service_name self.service_name = service_name
self.service_configs = app.core.config_service_configs
self.radiovar = tk.IntVar() self.radiovar = tk.IntVar()
self.radiovar.set(2) self.radiovar.set(2)
self.directories = [] self.directories = []
@ -95,9 +100,9 @@ class ConfigServiceConfigDialog(Dialog):
self.modes = sorted(x.name for x in response.modes) self.modes = sorted(x.name for x in response.modes)
self.mode_configs = {x.name: x.config for x in response.modes} self.mode_configs = {x.name: x.config for x in response.modes}
node_configs = self.service_configs.get(self.node_id, {}) service_config = self.canvas_node.config_service_configs.get(
service_config = node_configs.get(self.service_name, {}) self.service_name, {}
)
self.config = response.config self.config = response.config
self.default_config = {x.name: x.value for x in self.config.values()} self.default_config = {x.name: x.value for x in self.config.values()}
custom_config = service_config.get("config") custom_config = service_config.get("config")
@ -313,15 +318,15 @@ class ConfigServiceConfigDialog(Dialog):
def click_apply(self): def click_apply(self):
current_listbox = self.master.current.listbox current_listbox = self.master.current.listbox
if not self.is_custom(): if not self.is_custom():
if self.node_id in self.service_configs: self.canvas_node.config_service_configs.pop(self.service_name, None)
self.service_configs[self.node_id].pop(self.service_name, None)
current_listbox.itemconfig(current_listbox.curselection()[0], bg="") current_listbox.itemconfig(current_listbox.curselection()[0], bg="")
self.destroy() self.destroy()
return return
try: try:
node_config = self.service_configs.setdefault(self.node_id, {}) service_config = self.canvas_node.config_service_configs.setdefault(
service_config = node_config.setdefault(self.service_name, {}) self.service_name, {}
)
if self.config_frame: if self.config_frame:
self.config_frame.parse_config() self.config_frame.parse_config()
service_config["config"] = { service_config["config"] = {
@ -365,9 +370,10 @@ class ConfigServiceConfigDialog(Dialog):
return has_custom_templates or has_custom_config return has_custom_templates or has_custom_config
def click_defaults(self): def click_defaults(self):
if self.node_id in self.service_configs: self.canvas_node.config_service_configs.pop(self.service_name, None)
node_config = self.service_configs.get(self.node_id, {}) logging.info(
node_config.pop(self.service_name, None) "cleared config service config: %s", self.canvas_node.config_service_configs
)
self.temp_service_files = dict(self.original_service_files) self.temp_service_files = dict(self.original_service_files)
filename = self.templates_combobox.get() filename = self.templates_combobox.get()
self.template_text.text.delete(1.0, "end") self.template_text.text.delete(1.0, "end")

View file

@ -70,12 +70,10 @@ class NodeConfigServiceDialog(Dialog):
label_frame.grid(row=0, column=2, sticky="nsew") label_frame.grid(row=0, column=2, sticky="nsew")
label_frame.rowconfigure(0, weight=1) label_frame.rowconfigure(0, weight=1)
label_frame.columnconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1)
self.current = ListboxScroll(label_frame) self.current = ListboxScroll(label_frame)
self.current.grid(sticky="nsew") self.current.grid(sticky="nsew")
for service in sorted(self.current_services): self.draw_current_services()
self.current.listbox.insert(tk.END, service)
if self.is_custom_service(service):
self.current.listbox.itemconfig(tk.END, bg="green")
frame = ttk.Frame(self.top) frame = ttk.Frame(self.top)
frame.grid(stick="ew") frame.grid(stick="ew")
@ -108,24 +106,22 @@ class NodeConfigServiceDialog(Dialog):
self.current_services.add(name) self.current_services.add(name)
elif not var.get() and name in self.current_services: elif not var.get() and name in self.current_services:
self.current_services.remove(name) self.current_services.remove(name)
self.current.listbox.delete(0, tk.END) self.draw_current_services()
for name in sorted(self.current_services):
self.current.listbox.insert(tk.END, name)
if self.is_custom_service(name):
self.current.listbox.itemconfig(tk.END, bg="green")
self.canvas_node.core_node.config_services[:] = self.current_services self.canvas_node.core_node.config_services[:] = self.current_services
def click_configure(self): def click_configure(self):
current_selection = self.current.listbox.curselection() current_selection = self.current.listbox.curselection()
if len(current_selection): if len(current_selection):
dialog = ConfigServiceConfigDialog( dialog = ConfigServiceConfigDialog(
master=self, self,
app=self.app, self.app,
service_name=self.current.listbox.get(current_selection[0]), self.current.listbox.get(current_selection[0]),
node_id=self.node_id, self.canvas_node,
self.node_id,
) )
if not dialog.has_error: if not dialog.has_error:
dialog.show() dialog.show()
self.draw_current_services()
else: else:
messagebox.showinfo( messagebox.showinfo(
"Config Service Configuration", "Config Service Configuration",
@ -133,6 +129,13 @@ class NodeConfigServiceDialog(Dialog):
parent=self, parent=self,
) )
def draw_current_services(self):
self.current.listbox.delete(0, tk.END)
for name in sorted(self.current_services):
self.current.listbox.insert(tk.END, name)
if self.is_custom_service(name):
self.current.listbox.itemconfig(tk.END, bg="green")
def click_save(self): def click_save(self):
self.canvas_node.core_node.config_services[:] = self.current_services self.canvas_node.core_node.config_services[:] = self.current_services
logging.info( logging.info(
@ -156,9 +159,4 @@ class NodeConfigServiceDialog(Dialog):
return return
def is_custom_service(self, service: str) -> bool: def is_custom_service(self, service: str) -> bool:
node_configs = self.app.core.config_service_configs.get(self.node_id, {}) return service in self.canvas_node.config_service_configs
service_config = node_configs.get(service)
if node_configs and service_config:
return True
else:
return False

View file

@ -925,11 +925,13 @@ class CanvasGraph(tk.Canvas):
# copy configurations and services # copy configurations and services
node.core_node.services[:] = canvas_node.core_node.services node.core_node.services[:] = canvas_node.core_node.services
node.core_node.config_services[:] = canvas_node.core_node.config_services
node.emane_model_configs = deepcopy(canvas_node.emane_model_configs) node.emane_model_configs = deepcopy(canvas_node.emane_model_configs)
node.wlan_config = deepcopy(canvas_node.wlan_config) node.wlan_config = deepcopy(canvas_node.wlan_config)
node.mobility_config = deepcopy(canvas_node.mobility_config) node.mobility_config = deepcopy(canvas_node.mobility_config)
node.service_configs = deepcopy(canvas_node.service_configs) node.service_configs = deepcopy(canvas_node.service_configs)
node.service_file_configs = deepcopy(canvas_node.service_file_configs) node.service_file_configs = deepcopy(canvas_node.service_file_configs)
node.config_service_configs = deepcopy(canvas_node.config_service_configs)
# add new node to modified_service_nodes set if that set contains the # add new node to modified_service_nodes set if that set contains the
# to_copy node # to_copy node

View file

@ -64,6 +64,7 @@ class CanvasNode:
self.mobility_config = {} self.mobility_config = {}
self.service_configs = {} self.service_configs = {}
self.service_file_configs = {} self.service_file_configs = {}
self.config_service_configs = {}
self.setup_bindings() self.setup_bindings()
def setup_bindings(self): def setup_bindings(self):