From 0aa6566e50bcd0970f0ee09dc9ac8b9e7d14da2d Mon Sep 17 00:00:00 2001 From: grossmj Date: Tue, 17 Mar 2026 12:49:38 +0800 Subject: [PATCH] Prevent router to be duplicated when running and add tests --- gns3server/compute/base_manager.py | 1 - gns3server/compute/dynamips/__init__.py | 5 ++++- tests/compute/dynamips/test_dynamips_manager.py | 3 +++ tests/compute/test_manager.py | 4 ++++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/gns3server/compute/base_manager.py b/gns3server/compute/base_manager.py index a3ee38cec..076b802d1 100644 --- a/gns3server/compute/base_manager.py +++ b/gns3server/compute/base_manager.py @@ -35,7 +35,6 @@ from gns3server.utils.interfaces import is_interface_up from uuid import UUID, uuid4 from typing import Type from ..config import Config -from ..utils.asyncio import wait_run_in_executor from ..utils import force_unix_path from .project_manager import ProjectManager from .port_manager import PortManager diff --git a/gns3server/compute/dynamips/__init__.py b/gns3server/compute/dynamips/__init__.py index 4362b9be1..c9fa71483 100644 --- a/gns3server/compute/dynamips/__init__.py +++ b/gns3server/compute/dynamips/__init__.py @@ -32,7 +32,7 @@ import re log = logging.getLogger(__name__) -from gns3server.utils.interfaces import interfaces, is_interface_up +from gns3server.utils.interfaces import is_interface_up from gns3server.utils.asyncio import wait_run_in_executor, subprocess_check_output from gns3server.utils import parse_version from uuid import uuid4 @@ -644,6 +644,9 @@ class Dynamips(BaseManager): if not hasattr(source_node, "startup_config_path"): return await super().duplicate_node(source_node_id, destination_node_id) + if hasattr(source_node, "status") and source_node.status != "stopped": + raise DynamipsError("Cannot duplicate router data while the route is running") + try: with open(source_node.startup_config_path) as f: startup_config = f.read() diff --git a/tests/compute/dynamips/test_dynamips_manager.py b/tests/compute/dynamips/test_dynamips_manager.py index 94fd03e23..26fc280ca 100644 --- a/tests/compute/dynamips/test_dynamips_manager.py +++ b/tests/compute/dynamips/test_dynamips_manager.py @@ -128,3 +128,6 @@ async def test_duplicate_node(manager, compute_project): with open(destination_node.startup_config_path) as f: content = f.read() assert content == '!\nhostname R2\necho TEST' + with pytest.raises(DynamipsError): + source_node.status = "started" + await manager.duplicate_node(source_node.id, destination_node.id) diff --git a/tests/compute/test_manager.py b/tests/compute/test_manager.py index 0a2a81234..cddbeb3ea 100644 --- a/tests/compute/test_manager.py +++ b/tests/compute/test_manager.py @@ -26,6 +26,7 @@ from gns3server.compute.vpcs import VPCS from gns3server.compute.dynamips import Dynamips from gns3server.compute.qemu import Qemu from gns3server.compute.error import NodeError, ImageMissingError +from gns3server.compute.compute_error import ComputeError from gns3server.utils import force_unix_path @@ -290,6 +291,9 @@ async def test_duplicate_vpcs(vpcs, compute_project): with open(os.path.join(destination_node.working_dir, "startup.vpc")) as f: startup = f.read().strip() assert startup == "set pcname PC-2\nip dhcp\n".strip() + with pytest.raises(ComputeError): + source_node.status = "started" + await vpcs.duplicate_node(source_node_id, destination_node_id) @pytest.mark.asyncio