131 Commits

Author SHA1 Message Date
YueGuobin
8889cea38b
fix: recreate docker_exec console on reconnect after CLI exit
The reconnect-blank-screen bug: when sr_cli exited (quit / idle timeout /
crash) the while-true wrapper restarted it mid-session with no client
attached, so its startup CPR probe (\e[6n) went unanswered and the TUI
degraded/blocked. On reconnect lazy_started=True skipped recreation, so the
client saw a blank screen.

Fix: drop the while-true wrapper. Now when the CLI exits, the exec pty
closes (EOF), the broadcast task ends, and the next client connection
detects the dead upstream via _upstream_alive() and recreates the exec —
with a terminal attached, so CPR is answered. A live exec is reused
(just a Ctrl-L redraw).

_LazyExecTelnetServer is extracted from a closure to module level so the
reconnect/recreate logic is unit-testable. Add 9 tests covering
_upstream_alive states and the recreate-on-death / reuse-if-live /
close-half-dead-writer / no-while-true behaviors.

Full Docker suite (120) passes.
2026-08-13 02:05:17 +08:00
YueGuobin
1e154ac85f
test: add tests for VendorDockerVM and the docker_exec factory
25 tests covering:
- Docker.create_node factory: selects VendorDockerVM iff console_type ==
  docker_exec, DockerVM otherwise (including telnet/ssh/vnc/http/none/spice)
- GNS3_* env parsing: SKIP_INIT, INTERFACE_NAMES, CONSOLE_CMD (single and
  multiline), defaults
- create(): init.sh skipped under GNS3_SKIP_INIT, prepended otherwise;
  GNS3_MAX_ETHERNET follows the interface rename; /etc/network mount dropped
  under SKIP_INIT (and host skeleton dir removed) but kept without it
- _add_ubridge_connection: move_to_ns targets the renamed interface
  (mgmt0) or falls back to eth{N}
- start(): docker_exec console dispatch + SKIP_INIT volume bridge + permission
  fix; without SKIP_INIT the vendor passes are skipped
- _fix_permissions: skips dead/missing containers (no restart), targets
  /gns3volumes bind-mount paths
- _setup_skip_init_volumes: runs the docker exec bridge script
- _cleanup_console_resources: closes the exec pty writer

Full Docker suite (111) and compute suite (395) pass — the four hook
extractions in DockerVM introduce no regressions.
2026-08-13 02:05:17 +08:00
YueGuobin
2f70bd6daa
revert: drop _connect_nio thread-pool executor, restore async _ubridge_send
The _connect_nio thread-pool optimisation (send_batch_sync) targeted
node-start performance, but start_all already runs at concurrency=3
(by design, to avoid overwhelming the host).  It also introduced a
Python 3.13 incompatibility (trsock.setblocking forbidden) that
prevented docker nodes from starting.  Since node-start is not the
target of this branch (project-open link creation is), revert to the
simple per-command async _ubridge_send.

The project-open batch NIO dispatch (create_batch_nios) is unaffected —
it never called _connect_nio (nodes aren't started during open).
2026-08-11 01:16:13 +08:00
YueGuobin
05934fa8e8
perf: offload per-NIO ubridge commands to thread-pool executor
Replace the 3-5 sequential await _ubridge_send calls in _connect_nio
with a single run_in_executor batch.  The batch holds the node-level
asyncio Lock to prevent interleaving with async sends, then uses the
hypervisor's new send_batch_sync method which does blocking socket
sendall/recv inside the thread pool.  Different nodes' batches now
run in true OS-thread parallelism rather than serialising through
the asyncio event loop between every command.

- ubridge_hypervisor.send_batch_sync: blocking batch send using
  the underlying socket from the asyncio transport, protected by
  threading.Lock.
- _connect_nio: builds command list (add_nio_udp, start_capture,
  bridge start, reset_packet_filters, add_packet_filter) and
  dispatches to the default executor.
2026-08-10 23:06:54 +08:00
YueGuobin
e7dfe9c7c4
fix: SIGKILL docker container on stop instead of 5s grace period
Docker node stop took ~5s every time. The stop API grace period
(params t=5, unchanged since 2015) was always exhausted: the business
process (often an interactive shell) ignores SIGTERM, and GNS3 doesn't
depend on graceful shutdown — _fix_permissions and /gns3volumes already
persist container state before stop() is called.

Use POST /containers/{id}/kill (SIGKILL, zero delay) instead of stop.
The 409 (container already stopped) replaces the previous 304 handling
for the race where the container exits between the state check and the call.

t=5 traced to commit 33edbefa3 (2015-10-14) "Docker cleanup and
improvements" — introduced with no recorded rationale.
2026-08-10 21:48:26 +08:00
grossmj
544d15c87e
fix: tests after merging 2026-08-08 16:50:19 +02:00
grossmj
dff79f65d3
Merge branch '2.2' into 3.1
# Conflicts:
#	gns3server/compute/qemu/qemu_vm.py
#	gns3server/controller/import_project.py
#	gns3server/controller/project.py
#	gns3server/crash_report.py
#	gns3server/version.py
#	tests/compute/docker/test_docker_vm.py
#	tests/controller/test_import_project.py
#	tests/controller/test_project.py
2026-08-08 16:27:14 +02:00
Sanjay Santhanam
41e8777609 fix: correct always-true state check in DockerVM.stop()
The condition 'state != "stopped" or state != "exited"' is a tautology,
so the state check was a no-op and a stop request was sent even for a
container that had already exited.

_get_container_state() never returns "stopped" (only "running",
"paused" or "exited"), so the intended negation of the condition used in
_fix_permissions() requires 'and', not 'or' (De Morgan's law).

Added a regression test asserting no stop query is issued for an
already-exited container.
2026-07-25 10:30:16 -07:00
Cristi
2abc7e09a3 Adds controller and compute API support for explicitly pulling or updating Docker images. 2026-07-24 16:40:20 +03:00
YueGuobin
ce95c89b64
Fix _fix_permissions test: set process.returncode=0 and update assertion
- Set returncode=0 on mock process to follow the success path
- Update assertion to include stderr=asyncio.subprocess.PIPE parameter
2026-06-10 00:44:12 +08:00
grossmj
c5b9f379fe
Merge remote-tracking branch 'origin/2.2' into 3.0
# Conflicts:
#	Dockerfile
#	dev-requirements.txt
#	gns3server/compute/qemu/qemu_vm.py
#	gns3server/version.py
#	requirements.txt
2026-02-20 16:28:53 +08:00
grossmj
715b7032bc
Fix tests 2026-02-20 15:51:49 +08:00
grossmj
1d45df6613
Upgrade dependencies 2026-01-24 21:38:58 +08:00
grossmj
60c10e7ecc
Merge remote-tracking branch 'origin/2.2' into 3.0
# Conflicts:
#	.github/workflows/testing.yml
#	CHANGELOG
#	README.md
#	gns3server/appliances/infix.gns3a
#	gns3server/compute/docker/__init__.py
#	gns3server/compute/docker/docker_vm.py
#	gns3server/crash_report.py
#	gns3server/version.py
#	gns3server/web/web_server.py
#	setup.py
#	tests/controller/test_project.py
2025-11-29 11:42:02 +10:00
grossmj
f2aaf5ab38
Docker API version requirements and process to handle older daemons 2025-11-17 22:26:18 +10:00
grossmj
bae6221991
Set name of container in Docker 2025-11-17 10:59:05 +10:00
grossmj
232b9c2806
Fix tests 2025-05-25 17:35:45 +02:00
grossmj
8c7c17b889
Upgrade dependencies and fix Pydantic warnings 2024-10-31 17:09:52 +10:00
grossmj
7e902726bf
Fix issues after merge 2024-10-31 13:06:17 +10:00
grossmj
c4fcb43e78
Merge branch '2.2' into 3.0
# Conflicts:
#	.github/workflows/testing.yml
#	CHANGELOG
#	README.md
#	dev-requirements.txt
#	gns3server/compute/docker/docker_vm.py
#	gns3server/controller/export_project.py
#	gns3server/controller/import_project.py
#	gns3server/controller/project.py
#	gns3server/crash_report.py
#	gns3server/static/web-ui/index.html
#	gns3server/static/web-ui/main.df8c319a3da6fb0e3629.js
#	gns3server/version.py
#	requirements.txt
#	setup.py
#	tests/compute/docker/test_docker_vm.py
#	tests/controller/test_import_project.py
2024-10-31 12:54:35 +10:00
grossmj
48b7e6ca50
Fix run Docker containers with user namespaces enabled. Fixes #2414 2024-10-26 19:03:05 +10: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
d3138daa23
Fix Docker tests 2024-09-22 22:12:40 +07:00
grossmj
7619080a50
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/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-22 22:01:06 +07:00
grossmj
c41c11eb34
Backport auxiliary console support for Qemu, Docker and Dynamips nodes 2024-09-22 18:29:04 +07:00
grossmj
22f022cc22
Fix for running Docker containers with user namespaces enabled 2024-09-19 10:40:22 +07:00
grossmj
8429494280
Test base MAC address for Docker VMs 2024-09-19 10:19:07 +07:00
grossmj
3214f52e9e
Merge branch '2.2' into 3.0
# Conflicts:
#	gns3server/compute/docker/docker_vm.py
#	gns3server/handlers/api/compute/docker_handler.py
#	gns3server/schemas/docker.py
#	gns3server/schemas/docker_template.py
#	tests/compute/docker/test_docker_vm.py
2024-09-18 17:29:06 +07:00
grossmj
3792901dc7
Support for configuring MAC address in Docker containers 2024-09-18 16:30:22 +07:00
grossmj
d3860ba84b
Merge branch '2.2' into 3.0
# Conflicts:
#	CHANGELOG
#	dev-requirements.txt
#	gns3server/compute/qemu/__init__.py
#	gns3server/compute/vmware/__init__.py
#	gns3server/controller/snapshot.py
#	gns3server/crash_report.py
#	gns3server/handlers/api/compute/atm_switch_handler.py
#	gns3server/run.py
#	gns3server/static/web-ui/26.77d4bfd104f37c42e028.js
#	gns3server/static/web-ui/index.html
#	gns3server/static/web-ui/runtime.415291667f70565cd8ef.js
#	gns3server/utils/__init__.py
#	gns3server/utils/images.py
#	gns3server/utils/interfaces.py
#	gns3server/version.py
#	gns3server/web/web_server.py
#	pytest.ini
#	requirements.txt
#	scripts/update-bundled-web-ui.sh
#	setup.py
#	tests/api/routes/compute/test_dynamips_nodes.py
#	tests/compute/builtin/nodes/test_cloud.py
#	tests/compute/docker/test_docker.py
#	tests/compute/docker/test_docker_vm.py
#	tests/compute/dynamips/test_dynamips_manager.py
#	tests/compute/dynamips/test_dynamips_router.py
#	tests/compute/iou/test_iou_vm.py
#	tests/compute/qemu/test_qcow2.py
#	tests/compute/qemu/test_qemu_manager.py
#	tests/compute/qemu/test_qemu_vm.py
#	tests/compute/test_base_node.py
#	tests/compute/test_manager.py
#	tests/compute/test_project.py
#	tests/compute/traceng/test_traceng_vm.py
#	tests/compute/virtualbox/test_virtualbox_manager.py
#	tests/compute/virtualbox/test_virtualbox_vm.py
#	tests/compute/vmware/test_vmware_manager.py
#	tests/compute/vmware/test_vmware_vm.py
#	tests/compute/vpcs/test_vpcs_vm.py
#	tests/conftest.py
#	tests/controller/gns3vm/test_remote_gns3_vm.py
#	tests/controller/gns3vm/test_virtualbox_gns3_vm.py
#	tests/controller/gns3vm/test_vmware_gns3_vm.py
#	tests/controller/test_export_project.py
#	tests/controller/test_gns3vm.py
#	tests/controller/test_import_project.py
#	tests/test_config.py
#	tests/utils/test_asyncio.py
#	tests/utils/test_images.py
#	tests/web/test_response.py
2024-05-16 17:53:39 +07:00
grossmj
46a9fdb61d
Remove event_loop 2024-05-09 17:53:02 +07:00
grossmj
9958b876cf
Do not run Docker VM tests on Windows 2024-05-09 17:36:58 +07:00
grossmj
33499be425
Fix warnings in tests 2024-05-09 17:11:12 +07:00
grossmj
2609849507
Fix tests after updating error message when busybox is not installed. 2024-04-23 18:00:37 +07:00
grossmj
e9827653ae
Merge branch '2.2' into 3.0
# Conflicts:
#	gns3server/crash_report.py
#	gns3server/static/web-ui/index.html
#	gns3server/version.py
#	tests/compute/docker/test_docker_vm.py
2024-03-05 01:05:46 +08:00
grossmj
0137688ba7
Test busybox is installed 2024-02-22 13:05:48 +08:00
grossmj
84db3b9996
Fix not all Docker resources are copied to a writable location 2024-02-22 12:59:44 +08:00
grossmj
1a53c9aabf
Backport from v3: install Docker resources in a writable location at runtime. 2024-02-14 16:13:45 +08:00
grossmj
09ff807055 Install Docker resources in writable location 2023-11-13 11:23:26 +10:00
grossmj
1ec056c1a6 Merge branch '2.2' into 3.0
# Conflicts:
#	gns3server/compute/docker/docker_vm.py
#	gns3server/controller/__init__.py
#	gns3server/controller/appliance_manager.py
#	gns3server/web/route.py
#	requirements.txt
#	tests/compute/docker/test_docker_vm.py
2023-09-06 23:30:00 +07:00
grossmj
c2783d355f Fix test_create_vnc test 2023-08-27 18:41:25 +10:00
grossmj
1ce0c13fc9 Better mocking in Docker tests 2023-08-18 12:20:54 +10:00
grossmj
2f2aabeb5a Fix tests when running Python 3.7 2023-08-11 17:58:00 +10:00
grossmj
d9eb61efc4 Fix tests with asyncio_patch 2023-08-11 17:37:11 +10:00
grossmj
1fd8444d22 Add tests for install_busybox() 2023-08-11 17:32:05 +10:00
grossmj
1ff23348d3 Merge branch '2.2' into 3.0
# Conflicts:
#	gns3server/compute/base_node.py
#	gns3server/compute/docker/__init__.py
#	gns3server/compute/qemu/qemu_vm.py
#	gns3server/controller/compute.py
#	gns3server/controller/gns3vm/virtualbox_gns3_vm.py
#	gns3server/controller/node.py
#	gns3server/controller/project.py
#	gns3server/crash_report.py
#	gns3server/handlers/api/controller/template_handler.py
#	gns3server/static/web-ui/index.html
#	gns3server/static/web-ui/main.8448c96e4facbe79a613.js
#	gns3server/version.py
#	tests/compute/iou/test_iou_vm.py
#	tests/compute/qemu/test_qemu_vm.py
#	tests/handlers/api/controller/test_template.py
2023-06-20 16:06:53 +09:30
grossmj
4338afab7f Fix tests 2023-06-02 20:16:06 +09:30
grossmj
b3dfb87622 Merge branch '2.2' into 3.0
# Conflicts:
#	gns3server/controller/__init__.py
#	gns3server/crash_report.py
#	gns3server/static/web-ui/index.html
#	gns3server/static/web-ui/main.96be36058f5df0ca7e7f.js
#	gns3server/utils/images.py
#	gns3server/version.py
#	requirements.txt
#	tests/compute/docker/test_docker_vm.py
#	tests/controller/test_controller.py
2023-05-22 15:11:17 +08:00