Merge branch 'coretk' into coretk-color
This commit is contained in:
commit
e649f2642d
16 changed files with 140 additions and 107 deletions
|
@ -1,6 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from functools import partial
|
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
|
|
||||||
from coretk import appconfig, themes
|
from coretk import appconfig, themes
|
||||||
|
@ -42,11 +41,9 @@ class Application(tk.Frame):
|
||||||
|
|
||||||
def setup_theme(self):
|
def setup_theme(self):
|
||||||
themes.load(self.style)
|
themes.load(self.style)
|
||||||
|
self.master.bind_class("Menu", "<<ThemeChanged>>", themes.theme_change_menu)
|
||||||
|
self.master.bind("<<ThemeChanged>>", themes.theme_change)
|
||||||
self.style.theme_use(self.guiconfig["preferences"]["theme"])
|
self.style.theme_use(self.guiconfig["preferences"]["theme"])
|
||||||
func = partial(themes.theme_change_menu, self.style)
|
|
||||||
self.master.bind_class("Menu", "<<ThemeChanged>>", func)
|
|
||||||
func = partial(themes.theme_change, self.style)
|
|
||||||
self.master.bind("<<ThemeChanged>>", func)
|
|
||||||
|
|
||||||
def setup_app(self):
|
def setup_app(self):
|
||||||
self.master.title("CORE")
|
self.master.title("CORE")
|
||||||
|
|
|
@ -20,6 +20,7 @@ from coretk.graph.shapeutils import ShapeType
|
||||||
from coretk.interface import InterfaceManager
|
from coretk.interface import InterfaceManager
|
||||||
from coretk.nodeutils import NodeDraw, NodeUtils
|
from coretk.nodeutils import NodeDraw, NodeUtils
|
||||||
|
|
||||||
|
GUI_SOURCE = "gui"
|
||||||
OBSERVERS = {
|
OBSERVERS = {
|
||||||
"processes": "ps",
|
"processes": "ps",
|
||||||
"ifconfig": "ifconfig",
|
"ifconfig": "ifconfig",
|
||||||
|
@ -133,6 +134,14 @@ class CoreClient:
|
||||||
self.custom_observers[observer.name] = observer
|
self.custom_observers[observer.name] = observer
|
||||||
|
|
||||||
def handle_events(self, event):
|
def handle_events(self, event):
|
||||||
|
if event.session_id != self.session_id:
|
||||||
|
logging.warn(
|
||||||
|
"ignoring event session(%s) current(%s)",
|
||||||
|
event.session_id,
|
||||||
|
self.session_id,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
if event.HasField("link_event"):
|
if event.HasField("link_event"):
|
||||||
logging.info("link event: %s", event)
|
logging.info("link event: %s", event)
|
||||||
self.handle_link_event(event.link_event)
|
self.handle_link_event(event.link_event)
|
||||||
|
@ -176,7 +185,7 @@ class CoreClient:
|
||||||
logging.warning("unknown link event: %s", event.message_type)
|
logging.warning("unknown link event: %s", event.message_type)
|
||||||
|
|
||||||
def handle_node_event(self, event):
|
def handle_node_event(self, event):
|
||||||
if event.source == "gui":
|
if event.source == GUI_SOURCE:
|
||||||
return
|
return
|
||||||
node_id = event.node.id
|
node_id = event.node.id
|
||||||
x = event.node.position.x
|
x = event.node.position.x
|
||||||
|
@ -195,6 +204,11 @@ class CoreClient:
|
||||||
|
|
||||||
def handle_throughputs(self, event):
|
def handle_throughputs(self, event):
|
||||||
if event.session_id != self.session_id:
|
if event.session_id != self.session_id:
|
||||||
|
logging.warn(
|
||||||
|
"ignoring throughput event session(%s) current(%s)",
|
||||||
|
event.session_id,
|
||||||
|
self.session_id,
|
||||||
|
)
|
||||||
return
|
return
|
||||||
logging.info("handling throughputs event: %s", event)
|
logging.info("handling throughputs event: %s", event)
|
||||||
self.app.canvas.throughput_draw.process_grpc_throughput_event(
|
self.app.canvas.throughput_draw.process_grpc_throughput_event(
|
||||||
|
@ -424,7 +438,7 @@ class CoreClient:
|
||||||
def edit_node(self, core_node):
|
def edit_node(self, core_node):
|
||||||
try:
|
try:
|
||||||
self.client.edit_node(
|
self.client.edit_node(
|
||||||
self.session_id, core_node.id, core_node.position, source="gui"
|
self.session_id, core_node.id, core_node.position, source=GUI_SOURCE
|
||||||
)
|
)
|
||||||
except grpc.RpcError as e:
|
except grpc.RpcError as e:
|
||||||
show_grpc_error(e)
|
show_grpc_error(e)
|
||||||
|
|
|
@ -24,10 +24,11 @@ class AlertsDialog(Dialog):
|
||||||
self.top.columnconfigure(0, weight=1)
|
self.top.columnconfigure(0, weight=1)
|
||||||
self.top.rowconfigure(0, weight=1)
|
self.top.rowconfigure(0, weight=1)
|
||||||
self.top.rowconfigure(1, weight=1)
|
self.top.rowconfigure(1, weight=1)
|
||||||
row = 0
|
|
||||||
frame = ttk.Frame(self.top)
|
frame = ttk.Frame(self.top)
|
||||||
frame.columnconfigure(0, weight=1)
|
frame.columnconfigure(0, weight=1)
|
||||||
frame.grid(row=row, column=0, sticky="nsew", pady=PADY)
|
frame.rowconfigure(0, weight=1)
|
||||||
|
frame.grid(sticky="nsew", pady=PADY)
|
||||||
self.tree = ttk.Treeview(
|
self.tree = ttk.Treeview(
|
||||||
frame,
|
frame,
|
||||||
columns=("time", "level", "session_id", "node", "source"),
|
columns=("time", "level", "session_id", "node", "source"),
|
||||||
|
@ -35,15 +36,15 @@ class AlertsDialog(Dialog):
|
||||||
)
|
)
|
||||||
self.tree.grid(row=0, column=0, sticky="nsew")
|
self.tree.grid(row=0, column=0, sticky="nsew")
|
||||||
self.tree.column("time", stretch=tk.YES)
|
self.tree.column("time", stretch=tk.YES)
|
||||||
self.tree.heading("time", text="time", anchor="w")
|
self.tree.heading("time", text="Time")
|
||||||
self.tree.column("level", stretch=tk.YES)
|
self.tree.column("level", stretch=tk.YES)
|
||||||
self.tree.heading("level", text="level", anchor="w")
|
self.tree.heading("level", text="Level")
|
||||||
self.tree.column("session_id", stretch=tk.YES)
|
self.tree.column("session_id", stretch=tk.YES)
|
||||||
self.tree.heading("session_id", text="session id", anchor="w")
|
self.tree.heading("session_id", text="Session ID")
|
||||||
self.tree.column("node", stretch=tk.YES)
|
self.tree.column("node", stretch=tk.YES)
|
||||||
self.tree.heading("node", text="node", anchor="w")
|
self.tree.heading("node", text="Node")
|
||||||
self.tree.column("source", stretch=tk.YES)
|
self.tree.column("source", stretch=tk.YES)
|
||||||
self.tree.heading("source", text="source", anchor="w")
|
self.tree.heading("source", text="Source")
|
||||||
self.tree.bind("<<TreeviewSelect>>", self.click_select)
|
self.tree.bind("<<TreeviewSelect>>", self.click_select)
|
||||||
|
|
||||||
for alarm in self.app.statusbar.core_alarms:
|
for alarm in self.app.statusbar.core_alarms:
|
||||||
|
@ -74,15 +75,13 @@ class AlertsDialog(Dialog):
|
||||||
xscrollbar = ttk.Scrollbar(frame, orient="horizontal", command=self.tree.xview)
|
xscrollbar = ttk.Scrollbar(frame, orient="horizontal", command=self.tree.xview)
|
||||||
xscrollbar.grid(row=1, sticky="ew")
|
xscrollbar.grid(row=1, sticky="ew")
|
||||||
self.tree.configure(xscrollcommand=xscrollbar.set)
|
self.tree.configure(xscrollcommand=xscrollbar.set)
|
||||||
row = row + 1
|
|
||||||
|
|
||||||
self.text = CodeText(self.top)
|
self.text = CodeText(self.top)
|
||||||
self.text.config(state=tk.DISABLED)
|
self.text.config(state=tk.DISABLED)
|
||||||
self.text.grid(row=row, column=0, sticky="nsew", pady=PADY)
|
self.text.grid(sticky="nsew", pady=PADY)
|
||||||
row = row + 1
|
|
||||||
|
|
||||||
frame = ttk.Frame(self.top)
|
frame = ttk.Frame(self.top)
|
||||||
frame.grid(row=row, column=0, sticky="nsew")
|
frame.grid(sticky="ew")
|
||||||
frame.columnconfigure(0, weight=1)
|
frame.columnconfigure(0, weight=1)
|
||||||
frame.columnconfigure(1, weight=1)
|
frame.columnconfigure(1, weight=1)
|
||||||
frame.columnconfigure(2, weight=1)
|
frame.columnconfigure(2, weight=1)
|
||||||
|
|
|
@ -24,13 +24,17 @@ class ServicesSelectDialog(Dialog):
|
||||||
self.top.columnconfigure(0, weight=1)
|
self.top.columnconfigure(0, weight=1)
|
||||||
self.top.rowconfigure(0, weight=1)
|
self.top.rowconfigure(0, weight=1)
|
||||||
|
|
||||||
frame = ttk.Frame(self.top)
|
frame = ttk.LabelFrame(self.top)
|
||||||
frame.grid(stick="nsew", pady=PADY)
|
frame.grid(stick="nsew", pady=PADY)
|
||||||
frame.rowconfigure(0, weight=1)
|
frame.rowconfigure(0, weight=1)
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
frame.columnconfigure(i, weight=1)
|
frame.columnconfigure(i, weight=1)
|
||||||
self.groups = ListboxScroll(frame, text="Groups", padding=FRAME_PAD)
|
label_frame = ttk.LabelFrame(frame, text="Groups", padding=FRAME_PAD)
|
||||||
self.groups.grid(row=0, column=0, sticky="nsew")
|
label_frame.grid(row=0, column=0, sticky="nsew")
|
||||||
|
label_frame.rowconfigure(0, weight=1)
|
||||||
|
label_frame.columnconfigure(0, weight=1)
|
||||||
|
self.groups = ListboxScroll(label_frame)
|
||||||
|
self.groups.grid(sticky="nsew")
|
||||||
for group in sorted(self.app.core.services):
|
for group in sorted(self.app.core.services):
|
||||||
self.groups.listbox.insert(tk.END, group)
|
self.groups.listbox.insert(tk.END, group)
|
||||||
self.groups.listbox.bind("<<ListboxSelect>>", self.handle_group_change)
|
self.groups.listbox.bind("<<ListboxSelect>>", self.handle_group_change)
|
||||||
|
@ -45,8 +49,12 @@ class ServicesSelectDialog(Dialog):
|
||||||
)
|
)
|
||||||
self.services.grid(row=0, column=1, sticky="nsew")
|
self.services.grid(row=0, column=1, sticky="nsew")
|
||||||
|
|
||||||
self.current = ListboxScroll(frame, text="Selected", padding=FRAME_PAD)
|
label_frame = ttk.LabelFrame(frame, text="Selected", padding=FRAME_PAD)
|
||||||
self.current.grid(row=0, column=2, sticky="nsew")
|
label_frame.grid(row=0, column=2, sticky="nsew")
|
||||||
|
label_frame.rowconfigure(0, weight=1)
|
||||||
|
label_frame.columnconfigure(0, weight=1)
|
||||||
|
self.current = ListboxScroll(label_frame)
|
||||||
|
self.current.grid(sticky="nsew")
|
||||||
for service in sorted(self.current_services):
|
for service in sorted(self.current_services):
|
||||||
self.current.listbox.insert(tk.END, service)
|
self.current.listbox.insert(tk.END, service)
|
||||||
|
|
||||||
|
@ -109,12 +117,12 @@ class CustomNodesDialog(Dialog):
|
||||||
self.draw_buttons()
|
self.draw_buttons()
|
||||||
|
|
||||||
def draw_node_config(self):
|
def draw_node_config(self):
|
||||||
frame = ttk.Frame(self.top)
|
frame = ttk.LabelFrame(self.top, text="Nodes", padding=FRAME_PAD)
|
||||||
frame.grid(sticky="nsew", pady=PADY)
|
frame.grid(sticky="nsew", pady=PADY)
|
||||||
frame.columnconfigure(0, weight=1)
|
frame.columnconfigure(0, weight=1)
|
||||||
frame.rowconfigure(0, weight=1)
|
frame.rowconfigure(0, weight=1)
|
||||||
|
|
||||||
self.nodes_list = ListboxScroll(frame, text="Nodes", padding=FRAME_PAD)
|
self.nodes_list = ListboxScroll(frame)
|
||||||
self.nodes_list.grid(row=0, column=0, sticky="nsew", padx=PADX)
|
self.nodes_list.grid(row=0, column=0, sticky="nsew", padx=PADX)
|
||||||
self.nodes_list.listbox.bind("<<ListboxSelect>>", self.handle_node_select)
|
self.nodes_list.listbox.bind("<<ListboxSelect>>", self.handle_node_select)
|
||||||
for name in sorted(self.app.core.custom_nodes):
|
for name in sorted(self.app.core.custom_nodes):
|
||||||
|
|
|
@ -4,7 +4,7 @@ from tkinter import ttk
|
||||||
from core.api.grpc import core_pb2
|
from core.api.grpc import core_pb2
|
||||||
from coretk.dialogs.dialog import Dialog
|
from coretk.dialogs.dialog import Dialog
|
||||||
from coretk.themes import PADX, PADY
|
from coretk.themes import PADX, PADY
|
||||||
from coretk.widgets import CodeText
|
from coretk.widgets import CodeText, ListboxScroll
|
||||||
|
|
||||||
|
|
||||||
class HookDialog(Dialog):
|
class HookDialog(Dialog):
|
||||||
|
@ -96,8 +96,9 @@ class HooksDialog(Dialog):
|
||||||
self.top.columnconfigure(0, weight=1)
|
self.top.columnconfigure(0, weight=1)
|
||||||
self.top.rowconfigure(0, weight=1)
|
self.top.rowconfigure(0, weight=1)
|
||||||
|
|
||||||
self.listbox = tk.Listbox(self.top)
|
listbox_scroll = ListboxScroll(self.top)
|
||||||
self.listbox.grid(sticky="nsew", pady=PADY)
|
listbox_scroll.grid(sticky="nsew", pady=PADY)
|
||||||
|
self.listbox = listbox_scroll.listbox
|
||||||
self.listbox.bind("<<ListboxSelect>>", self.select)
|
self.listbox.bind("<<ListboxSelect>>", self.select)
|
||||||
for hook_file in self.app.core.hooks:
|
for hook_file in self.app.core.hooks:
|
||||||
self.listbox.insert(tk.END, hook_file)
|
self.listbox.insert(tk.END, hook_file)
|
||||||
|
|
|
@ -40,8 +40,12 @@ class NodeService(Dialog):
|
||||||
frame.rowconfigure(0, weight=1)
|
frame.rowconfigure(0, weight=1)
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
frame.columnconfigure(i, weight=1)
|
frame.columnconfigure(i, weight=1)
|
||||||
self.groups = ListboxScroll(frame, text="Groups", padding=FRAME_PAD)
|
label_frame = ttk.LabelFrame(frame, text="Groups", padding=FRAME_PAD)
|
||||||
self.groups.grid(row=0, column=0, sticky="nsew")
|
label_frame.grid(row=0, column=0, sticky="nsew")
|
||||||
|
label_frame.rowconfigure(0, weight=1)
|
||||||
|
label_frame.columnconfigure(0, weight=1)
|
||||||
|
self.groups = ListboxScroll(label_frame)
|
||||||
|
self.groups.grid(sticky="nsew")
|
||||||
for group in sorted(self.app.core.services):
|
for group in sorted(self.app.core.services):
|
||||||
self.groups.listbox.insert(tk.END, group)
|
self.groups.listbox.insert(tk.END, group)
|
||||||
self.groups.listbox.bind("<<ListboxSelect>>", self.handle_group_change)
|
self.groups.listbox.bind("<<ListboxSelect>>", self.handle_group_change)
|
||||||
|
@ -56,8 +60,12 @@ class NodeService(Dialog):
|
||||||
)
|
)
|
||||||
self.services.grid(row=0, column=1, sticky="nsew")
|
self.services.grid(row=0, column=1, sticky="nsew")
|
||||||
|
|
||||||
self.current = ListboxScroll(frame, text="Selected", padding=FRAME_PAD)
|
label_frame = ttk.LabelFrame(frame, text="Selected", padding=FRAME_PAD)
|
||||||
self.current.grid(row=0, column=2, sticky="nsew")
|
label_frame.grid(row=0, column=2, sticky="nsew")
|
||||||
|
label_frame.rowconfigure(0, weight=1)
|
||||||
|
label_frame.columnconfigure(0, weight=1)
|
||||||
|
self.current = ListboxScroll(label_frame)
|
||||||
|
self.current.grid(sticky="nsew")
|
||||||
for service in sorted(self.current_services):
|
for service in sorted(self.current_services):
|
||||||
self.current.listbox.insert(tk.END, service)
|
self.current.listbox.insert(tk.END, service)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from tkinter import ttk
|
||||||
from coretk.coreclient import Observer
|
from coretk.coreclient import Observer
|
||||||
from coretk.dialogs.dialog import Dialog
|
from coretk.dialogs.dialog import Dialog
|
||||||
from coretk.themes import PADX, PADY
|
from coretk.themes import PADX, PADY
|
||||||
|
from coretk.widgets import ListboxScroll
|
||||||
|
|
||||||
|
|
||||||
class ObserverDialog(Dialog):
|
class ObserverDialog(Dialog):
|
||||||
|
@ -27,24 +28,16 @@ class ObserverDialog(Dialog):
|
||||||
self.draw_apply_buttons()
|
self.draw_apply_buttons()
|
||||||
|
|
||||||
def draw_listbox(self):
|
def draw_listbox(self):
|
||||||
frame = ttk.Frame(self.top)
|
listbox_scroll = ListboxScroll(self.top)
|
||||||
frame.grid(sticky="nsew", pady=PADY)
|
listbox_scroll.grid(sticky="nsew", pady=PADY)
|
||||||
frame.columnconfigure(0, weight=1)
|
listbox_scroll.columnconfigure(0, weight=1)
|
||||||
frame.rowconfigure(0, weight=1)
|
listbox_scroll.rowconfigure(0, weight=1)
|
||||||
|
self.observers = listbox_scroll.listbox
|
||||||
scrollbar = ttk.Scrollbar(frame, orient=tk.VERTICAL)
|
|
||||||
scrollbar.grid(row=0, column=1, sticky="ns")
|
|
||||||
|
|
||||||
self.observers = tk.Listbox(
|
|
||||||
frame, selectmode=tk.SINGLE, yscrollcommand=scrollbar.set
|
|
||||||
)
|
|
||||||
self.observers.grid(row=0, column=0, sticky="nsew")
|
self.observers.grid(row=0, column=0, sticky="nsew")
|
||||||
self.observers.bind("<<ListboxSelect>>", self.handle_observer_change)
|
self.observers.bind("<<ListboxSelect>>", self.handle_observer_change)
|
||||||
for name in sorted(self.app.core.custom_observers):
|
for name in sorted(self.app.core.custom_observers):
|
||||||
self.observers.insert(tk.END, name)
|
self.observers.insert(tk.END, name)
|
||||||
|
|
||||||
scrollbar.config(command=self.observers.yview)
|
|
||||||
|
|
||||||
def draw_form_fields(self):
|
def draw_form_fields(self):
|
||||||
frame = ttk.Frame(self.top)
|
frame = ttk.Frame(self.top)
|
||||||
frame.grid(sticky="ew", pady=PADY)
|
frame.grid(sticky="ew", pady=PADY)
|
||||||
|
|
|
@ -4,6 +4,7 @@ from tkinter import ttk
|
||||||
from coretk.coreclient import CoreServer
|
from coretk.coreclient import CoreServer
|
||||||
from coretk.dialogs.dialog import Dialog
|
from coretk.dialogs.dialog import Dialog
|
||||||
from coretk.themes import FRAME_PAD, PADX, PADY
|
from coretk.themes import FRAME_PAD, PADX, PADY
|
||||||
|
from coretk.widgets import ListboxScroll
|
||||||
|
|
||||||
DEFAULT_NAME = "example"
|
DEFAULT_NAME = "example"
|
||||||
DEFAULT_ADDRESS = "127.0.0.1"
|
DEFAULT_ADDRESS = "127.0.0.1"
|
||||||
|
@ -32,25 +33,18 @@ class ServersDialog(Dialog):
|
||||||
self.draw_apply_buttons()
|
self.draw_apply_buttons()
|
||||||
|
|
||||||
def draw_servers(self):
|
def draw_servers(self):
|
||||||
frame = ttk.Frame(self.top)
|
listbox_scroll = ListboxScroll(self.top)
|
||||||
frame.grid(pady=PADY, sticky="nsew")
|
listbox_scroll.grid(pady=PADY, sticky="nsew")
|
||||||
frame.columnconfigure(0, weight=1)
|
listbox_scroll.columnconfigure(0, weight=1)
|
||||||
frame.rowconfigure(0, weight=1)
|
listbox_scroll.rowconfigure(0, weight=1)
|
||||||
|
|
||||||
scrollbar = ttk.Scrollbar(frame, orient=tk.VERTICAL)
|
self.servers = listbox_scroll.listbox
|
||||||
scrollbar.grid(row=0, column=1, sticky="ns")
|
|
||||||
|
|
||||||
self.servers = tk.Listbox(
|
|
||||||
frame, selectmode=tk.SINGLE, yscrollcommand=scrollbar.set
|
|
||||||
)
|
|
||||||
self.servers.grid(row=0, column=0, sticky="nsew")
|
self.servers.grid(row=0, column=0, sticky="nsew")
|
||||||
self.servers.bind("<<ListboxSelect>>", self.handle_server_change)
|
self.servers.bind("<<ListboxSelect>>", self.handle_server_change)
|
||||||
|
|
||||||
for server in self.app.core.servers:
|
for server in self.app.core.servers:
|
||||||
self.servers.insert(tk.END, server)
|
self.servers.insert(tk.END, server)
|
||||||
|
|
||||||
scrollbar.config(command=self.servers.yview)
|
|
||||||
|
|
||||||
def draw_server_configuration(self):
|
def draw_server_configuration(self):
|
||||||
frame = ttk.LabelFrame(self.top, text="Server Configuration", padding=FRAME_PAD)
|
frame = ttk.LabelFrame(self.top, text="Server Configuration", padding=FRAME_PAD)
|
||||||
frame.grid(pady=PADY, sticky="ew")
|
frame.grid(pady=PADY, sticky="ew")
|
||||||
|
|
|
@ -216,32 +216,32 @@ class ServiceConfiguration(Dialog):
|
||||||
tab.columnconfigure(0, weight=1)
|
tab.columnconfigure(0, weight=1)
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
tab.rowconfigure(i, weight=1)
|
tab.rowconfigure(i, weight=1)
|
||||||
self.notebook.add(tab, text="Startup/shutdown")
|
self.notebook.add(tab, text="Startup/Shutdown")
|
||||||
|
|
||||||
# tab 3
|
# tab 3
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
label_frame = None
|
label_frame = None
|
||||||
if i == 0:
|
if i == 0:
|
||||||
label_frame = ttk.LabelFrame(
|
label_frame = ttk.LabelFrame(
|
||||||
tab, text="Startup commands", padding=FRAME_PAD
|
tab, text="Startup Commands", padding=FRAME_PAD
|
||||||
)
|
)
|
||||||
commands = self.startup_commands
|
commands = self.startup_commands
|
||||||
elif i == 1:
|
elif i == 1:
|
||||||
label_frame = ttk.LabelFrame(
|
label_frame = ttk.LabelFrame(
|
||||||
tab, text="Shutdown commands", padding=FRAME_PAD
|
tab, text="Shutdown Commands", padding=FRAME_PAD
|
||||||
)
|
)
|
||||||
commands = self.shutdown_commands
|
commands = self.shutdown_commands
|
||||||
elif i == 2:
|
elif i == 2:
|
||||||
label_frame = ttk.LabelFrame(
|
label_frame = ttk.LabelFrame(
|
||||||
tab, text="Validation commands", padding=FRAME_PAD
|
tab, text="Validation Commands", padding=FRAME_PAD
|
||||||
)
|
)
|
||||||
commands = self.validation_commands
|
commands = self.validation_commands
|
||||||
label_frame.columnconfigure(0, weight=1)
|
label_frame.columnconfigure(0, weight=1)
|
||||||
label_frame.rowconfigure(1, weight=1)
|
label_frame.rowconfigure(1, weight=1)
|
||||||
label_frame.grid(row=i, column=0, sticky="nsew")
|
label_frame.grid(row=i, column=0, sticky="nsew", pady=PADY)
|
||||||
|
|
||||||
frame = ttk.Frame(label_frame)
|
frame = ttk.Frame(label_frame)
|
||||||
frame.grid(row=0, column=0, sticky="nsew")
|
frame.grid(row=0, column=0, sticky="nsew", pady=PADY)
|
||||||
frame.columnconfigure(0, weight=1)
|
frame.columnconfigure(0, weight=1)
|
||||||
entry = ttk.Entry(frame, textvariable=tk.StringVar())
|
entry = ttk.Entry(frame, textvariable=tk.StringVar())
|
||||||
entry.grid(row=0, column=0, stick="ew", padx=PADX)
|
entry.grid(row=0, column=0, stick="ew", padx=PADX)
|
||||||
|
@ -251,7 +251,7 @@ class ServiceConfiguration(Dialog):
|
||||||
button = ttk.Button(frame, image=self.editdelete_img)
|
button = ttk.Button(frame, image=self.editdelete_img)
|
||||||
button.grid(row=0, column=2, sticky="ew")
|
button.grid(row=0, column=2, sticky="ew")
|
||||||
button.bind("<Button-1>", self.delete_command)
|
button.bind("<Button-1>", self.delete_command)
|
||||||
listbox_scroll = ListboxScroll(label_frame, borderwidth=0)
|
listbox_scroll = ListboxScroll(label_frame)
|
||||||
listbox_scroll.listbox.bind("<<ListboxSelect>>", self.update_entry)
|
listbox_scroll.listbox.bind("<<ListboxSelect>>", self.update_entry)
|
||||||
for command in commands:
|
for command in commands:
|
||||||
listbox_scroll.listbox.insert("end", command)
|
listbox_scroll.listbox.insert("end", command)
|
||||||
|
@ -303,13 +303,21 @@ class ServiceConfiguration(Dialog):
|
||||||
)
|
)
|
||||||
self.validation_period_entry.grid(row=2, column=1, sticky="ew")
|
self.validation_period_entry.grid(row=2, column=1, sticky="ew")
|
||||||
|
|
||||||
listbox_scroll = ListboxScroll(tab, text="Executables", padding=FRAME_PAD)
|
label_frame = ttk.LabelFrame(tab, text="Executables", padding=FRAME_PAD)
|
||||||
listbox_scroll.grid(sticky="nsew", pady=PADY)
|
label_frame.grid(sticky="nsew", pady=PADY)
|
||||||
|
label_frame.columnconfigure(0, weight=1)
|
||||||
|
label_frame.rowconfigure(0, weight=1)
|
||||||
|
listbox_scroll = ListboxScroll(label_frame)
|
||||||
|
listbox_scroll.grid(sticky="nsew")
|
||||||
tab.rowconfigure(listbox_scroll.grid_info()["row"], weight=1)
|
tab.rowconfigure(listbox_scroll.grid_info()["row"], weight=1)
|
||||||
for executable in self.executables:
|
for executable in self.executables:
|
||||||
listbox_scroll.listbox.insert("end", executable)
|
listbox_scroll.listbox.insert("end", executable)
|
||||||
|
|
||||||
listbox_scroll = ListboxScroll(tab, text="Dependencies", padding=FRAME_PAD)
|
label_frame = ttk.LabelFrame(tab, text="Dependencies", padding=FRAME_PAD)
|
||||||
|
label_frame.grid(sticky="nsew", pady=PADY)
|
||||||
|
label_frame.columnconfigure(0, weight=1)
|
||||||
|
label_frame.rowconfigure(0, weight=1)
|
||||||
|
listbox_scroll = ListboxScroll(label_frame)
|
||||||
listbox_scroll.grid(sticky="nsew")
|
listbox_scroll.grid(sticky="nsew")
|
||||||
tab.rowconfigure(listbox_scroll.grid_info()["row"], weight=1)
|
tab.rowconfigure(listbox_scroll.grid_info()["row"], weight=1)
|
||||||
for dependency in self.dependencies:
|
for dependency in self.dependencies:
|
||||||
|
|
|
@ -168,7 +168,7 @@ class CanvasNode:
|
||||||
is_wlan = self.core_node.type == NodeType.WIRELESS_LAN
|
is_wlan = self.core_node.type == NodeType.WIRELESS_LAN
|
||||||
is_emane = self.core_node.type == NodeType.EMANE
|
is_emane = self.core_node.type == NodeType.EMANE
|
||||||
context = tk.Menu(self.canvas)
|
context = tk.Menu(self.canvas)
|
||||||
themes.update_menu(self.app.style, context)
|
themes.style_menu(context)
|
||||||
if self.app.core.is_runtime():
|
if self.app.core.is_runtime():
|
||||||
context.add_command(label="Configure", command=self.show_config)
|
context.add_command(label="Configure", command=self.show_config)
|
||||||
if NodeUtils.is_container_node(self.core_node.type):
|
if NodeUtils.is_container_node(self.core_node.type):
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import logging
|
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
|
from tkinter import ttk
|
||||||
|
|
||||||
THEME_DARK = "black"
|
THEME_DARK = "black"
|
||||||
PADX = (0, 5)
|
PADX = (0, 5)
|
||||||
|
@ -141,30 +141,43 @@ def load(style):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_bg(style, event):
|
def theme_change_menu(event):
|
||||||
logging.info("updating background: %s", event.widget)
|
|
||||||
bg = style.lookup(".", "background")
|
|
||||||
event.widget.config(background=bg)
|
|
||||||
|
|
||||||
|
|
||||||
def theme_change_menu(style, event):
|
|
||||||
if not isinstance(event.widget, tk.Menu):
|
if not isinstance(event.widget, tk.Menu):
|
||||||
return
|
return
|
||||||
update_menu(style, event.widget)
|
style_menu(event.widget)
|
||||||
|
|
||||||
|
|
||||||
def update_menu(style, widget):
|
def style_menu(widget):
|
||||||
|
style = ttk.Style()
|
||||||
bg = style.lookup(".", "background")
|
bg = style.lookup(".", "background")
|
||||||
fg = style.lookup(".", "foreground")
|
fg = style.lookup(".", "foreground")
|
||||||
abg = style.lookup(".", "lightcolor")
|
abg = style.lookup(".", "lightcolor")
|
||||||
if not abg:
|
if not abg:
|
||||||
abg = bg
|
abg = bg
|
||||||
widget.config(
|
widget.config(
|
||||||
background=bg, foreground=fg, activebackground=abg, activeforeground=fg
|
background=bg, foreground=fg, activebackground=abg, activeforeground=fg, bd=0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def theme_change(style, event):
|
def style_listbox(widget):
|
||||||
|
style = ttk.Style()
|
||||||
|
bg = style.lookup(".", "background")
|
||||||
|
fg = style.lookup(".", "foreground")
|
||||||
|
bc = style.lookup(".", "bordercolor")
|
||||||
|
if not bc:
|
||||||
|
bc = "black"
|
||||||
|
widget.config(
|
||||||
|
background=bg,
|
||||||
|
foreground=fg,
|
||||||
|
highlightthickness=1,
|
||||||
|
highlightcolor=bc,
|
||||||
|
highlightbackground=bc,
|
||||||
|
bd=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def theme_change(event):
|
||||||
|
style = ttk.Style()
|
||||||
style.configure(Styles.picker_button, font=("TkDefaultFont", 8, "normal"))
|
style.configure(Styles.picker_button, font=("TkDefaultFont", 8, "normal"))
|
||||||
style.configure(
|
style.configure(
|
||||||
Styles.green_alert,
|
Styles.green_alert,
|
||||||
|
|
|
@ -5,6 +5,7 @@ from tkinter import filedialog, font, ttk
|
||||||
from tkinter.scrolledtext import ScrolledText
|
from tkinter.scrolledtext import ScrolledText
|
||||||
|
|
||||||
from core.api.grpc import core_pb2
|
from core.api.grpc import core_pb2
|
||||||
|
from coretk import themes
|
||||||
from coretk.appconfig import ICONS_PATH
|
from coretk.appconfig import ICONS_PATH
|
||||||
from coretk.themes import FRAME_PAD, PADX, PADY
|
from coretk.themes import FRAME_PAD, PADX, PADY
|
||||||
|
|
||||||
|
@ -174,7 +175,7 @@ class ConfigFrame(FrameScroll):
|
||||||
return {x: self.config[x].value for x in self.config}
|
return {x: self.config[x].value for x in self.config}
|
||||||
|
|
||||||
|
|
||||||
class ListboxScroll(ttk.LabelFrame):
|
class ListboxScroll(ttk.Frame):
|
||||||
def __init__(self, master=None, **kw):
|
def __init__(self, master=None, **kw):
|
||||||
super().__init__(master, **kw)
|
super().__init__(master, **kw)
|
||||||
self.columnconfigure(0, weight=1)
|
self.columnconfigure(0, weight=1)
|
||||||
|
@ -184,6 +185,7 @@ class ListboxScroll(ttk.LabelFrame):
|
||||||
self.listbox = tk.Listbox(
|
self.listbox = tk.Listbox(
|
||||||
self, selectmode=tk.SINGLE, yscrollcommand=self.scrollbar.set
|
self, selectmode=tk.SINGLE, yscrollcommand=self.scrollbar.set
|
||||||
)
|
)
|
||||||
|
themes.style_listbox(self.listbox)
|
||||||
self.listbox.grid(row=0, column=0, sticky="nsew")
|
self.listbox.grid(row=0, column=0, sticky="nsew")
|
||||||
self.scrollbar.config(command=self.listbox.yview)
|
self.scrollbar.config(command=self.listbox.yview)
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,6 @@ def handle_session_event(event):
|
||||||
name=event.name,
|
name=event.name,
|
||||||
data=event.data,
|
data=event.data,
|
||||||
time=event_time,
|
time=event_time,
|
||||||
session_id=event.session,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,9 +118,6 @@ def handle_config_event(event):
|
||||||
:return: configuration event
|
:return: configuration event
|
||||||
:rtype: core.api.grpc.core_pb2.ConfigEvent
|
:rtype: core.api.grpc.core_pb2.ConfigEvent
|
||||||
"""
|
"""
|
||||||
session_id = None
|
|
||||||
if event.session is not None:
|
|
||||||
session_id = int(event.session)
|
|
||||||
return core_pb2.ConfigEvent(
|
return core_pb2.ConfigEvent(
|
||||||
message_type=event.message_type,
|
message_type=event.message_type,
|
||||||
node_id=event.node,
|
node_id=event.node,
|
||||||
|
@ -132,7 +128,6 @@ def handle_config_event(event):
|
||||||
data_values=event.data_values,
|
data_values=event.data_values,
|
||||||
possible_values=event.possible_values,
|
possible_values=event.possible_values,
|
||||||
groups=event.groups,
|
groups=event.groups,
|
||||||
session_id=session_id,
|
|
||||||
interface=event.interface_number,
|
interface=event.interface_number,
|
||||||
network_id=event.network_id,
|
network_id=event.network_id,
|
||||||
opaque=event.opaque,
|
opaque=event.opaque,
|
||||||
|
@ -150,7 +145,6 @@ def handle_exception_event(event):
|
||||||
"""
|
"""
|
||||||
return core_pb2.ExceptionEvent(
|
return core_pb2.ExceptionEvent(
|
||||||
node_id=event.node,
|
node_id=event.node,
|
||||||
session_id=int(event.session),
|
|
||||||
level=event.level,
|
level=event.level,
|
||||||
source=event.source,
|
source=event.source,
|
||||||
date=event.date,
|
date=event.date,
|
||||||
|
@ -175,7 +169,6 @@ def handle_file_event(event):
|
||||||
number=event.number,
|
number=event.number,
|
||||||
type=event.type,
|
type=event.type,
|
||||||
source=event.source,
|
source=event.source,
|
||||||
session_id=event.session,
|
|
||||||
data=event.data,
|
data=event.data,
|
||||||
compressed_data=event.compressed_data,
|
compressed_data=event.compressed_data,
|
||||||
)
|
)
|
||||||
|
@ -224,7 +217,7 @@ class EventStreamer:
|
||||||
:return: grpc event, or None when invalid event or queue timeout
|
:return: grpc event, or None when invalid event or queue timeout
|
||||||
:rtype: core.api.grpc.core_pb2.Event
|
:rtype: core.api.grpc.core_pb2.Event
|
||||||
"""
|
"""
|
||||||
event = core_pb2.Event()
|
event = core_pb2.Event(session_id=self.session.id)
|
||||||
try:
|
try:
|
||||||
data = self.queue.get(timeout=1)
|
data = self.queue.get(timeout=1)
|
||||||
if isinstance(data, NodeData):
|
if isinstance(data, NodeData):
|
||||||
|
@ -235,8 +228,6 @@ class EventStreamer:
|
||||||
event.session_event.CopyFrom(handle_session_event(data))
|
event.session_event.CopyFrom(handle_session_event(data))
|
||||||
elif isinstance(data, ConfigData):
|
elif isinstance(data, ConfigData):
|
||||||
event.config_event.CopyFrom(handle_config_event(data))
|
event.config_event.CopyFrom(handle_config_event(data))
|
||||||
# TODO: remove when config events are fixed
|
|
||||||
event.config_event.session_id = self.session.id
|
|
||||||
elif isinstance(data, ExceptionData):
|
elif isinstance(data, ExceptionData):
|
||||||
event.exception_event.CopyFrom(handle_exception_event(data))
|
event.exception_event.CopyFrom(handle_exception_event(data))
|
||||||
elif isinstance(data, FileData):
|
elif isinstance(data, FileData):
|
||||||
|
|
|
@ -27,7 +27,7 @@ from core.nodes.lxd import LxcNode
|
||||||
from core.services.coreservices import ServiceManager
|
from core.services.coreservices import ServiceManager
|
||||||
|
|
||||||
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
|
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
|
||||||
_INTERFACE_REGEX = re.compile(r"[0-9a-fA-F]+")
|
_INTERFACE_REGEX = re.compile(r"veth(?P<node>[0-9a-fA-F]+)")
|
||||||
|
|
||||||
|
|
||||||
class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
|
@ -479,7 +479,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
throughput = rx_kbps + tx_kbps
|
throughput = rx_kbps + tx_kbps
|
||||||
if key.startswith("veth"):
|
if key.startswith("veth"):
|
||||||
key = key.split(".")
|
key = key.split(".")
|
||||||
node_id = int(_INTERFACE_REGEX.search(key[0]).group(), base=16)
|
node_id = _INTERFACE_REGEX.search(key[0]).group("node")
|
||||||
|
node_id = int(node_id, base=16)
|
||||||
interface_id = int(key[1], base=16)
|
interface_id = int(key[1], base=16)
|
||||||
session_id = int(key[2], base=16)
|
session_id = int(key[2], base=16)
|
||||||
if session.id != session_id:
|
if session.id != session_id:
|
||||||
|
|
|
@ -301,6 +301,7 @@ message Event {
|
||||||
ExceptionEvent exception_event = 5;
|
ExceptionEvent exception_event = 5;
|
||||||
FileEvent file_event = 6;
|
FileEvent file_event = 6;
|
||||||
}
|
}
|
||||||
|
int32 session_id = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message NodeEvent {
|
message NodeEvent {
|
||||||
|
@ -319,7 +320,6 @@ message SessionEvent {
|
||||||
string name = 3;
|
string name = 3;
|
||||||
string data = 4;
|
string data = 4;
|
||||||
float time = 5;
|
float time = 5;
|
||||||
int32 session_id = 6;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message ConfigEvent {
|
message ConfigEvent {
|
||||||
|
@ -333,20 +333,18 @@ message ConfigEvent {
|
||||||
string bitmap = 8;
|
string bitmap = 8;
|
||||||
string possible_values = 9;
|
string possible_values = 9;
|
||||||
string groups = 10;
|
string groups = 10;
|
||||||
int32 session_id = 11;
|
int32 interface = 11;
|
||||||
int32 interface = 12;
|
int32 network_id = 12;
|
||||||
int32 network_id = 13;
|
string opaque = 13;
|
||||||
string opaque = 14;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message ExceptionEvent {
|
message ExceptionEvent {
|
||||||
int32 node_id = 1;
|
int32 node_id = 1;
|
||||||
int32 session_id = 2;
|
ExceptionLevel.Enum level = 2;
|
||||||
ExceptionLevel.Enum level = 3;
|
string source = 3;
|
||||||
string source = 4;
|
string date = 4;
|
||||||
string date = 5;
|
string text = 5;
|
||||||
string text = 6;
|
string opaque = 6;
|
||||||
string opaque = 7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message FileEvent {
|
message FileEvent {
|
||||||
|
@ -357,9 +355,8 @@ message FileEvent {
|
||||||
int32 number = 5;
|
int32 number = 5;
|
||||||
string type = 6;
|
string type = 6;
|
||||||
string source = 7;
|
string source = 7;
|
||||||
int32 session_id = 8;
|
string data = 8;
|
||||||
string data = 9;
|
string compressed_data = 9;
|
||||||
string compressed_data = 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddNodeRequest {
|
message AddNodeRequest {
|
||||||
|
|
|
@ -990,6 +990,7 @@ class TestGrpc:
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
|
|
||||||
def handle_event(event_data):
|
def handle_event(event_data):
|
||||||
|
assert event_data.session_id == session.id
|
||||||
assert event_data.HasField("node_event")
|
assert event_data.HasField("node_event")
|
||||||
queue.put(event_data)
|
queue.put(event_data)
|
||||||
|
|
||||||
|
@ -1014,6 +1015,7 @@ class TestGrpc:
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
|
|
||||||
def handle_event(event_data):
|
def handle_event(event_data):
|
||||||
|
assert event_data.session_id == session.id
|
||||||
assert event_data.HasField("link_event")
|
assert event_data.HasField("link_event")
|
||||||
queue.put(event_data)
|
queue.put(event_data)
|
||||||
|
|
||||||
|
@ -1036,6 +1038,7 @@ class TestGrpc:
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
|
|
||||||
def handle_event(event_data):
|
def handle_event(event_data):
|
||||||
|
assert event_data.session_id == session.id
|
||||||
queue.put(event_data)
|
queue.put(event_data)
|
||||||
|
|
||||||
# then
|
# then
|
||||||
|
@ -1053,6 +1056,7 @@ class TestGrpc:
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
|
|
||||||
def handle_event(event_data):
|
def handle_event(event_data):
|
||||||
|
assert event_data.session_id == session.id
|
||||||
assert event_data.HasField("session_event")
|
assert event_data.HasField("session_event")
|
||||||
queue.put(event_data)
|
queue.put(event_data)
|
||||||
|
|
||||||
|
@ -1075,6 +1079,7 @@ class TestGrpc:
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
|
|
||||||
def handle_event(event_data):
|
def handle_event(event_data):
|
||||||
|
assert event_data.session_id == session.id
|
||||||
assert event_data.HasField("config_event")
|
assert event_data.HasField("config_event")
|
||||||
queue.put(event_data)
|
queue.put(event_data)
|
||||||
|
|
||||||
|
@ -1098,6 +1103,7 @@ class TestGrpc:
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
|
|
||||||
def handle_event(event_data):
|
def handle_event(event_data):
|
||||||
|
assert event_data.session_id == session.id
|
||||||
assert event_data.HasField("exception_event")
|
assert event_data.HasField("exception_event")
|
||||||
queue.put(event_data)
|
queue.put(event_data)
|
||||||
|
|
||||||
|
@ -1120,6 +1126,7 @@ class TestGrpc:
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
|
|
||||||
def handle_event(event_data):
|
def handle_event(event_data):
|
||||||
|
assert event_data.session_id == session.id
|
||||||
assert event_data.HasField("file_event")
|
assert event_data.HasField("file_event")
|
||||||
queue.put(event_data)
|
queue.put(event_data)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue