35 Commits

Author SHA1 Message Date
YueGuobin
84e7ead465
fix: make node working directory deletion robust
The rmtree error handler in BaseNode.delete() was chmod'ing the failed
path to S_IWRITE (0o200). On POSIX this strips the search permission
from directories, turning a transient deletion failure into a directory
that can no longer be traversed or deleted. The node deletion itself
silently "succeeds" (rmtree gives up once its error handler returns)
and a later project deletion then fails with EACCES. The handler also
never retried the failed operation, so it did not help on Windows
either (the platform it was written for).

The transient failure exists in practice: a concurrent MD5 checksum
computation caching its result in the node directory (e.g. a properties
request racing the deletion) can recreate a file after rmtree has
listed the directory, making the final rmdir fail with ENOTEMPTY.

- add the missing user permissions instead of replacing the whole mode,
  and retry the failed unlink/rmdir
- retry the whole deletion a few times to absorb files recreated while
  the directory is being deleted
- raise a ComputeError when the directory cannot be fully deleted
  instead of failing silently
2026-09-15 01:23:31 +08:00
YueGuobin
3cf9dbff5b
fix: handle client disconnect in compute console WebSocket forwarding
The compute-side telnet_forward (and vnc_forward) let the
WebSocketDisconnect that starlette raises from send_bytes once the peer
is gone escape to the generic task-exception handler. Its str() is
empty, so every client disconnect during active node output logged a
message-less warning:

  WARNING gns3server.compute.base_node:658 Exception while forwarding
  WebSocket data to TELNET server:

Catch WebSocketDisconnect in both forwarders and log it at INFO as the
normal end of a session, and format the remaining task exceptions with
!r so their type stays visible. Mirrors the controller-side fix for
the same scenario (2324dcd74).
2026-08-29 10:09:05 +08:00
YueGuobin
5188ae625a
tests: pick a free console port instead of hardcoding 5011
A dev machine running a real gns3server (or qemu) can already listen on
5011; reserve_tcp_port then silently replaces it with the next free port
and test_console fails on the exact-echo assertion. Pick a port that is
actually free on the host first, like test_change_console_port does.
2026-08-21 21:41:51 +08:00
YueGuobin
958aa59d7e
fix: scope marker reconcile to the current bridge/NIO
The reconcile pass in _ubridge_apply_markers walked the node-wide
_marker_filter_bridges map but compared against `desired`, which only
carries the markers of the NIO being updated. Updating any one link
therefore deleted every other link's markers (and their pcaps) on that
node — a regression from the add-only→reconcile switch. IOU's override
had the same flaw across its ports.

Guard the delete pass with the current bridge (base_node) / IOL location
(IOU) so only markers on the NIO being reconciled can be removed. Added
a regression test that fails without the guard.
2026-08-11 22:11:44 +08:00
YueGuobin
958c45b6fc
fix: reconcile marker filters in _ubridge_apply_markers (delete/update)
The batch marker-def fan-out (PR #2848) routed create/update/delete
marker_definition through memory_only + a batch PUT /nios/batch that
re-applies markers via _ubridge_apply_markers. But _ubridge_apply_markers
was strictly add-only: it skipped any (name, link_id) already in
_marker_filter_bridges, and reset_packet_filters preserves mark filters
(contract). So:

  * delete_marker_definition left the deleted marker's filter alive in
    uBridge (still matching / signalling / writing pcap) until node restart.
  * update_marker_definition (bpf/tag/direction change) never reached
    uBridge — the live filter kept the old expression until node restart.

Make _ubridge_apply_markers a real reconcile against the desired
nio.markers:
  - installed but no longer desired  → delete_packet_filter + unlink pcap
                                       + unregister
  - desired with changed filter field → rebuild (delete + re-add)
  - desired with only enabled changed  → instant toggle (pcap preserved)
  - desired and unchanged              → skip
  - desired and new                    → add

Track installed specs in a parallel _marker_specs dict so changes can be
detected. Both base_node and the IOU iol_bridge override are updated.
Added tests for the delete-removed and rebuild-changed-bpf paths.
2026-08-11 21:00:03 +08:00
YueGuobin
3322233658
marker: serial-link (WAN) support via data_link_type -> uBridge linktype
Markers now work on serial links (Cisco HDLC / PPP / Frame Relay / ATM), not just Ethernet. A marker carries a data_link_type (default DLT_EN10MB); at the uBridge boundary it becomes the 'mark ... linktype <dlt>' keyword so the BPF compiles and the pcap is written with the matching link-layer.

- MarkerCreate / MarkerDefinitionCreate gain data_link_type (default DLT_EN10MB). Per-link it is create-only; definitions are updatable (a change re-fans-out).
- base_node._marker_linktype() normalizes the GNS3 DLT name (strip DLT_, uppercase, None for EN10MB). Single source is SerialPort.data_link_types, so Cisco PPP -> PPP_SERIAL (50), matching the capture path -- no second mapping table.
- _ubridge_add_marker_filter (generic) and the IOU marker loop append 'linktype <dlt>'.
- Definition fan-out branches on link_type in inherit_marker: Ethernet is always EN10MB; a serial link uses the definition's WAN encapsulation, or is SKIPPED when none was chosen (an EN10MB pcap on serial is undecodable). One definition covers a mixed topology.
- MCP marker_definition exposes data_link_type (None = not forwarded).
- No uBridge rebuild on a data_link_type change -- only that one marker's filter is swapped (delete + re-add), mirroring a BPF change; reset_packet_filters preserves sibling mark filters.

Requires the uBridge build with 'mark ... linktype' support.
2026-08-07 01:53:33 +08:00
YueGuobin
75f278228b
marker: drop deleted marker from port NIO cache to stop empty pcap on restart
Deleting a marker while its node was stopped, then starting the node, recreated
an empty pcap. Root cause: delete_marker_capture removed the uBridge filter and
the pcap file but not the marker spec cached on the port NIO (nio.markers) —
the data source _ubridge_apply_markers reads on node start. The stale spec
reinstalled the marker when uBridge came up.

This was a regression from switching stop_marker off update() (which re-sent
the NIO and implicitly refreshed nio.markers) to the fine-grained
node.delete(/markers/{name}) path.

Fix: make the delete port-aware so the compute can locate the NIO. The DELETE
marker route becomes /adapters/{a}/ports/{p}/markers/{name} across all six
node types; the handler resolves the NIO via get_nio and passes it to
delete_marker_capture, which now pops the marker from nio.markers. get_nio
works regardless of uBridge state, so the stopped-node case is covered. The
controller's stop_marker targets the capture side's adapter/port.
2026-08-05 00:08:12 +08:00
YueGuobin
95824b1861
marker: incremental apply, clear bridge map on uBridge stop
_ubridge_apply_markers now installs only markers not already on the bridge
(uBridge's reset_packet_filters preserves mark filters), so an NIO update no
longer re-adds — and reopens — sibling markers' pcaps. _stop_ubridge clears
_marker_filter_bridges so a node restart re-installs everything (the map would
otherwise keep stale entries pointing at a fresh, empty uBridge).
2026-08-04 22:19:43 +08:00
YueGuobin
caec71aa71
marker: fine-grained filter ops, clean pcap on remove
Deleting or updating a marker no longer triggers a full NIO reapply
(reset_packet_filters + re-add), which closed/reopened every sibling
marker's pcap via uBridge. Instead operate on single filters:

- stop_marker: bridge delete_packet_filter + unlink the pcap (works with
  the node stopped; filter removal is skipped, the file is still deleted).
- update_marker: bpf/tag/direction → rebuild just that filter (delete + add);
  enabled → instant toggle; color/highlight_duration → stored only.
- compute delete_marker_capture / rebuild_marker_filter + per-node routes
  (DELETE /markers/{name}, PUT /markers/{name}/rebuild) + MarkerRebuild schema.

IOU overrides _ubridge_delete_marker_filter for iol_bridge; rebuild reuses
the already-overridden add/delete/set, so IOU needs no rebuild override.
2026-08-04 21:35:31 +08:00
YueGuobin
ff907da5f6
marker: key _marker_filter_bridges by (name, link_id) so multi-link nodes toggle every copy
The _marker_filter_bridges dict was keyed by marker name alone, so when one
node hosted the same filter name on several links (IUOL-BRIDGE per node with
many bays/units, or a multi-interface router), successive apply calls
overwrote earlier entries. pause_marker_definition then toggled only the last
recorded bridge/location — other copies stayed active and kept emitting.

Key by (name, link_id) so each copy is independent, and iterate all matching
entries in _ubridge_set_marker_filter_state (both generic bridge and IOU
iol_bridge override). Toggle route existence checks also iterate matching
names. Tests updated.
2026-08-02 23:48:24 +08:00
YueGuobin
84179c239c
marker: test enabled/pause/resume and instant toggle
- compute (test_base_node.py): set_marker_filter_state on/off command,
  marker pause/resume command, and apply issues enable_packet_filter off
  for a disabled marker (+ records the name->bridge map).
- controller (test_marker.py): _markers_for_node keeps disabled markers
  and carries enabled; update_marker enabled-only hits the toggle route
  (not NIO rebuild) while a bpf change still rebuilds; pause/resume fan
  out to capture nodes.
2026-08-02 16:19:20 +08:00
grossmj
a7b56739a9
Fixes after merging 2024-09-23 14:08:24 +07:00
grossmj
8ce0cbf7f7
Merge branch '2.2' into 3.0
# Conflicts:
#	gns3server/compute/base_node.py
#	gns3server/compute/docker/docker_vm.py
#	gns3server/compute/dynamips/nodes/c1700.py
#	gns3server/compute/dynamips/nodes/c2600.py
#	gns3server/compute/dynamips/nodes/c2691.py
#	gns3server/compute/dynamips/nodes/c3600.py
#	gns3server/compute/dynamips/nodes/c3725.py
#	gns3server/compute/dynamips/nodes/c3745.py
#	gns3server/compute/dynamips/nodes/c7200.py
#	gns3server/compute/dynamips/nodes/router.py
#	gns3server/compute/qemu/qemu_vm.py
#	gns3server/controller/node.py
#	gns3server/controller/topology.py
#	gns3server/handlers/api/compute/docker_handler.py
#	gns3server/handlers/api/compute/dynamips_vm_handler.py
#	gns3server/handlers/api/compute/qemu_handler.py
#	gns3server/schemas/docker.py
#	gns3server/schemas/docker_template.py
#	gns3server/schemas/dynamips_template.py
#	gns3server/schemas/dynamips_vm.py
#	gns3server/schemas/node.py
#	gns3server/schemas/qemu.py
#	gns3server/schemas/qemu_template.py
2024-09-23 13:28:56 +07:00
Jeremy Grossmann
af6f34b2ca
Revert "Backport auxiliary console support for Qemu, Docker and Dynamips nodes" 2024-09-23 13:10:58 +07:00
grossmj
c41c11eb34
Backport auxiliary console support for Qemu, Docker and Dynamips nodes 2024-09-22 18:29:04 +07:00
grossmj
46a9fdb61d
Remove event_loop 2024-05-09 17:53:02 +07:00
grossmj
33499be425
Fix warnings in tests 2024-05-09 17:11:12 +07:00
grossmj
8f296e54f4 Add back loop 2022-08-27 23:41:52 +02:00
grossmj
fc7d5be736 Use pytest-asyncio auto mode 2022-08-27 21:10:17 +02:00
grossmj
d1c8f33fc5 Upgrade dev dependencies and fix issues after upgrading to pytest-aiohttp v1.0.4 2022-08-27 19:16:02 +02:00
grossmj
86c44cd6e7 Upgrade dev dependencies and fix tests to support pytest-asyncio strict mode 2022-08-24 21:03:16 +02:00
grossmj
eb3cb8a41f Migration to FastAPI 2020-10-02 16:07:50 +09:30
grossmj
7043d48f1a Auxiliary console support for Qemu. Ref #2873
Improvements for auxiliary console support for Docker and Dynamips.
2020-07-29 16:23:51 +09:30
grossmj
d3ea67da24 Refactor tests
* Use pytest-aiohttp
* Use the async def / await syntax.
* Fix tests to run with Python 3.8
2020-06-16 13:59:03 +09:30
grossmj
279b4d7b20 Fix link filters/suspend tests. 2018-03-19 18:25:56 +07:00
ziajka
d9a0ec9ff3 Replace asyncio.async with ensure_future because of deprecation, Fixes: #1269 2018-01-24 11:11:53 +01:00
ziajka
fd623a5ad2 Fix test_ubridge_apply_filters 2017-09-05 11:07:10 +02:00
Julien Duponchelle
536c708c16
Filter implementation for cloud & Nat
Fix #1111
2017-07-17 17:27:07 +02:00
Julien Duponchelle
86f1201276
Support packet filtering for dynamips
Fix #1109
2017-07-12 12:08:02 +02:00
Julien Duponchelle
8a8de1e2df
BPF filter support
Fix https://github.com/GNS3/gns3-gui/issues/765
2017-07-11 17:30:29 +02:00
Julien Duponchelle
08423eff96
Support packet filtering for VPCS
https://github.com/GNS3/gns3-gui/issues/765
2017-07-04 15:12:26 +02:00
Julien Duponchelle
ae1e027031
Raise error if using a non linked clone VM twice
Fix https://github.com/GNS3/gns3-gui/issues/1593
2016-10-24 21:39:35 +02:00
Julien Duponchelle
00fc2fa007
Avoid crash during tests if VNC server run on host PC 2016-10-24 12:21:57 +02:00
Julien Duponchelle
d8bdd16e13
Raise an error if image is missing on compute 2016-06-07 15:34:04 +02:00
grossmj
5a76f81271 Refactoring to use a common node class for all VMs and other (future) objects. 2016-05-11 11:35:36 -06:00