From 3fb138b9a11efdd6656f58565de23a1a69a90960 Mon Sep 17 00:00:00 2001 From: grossmj Date: Sun, 19 Mar 2023 17:29:29 +1000 Subject: [PATCH 1/2] Allow ':' in project name when Docker containers are used --- gns3server/compute/docker/docker_vm.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py index 01212982..cead5b15 100644 --- a/gns3server/compute/docker/docker_vm.py +++ b/gns3server/compute/docker/docker_vm.py @@ -303,7 +303,12 @@ class DockerVM(BaseNode): resources = get_resource("compute/docker/resources") if not os.path.exists(resources): raise DockerError(f"{resources} is missing, can't start Docker container") - binds = [f"{resources}:/gns3:ro"] + binds = [{ + "Type": "bind", + "Source": resources, + "Target": "/gns3", + "ReadOnly": True + }] # We mount our own etc/network try: @@ -334,7 +339,11 @@ class DockerVM(BaseNode): for volume in self._volumes: source = os.path.join(self.working_dir, os.path.relpath(volume, "/")) os.makedirs(source, exist_ok=True) - binds.append(f"{source}:/gns3volumes{volume}") + binds.append({ + "Type": "bind", + "Source": source, + "Target": "/gns3volumes{}".format(volume) + }) return binds @@ -410,7 +419,7 @@ class DockerVM(BaseNode): "HostConfig": { "CapAdd": ["ALL"], "Privileged": True, - "Binds": self._mount_binds(image_infos), + "Mounts": self._mount_binds(image_infos), "Memory": self._memory * (1024 * 1024), # convert memory to bytes "NanoCpus": int(self._cpus * 1e9), # convert cpus to nano cpus }, @@ -475,7 +484,11 @@ class DockerVM(BaseNode): "QT_GRAPHICSSYSTEM=native" ) # To fix a Qt issue: https://github.com/GNS3/gns3-server/issues/556 params["Env"].append(f"DISPLAY=:{self._display}") - params["HostConfig"]["Binds"].append("/tmp/.X11-unix/:/tmp/.X11-unix/") + params["HostConfig"]["Mounts"].append({ + "Type": "bind", + "Source": "/tmp/.X11-unix/", + "Target": "/tmp/.X11-unix/" + }) if self._extra_hosts: extra_hosts = self._format_extra_hosts(self._extra_hosts) From f347e21100362796a4cdb4fdca76cd8e7234d338 Mon Sep 17 00:00:00 2001 From: grossmj Date: Sun, 19 Mar 2023 17:56:07 +1000 Subject: [PATCH 2/2] Fix Docker tests --- tests/compute/docker/test_docker_vm.py | 316 ++++++++++++++++++++----- 1 file changed, 255 insertions(+), 61 deletions(-) diff --git a/tests/compute/docker/test_docker_vm.py b/tests/compute/docker/test_docker_vm.py index e6e9ee9d..822b63d3 100644 --- a/tests/compute/docker/test_docker_vm.py +++ b/tests/compute/docker/test_docker_vm.py @@ -103,9 +103,18 @@ async def test_create(compute_project, manager): "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")) + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + } ], "Privileged": True, "Memory": 0, @@ -144,9 +153,18 @@ async def test_create_with_tag(compute_project, manager): "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")) + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + } ], "Privileged": True, "Memory": 0, @@ -188,10 +206,23 @@ async def test_create_vnc(compute_project, manager): "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")), - '/tmp/.X11-unix/:/tmp/.X11-unix/' + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + }, + { + "Type": "bind", + "Source": "/tmp/.X11-unix/", + "Target": "/tmp/.X11-unix/" + } ], "Privileged": True, "Memory": 0, @@ -310,9 +341,18 @@ async def test_create_start_cmd(compute_project, manager): "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")) + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + } ], "Privileged": True, "Memory": 0, @@ -413,9 +453,18 @@ async def test_create_image_not_available(compute_project, manager): "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")) + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + } ], "Privileged": True, "Memory": 0, @@ -459,9 +508,18 @@ async def test_create_with_user(compute_project, manager): "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")) + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + } ], "Privileged": True, "Memory": 0, @@ -548,10 +606,23 @@ async def test_create_with_extra_volumes_duplicate_1_image(compute_project, mana "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")), - "{}:/gns3volumes/vol/1".format(os.path.join(vm.working_dir, "vol", "1")), + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "vol", "1"), + "Target": "/gns3volumes/vol/1" + } ], "Privileged": True, "Memory": 0, @@ -590,10 +661,23 @@ async def test_create_with_extra_volumes_duplicate_2_user(compute_project, manag "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")), - "{}:/gns3volumes/vol/1".format(os.path.join(vm.working_dir, "vol", "1")), + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "vol", "1"), + "Target": "/gns3volumes/vol/1" + } ], "Privileged": True, "Memory": 0, @@ -632,10 +716,23 @@ async def test_create_with_extra_volumes_duplicate_3_subdir(compute_project, man "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")), - "{}:/gns3volumes/vol".format(os.path.join(vm.working_dir, "vol")), + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "vol"), + "Target": "/gns3volumes/vol" + } ], "Privileged": True, "Memory": 0, @@ -674,10 +771,23 @@ async def test_create_with_extra_volumes_duplicate_4_backslash(compute_project, "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")), - "{}:/gns3volumes/vol".format(os.path.join(vm.working_dir, "vol")), + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "vol"), + "Target": "/gns3volumes/vol" + } ], "Privileged": True, "Memory": 0, @@ -716,9 +826,18 @@ async def test_create_with_extra_volumes_duplicate_5_subdir_issue_1595(compute_p "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc".format(os.path.join(vm.working_dir, "etc")), + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc"), + "Target": "/gns3volumes/etc" + } ], "Privileged": True, "Memory": 0, @@ -757,9 +876,18 @@ async def test_create_with_extra_volumes_duplicate_6_subdir_issue_1595(compute_p "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc".format(os.path.join(vm.working_dir, "etc")), + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc"), + "Target": "/gns3volumes/etc" + } ], "Privileged": True, "Memory": 0, @@ -804,11 +932,28 @@ async def test_create_with_extra_volumes(compute_project, manager): "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")), - "{}:/gns3volumes/vol/1".format(os.path.join(vm.working_dir, "vol", "1")), - "{}:/gns3volumes/vol/2".format(os.path.join(vm.working_dir, "vol", "2")), + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "vol", "1"), + "Target": "/gns3volumes/vol/1" + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "vol", "2"), + "Target": "/gns3volumes/vol/2" + } ], "Privileged": True, "Memory": 0, @@ -1043,9 +1188,18 @@ async def test_update(vm): "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")) + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + } ], "Privileged": True, "Memory": 0, @@ -1115,9 +1269,18 @@ async def test_update_running(vm): "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")) + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + } ], "Privileged": True, "Memory": 0, @@ -1397,9 +1560,22 @@ async def test_mount_binds(vm): dst = os.path.join(vm.working_dir, "test/experimental") assert vm._mount_binds(image_infos) == [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")), - "{}:/gns3volumes{}".format(dst, "/test/experimental") + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + }, + { + "Type": "bind", + "Source": dst, + "Target": "/gns3volumes/test/experimental" + } ] assert vm._volumes == ["/etc/network", "/test/experimental"] @@ -1527,9 +1703,18 @@ async def test_cpus(compute_project, manager): "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")) + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + } ], "Privileged": True, "Memory": 0, @@ -1568,9 +1753,18 @@ async def test_memory(compute_project, manager): "HostConfig": { "CapAdd": ["ALL"], - "Binds": [ - "{}:/gns3:ro".format(get_resource("compute/docker/resources")), - "{}:/gns3volumes/etc/network".format(os.path.join(vm.working_dir, "etc", "network")) + "Mounts": [ + { + "Type": "bind", + "Source": get_resource("compute/docker/resources"), + "Target": "/gns3", + "ReadOnly": True + }, + { + "Type": "bind", + "Source": os.path.join(vm.working_dir, "etc", "network"), + "Target": "/gns3volumes/etc/network" + } ], "Privileged": True, "Memory": 33554432, # 32MB in bytes