pygui: updates to leveraged wrapped grpc client for proper type hinting without manual conversion
This commit is contained in:
parent
be0e0175a2
commit
f7f54d9aa6
11 changed files with 160 additions and 294 deletions
|
@ -66,6 +66,7 @@ from core.api.grpc.wlan_pb2 import (
|
|||
WlanConfig,
|
||||
WlanLinkRequest,
|
||||
)
|
||||
from core.api.grpc.wrappers import Hook
|
||||
from core.emulator.data import IpPrefixes
|
||||
|
||||
|
||||
|
@ -859,25 +860,16 @@ class CoreGrpcClient:
|
|||
hooks.append(hook)
|
||||
return hooks
|
||||
|
||||
def add_hook(
|
||||
self,
|
||||
session_id: int,
|
||||
state: wrappers.SessionState,
|
||||
file_name: str,
|
||||
file_data: str,
|
||||
) -> bool:
|
||||
def add_hook(self, session_id: int, hook: Hook) -> bool:
|
||||
"""
|
||||
Add hook scripts.
|
||||
|
||||
:param session_id: session id
|
||||
:param state: state to trigger hook
|
||||
:param file_name: name of file for hook script
|
||||
:param file_data: hook script contents
|
||||
:param hook: hook to add
|
||||
:return: True for success, False otherwise
|
||||
:raises grpc.RpcError: when session doesn't exist
|
||||
"""
|
||||
hook = core_pb2.Hook(state=state.value, file=file_name, data=file_data)
|
||||
request = core_pb2.AddHookRequest(session_id=session_id, hook=hook)
|
||||
request = core_pb2.AddHookRequest(session_id=session_id, hook=hook.to_proto())
|
||||
response = self.stub.AddHook(request)
|
||||
return response.result
|
||||
|
||||
|
@ -1277,7 +1269,7 @@ class CoreGrpcClient:
|
|||
|
||||
:param file_path: path of scenario XML file
|
||||
:param start: tuple of result and session id when successful
|
||||
:return: response with opened session id
|
||||
:return: tuple of result and session id
|
||||
"""
|
||||
with open(file_path, "r") as xml_file:
|
||||
data = xml_file.read()
|
||||
|
|
|
@ -171,15 +171,16 @@ class ConfigServiceData:
|
|||
class ConfigServiceDefaults:
|
||||
templates: Dict[str, str]
|
||||
config: Dict[str, "ConfigOption"]
|
||||
modes: List[str]
|
||||
modes: Dict[str, Dict[str, str]]
|
||||
|
||||
@classmethod
|
||||
def from_proto(
|
||||
cls, proto: configservices_pb2.GetConfigServicesResponse
|
||||
) -> "ConfigServiceDefaults":
|
||||
config = ConfigOption.from_dict(proto.config)
|
||||
modes = {x.name: dict(x.config) for x in proto.modes}
|
||||
return ConfigServiceDefaults(
|
||||
templates=dict(proto.templates), config=config, modes=list(proto.modes)
|
||||
templates=dict(proto.templates), config=config, modes=modes
|
||||
)
|
||||
|
||||
|
||||
|
@ -598,11 +599,12 @@ class EmaneModelConfig:
|
|||
)
|
||||
|
||||
def to_proto(self) -> emane_pb2.EmaneModelConfig:
|
||||
config = ConfigOption.to_dict(self.config)
|
||||
return emane_pb2.EmaneModelConfig(
|
||||
node_id=self.node_id,
|
||||
model=self.model,
|
||||
iface_id=self.iface_id,
|
||||
config=self.config,
|
||||
config=config,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -11,18 +11,12 @@ from typing import TYPE_CHECKING, Dict, Iterable, List, Optional, Set, Tuple
|
|||
|
||||
import grpc
|
||||
|
||||
from core.api.grpc import (
|
||||
client,
|
||||
configservices_pb2,
|
||||
core_pb2,
|
||||
emane_pb2,
|
||||
mobility_pb2,
|
||||
services_pb2,
|
||||
wlan_pb2,
|
||||
)
|
||||
from core.api.grpc import clientw, configservices_pb2, core_pb2
|
||||
from core.api.grpc.wrappers import (
|
||||
ConfigOption,
|
||||
ConfigService,
|
||||
EmaneModelConfig,
|
||||
Event,
|
||||
ExceptionEvent,
|
||||
Link,
|
||||
LinkEvent,
|
||||
|
@ -33,6 +27,7 @@ from core.api.grpc.wrappers import (
|
|||
NodeServiceData,
|
||||
NodeType,
|
||||
Position,
|
||||
ServiceConfig,
|
||||
Session,
|
||||
SessionLocation,
|
||||
SessionState,
|
||||
|
@ -67,7 +62,7 @@ class CoreClient:
|
|||
"""
|
||||
self.app: "Application" = app
|
||||
self.master: tk.Tk = app.master
|
||||
self._client: client.CoreGrpcClient = client.CoreGrpcClient(proxy=proxy)
|
||||
self._client: clientw.CoreGrpcClient = clientw.CoreGrpcClient(proxy=proxy)
|
||||
self.session: Optional[Session] = None
|
||||
self.user = getpass.getuser()
|
||||
|
||||
|
@ -96,10 +91,9 @@ class CoreClient:
|
|||
self.handling_events: Optional[grpc.Future] = None
|
||||
|
||||
@property
|
||||
def client(self) -> client.CoreGrpcClient:
|
||||
def client(self) -> clientw.CoreGrpcClient:
|
||||
if self.session:
|
||||
response = self._client.check_session(self.session.id)
|
||||
if not response.result:
|
||||
if not self._client.check_session(self.session.id):
|
||||
throughputs_enabled = self.handling_throughputs is not None
|
||||
self.cancel_throughputs()
|
||||
self.cancel_events()
|
||||
|
@ -150,7 +144,7 @@ class CoreClient:
|
|||
for observer in self.app.guiconfig.observers:
|
||||
self.custom_observers[observer.name] = observer
|
||||
|
||||
def handle_events(self, event: core_pb2.Event) -> None:
|
||||
def handle_events(self, event: Event) -> None:
|
||||
if not self.session or event.source == GUI_SOURCE:
|
||||
return
|
||||
if event.session_id != self.session.id:
|
||||
|
@ -160,11 +154,9 @@ class CoreClient:
|
|||
self.session.id,
|
||||
)
|
||||
return
|
||||
|
||||
if event.HasField("link_event"):
|
||||
link_event = LinkEvent.from_proto(event.link_event)
|
||||
self.app.after(0, self.handle_link_event, link_event)
|
||||
elif event.HasField("session_event"):
|
||||
if event.link_event:
|
||||
self.app.after(0, self.handle_link_event, event.link_event)
|
||||
elif event.session_event:
|
||||
logging.info("session event: %s", event)
|
||||
session_event = event.session_event
|
||||
if session_event.event <= SessionState.SHUTDOWN.value:
|
||||
|
@ -181,14 +173,12 @@ class CoreClient:
|
|||
dialog.set_pause()
|
||||
else:
|
||||
logging.warning("unknown session event: %s", session_event)
|
||||
elif event.HasField("node_event"):
|
||||
node_event = NodeEvent.from_proto(event.node_event)
|
||||
self.app.after(0, self.handle_node_event, node_event)
|
||||
elif event.HasField("config_event"):
|
||||
elif event.node_event:
|
||||
self.app.after(0, self.handle_node_event, event.node_event)
|
||||
elif event.config_event:
|
||||
logging.info("config event: %s", event)
|
||||
elif event.HasField("exception_event"):
|
||||
event = ExceptionEvent.from_proto(event.session_id, event.exception_event)
|
||||
self.handle_exception_event(event)
|
||||
elif event.exception_event:
|
||||
self.handle_exception_event(event.exception_event)
|
||||
else:
|
||||
logging.info("unhandled event: %s", event)
|
||||
|
||||
|
@ -278,8 +268,7 @@ class CoreClient:
|
|||
CPU_USAGE_DELAY, self.handle_cpu_event
|
||||
)
|
||||
|
||||
def handle_throughputs(self, event: core_pb2.ThroughputsEvent) -> None:
|
||||
event = ThroughputsEvent.from_proto(event)
|
||||
def handle_throughputs(self, event: ThroughputsEvent) -> None:
|
||||
if event.session_id != self.session.id:
|
||||
logging.warning(
|
||||
"ignoring throughput event session(%s) current(%s)",
|
||||
|
@ -301,8 +290,7 @@ class CoreClient:
|
|||
logging.info("joining session(%s)", session_id)
|
||||
self.reset()
|
||||
try:
|
||||
response = self.client.get_session(session_id)
|
||||
self.session = Session.from_proto(response.session)
|
||||
self.session = self.client.get_session(session_id)
|
||||
self.client.set_session_user(self.session.id, self.user)
|
||||
title_file = self.session.file.name if self.session.file else ""
|
||||
self.master.title(f"CORE Session({self.session.id}) {title_file}")
|
||||
|
@ -364,9 +352,9 @@ class CoreClient:
|
|||
Create a new session
|
||||
"""
|
||||
try:
|
||||
response = self.client.create_session()
|
||||
logging.info("created session: %s", response)
|
||||
self.join_session(response.session_id)
|
||||
session_id = self.client.create_session()
|
||||
logging.info("created session: %s", session_id)
|
||||
self.join_session(session_id)
|
||||
location_config = self.app.guiconfig.location
|
||||
self.session.location = SessionLocation(
|
||||
x=location_config.x,
|
||||
|
@ -398,22 +386,19 @@ class CoreClient:
|
|||
try:
|
||||
self.client.connect()
|
||||
# get all available services
|
||||
response = self.client.get_services()
|
||||
for service in response.services:
|
||||
for service in self.client.get_services():
|
||||
group_services = self.services.setdefault(service.group, set())
|
||||
group_services.add(service.name)
|
||||
# get config service informations
|
||||
response = self.client.get_config_services()
|
||||
for service in response.services:
|
||||
self.config_services[service.name] = ConfigService.from_proto(service)
|
||||
for service in self.client.get_config_services():
|
||||
self.config_services[service.name] = service
|
||||
group_services = self.config_services_groups.setdefault(
|
||||
service.group, set()
|
||||
)
|
||||
group_services.add(service.name)
|
||||
# join provided session, create new session, or show dialog to select an
|
||||
# existing session
|
||||
response = self.client.get_sessions()
|
||||
sessions = response.sessions
|
||||
sessions = self.client.get_sessions()
|
||||
if session_id:
|
||||
session_ids = set(x.id for x in sessions)
|
||||
if session_id not in session_ids:
|
||||
|
@ -438,9 +423,8 @@ class CoreClient:
|
|||
|
||||
def edit_node(self, core_node: Node) -> None:
|
||||
try:
|
||||
position = core_node.position.to_proto()
|
||||
self.client.edit_node(
|
||||
self.session.id, core_node.id, position, source=GUI_SOURCE
|
||||
self.session.id, core_node.id, core_node.position, source=GUI_SOURCE
|
||||
)
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Edit Node Error", e)
|
||||
|
@ -451,7 +435,6 @@ class CoreClient:
|
|||
|
||||
def start_session(self) -> Tuple[bool, List[str]]:
|
||||
self.ifaces_manager.set_macs([x.link for x in self.links.values()])
|
||||
nodes = [x.to_proto() for x in self.session.nodes.values()]
|
||||
links = []
|
||||
asymmetric_links = []
|
||||
for edge in self.links.values():
|
||||
|
@ -460,43 +443,20 @@ class CoreClient:
|
|||
link.iface1.mac = self.ifaces_manager.next_mac()
|
||||
if link.iface2 and not link.iface2.mac:
|
||||
link.iface2.mac = self.ifaces_manager.next_mac()
|
||||
links.append(link.to_proto())
|
||||
links.append(link)
|
||||
if edge.asymmetric_link:
|
||||
asymmetric_links.append(edge.asymmetric_link.to_proto())
|
||||
wlan_configs = self.get_wlan_configs_proto()
|
||||
mobility_configs = self.get_mobility_configs_proto()
|
||||
emane_model_configs = self.get_emane_model_configs_proto()
|
||||
hooks = [x.to_proto() for x in self.session.hooks.values()]
|
||||
service_configs = self.get_service_configs_proto()
|
||||
file_configs = self.get_service_file_configs_proto()
|
||||
config_service_configs = self.get_config_service_configs_proto()
|
||||
emane_config = to_dict(self.session.emane_config)
|
||||
asymmetric_links.append(edge.asymmetric_link)
|
||||
self.session.links = links
|
||||
result = False
|
||||
exceptions = []
|
||||
try:
|
||||
self.send_servers()
|
||||
response = self.client.start_session(
|
||||
self.session.id,
|
||||
nodes,
|
||||
links,
|
||||
self.session.location.to_proto(),
|
||||
hooks,
|
||||
emane_config,
|
||||
emane_model_configs,
|
||||
wlan_configs,
|
||||
mobility_configs,
|
||||
service_configs,
|
||||
file_configs,
|
||||
asymmetric_links,
|
||||
config_service_configs,
|
||||
result, exceptions = self.client.start_session(
|
||||
self.session, asymmetric_links
|
||||
)
|
||||
logging.info(
|
||||
"start session(%s), result: %s", self.session.id, response.result
|
||||
)
|
||||
if response.result:
|
||||
logging.info("start session(%s), result: %s", self.session.id, result)
|
||||
if result:
|
||||
self.set_metadata()
|
||||
result = response.result
|
||||
exceptions = response.exceptions
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Start Session Error", e)
|
||||
return result, exceptions
|
||||
|
@ -506,9 +466,8 @@ class CoreClient:
|
|||
session_id = self.session.id
|
||||
result = False
|
||||
try:
|
||||
response = self.client.stop_session(session_id)
|
||||
logging.info("stopped session(%s), result: %s", session_id, response)
|
||||
result = response.result
|
||||
result = self.client.stop_session(session_id)
|
||||
logging.info("stopped session(%s), result: %s", session_id, result)
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Stop Session Error", e)
|
||||
return result
|
||||
|
@ -564,8 +523,8 @@ class CoreClient:
|
|||
parent=self.app,
|
||||
)
|
||||
return
|
||||
response = self.client.get_node_terminal(self.session.id, node_id)
|
||||
cmd = f"{terminal} {response.terminal} &"
|
||||
node_term = self.client.get_node_terminal(self.session.id, node_id)
|
||||
cmd = f"{terminal} {node_term} &"
|
||||
logging.info("launching terminal %s", cmd)
|
||||
os.system(cmd)
|
||||
except grpc.RpcError as e:
|
||||
|
@ -587,8 +546,8 @@ class CoreClient:
|
|||
if not self.is_runtime():
|
||||
logging.debug("Send session data to the daemon")
|
||||
self.send_data()
|
||||
response = self.client.save_xml(self.session.id, file_path)
|
||||
logging.info("saved xml file %s, result: %s", file_path, response)
|
||||
self.client.save_xml(self.session.id, file_path)
|
||||
logging.info("saved xml file %s", file_path)
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Save XML Error", e)
|
||||
|
||||
|
@ -597,72 +556,50 @@ class CoreClient:
|
|||
Open core xml
|
||||
"""
|
||||
try:
|
||||
response = self._client.open_xml(file_path)
|
||||
logging.info("open xml file %s, response: %s", file_path, response)
|
||||
self.join_session(response.session_id)
|
||||
result, session_id = self._client.open_xml(file_path)
|
||||
logging.info(
|
||||
"open xml file %s, result(%s) session(%s)",
|
||||
file_path,
|
||||
result,
|
||||
session_id,
|
||||
)
|
||||
self.join_session(session_id)
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Open XML Error", e)
|
||||
|
||||
def get_node_service(self, node_id: int, service_name: str) -> NodeServiceData:
|
||||
response = self.client.get_node_service(self.session.id, node_id, service_name)
|
||||
node_service = self.client.get_node_service(
|
||||
self.session.id, node_id, service_name
|
||||
)
|
||||
logging.debug(
|
||||
"get node(%s) %s service, response: %s", node_id, service_name, response
|
||||
"get node(%s) service(%s): %s", node_id, service_name, node_service
|
||||
)
|
||||
return NodeServiceData.from_proto(response.service)
|
||||
return node_service
|
||||
|
||||
def set_node_service(
|
||||
self,
|
||||
node_id: int,
|
||||
service_name: str,
|
||||
dirs: List[str],
|
||||
files: List[str],
|
||||
startups: List[str],
|
||||
validations: List[str],
|
||||
shutdowns: List[str],
|
||||
) -> NodeServiceData:
|
||||
response = self.client.set_node_service(
|
||||
self.session.id,
|
||||
node_id,
|
||||
service_name,
|
||||
directories=dirs,
|
||||
files=files,
|
||||
startup=startups,
|
||||
validate=validations,
|
||||
shutdown=shutdowns,
|
||||
)
|
||||
logging.info(
|
||||
"Set %s service for node(%s), files: %s, Startup: %s, "
|
||||
"Validation: %s, Shutdown: %s, Result: %s",
|
||||
service_name,
|
||||
node_id,
|
||||
files,
|
||||
startups,
|
||||
validations,
|
||||
shutdowns,
|
||||
response,
|
||||
)
|
||||
response = self.client.get_node_service(self.session.id, node_id, service_name)
|
||||
return NodeServiceData.from_proto(response.service)
|
||||
def set_node_service(self, node_id: int, config: ServiceConfig) -> NodeServiceData:
|
||||
result = self.client.set_node_service(self.session.id, config)
|
||||
logging.info("set node service result(%s): %s", result, config)
|
||||
return self.client.get_node_service(self.session.id, node_id, config.service)
|
||||
|
||||
def get_node_service_file(
|
||||
self, node_id: int, service_name: str, file_name: str
|
||||
) -> str:
|
||||
response = self.client.get_node_service_file(
|
||||
data = self.client.get_node_service_file(
|
||||
self.session.id, node_id, service_name, file_name
|
||||
)
|
||||
logging.debug(
|
||||
"get service file for node(%s), service: %s, file: %s, result: %s",
|
||||
"get service file for node(%s), service: %s, file: %s, data: %s",
|
||||
node_id,
|
||||
service_name,
|
||||
file_name,
|
||||
response,
|
||||
data,
|
||||
)
|
||||
return response.data
|
||||
return data
|
||||
|
||||
def set_node_service_file(
|
||||
self, node_id: int, service_name: str, file_name: str, data: str
|
||||
) -> None:
|
||||
response = self.client.set_node_service_file(
|
||||
result = self.client.set_node_service_file(
|
||||
self.session.id, node_id, service_name, file_name, data
|
||||
)
|
||||
logging.info(
|
||||
|
@ -671,19 +608,17 @@ class CoreClient:
|
|||
service_name,
|
||||
file_name,
|
||||
data,
|
||||
response,
|
||||
result,
|
||||
)
|
||||
|
||||
def create_nodes_and_links(self) -> None:
|
||||
"""
|
||||
create nodes and links that have not been created yet
|
||||
"""
|
||||
self.client.set_session_state(self.session.id, SessionState.DEFINITION.value)
|
||||
self.client.set_session_state(self.session.id, SessionState.DEFINITION)
|
||||
for node in self.session.nodes.values():
|
||||
response = self.client.add_node(
|
||||
self.session.id, node.to_proto(), source=GUI_SOURCE
|
||||
)
|
||||
logging.debug("created node: %s", response)
|
||||
node_id = self.client.add_node(self.session.id, node, source=GUI_SOURCE)
|
||||
logging.debug("created node: %s", node_id)
|
||||
asymmetric_links = []
|
||||
for edge in self.links.values():
|
||||
self.add_link(edge.link)
|
||||
|
@ -698,58 +633,23 @@ class CoreClient:
|
|||
"""
|
||||
self.send_servers()
|
||||
self.create_nodes_and_links()
|
||||
for config_proto in self.get_wlan_configs_proto():
|
||||
self.client.set_wlan_config(
|
||||
self.session.id, config_proto.node_id, config_proto.config
|
||||
)
|
||||
for config_proto in self.get_mobility_configs_proto():
|
||||
self.client.set_mobility_config(
|
||||
self.session.id, config_proto.node_id, config_proto.config
|
||||
)
|
||||
for config_proto in self.get_service_configs_proto():
|
||||
self.client.set_node_service(
|
||||
self.session.id,
|
||||
config_proto.node_id,
|
||||
config_proto.service,
|
||||
config_proto.files,
|
||||
config_proto.directories,
|
||||
config_proto.startup,
|
||||
config_proto.validate,
|
||||
config_proto.shutdown,
|
||||
)
|
||||
for config_proto in self.get_service_file_configs_proto():
|
||||
for node_id, config in self.get_wlan_configs():
|
||||
self.client.set_wlan_config(self.session.id, node_id, config)
|
||||
for node_id, config in self.get_mobility_configs():
|
||||
self.client.set_mobility_config(self.session.id, node_id, config)
|
||||
for config in self.get_service_configs():
|
||||
self.client.set_node_service(self.session.id, config)
|
||||
for node_id, service, file, data in self.get_service_file_configs():
|
||||
self.client.set_node_service_file(
|
||||
self.session.id,
|
||||
config_proto.node_id,
|
||||
config_proto.service,
|
||||
config_proto.file,
|
||||
config_proto.data,
|
||||
self.session.id, node_id, service, file, data
|
||||
)
|
||||
for hook in self.session.hooks.values():
|
||||
self.client.add_hook(
|
||||
self.session.id, hook.state.value, hook.file, hook.data
|
||||
)
|
||||
for config_proto in self.get_emane_model_configs_proto():
|
||||
self.client.set_emane_model_config(
|
||||
self.session.id,
|
||||
config_proto.node_id,
|
||||
config_proto.model,
|
||||
config_proto.config,
|
||||
config_proto.iface_id,
|
||||
)
|
||||
self.client.add_hook(self.session.id, hook)
|
||||
for config in self.get_emane_model_configs():
|
||||
self.client.set_emane_model_config(self.session.id, config)
|
||||
config = to_dict(self.session.emane_config)
|
||||
self.client.set_emane_config(self.session.id, config)
|
||||
location = self.session.location
|
||||
self.client.set_session_location(
|
||||
self.session.id,
|
||||
location.x,
|
||||
location.y,
|
||||
location.z,
|
||||
location.lat,
|
||||
location.lon,
|
||||
location.alt,
|
||||
location.scale,
|
||||
)
|
||||
self.client.set_session_location(self.session.id, self.session.location)
|
||||
self.set_metadata()
|
||||
|
||||
def close(self) -> None:
|
||||
|
@ -850,7 +750,7 @@ class CoreClient:
|
|||
dst_iface_id = edge.link.iface2.id
|
||||
self.iface_to_edge[(dst_node.id, dst_iface_id)] = edge
|
||||
|
||||
def get_wlan_configs_proto(self) -> List[wlan_pb2.WlanConfig]:
|
||||
def get_wlan_configs(self) -> List[Tuple[int, Dict[str, str]]]:
|
||||
configs = []
|
||||
for node in self.session.nodes.values():
|
||||
if node.type != NodeType.WIRELESS_LAN:
|
||||
|
@ -858,11 +758,10 @@ class CoreClient:
|
|||
if not node.wlan_config:
|
||||
continue
|
||||
config = ConfigOption.to_dict(node.wlan_config)
|
||||
wlan_config = wlan_pb2.WlanConfig(node_id=node.id, config=config)
|
||||
configs.append(wlan_config)
|
||||
configs.append((node.id, config))
|
||||
return configs
|
||||
|
||||
def get_mobility_configs_proto(self) -> List[mobility_pb2.MobilityConfig]:
|
||||
def get_mobility_configs(self) -> List[Tuple[int, Dict[str, str]]]:
|
||||
configs = []
|
||||
for node in self.session.nodes.values():
|
||||
if not nutils.is_mobility(node):
|
||||
|
@ -870,27 +769,24 @@ class CoreClient:
|
|||
if not node.mobility_config:
|
||||
continue
|
||||
config = ConfigOption.to_dict(node.mobility_config)
|
||||
mobility_config = mobility_pb2.MobilityConfig(
|
||||
node_id=node.id, config=config
|
||||
)
|
||||
configs.append(mobility_config)
|
||||
configs.append((node.id, config))
|
||||
return configs
|
||||
|
||||
def get_emane_model_configs_proto(self) -> List[emane_pb2.EmaneModelConfig]:
|
||||
def get_emane_model_configs(self) -> List[EmaneModelConfig]:
|
||||
configs = []
|
||||
for node in self.session.nodes.values():
|
||||
for key, config in node.emane_model_configs.items():
|
||||
model, iface_id = key
|
||||
config = ConfigOption.to_dict(config)
|
||||
# config = ConfigOption.to_dict(config)
|
||||
if iface_id is None:
|
||||
iface_id = -1
|
||||
config_proto = emane_pb2.EmaneModelConfig(
|
||||
node_id=node.id, iface_id=iface_id, model=model, config=config
|
||||
config = EmaneModelConfig(
|
||||
node_id=node.id, model=model, iface_id=iface_id, config=config
|
||||
)
|
||||
configs.append(config_proto)
|
||||
configs.append(config)
|
||||
return configs
|
||||
|
||||
def get_service_configs_proto(self) -> List[services_pb2.ServiceConfig]:
|
||||
def get_service_configs(self) -> List[ServiceConfig]:
|
||||
configs = []
|
||||
for node in self.session.nodes.values():
|
||||
if not nutils.is_container(node):
|
||||
|
@ -898,19 +794,19 @@ class CoreClient:
|
|||
if not node.service_configs:
|
||||
continue
|
||||
for name, config in node.service_configs.items():
|
||||
config_proto = services_pb2.ServiceConfig(
|
||||
config = ServiceConfig(
|
||||
node_id=node.id,
|
||||
service=name,
|
||||
directories=config.dirs,
|
||||
files=config.configs,
|
||||
directories=config.dirs,
|
||||
startup=config.startup,
|
||||
validate=config.validate,
|
||||
shutdown=config.shutdown,
|
||||
)
|
||||
configs.append(config_proto)
|
||||
configs.append(config)
|
||||
return configs
|
||||
|
||||
def get_service_file_configs_proto(self) -> List[services_pb2.ServiceFileConfig]:
|
||||
def get_service_file_configs(self) -> List[Tuple[int, str, str, str]]:
|
||||
configs = []
|
||||
for node in self.session.nodes.values():
|
||||
if not nutils.is_container(node):
|
||||
|
@ -919,10 +815,7 @@ class CoreClient:
|
|||
continue
|
||||
for service, file_configs in node.service_file_configs.items():
|
||||
for file, data in file_configs.items():
|
||||
config_proto = services_pb2.ServiceFileConfig(
|
||||
node_id=node.id, service=service, file=file, data=data
|
||||
)
|
||||
configs.append(config_proto)
|
||||
configs.append((node.id, service, file, data))
|
||||
return configs
|
||||
|
||||
def get_config_service_configs_proto(
|
||||
|
@ -946,37 +839,35 @@ class CoreClient:
|
|||
|
||||
def run(self, node_id: int) -> str:
|
||||
logging.info("running node(%s) cmd: %s", node_id, self.observer)
|
||||
return self.client.node_command(self.session.id, node_id, self.observer).output
|
||||
_, output = self.client.node_command(self.session.id, node_id, self.observer)
|
||||
return output
|
||||
|
||||
def get_wlan_config(self, node_id: int) -> Dict[str, ConfigOption]:
|
||||
response = self.client.get_wlan_config(self.session.id, node_id)
|
||||
config = response.config
|
||||
config = self.client.get_wlan_config(self.session.id, node_id)
|
||||
logging.debug(
|
||||
"get wlan configuration from node %s, result configuration: %s",
|
||||
node_id,
|
||||
config,
|
||||
)
|
||||
return ConfigOption.from_dict(config)
|
||||
return config
|
||||
|
||||
def get_mobility_config(self, node_id: int) -> Dict[str, ConfigOption]:
|
||||
response = self.client.get_mobility_config(self.session.id, node_id)
|
||||
config = response.config
|
||||
config = self.client.get_mobility_config(self.session.id, node_id)
|
||||
logging.debug(
|
||||
"get mobility config from node %s, result configuration: %s",
|
||||
node_id,
|
||||
config,
|
||||
)
|
||||
return ConfigOption.from_dict(config)
|
||||
return config
|
||||
|
||||
def get_emane_model_config(
|
||||
self, node_id: int, model: str, iface_id: int = None
|
||||
) -> Dict[str, ConfigOption]:
|
||||
if iface_id is None:
|
||||
iface_id = -1
|
||||
response = self.client.get_emane_model_config(
|
||||
config = self.client.get_emane_model_config(
|
||||
self.session.id, node_id, model, iface_id
|
||||
)
|
||||
config = response.config
|
||||
logging.debug(
|
||||
"get emane model config: node id: %s, EMANE model: %s, "
|
||||
"interface: %s, config: %s",
|
||||
|
@ -985,42 +876,21 @@ class CoreClient:
|
|||
iface_id,
|
||||
config,
|
||||
)
|
||||
return ConfigOption.from_dict(config)
|
||||
return config
|
||||
|
||||
def execute_script(self, script) -> None:
|
||||
response = self.client.execute_script(script)
|
||||
logging.info("execute python script %s", response)
|
||||
if response.session_id != -1:
|
||||
self.join_session(response.session_id)
|
||||
session_id = self.client.execute_script(script)
|
||||
logging.info("execute python script %s", session_id)
|
||||
if session_id != -1:
|
||||
self.join_session(session_id)
|
||||
|
||||
def add_link(self, link: Link) -> None:
|
||||
iface1 = link.iface1.to_proto() if link.iface1 else None
|
||||
iface2 = link.iface2.to_proto() if link.iface2 else None
|
||||
options = link.options.to_proto() if link.options else None
|
||||
response = self.client.add_link(
|
||||
self.session.id,
|
||||
link.node1_id,
|
||||
link.node2_id,
|
||||
iface1,
|
||||
iface2,
|
||||
options,
|
||||
source=GUI_SOURCE,
|
||||
)
|
||||
logging.debug("added link: %s", response)
|
||||
if not response.result:
|
||||
result, _, _ = self.client.add_link(self.session.id, link, source=GUI_SOURCE)
|
||||
logging.debug("added link: %s", result)
|
||||
if not result:
|
||||
logging.error("error adding link: %s", link)
|
||||
|
||||
def edit_link(self, link: Link) -> None:
|
||||
iface1_id = link.iface1.id if link.iface1 else None
|
||||
iface2_id = link.iface2.id if link.iface2 else None
|
||||
response = self.client.edit_link(
|
||||
self.session.id,
|
||||
link.node1_id,
|
||||
link.node2_id,
|
||||
link.options.to_proto(),
|
||||
iface1_id,
|
||||
iface2_id,
|
||||
source=GUI_SOURCE,
|
||||
)
|
||||
if not response.result:
|
||||
result = self.client.edit_link(self.session.id, link, source=GUI_SOURCE)
|
||||
if not result:
|
||||
logging.error("error editing link: %s", link)
|
||||
|
|
|
@ -86,12 +86,12 @@ class ConfigServiceConfigDialog(Dialog):
|
|||
self.validation_time = service.validation_timer
|
||||
self.validation_period.set(service.validation_period)
|
||||
|
||||
response = self.core.client.get_config_service_defaults(self.service_name)
|
||||
self.original_service_files = response.templates
|
||||
defaults = self.core.client.get_config_service_defaults(self.service_name)
|
||||
self.original_service_files = defaults.templates
|
||||
self.temp_service_files = dict(self.original_service_files)
|
||||
self.modes = sorted(x.name for x in response.modes)
|
||||
self.mode_configs = {x.name: x.config for x in response.modes}
|
||||
self.config = ConfigOption.from_dict(response.config)
|
||||
self.modes = sorted(defaults.modes)
|
||||
self.mode_configs = defaults.modes
|
||||
self.config = ConfigOption.from_dict(defaults.config)
|
||||
self.default_config = {x.name: x.value for x in self.config.values()}
|
||||
service_config = self.node.config_service_configs.get(self.service_name)
|
||||
if service_config:
|
||||
|
|
|
@ -134,7 +134,7 @@ class MobilityPlayerDialog(Dialog):
|
|||
session_id = self.app.core.session.id
|
||||
try:
|
||||
self.app.core.client.mobility_action(
|
||||
session_id, self.node.id, MobilityAction.START.value
|
||||
session_id, self.node.id, MobilityAction.START
|
||||
)
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Mobility Error", e)
|
||||
|
@ -144,7 +144,7 @@ class MobilityPlayerDialog(Dialog):
|
|||
session_id = self.app.core.session.id
|
||||
try:
|
||||
self.app.core.client.mobility_action(
|
||||
session_id, self.node.id, MobilityAction.PAUSE.value
|
||||
session_id, self.node.id, MobilityAction.PAUSE
|
||||
)
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Mobility Error", e)
|
||||
|
@ -154,7 +154,7 @@ class MobilityPlayerDialog(Dialog):
|
|||
session_id = self.app.core.session.id
|
||||
try:
|
||||
self.app.core.client.mobility_action(
|
||||
session_id, self.node.id, MobilityAction.STOP.value
|
||||
session_id, self.node.id, MobilityAction.STOP
|
||||
)
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Mobility Error", e)
|
||||
|
|
|
@ -260,17 +260,17 @@ class NodeConfigDialog(Dialog):
|
|||
row += 1
|
||||
|
||||
if nutils.is_rj45(self.node):
|
||||
response = self.app.core.client.get_ifaces()
|
||||
logging.debug("host machine available interfaces: %s", response)
|
||||
ifaces = ListboxScroll(frame)
|
||||
ifaces.listbox.config(state=state)
|
||||
ifaces.grid(
|
||||
ifaces = self.app.core.client.get_ifaces()
|
||||
logging.debug("host machine available interfaces: %s", ifaces)
|
||||
ifaces_scroll = ListboxScroll(frame)
|
||||
ifaces_scroll.listbox.config(state=state)
|
||||
ifaces_scroll.grid(
|
||||
row=row, column=0, columnspan=2, sticky=tk.EW, padx=PADX, pady=PADY
|
||||
)
|
||||
for inf in sorted(response.ifaces[:]):
|
||||
ifaces.listbox.insert(tk.END, inf)
|
||||
for inf in sorted(ifaces):
|
||||
ifaces_scroll.listbox.insert(tk.END, inf)
|
||||
row += 1
|
||||
ifaces.listbox.bind("<<ListboxSelect>>", self.iface_select)
|
||||
ifaces_scroll.listbox.bind("<<ListboxSelect>>", self.iface_select)
|
||||
|
||||
# interfaces
|
||||
if self.canvas_node.ifaces:
|
||||
|
|
|
@ -106,10 +106,8 @@ class RunToolDialog(Dialog):
|
|||
for selection in self.node_list.listbox.curselection():
|
||||
node_name = self.node_list.listbox.get(selection)
|
||||
node_id = self.executable_nodes[node_name]
|
||||
response = self.app.core.client.node_command(
|
||||
_, output = self.app.core.client.node_command(
|
||||
self.app.core.session.id, node_id, command
|
||||
)
|
||||
self.result.text.insert(
|
||||
tk.END, f"> {node_name} > {command}:\n{response.output}\n"
|
||||
)
|
||||
self.result.text.insert(tk.END, f"> {node_name} > {command}:\n{output}\n")
|
||||
self.result.text.config(state=tk.DISABLED)
|
||||
|
|
|
@ -7,7 +7,12 @@ from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple
|
|||
import grpc
|
||||
from PIL.ImageTk import PhotoImage
|
||||
|
||||
from core.api.grpc.wrappers import Node, NodeServiceData, ServiceValidationMode
|
||||
from core.api.grpc.wrappers import (
|
||||
Node,
|
||||
NodeServiceData,
|
||||
ServiceConfig,
|
||||
ServiceValidationMode,
|
||||
)
|
||||
from core.gui import images
|
||||
from core.gui.dialogs.copyserviceconfig import CopyServiceConfigDialog
|
||||
from core.gui.dialogs.dialog import Dialog
|
||||
|
@ -455,16 +460,17 @@ class ServiceConfigDialog(Dialog):
|
|||
or self.is_custom_directory()
|
||||
):
|
||||
startup, validate, shutdown = self.get_commands()
|
||||
config = self.core.set_node_service(
|
||||
self.node.id,
|
||||
self.service_name,
|
||||
dirs=self.temp_directories,
|
||||
config = ServiceConfig(
|
||||
node_id=self.node.id,
|
||||
service=self.service_name,
|
||||
files=list(self.filename_combobox["values"]),
|
||||
startups=startup,
|
||||
validations=validate,
|
||||
shutdowns=shutdown,
|
||||
directories=self.temp_directories,
|
||||
startup=startup,
|
||||
validate=validate,
|
||||
shutdown=shutdown,
|
||||
)
|
||||
self.node.service_configs[self.service_name] = config
|
||||
service_data = self.core.set_node_service(self.node.id, config)
|
||||
self.node.service_configs[self.service_name] = service_data
|
||||
for file in self.modified_files:
|
||||
file_configs = self.node.service_file_configs.setdefault(
|
||||
self.service_name, {}
|
||||
|
|
|
@ -27,8 +27,7 @@ class SessionOptionsDialog(Dialog):
|
|||
def get_config(self) -> Dict[str, ConfigOption]:
|
||||
try:
|
||||
session_id = self.app.core.session.id
|
||||
response = self.app.core.client.get_session_options(session_id)
|
||||
return ConfigOption.from_dict(response.config)
|
||||
return self.app.core.client.get_session_options(session_id)
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Get Session Options Error", e)
|
||||
self.has_error = True
|
||||
|
@ -55,8 +54,8 @@ class SessionOptionsDialog(Dialog):
|
|||
config = self.config_frame.parse_config()
|
||||
try:
|
||||
session_id = self.app.core.session.id
|
||||
response = self.app.core.client.set_session_options(session_id, config)
|
||||
logging.info("saved session config: %s", response)
|
||||
result = self.app.core.client.set_session_options(session_id, config)
|
||||
logging.info("saved session config: %s", result)
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Set Session Options Error", e)
|
||||
self.destroy()
|
||||
|
|
|
@ -30,10 +30,9 @@ class SessionsDialog(Dialog):
|
|||
|
||||
def get_sessions(self) -> List[SessionSummary]:
|
||||
try:
|
||||
response = self.app.core.client.get_sessions()
|
||||
logging.info("sessions: %s", response)
|
||||
sessions = sorted(response.sessions, key=lambda x: x.id)
|
||||
return [SessionSummary.from_proto(x) for x in sessions]
|
||||
sessions = self.app.core.client.get_sessions()
|
||||
logging.info("sessions: %s", sessions)
|
||||
return sorted(sessions, key=lambda x: x.id)
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Get Sessions Error", e)
|
||||
self.destroy()
|
||||
|
|
|
@ -459,10 +459,10 @@ class CanvasNode:
|
|||
def _service_action(self, service: str, action: ServiceAction) -> None:
|
||||
session_id = self.app.core.session.id
|
||||
try:
|
||||
response = self.app.core.client.service_action(
|
||||
result = self.app.core.client.service_action(
|
||||
session_id, self.core_node.id, service, action
|
||||
)
|
||||
if not response.result:
|
||||
if not result:
|
||||
self.app.show_error("Service Action Error", "Action Failed!")
|
||||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Service Error", e)
|
||||
|
|
Loading…
Reference in a new issue