7 Commits

Author SHA1 Message Date
YueGuobin
0ca9ccc637
feat: model IOL adapters as 4-port units like the IOU node type
IOL interfaces come in 4-port units (Ethernet0/0-3, Ethernet1/0-3, ...),
addressed like IOU as (adapter_number, port_number 0-3):

- IOLDockerVM builds EthernetAdapter(interfaces=4) per adapter and asks
  the runner for adapters x 4 interfaces (num-eth).
- DockerVM threads port_number through the NIO/capture API (the compute
  routes parsed it from the URL but dropped it); single-port adapters
  keep the historical bridge{N} names and command sequence, multi-port
  adapters get one bridge per port (bridge{a}_{p}).
- The unix-socket NIO wiring addresses sockets flat across adapters:
  adapter x ports-per-adapter + port, so single-port images keep their
  exact socket layout.
- The controller port list for GNS3_IOL_RUNNER docker nodes is generated
  by StandardPortFactory with the IOU naming (Ethernet{segment0}/{port0},
  segment size 4); plain docker nodes keep eth{N}.
2026-09-05 21:54:51 +08:00
YueGuobin
9b55164064
revert IOL port-name override; document custom_adapters instead
_get_container_ifname only names the kernel interface inside the
container's network namespace (single call site: docker move_to_ns) -
IOL never uses that path, and the controller port list never reads it.
Name the ports through the template's custom_adapters instead (the
mechanism SR Linux appliances use for mgmt0/e1-1): adapter N shows as
Ethernet{N/4}/{N%4}, matching the IOS CLI, with no server-side changes.
2026-09-05 21:54:12 +08:00
YueGuobin
4c818c6b37
feat: show IOL-style interface names on iol-runner ports
Name ports after the IOL interface they map to (Ethernet0/0, one 4-port
unit per adapter range) via the _get_container_ifname override point, so
the GNS3 UI matches the IOS CLI. Display only — the flat adapter number
remains the socket index.
2026-09-05 21:54:12 +08:00
YueGuobin
d04a99f934
refactor: wire unix-socket NIOs through a per-node runtime directory
uBridge cannot reach sockets bind-mounted from the node's projects
directory: the path exceeds AF_UNIX's 107-byte sun_path cap. The /proc
detour from the previous commit is a dead end too - the runner drops
from root to the server uid, which makes the process non-dumpable and
its /proc/<pid>/root unreadable for the unprivileged server.

Instead, mirror how CML itself runs the image (source=<scratch>/tmp,
target=/tmp in its node definition): bind a per-node directory from the
runtime directory (<XDG_RUNTIME_DIR>/gns3/unixio/<node-id>, next to the
uBridge control sockets) at the image's socket directory. The path is
short, the directory is owned by the server user (whom the agent drops
its privileges to), and it is removed with the node. A socket directory
covered by a persisted volume keeps working as before.

IOLDockerVM persists only /tmp/run (nested bind at /tmp/run) and cleans
stale sockets/netio dirs from the socket directory on start, skipping
the cleanup when the container is already running. A failed wiring now
stops uBridge so the next start does not hit 'bridge already exist'.
2026-09-05 21:54:12 +08:00
YueGuobin
165f271bb8
refactor: reach unix-socket NIOs through the container root in /proc
The unix-socket NIO no longer requires the socket directory to be a
persisted volume: uBridge references the sockets through
/proc/<container-pid>/root<dir>/..., which is always well under the
107-byte sun_path cap (a project directory path alone exceeds it) and
leaves the sockets ephemeral in the container's own filesystem.

This replaces the runtime-dir symlink alias and its cleanup, and the
mount-time volume enforcement. IOLDockerVM now persists only /tmp/run
(the IOL working directory: startup-config + NVRAM) as a nested bind
instead of the whole /tmp; stale socket cleanup is gone with it, as
containers are recreated on every start.
2026-09-05 21:54:12 +08:00
YueGuobin
42e26717e6
fix: alias long unix-socket NIO paths through the runtime dir
AF_UNIX sun_path caps at 107 bytes and node volume directories
(projects/<uuid>/project-files/docker/<uuid>/tmp) exceed it — uBridge
rejects the NIO with 'invalid file path size'. When the wiring path is
too long, create <XDG_RUNTIME_DIR>/gns3/unixio-<node-id> as a symlink
to the real volume directory (same trick as the uBridge control
socket) and reference the alias in the uBridge commands; the symlink is
removed when uBridge stops. Found during E2E with iol-xe:17-18-02.
2026-09-05 21:54:12 +08:00
YueGuobin
e272ad915b
feat: add IOL (iol-runner) Docker node support
Run Cisco CML containerized IOL images (e.g. iol-xe/iol-xe:17-18-02,
driven by virl.lab/cmd/iol-runner) as GNS3 Docker router nodes:

- VendorDockerVM: generic GNS3_UNIX_SOCKET_NIO/GNS3_UNIX_SOCKET_DIR knobs
  wiring adapters through AF_UNIX datagram socket pairs
  (add_nio_unix cNN.sock sNN.sock) instead of TAP + move_to_ns; node
  creation fails if the socket dir is not a persisted volume.
- IOLDockerVM (GNS3_IOL_RUNNER=1): forces skip-init + unix-socket NIO +
  /config,/tmp volumes, writes iol-config.json on every start (num-eth
  tracks adapters, runner drops to the server uid/gid so the sockets are
  reachable), pre-creates tmp/run, cleans stale sockets after unclean
  kills, and makes reload a graceful stop + full start (NVRAM flush +
  rewiring). Console stays telnet on PID 1 stdio.
- Manager selects the node class from console_type or GNS3_* environment
  markers (create-time, like console_type).
- Image-free tests (25) and feature documentation.
2026-09-05 21:54:12 +08:00