diff --git a/gns3server/api/routes/compute/qemu_nodes.py b/gns3server/api/routes/compute/qemu_nodes.py index e8be9b003..4b9da897f 100644 --- a/gns3server/api/routes/compute/qemu_nodes.py +++ b/gns3server/api/routes/compute/qemu_nodes.py @@ -32,6 +32,9 @@ from gns3server.compute.qemu.qemu_vm import QemuVM from .dependencies.authentication import compute_authentication, ws_compute_authentication +import logging +log = logging.getLogger(__name__) + responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project or Qemu node"}} router = APIRouter(responses=responses) @@ -74,6 +77,15 @@ async def create_qemu_node(project_id: UUID, node_data: schemas.QemuCreate) -> s platform=node_data.pop("platform", None), ) + # update the disk image with the backing file if provided + # this is needed when duplicating a node that uses backed disk images + drives = ["a", "b", "c", "d"] + for disk_index, drive in enumerate(drives): + disk_image_backing_file = node_data.get(f"hd{drive}_disk_image_backing_file") + if disk_image_backing_file: + log.info(f"Updating disk image for drive {drive} with backing file {disk_image_backing_file}") + node_data[f"hd{drive}_disk_image"] = disk_image_backing_file + for name, value in node_data.items(): if hasattr(vm, name) and getattr(vm, name) != value: setattr(vm, name, value) diff --git a/gns3server/api/routes/controller/acl.py b/gns3server/api/routes/controller/acl.py index ae33bd09e..f4b0e8897 100644 --- a/gns3server/api/routes/controller/acl.py +++ b/gns3server/api/routes/controller/acl.py @@ -115,19 +115,19 @@ async def endpoints( add_to_endpoints("/access/users", "All users", "user") users = await users_repo.get_users() for user in users: - add_to_endpoints(f"/users/{user.user_id}", f'User "{user.username}"', "user") + add_to_endpoints(f"/access/users/{user.user_id}", f'User "{user.username}"', "user") # groups add_to_endpoints("/access/groups", "All groups", "group") groups = await users_repo.get_user_groups() for group in groups: - add_to_endpoints(f"/groups/{group.user_group_id}", f'Group "{group.name}"', "group") + add_to_endpoints(f"/access/groups/{group.user_group_id}", f'Group "{group.name}"', "group") # roles add_to_endpoints("/access/roles", "All roles", "role") roles = await rbac_repo.get_roles() for role in roles: - add_to_endpoints(f"/roles/{role.role_id}", f'Role "{role.name}"', "role") + add_to_endpoints(f"/access/roles/{role.role_id}", f'Role "{role.name}"', "role") # images add_to_endpoints("/images", "All images", "image") diff --git a/gns3server/compute/iou/iou_vm.py b/gns3server/compute/iou/iou_vm.py index d8fb2899b..2322e7723 100644 --- a/gns3server/compute/iou/iou_vm.py +++ b/gns3server/compute/iou/iou_vm.py @@ -97,11 +97,11 @@ class IOUVM(BaseNode): self._serial_adapters = [] self.ethernet_adapters = 2 # one adapter = 4 interfaces self.serial_adapters = 2 # one adapter = 4 interfaces - self._use_default_iou_values = True # for RAM & NVRAM values - self._nvram = 128 # Kilobytes + self._use_default_iou_values = False # for RAM & NVRAM values + self._nvram = 256 # Kilobytes self._startup_config = "" self._private_config = "" - self._ram = 256 # Megabytes + self._ram = 1024 # Megabytes self._application_id = application_id self._l1_keepalives = False # used to overcome the always-up Ethernet interfaces (not supported by all IOSes). diff --git a/gns3server/schemas/compute/iou_nodes.py b/gns3server/schemas/compute/iou_nodes.py index 7e3d3a91b..fe3fe8570 100644 --- a/gns3server/schemas/compute/iou_nodes.py +++ b/gns3server/schemas/compute/iou_nodes.py @@ -39,7 +39,7 @@ class IOUBase(BaseModel): ram: Optional[int] = Field(None, gt=0, description="Amount of RAM in MB") nvram: Optional[int] = Field(None, gt=0, description="Amount of NVRAM in KB") l1_keepalives: Optional[bool] = Field(None, description="Use default IOU values") - use_default_iou_values: Optional[bool] = Field(None, description="Always up Ethernet interfaces") + use_default_iou_values: Optional[bool] = Field(None, description="Use default IOU values") startup_config_content: Optional[str] = Field(None, description="Content of IOU startup configuration file") private_config_content: Optional[str] = Field(None, description="Content of IOU private configuration file") diff --git a/gns3server/schemas/controller/templates/iou_templates.py b/gns3server/schemas/controller/templates/iou_templates.py index e906f74f6..6dd83d14b 100644 --- a/gns3server/schemas/controller/templates/iou_templates.py +++ b/gns3server/schemas/controller/templates/iou_templates.py @@ -30,9 +30,9 @@ class IOUTemplate(TemplateBase): path: str = Field(..., description="Path of IOU executable") ethernet_adapters: Optional[int] = Field(2, ge=0, description="Number of ethernet adapters") serial_adapters: Optional[int] = Field(2, ge=0, description="Number of serial adapters") - ram: Optional[int] = Field(256, gt=0, description="Amount of RAM in MB") - nvram: Optional[int] = Field(128, gt=0, description="Amount of NVRAM in KB") - use_default_iou_values: Optional[bool] = Field(True, description="Use default IOU values") + ram: Optional[int] = Field(1024, gt=0, description="Amount of RAM in MB") + nvram: Optional[int] = Field(256, gt=0, description="Amount of NVRAM in KB") + use_default_iou_values: Optional[bool] = Field(False, description="Use default IOU values") startup_config: Optional[str] = Field("iou_l3_base_startup-config.txt", description="Startup-config of IOU") private_config: Optional[str] = Field("", description="Private-config of IOU") l1_keepalives: Optional[bool] = Field(False, description="Always keep up Ethernet interface (does not always work)") diff --git a/tests/api/routes/compute/test_iou_nodes.py b/tests/api/routes/compute/test_iou_nodes.py index b0de85b57..75fa6bdf0 100644 --- a/tests/api/routes/compute/test_iou_nodes.py +++ b/tests/api/routes/compute/test_iou_nodes.py @@ -86,8 +86,8 @@ class TestIOUNodesRoutes: assert response.json()["project_id"] == compute_project.id assert response.json()["serial_adapters"] == 2 assert response.json()["ethernet_adapters"] == 2 - assert response.json()["ram"] == 256 - assert response.json()["nvram"] == 128 + assert response.json()["ram"] == 1024 + assert response.json()["nvram"] == 256 assert response.json()["l1_keepalives"] is False @@ -190,8 +190,8 @@ class TestIOUNodesRoutes: assert response.json()["project_id"] == compute_project.id assert response.json()["serial_adapters"] == 2 assert response.json()["ethernet_adapters"] == 2 - assert response.json()["ram"] == 256 - assert response.json()["nvram"] == 128 + assert response.json()["ram"] == 1024 + assert response.json()["nvram"] == 256 assert response.json()["l1_keepalives"] is False diff --git a/tests/api/routes/controller/test_templates.py b/tests/api/routes/controller/test_templates.py index 38f01fb59..ba7055755 100644 --- a/tests/api/routes/controller/test_templates.py +++ b/tests/api/routes/controller/test_templates.py @@ -718,14 +718,14 @@ class TestIOUTemplate: "default_name_format": "IOU{0}", "ethernet_adapters": 2, "name": "IOU template", - "nvram": 128, + "nvram": 256, "path": image_path, "private_config": "", - "ram": 256, + "ram": 1024, "serial_adapters": 2, "startup_config": "iou_l3_base_startup-config.txt", "symbol": unittest.mock.ANY, - "use_default_iou_values": True, + "use_default_iou_values": False, "l1_keepalives": False} for item, value in expected_response.items(): diff --git a/tests/compute/iou/test_iou_vm.py b/tests/compute/iou/test_iou_vm.py index 211b8e3c1..446a6544b 100644 --- a/tests/compute/iou/test_iou_vm.py +++ b/tests/compute/iou/test_iou_vm.py @@ -264,7 +264,7 @@ def test_create_netmap_config(vm): @pytest.mark.asyncio async def test_build_command(vm): - assert await vm._build_command() == [vm.path, str(vm.application_id)] + assert await vm._build_command() == [vm.path, "-n", "256", "-m", "1024", str(vm.application_id)] def test_get_startup_config(vm):