Merge branch 'coretk' into coretk-linkconfig
This commit is contained in:
commit
57bbac5c55
12 changed files with 129 additions and 91 deletions
|
@ -38,7 +38,7 @@ class AboutDialog(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)
|
||||||
|
|
||||||
text = CodeText(self.top)
|
codetext = CodeText(self.top)
|
||||||
text.insert("1.0", LICENSE)
|
codetext.text.insert("1.0", LICENSE)
|
||||||
text.config(state=tk.DISABLED)
|
codetext.text.config(state=tk.DISABLED)
|
||||||
text.grid(sticky="nsew")
|
codetext.grid(sticky="nsew")
|
||||||
|
|
|
@ -17,7 +17,7 @@ class AlertsDialog(Dialog):
|
||||||
super().__init__(master, app, "Alerts", modal=True)
|
super().__init__(master, app, "Alerts", modal=True)
|
||||||
self.app = app
|
self.app = app
|
||||||
self.tree = None
|
self.tree = None
|
||||||
self.text = None
|
self.codetext = None
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
|
@ -76,9 +76,9 @@ class AlertsDialog(Dialog):
|
||||||
xscrollbar.grid(row=1, sticky="ew")
|
xscrollbar.grid(row=1, sticky="ew")
|
||||||
self.tree.configure(xscrollcommand=xscrollbar.set)
|
self.tree.configure(xscrollcommand=xscrollbar.set)
|
||||||
|
|
||||||
self.text = CodeText(self.top)
|
self.codetext = CodeText(self.top)
|
||||||
self.text.config(state=tk.DISABLED)
|
self.codetext.text.config(state=tk.DISABLED)
|
||||||
self.text.grid(sticky="nsew", pady=PADY)
|
self.codetext.grid(sticky="nsew", pady=PADY)
|
||||||
|
|
||||||
frame = ttk.Frame(self.top)
|
frame = ttk.Frame(self.top)
|
||||||
frame.grid(sticky="ew")
|
frame.grid(sticky="ew")
|
||||||
|
@ -96,7 +96,7 @@ class AlertsDialog(Dialog):
|
||||||
button.grid(row=0, column=3, sticky="ew")
|
button.grid(row=0, column=3, sticky="ew")
|
||||||
|
|
||||||
def reset_alerts(self):
|
def reset_alerts(self):
|
||||||
self.text.delete("1.0", tk.END)
|
self.codetext.text.delete("1.0", tk.END)
|
||||||
for item in self.tree.get_children():
|
for item in self.tree.get_children():
|
||||||
self.tree.delete(item)
|
self.tree.delete(item)
|
||||||
self.app.statusbar.core_alarms.clear()
|
self.app.statusbar.core_alarms.clear()
|
||||||
|
@ -137,8 +137,8 @@ class AlertsDialog(Dialog):
|
||||||
text = text + "node created"
|
text = text + "node created"
|
||||||
except RpcError:
|
except RpcError:
|
||||||
text = text + "node not created"
|
text = text + "node not created"
|
||||||
self.text.delete("1.0", "end")
|
self.codetext.text.delete("1.0", "end")
|
||||||
self.text.insert("1.0", text)
|
self.codetext.text.insert("1.0", text)
|
||||||
|
|
||||||
|
|
||||||
class DaemonLog(Dialog):
|
class DaemonLog(Dialog):
|
||||||
|
@ -155,8 +155,8 @@ class DaemonLog(Dialog):
|
||||||
frame.grid(row=0, column=0, sticky="ew", pady=PADY)
|
frame.grid(row=0, column=0, sticky="ew", pady=PADY)
|
||||||
frame.columnconfigure(0, weight=1)
|
frame.columnconfigure(0, weight=1)
|
||||||
frame.columnconfigure(1, weight=9)
|
frame.columnconfigure(1, weight=9)
|
||||||
label = ttk.Label(frame, text="File: ")
|
label = ttk.Label(frame, text="File", anchor="w")
|
||||||
label.grid(row=0, column=0)
|
label.grid(row=0, column=0, sticky="ew")
|
||||||
entry = ttk.Entry(frame, textvariable=self.path, state="disabled")
|
entry = ttk.Entry(frame, textvariable=self.path, state="disabled")
|
||||||
entry.grid(row=0, column=1, sticky="ew")
|
entry.grid(row=0, column=1, sticky="ew")
|
||||||
try:
|
try:
|
||||||
|
@ -164,8 +164,8 @@ class DaemonLog(Dialog):
|
||||||
log = file.readlines()
|
log = file.readlines()
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
log = "Log file not found"
|
log = "Log file not found"
|
||||||
text = CodeText(self.top)
|
codetext = CodeText(self.top)
|
||||||
text.insert("1.0", log)
|
codetext.text.insert("1.0", log)
|
||||||
text.see("end")
|
codetext.text.see("end")
|
||||||
text.config(state=tk.DISABLED)
|
codetext.text.config(state=tk.DISABLED)
|
||||||
text.grid(row=1, column=0, sticky="nsew")
|
codetext.grid(row=1, column=0, sticky="nsew")
|
||||||
|
|
|
@ -3,12 +3,13 @@ set wallpaper
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import filedialog, ttk
|
from tkinter import ttk
|
||||||
|
|
||||||
from coretk.appconfig import BACKGROUNDS_PATH
|
from coretk.appconfig import BACKGROUNDS_PATH
|
||||||
from coretk.dialogs.dialog import Dialog
|
from coretk.dialogs.dialog import Dialog
|
||||||
from coretk.images import Images
|
from coretk.images import Images
|
||||||
from coretk.themes import PADX, PADY
|
from coretk.themes import PADX, PADY
|
||||||
|
from coretk.widgets import image_chooser
|
||||||
|
|
||||||
|
|
||||||
class CanvasBackgroundDialog(Dialog):
|
class CanvasBackgroundDialog(Dialog):
|
||||||
|
@ -126,14 +127,7 @@ class CanvasBackgroundDialog(Dialog):
|
||||||
button.grid(row=0, column=1, sticky="ew")
|
button.grid(row=0, column=1, sticky="ew")
|
||||||
|
|
||||||
def click_open_image(self):
|
def click_open_image(self):
|
||||||
filename = filedialog.askopenfilename(
|
filename = image_chooser(self, BACKGROUNDS_PATH)
|
||||||
initialdir=str(BACKGROUNDS_PATH),
|
|
||||||
title="Open",
|
|
||||||
filetypes=(
|
|
||||||
("images", "*.gif *.jpg *.png *.bmp *pcx *.tga ..."),
|
|
||||||
("All Files", "*"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if filename:
|
if filename:
|
||||||
self.filename.set(filename)
|
self.filename.set(filename)
|
||||||
self.draw_preview()
|
self.draw_preview()
|
||||||
|
|
|
@ -4,6 +4,7 @@ from pathlib import Path
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
|
|
||||||
from coretk import nodeutils
|
from coretk import nodeutils
|
||||||
|
from coretk.appconfig import ICONS_PATH
|
||||||
from coretk.dialogs.dialog import Dialog
|
from coretk.dialogs.dialog import Dialog
|
||||||
from coretk.images import Images
|
from coretk.images import Images
|
||||||
from coretk.nodeutils import NodeDraw
|
from coretk.nodeutils import NodeDraw
|
||||||
|
@ -179,7 +180,7 @@ class CustomNodesDialog(Dialog):
|
||||||
self.image_button.config(image="")
|
self.image_button.config(image="")
|
||||||
|
|
||||||
def click_icon(self):
|
def click_icon(self):
|
||||||
file_path = image_chooser(self)
|
file_path = image_chooser(self, ICONS_PATH)
|
||||||
if file_path:
|
if file_path:
|
||||||
image = Images.create(file_path, nodeutils.ICON_SIZE)
|
image = Images.create(file_path, nodeutils.ICON_SIZE)
|
||||||
self.image = image
|
self.image = image
|
||||||
|
|
|
@ -11,7 +11,7 @@ class HookDialog(Dialog):
|
||||||
def __init__(self, master, app):
|
def __init__(self, master, app):
|
||||||
super().__init__(master, app, "Hook", modal=True)
|
super().__init__(master, app, "Hook", modal=True)
|
||||||
self.name = tk.StringVar()
|
self.name = tk.StringVar()
|
||||||
self.data = None
|
self.codetext = None
|
||||||
self.hook = core_pb2.Hook()
|
self.hook = core_pb2.Hook()
|
||||||
self.state = tk.StringVar()
|
self.state = tk.StringVar()
|
||||||
self.draw()
|
self.draw()
|
||||||
|
@ -41,8 +41,8 @@ class HookDialog(Dialog):
|
||||||
combobox.bind("<<ComboboxSelected>>", self.state_change)
|
combobox.bind("<<ComboboxSelected>>", self.state_change)
|
||||||
|
|
||||||
# data
|
# data
|
||||||
self.data = CodeText(self.top)
|
self.codetext = CodeText(self.top)
|
||||||
self.data.insert(
|
self.codetext.text.insert(
|
||||||
1.0,
|
1.0,
|
||||||
(
|
(
|
||||||
"#!/bin/sh\n"
|
"#!/bin/sh\n"
|
||||||
|
@ -50,7 +50,7 @@ class HookDialog(Dialog):
|
||||||
"# specified state\n"
|
"# specified state\n"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.data.grid(sticky="nsew")
|
self.codetext.grid(sticky="nsew", pady=PADY)
|
||||||
|
|
||||||
# button row
|
# button row
|
||||||
frame = ttk.Frame(self.top)
|
frame = ttk.Frame(self.top)
|
||||||
|
@ -69,13 +69,13 @@ class HookDialog(Dialog):
|
||||||
def set(self, hook):
|
def set(self, hook):
|
||||||
self.hook = hook
|
self.hook = hook
|
||||||
self.name.set(hook.file)
|
self.name.set(hook.file)
|
||||||
self.data.delete(1.0, tk.END)
|
self.codetext.text.delete(1.0, tk.END)
|
||||||
self.data.insert(tk.END, hook.data)
|
self.codetext.text.insert(tk.END, hook.data)
|
||||||
state_name = core_pb2.SessionState.Enum.Name(hook.state)
|
state_name = core_pb2.SessionState.Enum.Name(hook.state)
|
||||||
self.state.set(state_name)
|
self.state.set(state_name)
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
data = self.data.get("1.0", tk.END).strip()
|
data = self.codetext.text.get("1.0", tk.END).strip()
|
||||||
state_value = core_pb2.SessionState.Enum.Value(self.state.get())
|
state_value = core_pb2.SessionState.Enum.Value(self.state.get())
|
||||||
self.hook.file = self.name.get()
|
self.hook.file = self.name.get()
|
||||||
self.hook.data = data
|
self.hook.data = data
|
||||||
|
|
|
@ -4,11 +4,13 @@ from functools import partial
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
|
|
||||||
from coretk import nodeutils
|
from coretk import nodeutils
|
||||||
|
from coretk.appconfig import ICONS_PATH
|
||||||
from coretk.dialogs.dialog import Dialog
|
from coretk.dialogs.dialog import Dialog
|
||||||
|
from coretk.dialogs.emaneconfig import EmaneModelDialog
|
||||||
from coretk.images import Images
|
from coretk.images import Images
|
||||||
from coretk.nodeutils import NodeUtils
|
from coretk.nodeutils import NodeUtils
|
||||||
from coretk.themes import FRAME_PAD, PADX, PADY
|
from coretk.themes import FRAME_PAD, PADX, PADY
|
||||||
from coretk.widgets import FrameScroll, image_chooser
|
from coretk.widgets import image_chooser
|
||||||
|
|
||||||
|
|
||||||
def mac_auto(is_auto, entry):
|
def mac_auto(is_auto, entry):
|
||||||
|
@ -137,42 +139,57 @@ class NodeConfigDialog(Dialog):
|
||||||
self.draw_buttons()
|
self.draw_buttons()
|
||||||
|
|
||||||
def draw_interfaces(self):
|
def draw_interfaces(self):
|
||||||
scroll = FrameScroll(self.top, self.app, text="Interfaces")
|
notebook = ttk.Notebook(self.top)
|
||||||
scroll.grid(sticky="nsew")
|
notebook.grid(sticky="nsew", pady=PADY)
|
||||||
scroll.frame.columnconfigure(0, weight=1)
|
self.top.rowconfigure(notebook.grid_info()["row"], weight=1)
|
||||||
scroll.frame.rowconfigure(0, weight=1)
|
|
||||||
for interface in self.canvas_node.interfaces:
|
for interface in self.canvas_node.interfaces:
|
||||||
logging.info("interface: %s", interface)
|
logging.info("interface: %s", interface)
|
||||||
frame = ttk.LabelFrame(scroll.frame, text=interface.name, padding=FRAME_PAD)
|
tab = ttk.Frame(notebook, padding=FRAME_PAD)
|
||||||
frame.grid(sticky="ew", pady=PADY)
|
tab.grid(sticky="nsew", pady=PADY)
|
||||||
frame.columnconfigure(1, weight=1)
|
tab.columnconfigure(1, weight=1)
|
||||||
frame.columnconfigure(2, weight=1)
|
tab.columnconfigure(2, weight=1)
|
||||||
|
notebook.add(tab, text=interface.name)
|
||||||
|
|
||||||
label = ttk.Label(frame, text="MAC")
|
row = 0
|
||||||
label.grid(row=0, column=0, padx=PADX, pady=PADY)
|
emane_node = self.canvas_node.has_emane_link(interface.id)
|
||||||
|
if emane_node:
|
||||||
|
emane_model = emane_node.emane.split("_")[1]
|
||||||
|
button = ttk.Button(
|
||||||
|
tab,
|
||||||
|
text=f"Configure EMANE {emane_model}",
|
||||||
|
command=lambda: self.click_emane_config(emane_model, interface.id),
|
||||||
|
)
|
||||||
|
button.grid(row=row, sticky="ew", columnspan=3, pady=PADY)
|
||||||
|
row += 1
|
||||||
|
|
||||||
|
label = ttk.Label(tab, text="MAC")
|
||||||
|
label.grid(row=row, column=0, padx=PADX, pady=PADY)
|
||||||
is_auto = tk.BooleanVar(value=True)
|
is_auto = tk.BooleanVar(value=True)
|
||||||
checkbutton = ttk.Checkbutton(frame, text="Auto?", variable=is_auto)
|
checkbutton = ttk.Checkbutton(tab, text="Auto?", variable=is_auto)
|
||||||
checkbutton.var = is_auto
|
checkbutton.var = is_auto
|
||||||
checkbutton.grid(row=0, column=1, padx=PADX)
|
checkbutton.grid(row=row, column=1, padx=PADX)
|
||||||
mac = tk.StringVar(value=interface.mac)
|
mac = tk.StringVar(value=interface.mac)
|
||||||
entry = ttk.Entry(frame, textvariable=mac, state=tk.DISABLED)
|
entry = ttk.Entry(tab, textvariable=mac, state=tk.DISABLED)
|
||||||
entry.grid(row=0, column=2, sticky="ew")
|
entry.grid(row=row, column=2, sticky="ew")
|
||||||
func = partial(mac_auto, is_auto, entry)
|
func = partial(mac_auto, is_auto, entry)
|
||||||
checkbutton.config(command=func)
|
checkbutton.config(command=func)
|
||||||
|
row += 1
|
||||||
|
|
||||||
label = ttk.Label(frame, text="IPv4")
|
label = ttk.Label(tab, text="IPv4")
|
||||||
label.grid(row=1, column=0, padx=PADX, pady=PADY)
|
label.grid(row=row, column=0, padx=PADX, pady=PADY)
|
||||||
ip4 = tk.StringVar(value=f"{interface.ip4}/{interface.ip4mask}")
|
ip4 = tk.StringVar(value=f"{interface.ip4}/{interface.ip4mask}")
|
||||||
entry = ttk.Entry(frame, textvariable=ip4)
|
entry = ttk.Entry(tab, textvariable=ip4)
|
||||||
entry.bind("<FocusOut>", self.app.validation.ip_focus_out)
|
entry.bind("<FocusOut>", self.app.validation.ip_focus_out)
|
||||||
entry.grid(row=1, column=1, columnspan=2, sticky="ew")
|
entry.grid(row=row, column=1, columnspan=2, sticky="ew")
|
||||||
|
row += 1
|
||||||
|
|
||||||
label = ttk.Label(frame, text="IPv6")
|
label = ttk.Label(tab, text="IPv6")
|
||||||
label.grid(row=2, column=0, padx=PADX, pady=PADY)
|
label.grid(row=row, column=0, padx=PADX, pady=PADY)
|
||||||
ip6 = tk.StringVar(value=f"{interface.ip6}/{interface.ip6mask}")
|
ip6 = tk.StringVar(value=f"{interface.ip6}/{interface.ip6mask}")
|
||||||
entry = ttk.Entry(frame, textvariable=ip6)
|
entry = ttk.Entry(tab, textvariable=ip6)
|
||||||
entry.bind("<FocusOut>", self.app.validation.ip_focus_out)
|
entry.bind("<FocusOut>", self.app.validation.ip_focus_out)
|
||||||
entry.grid(row=2, column=1, columnspan=2, sticky="ew")
|
entry.grid(row=row, column=1, columnspan=2, sticky="ew")
|
||||||
|
|
||||||
self.interfaces[interface.id] = InterfaceData(is_auto, mac, ip4, ip6)
|
self.interfaces[interface.id] = InterfaceData(is_auto, mac, ip4, ip6)
|
||||||
|
|
||||||
|
@ -188,8 +205,12 @@ class NodeConfigDialog(Dialog):
|
||||||
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
button = ttk.Button(frame, text="Cancel", command=self.destroy)
|
||||||
button.grid(row=0, column=1, sticky="ew")
|
button.grid(row=0, column=1, sticky="ew")
|
||||||
|
|
||||||
|
def click_emane_config(self, emane_model, interface_id):
|
||||||
|
dialog = EmaneModelDialog(self, self.app, self.node, emane_model, interface_id)
|
||||||
|
dialog.show()
|
||||||
|
|
||||||
def click_icon(self):
|
def click_icon(self):
|
||||||
file_path = image_chooser(self)
|
file_path = image_chooser(self, ICONS_PATH)
|
||||||
if file_path:
|
if file_path:
|
||||||
self.image = Images.create(file_path, nodeutils.ICON_SIZE)
|
self.image = Images.create(file_path, nodeutils.ICON_SIZE)
|
||||||
self.image_button.config(image=self.image)
|
self.image_button.config(image=self.image)
|
||||||
|
|
|
@ -110,7 +110,7 @@ class ServiceConfiguration(Dialog):
|
||||||
|
|
||||||
# draw notebook
|
# draw notebook
|
||||||
self.notebook = ttk.Notebook(self.top)
|
self.notebook = ttk.Notebook(self.top)
|
||||||
self.notebook.grid(sticky="nsew")
|
self.notebook.grid(sticky="nsew", pady=PADY)
|
||||||
self.draw_tab_files()
|
self.draw_tab_files()
|
||||||
self.draw_tab_directories()
|
self.draw_tab_directories()
|
||||||
self.draw_tab_startstop()
|
self.draw_tab_startstop()
|
||||||
|
@ -192,11 +192,13 @@ class ServiceConfiguration(Dialog):
|
||||||
tab.rowconfigure(self.service_file_data.grid_info()["row"], weight=1)
|
tab.rowconfigure(self.service_file_data.grid_info()["row"], weight=1)
|
||||||
if len(self.filenames) > 0:
|
if len(self.filenames) > 0:
|
||||||
self.filename_combobox.current(0)
|
self.filename_combobox.current(0)
|
||||||
self.service_file_data.delete(1.0, "end")
|
self.service_file_data.text.delete(1.0, "end")
|
||||||
self.service_file_data.insert(
|
self.service_file_data.text.insert(
|
||||||
"end", self.temp_service_files[self.filenames[0]]
|
"end", self.temp_service_files[self.filenames[0]]
|
||||||
)
|
)
|
||||||
self.service_file_data.bind("<FocusOut>", self.update_temp_service_file_data)
|
self.service_file_data.text.bind(
|
||||||
|
"<FocusOut>", self.update_temp_service_file_data
|
||||||
|
)
|
||||||
|
|
||||||
def draw_tab_directories(self):
|
def draw_tab_directories(self):
|
||||||
tab = ttk.Frame(self.notebook, padding=FRAME_PAD)
|
tab = ttk.Frame(self.notebook, padding=FRAME_PAD)
|
||||||
|
@ -275,14 +277,14 @@ class ServiceConfiguration(Dialog):
|
||||||
frame.columnconfigure(1, weight=1)
|
frame.columnconfigure(1, weight=1)
|
||||||
|
|
||||||
label = ttk.Label(frame, text="Validation Time")
|
label = ttk.Label(frame, text="Validation Time")
|
||||||
label.grid(row=0, column=0, sticky="w")
|
label.grid(row=0, column=0, sticky="w", padx=PADX)
|
||||||
self.validation_time_entry = ttk.Entry(frame)
|
self.validation_time_entry = ttk.Entry(frame)
|
||||||
self.validation_time_entry.insert("end", self.validation_time)
|
self.validation_time_entry.insert("end", self.validation_time)
|
||||||
self.validation_time_entry.config(state=tk.DISABLED)
|
self.validation_time_entry.config(state=tk.DISABLED)
|
||||||
self.validation_time_entry.grid(row=0, column=1, sticky="ew")
|
self.validation_time_entry.grid(row=0, column=1, sticky="ew", pady=PADY)
|
||||||
|
|
||||||
label = ttk.Label(frame, text="Validation Mode")
|
label = ttk.Label(frame, text="Validation Mode")
|
||||||
label.grid(row=1, column=0, sticky="w")
|
label.grid(row=1, column=0, sticky="w", padx=PADX)
|
||||||
if self.validation_mode == core_pb2.ServiceValidationMode.BLOCKING:
|
if self.validation_mode == core_pb2.ServiceValidationMode.BLOCKING:
|
||||||
mode = "BLOCKING"
|
mode = "BLOCKING"
|
||||||
elif self.validation_mode == core_pb2.ServiceValidationMode.NON_BLOCKING:
|
elif self.validation_mode == core_pb2.ServiceValidationMode.NON_BLOCKING:
|
||||||
|
@ -294,14 +296,14 @@ class ServiceConfiguration(Dialog):
|
||||||
)
|
)
|
||||||
self.validation_mode_entry.insert("end", mode)
|
self.validation_mode_entry.insert("end", mode)
|
||||||
self.validation_mode_entry.config(state=tk.DISABLED)
|
self.validation_mode_entry.config(state=tk.DISABLED)
|
||||||
self.validation_mode_entry.grid(row=1, column=1, sticky="ew")
|
self.validation_mode_entry.grid(row=1, column=1, sticky="ew", pady=PADY)
|
||||||
|
|
||||||
label = ttk.Label(frame, text="Validation Period")
|
label = ttk.Label(frame, text="Validation Period")
|
||||||
label.grid(row=2, column=0, sticky="w")
|
label.grid(row=2, column=0, sticky="w", padx=PADX)
|
||||||
self.validation_period_entry = ttk.Entry(
|
self.validation_period_entry = ttk.Entry(
|
||||||
frame, state=tk.DISABLED, textvariable=tk.StringVar()
|
frame, state=tk.DISABLED, textvariable=tk.StringVar()
|
||||||
)
|
)
|
||||||
self.validation_period_entry.grid(row=2, column=1, sticky="ew")
|
self.validation_period_entry.grid(row=2, column=1, sticky="ew", pady=PADY)
|
||||||
|
|
||||||
label_frame = ttk.LabelFrame(tab, text="Executables", padding=FRAME_PAD)
|
label_frame = ttk.LabelFrame(tab, text="Executables", padding=FRAME_PAD)
|
||||||
label_frame.grid(sticky="nsew", pady=PADY)
|
label_frame.grid(sticky="nsew", pady=PADY)
|
||||||
|
@ -429,8 +431,8 @@ class ServiceConfiguration(Dialog):
|
||||||
def display_service_file_data(self, event):
|
def display_service_file_data(self, event):
|
||||||
combobox = event.widget
|
combobox = event.widget
|
||||||
filename = combobox.get()
|
filename = combobox.get()
|
||||||
self.service_file_data.delete(1.0, "end")
|
self.service_file_data.text.delete(1.0, "end")
|
||||||
self.service_file_data.insert("end", self.temp_service_files[filename])
|
self.service_file_data.text.insert("end", self.temp_service_files[filename])
|
||||||
|
|
||||||
def update_temp_service_file_data(self, event):
|
def update_temp_service_file_data(self, event):
|
||||||
scrolledtext = event.widget
|
scrolledtext = event.widget
|
||||||
|
|
|
@ -246,6 +246,23 @@ class CanvasNode:
|
||||||
dialog = NodeService(self.app.master, self.app, self)
|
dialog = NodeService(self.app.master, self.app, self)
|
||||||
dialog.show()
|
dialog.show()
|
||||||
|
|
||||||
|
def has_emane_link(self, interface_id):
|
||||||
|
result = None
|
||||||
|
for edge in self.edges:
|
||||||
|
if self.id == edge.src:
|
||||||
|
other_id = edge.dst
|
||||||
|
edge_interface_id = edge.src_interface.id
|
||||||
|
else:
|
||||||
|
other_id = edge.src
|
||||||
|
edge_interface_id = edge.dst_interface.id
|
||||||
|
if edge_interface_id != interface_id:
|
||||||
|
continue
|
||||||
|
other_node = self.canvas.nodes[other_id]
|
||||||
|
if other_node.core_node.type == NodeType.EMANE:
|
||||||
|
result = other_node.core_node
|
||||||
|
break
|
||||||
|
return result
|
||||||
|
|
||||||
def wireless_link_selected(self):
|
def wireless_link_selected(self):
|
||||||
self.canvas.context = None
|
self.canvas.context = None
|
||||||
for canvas_nid in [
|
for canvas_nid in [
|
||||||
|
|
|
@ -2,11 +2,9 @@ import logging
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from tkinter import filedialog, font, ttk
|
from tkinter import filedialog, font, ttk
|
||||||
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 import themes
|
||||||
from coretk.appconfig import ICONS_PATH
|
|
||||||
from coretk.themes import FRAME_PAD, PADX, PADY
|
from coretk.themes import FRAME_PAD, PADX, PADY
|
||||||
|
|
||||||
INT_TYPES = {
|
INT_TYPES = {
|
||||||
|
@ -208,10 +206,13 @@ class CodeFont(font.Font):
|
||||||
super().__init__(font="TkFixedFont", color="green")
|
super().__init__(font="TkFixedFont", color="green")
|
||||||
|
|
||||||
|
|
||||||
class CodeText(ScrolledText):
|
class CodeText(ttk.Frame):
|
||||||
def __init__(self, master, **kwargs):
|
def __init__(self, master, **kwargs):
|
||||||
super().__init__(
|
super().__init__(master, **kwargs)
|
||||||
master,
|
self.rowconfigure(0, weight=1)
|
||||||
|
self.columnconfigure(0, weight=1)
|
||||||
|
self.text = tk.Text(
|
||||||
|
self,
|
||||||
bd=0,
|
bd=0,
|
||||||
bg="black",
|
bg="black",
|
||||||
cursor="xterm lime lime",
|
cursor="xterm lime lime",
|
||||||
|
@ -222,8 +223,11 @@ class CodeText(ScrolledText):
|
||||||
selectbackground="lime",
|
selectbackground="lime",
|
||||||
selectforeground="black",
|
selectforeground="black",
|
||||||
relief=tk.FLAT,
|
relief=tk.FLAT,
|
||||||
**kwargs
|
|
||||||
)
|
)
|
||||||
|
self.text.grid(row=0, column=0, sticky="nsew")
|
||||||
|
yscrollbar = ttk.Scrollbar(self, orient=tk.VERTICAL, command=self.text.yview)
|
||||||
|
yscrollbar.grid(row=0, column=1, sticky="ns")
|
||||||
|
self.text.configure(yscrollcommand=yscrollbar.set)
|
||||||
|
|
||||||
|
|
||||||
class Spinbox(ttk.Entry):
|
class Spinbox(ttk.Entry):
|
||||||
|
@ -234,11 +238,11 @@ class Spinbox(ttk.Entry):
|
||||||
self.tk.call(self._w, "set", value)
|
self.tk.call(self._w, "set", value)
|
||||||
|
|
||||||
|
|
||||||
def image_chooser(parent):
|
def image_chooser(parent, path):
|
||||||
return filedialog.askopenfilename(
|
return filedialog.askopenfilename(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
initialdir=str(ICONS_PATH),
|
initialdir=str(path),
|
||||||
title="Select Icon",
|
title="Select",
|
||||||
filetypes=(
|
filetypes=(
|
||||||
("images", "*.gif *.jpg *.png *.bmp *pcx *.tga ..."),
|
("images", "*.gif *.jpg *.png *.bmp *pcx *.tga ..."),
|
||||||
("All Files", "*"),
|
("All Files", "*"),
|
||||||
|
|
|
@ -68,7 +68,7 @@ Virtual networks generally require some form of routing in order to work (e.g. t
|
||||||
tables for routing packets from one subnet to another.) CORE builds OSPF routing protocol configurations by
|
tables for routing packets from one subnet to another.) CORE builds OSPF routing protocol configurations by
|
||||||
default when the blue router node type is used.
|
default when the blue router node type is used.
|
||||||
|
|
||||||
* [OSPF MANET Designated Routers](http://www.nrl.navy.mil/itd/ncs/products/ospf-manet) (MDR) - the Quagga routing
|
* [OSPF MANET Designated Routers](https://github.com/USNavalResearchLaboratory/ospf-mdr) (MDR) - the Quagga routing
|
||||||
suite with a modified version of OSPFv3, optimized for use with mobile wireless networks. The **mdr** node type
|
suite with a modified version of OSPFv3, optimized for use with mobile wireless networks. The **mdr** node type
|
||||||
(and the MDR service) requires this variant of Quagga.
|
(and the MDR service) requires this variant of Quagga.
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ suite with a modified version of OSPFv3, optimized for use with mobile wireless
|
||||||
There is a built package which can be used.
|
There is a built package which can be used.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
wget https://downloads.pf.itd.nrl.navy.mil/ospf-manet/quagga-0.99.21mr2.2/quagga-mr_0.99.21mr2.2_amd64.deb
|
wget https://github.com/USNavalResearchLaboratory/ospf-mdr/releases/download/v0.99.21mr2.2/quagga-mr_0.99.21mr2.2_amd64.deb
|
||||||
sudo dpkg -i quagga-mr_0.99.21mr2.2_amd64.deb
|
sudo dpkg -i quagga-mr_0.99.21mr2.2_amd64.deb
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -89,9 +89,8 @@ Requires building from source, from the latest nightly snapshot.
|
||||||
# packages needed beyond what's normally required to build core on ubuntu
|
# packages needed beyond what's normally required to build core on ubuntu
|
||||||
sudo apt install libtool libreadline-dev autoconf
|
sudo apt install libtool libreadline-dev autoconf
|
||||||
|
|
||||||
wget https://downloads.pf.itd.nrl.navy.mil/ospf-manet/nightly_snapshots/quagga-svnsnap.tgz
|
git clone https://github.com/USNavalResearchLaboratory/ospf-mdr
|
||||||
tar xzf quagga-svnsnap.tgz
|
cd ospf-mdr
|
||||||
cd quagga
|
|
||||||
./bootstrap.sh
|
./bootstrap.sh
|
||||||
./configure --disable-doc --enable-user=root --enable-group=root --with-cflags=-ggdb \
|
./configure --disable-doc --enable-user=root --enable-group=root --with-cflags=-ggdb \
|
||||||
--sysconfdir=/usr/local/etc/quagga --enable-vtysh \
|
--sysconfdir=/usr/local/etc/quagga --enable-vtysh \
|
||||||
|
|
|
@ -312,17 +312,17 @@ Currently the Naval Research Laboratory uses this library to develop a wide vari
|
||||||
* arouted
|
* arouted
|
||||||
|
|
||||||
#### NRL Installation
|
#### NRL Installation
|
||||||
In order to be able to use the different protocols that NRL offers, you must first download the support library itself. You can get the source code from their [official nightly snapshots website](https://downloads.pf.itd.nrl.navy.mil/protolib/nightly_snapshots/).
|
In order to be able to use the different protocols that NRL offers, you must first download the support library itself. You can get the source code from their [NRL Protolib Repo](https://github.com/USNavalResearchLaboratory/protolib).
|
||||||
|
|
||||||
#### Multi-Generator (MGEN)
|
#### Multi-Generator (MGEN)
|
||||||
Download MGEN from the [NRL MGEN nightly snapshots](https://downloads.pf.itd.nrl.navy.mil/mgen/nightly_snapshots/), unpack it and copy the protolib library into the main folder *mgen*. Execute the following commands to build the protocol.
|
Download MGEN from the [NRL MGEN Repo](https://github.com/USNavalResearchLaboratory/mgen), unpack it and copy the protolib library into the main folder *mgen*. Execute the following commands to build the protocol.
|
||||||
```shell
|
```shell
|
||||||
cd mgen/makefiles
|
cd mgen/makefiles
|
||||||
make -f Makefile.{os} mgen
|
make -f Makefile.{os} mgen
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Neighborhood Discovery Protocol (NHDP)
|
#### Neighborhood Discovery Protocol (NHDP)
|
||||||
Download NHDP from the [NRL NHDP nightly snapshots](https://downloads.pf.itd.nrl.navy.mil/nhdp/nightly_snapshots/).
|
Download NHDP from the [NRL NHDP Repo](https://github.com/USNavalResearchLaboratory/NCS-Downloads/tree/master/nhdp).
|
||||||
```shell
|
```shell
|
||||||
sudo apt-get install libpcap-dev libboost-all-dev
|
sudo apt-get install libpcap-dev libboost-all-dev
|
||||||
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.8.0/protoc-3.8.0-linux-x86_64.zip
|
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.8.0/protoc-3.8.0-linux-x86_64.zip
|
||||||
|
@ -339,14 +339,14 @@ make -f Makefile.{os}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Simplified Multicast Forwarding (SMF)
|
#### Simplified Multicast Forwarding (SMF)
|
||||||
Download SMF from the [NRL SMF nightly snapshot](https://downloads.pf.itd.nrl.navy.mil/smf/nightly_snapshots/) , unpack it and place the protolib library inside the *smf* main folder.
|
Download SMF from the [NRL SMF Repo](https://github.com/USNavalResearchLaboratory/nrlsmf) , unpack it and place the protolib library inside the *smf* main folder.
|
||||||
```shell
|
```shell
|
||||||
cd mgen/makefiles
|
cd mgen/makefiles
|
||||||
make -f Makefile.{os}
|
make -f Makefile.{os}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Optimized Link State Routing Protocol (OLSR)
|
#### Optimized Link State Routing Protocol (OLSR)
|
||||||
To install the OLSR protocol, download their source code from their [nightly snapshots](https://downloads.pf.itd.nrl.navy.mil/olsr/nightly_snapshots/nrlolsr-svnsnap.tgz). Unpack it and place the previously downloaded protolib library inside the *nrlolsr* main directory. Then execute the following commands:
|
To install the OLSR protocol, download their source code from their [NRL OLSR Repo](https://github.com/USNavalResearchLaboratory/nrlolsr). Unpack it and place the previously downloaded protolib library inside the *nrlolsr* main directory. Then execute the following commands:
|
||||||
```shell
|
```shell
|
||||||
cd ./unix
|
cd ./unix
|
||||||
make -f Makefile.{os}
|
make -f Makefile.{os}
|
||||||
|
|
|
@ -650,7 +650,7 @@ Any time you edit the topology
|
||||||
file, you will need to stop the emulation if it were running and reload the
|
file, you will need to stop the emulation if it were running and reload the
|
||||||
file.
|
file.
|
||||||
|
|
||||||
The **.xml** [file schema is specified by NRL](http://www.nrl.navy.mil/itd/ncs/products/mnmtools) and there are two versions to date:
|
The **.xml** [file schema is specified by NRL](https://github.com/USNavalResearchLaboratory/NCS-Downloads/blob/master/mnmtools/EmulationScriptSchemaDescription.pdf) and there are two versions to date:
|
||||||
version 0.0 and version 1.0,
|
version 0.0 and version 1.0,
|
||||||
with 1.0 as the current default. CORE can open either XML version. However, the
|
with 1.0 as the current default. CORE can open either XML version. However, the
|
||||||
xmlfilever line in **/etc/core/core.conf** controls the version of the XML file
|
xmlfilever line in **/etc/core/core.conf** controls the version of the XML file
|
||||||
|
|
Loading…
Add table
Reference in a new issue