diff --git a/gns3server/agent/web_wireshark/manager.py b/gns3server/agent/web_wireshark/manager.py index 696226675..8fedb8f22 100644 --- a/gns3server/agent/web_wireshark/manager.py +++ b/gns3server/agent/web_wireshark/manager.py @@ -526,6 +526,50 @@ class WebWiresharkManager: return None + async def get_container_ip(self, container_name: str, container_id: str = None) -> Optional[str]: + """Get the container IP address in the wireshark network. + + Args: + container_name: Container name (e.g., "gns3-wireshark-project_id") + container_id: Container ID (optional, only used for fallback method) + + Returns: + Container IP address (e.g., 172.31.0.2) or None if not found + """ + # Method 1: Get from Docker Container API (fastest) + try: + container = await self.docker.get_container(container_name) + if container: + networks = container.get("NetworkSettings", {}).get("Networks", {}) + # Find gns3-wireshark network + for network_name, network_config in networks.items(): + if "wireshark" in network_name.lower(): + container_ip = network_config.get("IPAddress") + if container_ip: + logger.info(f"Got container IP from Docker API: {container_ip}") + return container_ip + except Exception as e: + logger.debug(f"Cannot get container IP from Docker API: {e}") + + # Fallback: Execute command inside container to get IP (slower) + if container_id: + try: + # Use 'hostname -I' to get all IP addresses and take the first one + # This works on most Linux systems and is more portable than 'ip' command + returncode, stdout, stderr = await self._exec_in_container( + container_id, + "hostname -I 2>/dev/null | awk '{print $1}'" + ) + if returncode == 0 and stdout.strip(): + container_ip = stdout.strip() + logger.info(f"Got container IP from container command: {container_ip}") + return container_ip + except Exception as e: + logger.debug(f"Cannot get container IP from container command: {e}") + + logger.warning(f"Failed to get container IP for {container_name}") + return None + async def _fix_localhost_url(self, url: str, container_id: str) -> str: """Fix URL with localhost/127.0.0.1 for container access. diff --git a/gns3server/api/routes/controller/links.py b/gns3server/api/routes/controller/links.py index 5f812fa00..2a6eec200 100644 --- a/gns3server/api/routes/controller/links.py +++ b/gns3server/api/routes/controller/links.py @@ -37,6 +37,7 @@ from gns3server.utils.http_client import HTTPClient from gns3server.utils.port_allocator import link_id_to_port from gns3server.utils.websocket_to_websocket import websocket_proxy from gns3server import schemas +from gns3server.agent.web_wireshark.manager import WebWiresharkManager from .dependencies.database import get_repository from .dependencies.rbac import has_privilege, has_privilege_on_websocket @@ -385,22 +386,8 @@ async def web_wireshark_websocket( xpra_port = link_id_to_port(link_id) # Get container IP - from gns3server.compute.docker import Docker - - docker_manager = Docker.instance() - container_info = await docker_manager.query( - "GET", - f"containers/{container_name}/json" - ) - - networks = container_info["NetworkSettings"]["Networks"] - container_ip = None - - # Find gns3-wireshark network - for network_name, network_config in networks.items(): - if "wireshark" in network_name.lower(): - container_ip = network_config["IPAddress"] - break + manager = WebWiresharkManager() + container_ip = await manager.get_container_ip(container_name) if not container_ip: log.error(f"Container {container_name} not found in wireshark network")