feat(web-wireshark): add method to retrieve container IP and refactor websocket endpoint

- Add `get_container_ip` method to WebWiresharkManager for retrieving container IP addresses in wireshark network
- Method uses Docker API as primary approach with container command execution as fallback
- Refactor web_wireshark_websocket endpoint to use new method instead of direct Docker queries
- Improve error handling and logging for container IP retrieval failures
This commit is contained in:
YueGuobin 2026-04-22 22:35:50 +08:00
parent e304b19076
commit 6c96e7493f
No known key found for this signature in database
2 changed files with 47 additions and 16 deletions

View File

@ -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.

View File

@ -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")