Merge branch 'coretk' into coretk-linkconfig

This commit is contained in:
Huy Pham 2019-12-17 11:50:01 -08:00
commit 57bbac5c55
12 changed files with 129 additions and 91 deletions

View file

@ -38,7 +38,7 @@ class AboutDialog(Dialog):
self.top.columnconfigure(0, weight=1)
self.top.rowconfigure(0, weight=1)
text = CodeText(self.top)
text.insert("1.0", LICENSE)
text.config(state=tk.DISABLED)
text.grid(sticky="nsew")
codetext = CodeText(self.top)
codetext.text.insert("1.0", LICENSE)
codetext.text.config(state=tk.DISABLED)
codetext.grid(sticky="nsew")

View file

@ -17,7 +17,7 @@ class AlertsDialog(Dialog):
super().__init__(master, app, "Alerts", modal=True)
self.app = app
self.tree = None
self.text = None
self.codetext = None
self.draw()
def draw(self):
@ -76,9 +76,9 @@ class AlertsDialog(Dialog):
xscrollbar.grid(row=1, sticky="ew")
self.tree.configure(xscrollcommand=xscrollbar.set)
self.text = CodeText(self.top)
self.text.config(state=tk.DISABLED)
self.text.grid(sticky="nsew", pady=PADY)
self.codetext = CodeText(self.top)
self.codetext.text.config(state=tk.DISABLED)
self.codetext.grid(sticky="nsew", pady=PADY)
frame = ttk.Frame(self.top)
frame.grid(sticky="ew")
@ -96,7 +96,7 @@ class AlertsDialog(Dialog):
button.grid(row=0, column=3, sticky="ew")
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():
self.tree.delete(item)
self.app.statusbar.core_alarms.clear()
@ -137,8 +137,8 @@ class AlertsDialog(Dialog):
text = text + "node created"
except RpcError:
text = text + "node not created"
self.text.delete("1.0", "end")
self.text.insert("1.0", text)
self.codetext.text.delete("1.0", "end")
self.codetext.text.insert("1.0", text)
class DaemonLog(Dialog):
@ -155,8 +155,8 @@ class DaemonLog(Dialog):
frame.grid(row=0, column=0, sticky="ew", pady=PADY)
frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=9)
label = ttk.Label(frame, text="File: ")
label.grid(row=0, column=0)
label = ttk.Label(frame, text="File", anchor="w")
label.grid(row=0, column=0, sticky="ew")
entry = ttk.Entry(frame, textvariable=self.path, state="disabled")
entry.grid(row=0, column=1, sticky="ew")
try:
@ -164,8 +164,8 @@ class DaemonLog(Dialog):
log = file.readlines()
except FileNotFoundError:
log = "Log file not found"
text = CodeText(self.top)
text.insert("1.0", log)
text.see("end")
text.config(state=tk.DISABLED)
text.grid(row=1, column=0, sticky="nsew")
codetext = CodeText(self.top)
codetext.text.insert("1.0", log)
codetext.text.see("end")
codetext.text.config(state=tk.DISABLED)
codetext.grid(row=1, column=0, sticky="nsew")

View file

@ -3,12 +3,13 @@ set wallpaper
"""
import logging
import tkinter as tk
from tkinter import filedialog, ttk
from tkinter import ttk
from coretk.appconfig import BACKGROUNDS_PATH
from coretk.dialogs.dialog import Dialog
from coretk.images import Images
from coretk.themes import PADX, PADY
from coretk.widgets import image_chooser
class CanvasBackgroundDialog(Dialog):
@ -126,14 +127,7 @@ class CanvasBackgroundDialog(Dialog):
button.grid(row=0, column=1, sticky="ew")
def click_open_image(self):
filename = filedialog.askopenfilename(
initialdir=str(BACKGROUNDS_PATH),
title="Open",
filetypes=(
("images", "*.gif *.jpg *.png *.bmp *pcx *.tga ..."),
("All Files", "*"),
),
)
filename = image_chooser(self, BACKGROUNDS_PATH)
if filename:
self.filename.set(filename)
self.draw_preview()

View file

@ -4,6 +4,7 @@ from pathlib import Path
from tkinter import ttk
from coretk import nodeutils
from coretk.appconfig import ICONS_PATH
from coretk.dialogs.dialog import Dialog
from coretk.images import Images
from coretk.nodeutils import NodeDraw
@ -179,7 +180,7 @@ class CustomNodesDialog(Dialog):
self.image_button.config(image="")
def click_icon(self):
file_path = image_chooser(self)
file_path = image_chooser(self, ICONS_PATH)
if file_path:
image = Images.create(file_path, nodeutils.ICON_SIZE)
self.image = image

View file

@ -11,7 +11,7 @@ class HookDialog(Dialog):
def __init__(self, master, app):
super().__init__(master, app, "Hook", modal=True)
self.name = tk.StringVar()
self.data = None
self.codetext = None
self.hook = core_pb2.Hook()
self.state = tk.StringVar()
self.draw()
@ -41,8 +41,8 @@ class HookDialog(Dialog):
combobox.bind("<<ComboboxSelected>>", self.state_change)
# data
self.data = CodeText(self.top)
self.data.insert(
self.codetext = CodeText(self.top)
self.codetext.text.insert(
1.0,
(
"#!/bin/sh\n"
@ -50,7 +50,7 @@ class HookDialog(Dialog):
"# specified state\n"
),
)
self.data.grid(sticky="nsew")
self.codetext.grid(sticky="nsew", pady=PADY)
# button row
frame = ttk.Frame(self.top)
@ -69,13 +69,13 @@ class HookDialog(Dialog):
def set(self, hook):
self.hook = hook
self.name.set(hook.file)
self.data.delete(1.0, tk.END)
self.data.insert(tk.END, hook.data)
self.codetext.text.delete(1.0, tk.END)
self.codetext.text.insert(tk.END, hook.data)
state_name = core_pb2.SessionState.Enum.Name(hook.state)
self.state.set(state_name)
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())
self.hook.file = self.name.get()
self.hook.data = data

View file

@ -4,11 +4,13 @@ from functools import partial
from tkinter import ttk
from coretk import nodeutils
from coretk.appconfig import ICONS_PATH
from coretk.dialogs.dialog import Dialog
from coretk.dialogs.emaneconfig import EmaneModelDialog
from coretk.images import Images
from coretk.nodeutils import NodeUtils
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):
@ -137,42 +139,57 @@ class NodeConfigDialog(Dialog):
self.draw_buttons()
def draw_interfaces(self):
scroll = FrameScroll(self.top, self.app, text="Interfaces")
scroll.grid(sticky="nsew")
scroll.frame.columnconfigure(0, weight=1)
scroll.frame.rowconfigure(0, weight=1)
notebook = ttk.Notebook(self.top)
notebook.grid(sticky="nsew", pady=PADY)
self.top.rowconfigure(notebook.grid_info()["row"], weight=1)
for interface in self.canvas_node.interfaces:
logging.info("interface: %s", interface)
frame = ttk.LabelFrame(scroll.frame, text=interface.name, padding=FRAME_PAD)
frame.grid(sticky="ew", pady=PADY)
frame.columnconfigure(1, weight=1)
frame.columnconfigure(2, weight=1)
tab = ttk.Frame(notebook, padding=FRAME_PAD)
tab.grid(sticky="nsew", pady=PADY)
tab.columnconfigure(1, weight=1)
tab.columnconfigure(2, weight=1)
notebook.add(tab, text=interface.name)
label = ttk.Label(frame, text="MAC")
label.grid(row=0, column=0, padx=PADX, pady=PADY)
row = 0
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)
checkbutton = ttk.Checkbutton(frame, text="Auto?", variable=is_auto)
checkbutton = ttk.Checkbutton(tab, text="Auto?", variable=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)
entry = ttk.Entry(frame, textvariable=mac, state=tk.DISABLED)
entry.grid(row=0, column=2, sticky="ew")
entry = ttk.Entry(tab, textvariable=mac, state=tk.DISABLED)
entry.grid(row=row, column=2, sticky="ew")
func = partial(mac_auto, is_auto, entry)
checkbutton.config(command=func)
row += 1
label = ttk.Label(frame, text="IPv4")
label.grid(row=1, column=0, padx=PADX, pady=PADY)
label = ttk.Label(tab, text="IPv4")
label.grid(row=row, column=0, padx=PADX, pady=PADY)
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.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.grid(row=2, column=0, padx=PADX, pady=PADY)
label = ttk.Label(tab, text="IPv6")
label.grid(row=row, column=0, padx=PADX, pady=PADY)
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.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)
@ -188,8 +205,12 @@ class NodeConfigDialog(Dialog):
button = ttk.Button(frame, text="Cancel", command=self.destroy)
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):
file_path = image_chooser(self)
file_path = image_chooser(self, ICONS_PATH)
if file_path:
self.image = Images.create(file_path, nodeutils.ICON_SIZE)
self.image_button.config(image=self.image)

View file

@ -110,7 +110,7 @@ class ServiceConfiguration(Dialog):
# draw notebook
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_directories()
self.draw_tab_startstop()
@ -192,11 +192,13 @@ class ServiceConfiguration(Dialog):
tab.rowconfigure(self.service_file_data.grid_info()["row"], weight=1)
if len(self.filenames) > 0:
self.filename_combobox.current(0)
self.service_file_data.delete(1.0, "end")
self.service_file_data.insert(
self.service_file_data.text.delete(1.0, "end")
self.service_file_data.text.insert(
"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):
tab = ttk.Frame(self.notebook, padding=FRAME_PAD)
@ -275,14 +277,14 @@ class ServiceConfiguration(Dialog):
frame.columnconfigure(1, weight=1)
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.insert("end", self.validation_time)
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.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:
mode = "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.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.grid(row=2, column=0, sticky="w")
label.grid(row=2, column=0, sticky="w", padx=PADX)
self.validation_period_entry = ttk.Entry(
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.grid(sticky="nsew", pady=PADY)
@ -429,8 +431,8 @@ class ServiceConfiguration(Dialog):
def display_service_file_data(self, event):
combobox = event.widget
filename = combobox.get()
self.service_file_data.delete(1.0, "end")
self.service_file_data.insert("end", self.temp_service_files[filename])
self.service_file_data.text.delete(1.0, "end")
self.service_file_data.text.insert("end", self.temp_service_files[filename])
def update_temp_service_file_data(self, event):
scrolledtext = event.widget

View file

@ -246,6 +246,23 @@ class CanvasNode:
dialog = NodeService(self.app.master, self.app, self)
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):
self.canvas.context = None
for canvas_nid in [

View file

@ -2,11 +2,9 @@ import logging
import tkinter as tk
from functools import partial
from tkinter import filedialog, font, ttk
from tkinter.scrolledtext import ScrolledText
from core.api.grpc import core_pb2
from coretk import themes
from coretk.appconfig import ICONS_PATH
from coretk.themes import FRAME_PAD, PADX, PADY
INT_TYPES = {
@ -208,10 +206,13 @@ class CodeFont(font.Font):
super().__init__(font="TkFixedFont", color="green")
class CodeText(ScrolledText):
class CodeText(ttk.Frame):
def __init__(self, master, **kwargs):
super().__init__(
master,
super().__init__(master, **kwargs)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.text = tk.Text(
self,
bd=0,
bg="black",
cursor="xterm lime lime",
@ -222,8 +223,11 @@ class CodeText(ScrolledText):
selectbackground="lime",
selectforeground="black",
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):
@ -234,11 +238,11 @@ class Spinbox(ttk.Entry):
self.tk.call(self._w, "set", value)
def image_chooser(parent):
def image_chooser(parent, path):
return filedialog.askopenfilename(
parent=parent,
initialdir=str(ICONS_PATH),
title="Select Icon",
initialdir=str(path),
title="Select",
filetypes=(
("images", "*.gif *.jpg *.png *.bmp *pcx *.tga ..."),
("All Files", "*"),

View file

@ -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
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
(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.
```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
```
@ -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
sudo apt install libtool libreadline-dev autoconf
wget https://downloads.pf.itd.nrl.navy.mil/ospf-manet/nightly_snapshots/quagga-svnsnap.tgz
tar xzf quagga-svnsnap.tgz
cd quagga
git clone https://github.com/USNavalResearchLaboratory/ospf-mdr
cd ospf-mdr
./bootstrap.sh
./configure --disable-doc --enable-user=root --enable-group=root --with-cflags=-ggdb \
--sysconfdir=/usr/local/etc/quagga --enable-vtysh \

View file

@ -312,17 +312,17 @@ Currently the Naval Research Laboratory uses this library to develop a wide vari
* arouted
#### 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)
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
cd mgen/makefiles
make -f Makefile.{os} mgen
```
#### 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
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
@ -339,14 +339,14 @@ make -f Makefile.{os}
```
#### 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
cd mgen/makefiles
make -f Makefile.{os}
```
#### 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
cd ./unix
make -f Makefile.{os}

View file

@ -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.
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,
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