async def from_udid(self, udid: Optional[str]) -> AsyncGenerator[Client, None]: await self._spawn_notifier() try: companion_info = await self._direct_companion_manager.get_companion_info( target_udid=udid) self._logger.debug(f"Got existing companion {companion_info}") async with Client.build( address=companion_info.address, is_local=companion_info.is_local, logger=self._logger, ) as client: self._logger.debug(f"Constructed client for companion {udid}") yield client except IdbException as e: self._logger.debug( f"No companion info for {udid}, spawning one...") # will try to spawn a companion if on mac. if udid is None: raise e companion_info = await self._spawn_companion(target_udid=udid) if companion_info is None: raise e self._logger.debug( f"Got newly launched {companion_info} for udid {udid}") async with Client.build( address=companion_info.address, is_local=companion_info.is_local, logger=self._logger, ) as client: self._logger.debug(f"Constructed client for companion {udid}") yield client
async def from_udid(self, udid: Optional[str]) -> AsyncGenerator[Client, None]: companions = { companion.udid: companion for companion in await self._companion_set.get_companions() } if udid is not None and udid in companions: companion = companions[udid] self._logger.debug( f"Got existing companion {companion} for udid {udid}") elif udid is not None: self._logger.debug( f"No running companion for {udid}, spawning one") companion = await self._spawn_companion_server(udid=udid) elif len(companions) == 1: self._logger.debug( "No udid provided, and there is a sole companion, using it") companion = list(companions.values())[0] elif len(companions) == 0: raise IdbException( "No udid provided and there no companions, unclear which target to run against. Please specify a UDID" ) else: raise IdbException( f"No udid provided and there are multiple companions to run against {companions.keys()}. Please specify a UDID unclear which target to run against" ) async with Client.build( address=companion.address, logger=self._logger, ) as client: self._logger.debug(f"Constructed client for companion {companion}") yield client
async def _companion_to_target( companion: CompanionInfo, ) -> Optional[TargetDescription]: try: async with Client.build(address=companion.address, logger=logger) as client: return await client.describe() except Exception: if not prune_dead_companion: logger.warning( f"Failed to describe {companion}, but not removing it") return None logger.warning(f"Failed to describe {companion}, removing it") await companion_set.remove_companion(companion.address) return None
async def _get_client( args: Namespace, logger: logging.Logger) -> AsyncGenerator[GrpcClient, None]: companion = vars(args).get("companion") if companion is not None: async with GrpcClient.build( address=_parse_address(companion), logger=logger, use_tls=args.companion_tls, ) as client: yield client else: async with GrpcClientManager( logger=logger, companion_path=args.companion_path).from_udid( udid=vars(args).get("udid")) as client: yield client
async def _companion_to_target( self, companion: CompanionInfo) -> Optional[TargetDescription]: try: async with Client.build(address=companion.address, is_local=False, logger=self._logger) as client: return await client.describe() except Exception: if not self._prune_dead_companion: self._logger.warning( f"Failed to describe {companion}, but not removing it") return None self._logger.warning( f"Failed to describe {companion}, removing it") await self._direct_companion_manager.remove_companion( companion.address) return None
async def from_udid(self, udid: Optional[str]) -> AsyncGenerator[Client, None]: await self._spawn_notifier() try: companion_info = await self._direct_companion_manager.get_companion_info( target_udid=udid) except IdbException as e: # will try to spawn a companion if on mac. if udid is None: raise e companion_info = await self._spawn_companion(target_udid=udid) if companion_info is None: raise e async with Client.build( address=companion_info.address, is_local=companion_info.is_local, logger=self._logger, ) as client: yield client
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 Client.build(address=destination, logger=self._logger) as client: companion = client.companion self._logger.debug(f"Connected directly to {companion}") await self._companion_set.add_companion(companion) return companion else: companion = await self._spawn_companion_server(udid=destination) if companion: return companion else: raise IdbException(f"can't find target for udid {destination}")