async def connect( self, destination: ConnectionDestination, metadata: Optional[Dict[str, str]] = None, ) -> CompanionInfo: self._logger.debug(f"Connecting directly to {destination} with meta {metadata}") if isinstance(destination, TCPAddress) or isinstance( destination, DomainSocketAddress ): async with IdbClient.build( address=destination, is_local=False, logger=self._logger ) as client: with tempfile.NamedTemporaryFile(mode="w+b") as f: response = await client.stub.connect( ConnectRequest(metadata=metadata, local_file_path=f.name) ) companion = companion_to_py( companion=response.companion, address=destination ) self._logger.debug(f"Connected directly to {companion}") await self._direct_companion_manager.add_companion(companion) return companion else: companion = await self._spawn_companion(target_udid=destination) if companion: return companion else: raise IdbException(f"can't find target for udid {destination}")
async def build( cls, address: Address, logger: logging.Logger, is_local: Optional[bool] = None, exchange_metadata: bool = True, extra_metadata: Optional[Dict[str, str]] = None, use_tls: bool = False, ) -> AsyncGenerator["Client", None]: metadata_to_companion = ( { **{ key: value for (key, value) in plugin.resolve_metadata(logger=logger).items() if isinstance(value, str) }, **(extra_metadata or {}), } if exchange_metadata else {} ) ssl_context = plugin.channel_ssl_context() if use_tls else None if use_tls: assert ssl_context is not None async with ( Channel( host=address.host, port=address.port, loop=asyncio.get_event_loop(), ssl=ssl_context, ) if isinstance(address, TCPAddress) else Channel(path=address.path, loop=asyncio.get_event_loop()) ) as channel: stub = CompanionServiceStub(channel=channel) with tempfile.NamedTemporaryFile(mode="w+b") as f: try: response = await stub.connect( ConnectRequest( metadata=metadata_to_companion, local_file_path=f.name ) ) except Exception as ex: raise IdbException( f"Failed to connect to companion at address {address}: {ex}" ) companion = companion_to_py( companion=response.companion, address=address, is_local=is_local ) if exchange_metadata: metadata_from_companion = { key: value for (key, value) in companion.metadata.items() if isinstance(value, str) } plugin.append_companion_metadata( logger=logger, metadata=metadata_from_companion ) yield Client(stub=stub, companion=companion, logger=logger)