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…
	
	Add table
		Add a link
		
	
		Reference in a new issue