fix: repair imports lost in the 3.1 rebase and meet the new lint baseline

The rebase onto upstream 3.1 (mypy + ruff I001/F401 waves) left the tree
short of the newly enforced baselines in three ways:

* contextlib / UbridgeError imports dropped as false duplicates during
  conflict resolution left NameErrors in iou_vm and qemu_vm (F821);
  the Dynamips router grabbed the compute-level NIOTAP instead of the
  hypervisor one, breaking TAP anchoring (test failure).
* unused imports (KERNEL_UNSUPPORTED_FILTERS, UbridgeError, List) and
  unsorted blocks left behind where the stack's later commits moved the
  last usage elsewhere — ruff I001/F401/RUF022 now enforce these.
* mypy, now baseline-free: cache dict annotations in tc_probe, the
  locators candidate list, the resolved-params None branch in the MCP
  runner, and validate_bpf_syntax keeps the upstream Dict[str, Any]
  return (the strict Optional[str] was wrong for the "valid" bool entry).

The e2e raw-frame probe resolves its compiler via shutil.which (S607)
and zips with strict= (B905); the remaining subprocess call is S603 by
nature and gets a per-file ignore like other test files.

ruff check/format clean, mypy at upstream parity (no new errors),
full unit suite 2167 passed.
This commit is contained in:
YueGuobin committed 2026-10-06 00:21:11 +08:00
1 parent e13e5f3804
commit 7d04d08dba
35 files changed
+165 -136

No files matched your search

+12 -12
View File
@@ -32,29 +32,31 @@ failure (missing binary, old build answering "Unknown command", timeout)
means unknown, reported as None and cached as such.
"""
import os
import uuid
import shutil
import asyncio
import tempfile
import logging
import contextlib
import logging
import os
import shutil
import tempfile
import uuid
from typing import Optional
from gns3server.config import Config
from gns3server.utils.tc_capabilities import parse_tc_capabilities
from .hypervisor import Hypervisor
from .ubridge_error import UbridgeError
log = logging.getLogger(__name__)
# binary identity -> parsed report (None = probed and unusable)
_cache = {}
_cache: dict[tuple[str, int, int], Optional[dict[str, str]]] = {}
# binary identity -> whether the tap module works (None = unknown)
_tap_cache = {}
_tap_cache: dict[tuple[str, int, int], Optional[bool]] = {}
# binary identity -> whether iol_bridge can bind a port to a TAP (None = unknown)
_iol_tap_cache = {}
_iol_tap_cache: dict[tuple[str, int, int], Optional[bool]] = {}
# binary identity -> whether the bridge module can release a named TAP NIO (None = unknown)
_bridge_tap_cache = {}
_bridge_tap_cache: dict[tuple[str, int, int], Optional[bool]] = {}
_lock = asyncio.Lock()
@@ -252,9 +254,7 @@ async def _probe_iol_tap(path, config, timeout):
await hypervisor.send(f"iol_bridge create {bridge} {_IOL_PROBE_BRIDGE_ID}")
try:
await hypervisor.send(f"tap create {tap}")
await hypervisor.send(
f"iol_bridge add_nio_tap {bridge} {_IOL_PROBE_BRIDGE_ID - 1} 0 0 {tap}"
)
await hypervisor.send(f"iol_bridge add_nio_tap {bridge} {_IOL_PROBE_BRIDGE_ID - 1} 0 0 {tap}")
await hypervisor.send(f"iol_bridge delete_nio_tap {bridge} 0 0")
finally:
# iol_bridge delete releases every port NIO (the TAP fd),