diff --git a/gns3server/handlers/api/docker_handler.py b/gns3server/handlers/api/docker_handler.py index 42957f032..85c2183eb 100644 --- a/gns3server/handlers/api/docker_handler.py +++ b/gns3server/handlers/api/docker_handler.py @@ -73,6 +73,7 @@ class DockerHandler: adapters=request.json.get("adapters"), console=request.json.get("console"), console_type=request.json.get("console_type"), + console_resolution=request.json.get("console_resolution", "1024x768"), aux=request.json.get("aux") ) for name, value in request.json.items(): @@ -277,6 +278,8 @@ class DockerHandler: vm = docker_manager.get_vm(request.match_info["vm_id"], project_id=request.match_info["project_id"]) vm.name = request.json.get("name", vm.name) vm.console = request.json.get("console", vm.console) + vm.aux = request.json.get("aux", vm.aux) + vm.console_resolution = request.json.get("console_resolution", vm.console_resolution) vm.start_command = request.json.get("start_command", vm.start_command) vm.environment = request.json.get("environment", vm.environment) vm.adapters = request.json.get("adapters", vm.adapters) diff --git a/gns3server/modules/docker/docker_vm.py b/gns3server/modules/docker/docker_vm.py index df32f6086..eafe68681 100644 --- a/gns3server/modules/docker/docker_vm.py +++ b/gns3server/modules/docker/docker_vm.py @@ -53,11 +53,13 @@ class DockerVM(BaseVM): :param console: TCP console port :param console_type: Console type :param aux: TCP aux console port + :param console_resolution: Resolution of the VNC display """ def __init__(self, name, vm_id, project, manager, image, console=None, aux=None, start_command=None, - adapters=None, environment=None, console_type="telnet"): + adapters=None, environment=None, console_type="telnet", + console_resolution="1024x768"): super().__init__(name, vm_id, project, manager, console=console, aux=aux, allocate_aux=True, console_type=console_type) self._image = image @@ -69,6 +71,7 @@ class DockerVM(BaseVM): self._temporary_directory = None self._telnet_servers = [] self._x11vnc_process = None + self._console_resolution = console_resolution if adapters is None: self.adapters = 1 @@ -91,6 +94,7 @@ class DockerVM(BaseVM): "adapters": self.adapters, "console": self.console, "console_type": self.console_type, + "console_resolution": self.console_resolution, "aux": self.aux, "start_command": self.start_command, "environment": self.environment, @@ -121,6 +125,14 @@ class DockerVM(BaseVM): else: self._start_command = command + @property + def console_resolution(self): + return self._console_resolution + + @console_resolution.setter + def console_resolution(self, resolution): + self._console_resolution = resolution + @property def environment(self): return self._environment @@ -343,8 +355,7 @@ class DockerVM(BaseVM): self._display = self._get_free_display_port() if shutil.which("Xvfb") is None or shutil.which("x11vnc") is None: raise DockerError("Please install Xvfb and x11vnc before using the VNC support") - screen_resolution = "1024x768" - self._xvfb_process = yield from asyncio.create_subprocess_exec("Xvfb", "-nolisten", "tcp", ":{}".format(self._display), "-screen", "0", screen_resolution + "x16") + self._xvfb_process = yield from asyncio.create_subprocess_exec("Xvfb", "-nolisten", "tcp", ":{}".format(self._display), "-screen", "0", self._console_resolution + "x16") self._x11vnc_process = yield from asyncio.create_subprocess_exec("x11vnc", "-forever", "-nopw", "-display", "WAIT:{}".format(self._display), "-rfbport", str(self.console), "-noncache", "-listen", self._manager.port_manager.console_host) x11_socket = os.path.join("/tmp/.X11-unix/", "X{}".format(self._display)) diff --git a/gns3server/schemas/docker.py b/gns3server/schemas/docker.py index 47baf97a1..dc69fb362 100644 --- a/gns3server/schemas/docker.py +++ b/gns3server/schemas/docker.py @@ -43,6 +43,11 @@ DOCKER_CREATE_SCHEMA = { "description": "console type", "enum": ["telnet", "vnc"] }, + "console_resolution": { + "description": "console resolution for VNC", + "type": ["string", "null"], + "pattern": "^[0-9]+x[0-9]+$" + }, "aux": { "description": "auxilary TCP port", "minimum": 1, @@ -92,6 +97,11 @@ DOCKER_UPDATE_SCHEMA = { "maximum": 65535, "type": ["integer", "null"] }, + "console_resolution": { + "description": "console resolution for VNC", + "type": ["string", "null"], + "pattern": "^[0-9]+x[0-9]+$" + }, "console_type": { "description": "console type", "enum": ["telnet", "vnc"] @@ -143,13 +153,18 @@ DOCKER_OBJECT_SCHEMA = { "description": "auxilary TCP port", "minimum": 1, "maximum": 65535, - "type": ["integer", "null"] + "type": "integer" }, "console": { "description": "console TCP port", "minimum": 1, "maximum": 65535, - "type": ["integer", "null"] + "type": "integer" + }, + "console_resolution": { + "description": "console resolution for VNC", + "type": "string", + "pattern": "^[0-9]+x[0-9]+$" }, "console_type": { "description": "console type", @@ -196,7 +211,7 @@ DOCKER_OBJECT_SCHEMA = { } }, "additionalProperties": False, - "required": ["vm_id", "project_id", "image", "container_id", "adapters", "aux", "console", "console_type", "start_command", "environment", "vm_directory"] + "required": ["vm_id", "project_id", "image", "container_id", "adapters", "aux", "console", "console_type", "console_resolution", "start_command", "environment", "vm_directory"] } diff --git a/tests/handlers/api/test_docker.py b/tests/handlers/api/test_docker.py index 5a9b96e5c..c87d6d186 100644 --- a/tests/handlers/api/test_docker.py +++ b/tests/handlers/api/test_docker.py @@ -30,7 +30,7 @@ from gns3server.modules.docker import Docker @pytest.fixture def base_params(): """Return standard parameters""" - return {"name": "PC TEST 1", "image": "nginx", "start_command": "nginx-daemon", "adapters": 2, "environment": "YES=1\nNO=0", "console_type": "telnet"} + return {"name": "PC TEST 1", "image": "nginx", "start_command": "nginx-daemon", "adapters": 2, "environment": "YES=1\nNO=0", "console_type": "telnet", "console_resolution": "1280x1024"} @pytest.yield_fixture(autouse=True) @@ -65,6 +65,7 @@ def test_docker_create(server, project, base_params): assert response.json["image"] == "nginx" assert response.json["adapters"] == 2 assert response.json["environment"] == "YES=1\nNO=0" + assert response.json["console_resolution"] == "1280x1024" def test_docker_start(server, vm): diff --git a/tests/modules/docker/test_docker_vm.py b/tests/modules/docker/test_docker_vm.py index 64c589fb5..c60645d0b 100644 --- a/tests/modules/docker/test_docker_vm.py +++ b/tests/modules/docker/test_docker_vm.py @@ -57,6 +57,7 @@ def test_json(vm, project): 'adapters': 1, 'console': vm.console, 'console_type': 'telnet', + 'console_resolution': '1024x768', 'aux': vm.aux, 'start_command': vm.start_command, 'environment': vm.environment, @@ -816,12 +817,13 @@ def test_mount_binds(vm, tmpdir): def test_start_vnc(vm, loop): + vm.console_resolution = "1280x1024" with patch("shutil.which", return_value="/bin/x"): with asyncio_patch("gns3server.modules.docker.docker_vm.wait_for_file_creation") as mock_wait: with asyncio_patch("asyncio.create_subprocess_exec") as mock_exec: loop.run_until_complete(asyncio.async(vm._start_vnc())) assert vm._display is not None - mock_exec.assert_any_call("Xvfb", "-nolisten", "tcp", ":{}".format(vm._display), "-screen", "0", "1024x768x16") + mock_exec.assert_any_call("Xvfb", "-nolisten", "tcp", ":{}".format(vm._display), "-screen", "0", "1280x1024x16") mock_exec.assert_any_call("x11vnc", "-forever", "-nopw", "-display", "WAIT:{}".format(vm._display), "-rfbport", str(vm.console), "-noncache", "-listen", "127.0.0.1") mock_wait.assert_called_with("/tmp/.X11-unix/X{}".format(vm._display))