mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-28 11:18:11 +00:00
Merge branch '2.2' into appliance-api
This commit is contained in:
commit
f91d3c9dbb
@ -24,6 +24,7 @@ import shutil
|
|||||||
import psutil
|
import psutil
|
||||||
import shlex
|
import shlex
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
import subprocess
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
|
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
|
||||||
@ -82,7 +83,7 @@ class DockerVM(BaseNode):
|
|||||||
self._temporary_directory = None
|
self._temporary_directory = None
|
||||||
self._telnet_servers = []
|
self._telnet_servers = []
|
||||||
self._xvfb_process = None
|
self._xvfb_process = None
|
||||||
self._x11vnc_process = None
|
self._vnc_process = None
|
||||||
self._console_resolution = console_resolution
|
self._console_resolution = console_resolution
|
||||||
self._console_http_path = console_http_path
|
self._console_http_path = console_http_path
|
||||||
self._console_http_port = console_http_port
|
self._console_http_port = console_http_port
|
||||||
@ -423,9 +424,10 @@ class DockerVM(BaseNode):
|
|||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
|
||||||
if self._console_type == "vnc" and not self._x11vnc_process:
|
if self._console_type == "vnc" and not self._vnc_process:
|
||||||
# start the x11vnc process in case it had previously crashed
|
# restart the vnc process in case it had previously crashed
|
||||||
self._x11vnc_process = await asyncio.create_subprocess_exec("x11vnc", "-forever", "-nopw", "-shared", "-geometry", self._console_resolution, "-display", "WAIT:{}".format(self._display), "-rfbport", str(self.console), "-rfbportv6", str(self.console), "-noncache", "-listen", self._manager.port_manager.console_host)
|
await self._start_vnc_process(restart=True)
|
||||||
|
monitor_process(self._vnc_process, self._vnc_callback)
|
||||||
|
|
||||||
await self._clean_servers()
|
await self._clean_servers()
|
||||||
|
|
||||||
@ -520,24 +522,60 @@ class DockerVM(BaseNode):
|
|||||||
raise DockerError("Could not fix permissions for {}: {}".format(volume, e))
|
raise DockerError("Could not fix permissions for {}: {}".format(volume, e))
|
||||||
await process.wait()
|
await process.wait()
|
||||||
|
|
||||||
|
async def _start_vnc_process(self, restart=False):
|
||||||
|
"""
|
||||||
|
Starts the VNC process.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if shutil.which("Xtigervnc"):
|
||||||
|
with open(os.path.join(self.working_dir, "vnc.log"), "w") as fd:
|
||||||
|
self._vnc_process = await asyncio.create_subprocess_exec("Xtigervnc",
|
||||||
|
"-geometry", self._console_resolution,
|
||||||
|
"-depth", "16",
|
||||||
|
"-interface", self._manager.port_manager.console_host,
|
||||||
|
"-rfbport", str(self.console),
|
||||||
|
"-AlwaysShared",
|
||||||
|
"-SecurityTypes", "None",
|
||||||
|
":{}".format(self._display),
|
||||||
|
stdout=fd, stderr=subprocess.STDOUT)
|
||||||
|
else:
|
||||||
|
if restart is False:
|
||||||
|
self._xvfb_process = await asyncio.create_subprocess_exec("Xvfb",
|
||||||
|
"-nolisten",
|
||||||
|
"tcp", ":{}".format(self._display),
|
||||||
|
"-screen", "0",
|
||||||
|
self._console_resolution + "x16")
|
||||||
|
|
||||||
|
# We pass a port for TCPV6 due to a crash in X11VNC if not here: https://github.com/GNS3/gns3-server/issues/569
|
||||||
|
with open(os.path.join(self.working_dir, "vnc.log"), "w") as fd:
|
||||||
|
self._vnc_process = await asyncio.create_subprocess_exec("x11vnc",
|
||||||
|
"-forever",
|
||||||
|
"-nopw"
|
||||||
|
"-shared",
|
||||||
|
"-geometry", self._console_resolution,
|
||||||
|
"-display", "WAIT:{}".format(self._display),
|
||||||
|
"-rfbport", str(self.console),
|
||||||
|
"-rfbportv6", str(self.console),
|
||||||
|
"-noncache",
|
||||||
|
"-listen", self._manager.port_manager.console_host,
|
||||||
|
stdout=fd, stderr=subprocess.STDOUT)
|
||||||
|
|
||||||
async def _start_vnc(self):
|
async def _start_vnc(self):
|
||||||
"""
|
"""
|
||||||
Starts a VNC server for this container
|
Starts a VNC server for this container
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self._display = self._get_free_display_port()
|
self._display = self._get_free_display_port()
|
||||||
if shutil.which("Xvfb") is None or shutil.which("x11vnc") is None:
|
if not (shutil.which("Xtigervnc") or shutil.which("Xvfb") and shutil.which("x11vnc")):
|
||||||
raise DockerError("Please install Xvfb and x11vnc before using VNC support")
|
raise DockerError("Please install tigervnc-standalone-server (recommended) or Xvfb + x11vnc before using VNC support")
|
||||||
self._xvfb_process = await asyncio.create_subprocess_exec("Xvfb", "-nolisten", "tcp", ":{}".format(self._display), "-screen", "0", self._console_resolution + "x16")
|
await self._start_vnc_process()
|
||||||
# We pass a port for TCPV6 due to a crash in X11VNC if not here: https://github.com/GNS3/gns3-server/issues/569
|
|
||||||
self._x11vnc_process = await asyncio.create_subprocess_exec("x11vnc", "-forever", "-nopw", "-shared", "-geometry", self._console_resolution, "-display", "WAIT:{}".format(self._display), "-rfbport", str(self.console), "-rfbportv6", str(self.console), "-noncache", "-listen", self._manager.port_manager.console_host)
|
|
||||||
x11_socket = os.path.join("/tmp/.X11-unix/", "X{}".format(self._display))
|
x11_socket = os.path.join("/tmp/.X11-unix/", "X{}".format(self._display))
|
||||||
await wait_for_file_creation(x11_socket)
|
await wait_for_file_creation(x11_socket)
|
||||||
|
|
||||||
# sometimes the x11vnc process can crash
|
# sometimes the VNC process can crash
|
||||||
monitor_process(self._x11vnc_process, self._x11vnc_callback)
|
monitor_process(self._vnc_process, self._vnc_callback)
|
||||||
|
|
||||||
def _x11vnc_callback(self, returncode):
|
def _vnc_callback(self, returncode):
|
||||||
"""
|
"""
|
||||||
Called when the process has stopped.
|
Called when the process has stopped.
|
||||||
|
|
||||||
@ -545,8 +583,8 @@ class DockerVM(BaseNode):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if returncode != 0 and self._closing is False:
|
if returncode != 0 and self._closing is False:
|
||||||
self.project.emit("log.error", {"message": "The x11vnc process has stopped with return code {} for node '{}'. Please restart this node.".format(returncode, self.name)})
|
self.project.emit("log.error", {"message": "The vnc process has stopped with return code {} for node '{}'. Please restart this node.".format(returncode, self.name)})
|
||||||
self._x11vnc_process = None
|
self._vnc_process = None
|
||||||
|
|
||||||
async def _start_http(self):
|
async def _start_http(self):
|
||||||
"""
|
"""
|
||||||
@ -731,10 +769,10 @@ class DockerVM(BaseNode):
|
|||||||
await self.stop()
|
await self.stop()
|
||||||
|
|
||||||
if self.console_type == "vnc":
|
if self.console_type == "vnc":
|
||||||
if self._x11vnc_process:
|
if self._vnc_process:
|
||||||
try:
|
try:
|
||||||
self._x11vnc_process.terminate()
|
self._vnc_process.terminate()
|
||||||
await self._x11vnc_process.wait()
|
await self._vnc_process.wait()
|
||||||
except ProcessLookupError:
|
except ProcessLookupError:
|
||||||
pass
|
pass
|
||||||
if self._xvfb_process:
|
if self._xvfb_process:
|
||||||
|
@ -975,12 +975,11 @@ def test_start_vnc(vm, loop):
|
|||||||
with asyncio_patch("asyncio.create_subprocess_exec") as mock_exec:
|
with asyncio_patch("asyncio.create_subprocess_exec") as mock_exec:
|
||||||
loop.run_until_complete(asyncio.ensure_future(vm._start_vnc()))
|
loop.run_until_complete(asyncio.ensure_future(vm._start_vnc()))
|
||||||
assert vm._display is not None
|
assert vm._display is not None
|
||||||
mock_exec.assert_any_call("Xvfb", "-nolisten", "tcp", ":{}".format(vm._display), "-screen", "0", "1280x1024x16")
|
assert mock_exec.call_args[0] == ("Xtigervnc", "-geometry", vm.console_resolution, "-depth", "16", "-interface", "127.0.0.1", "-rfbport", str(vm.console), "-AlwaysShared", "-SecurityTypes", "None", ":{}".format(vm._display))
|
||||||
mock_exec.assert_any_call("x11vnc", "-forever", "-nopw", "-shared", "-geometry", "1280x1024", "-display", "WAIT:{}".format(vm._display), "-rfbport", str(vm.console), "-rfbportv6", str(vm.console), "-noncache", "-listen", "127.0.0.1")
|
|
||||||
mock_wait.assert_called_with("/tmp/.X11-unix/X{}".format(vm._display))
|
mock_wait.assert_called_with("/tmp/.X11-unix/X{}".format(vm._display))
|
||||||
|
|
||||||
|
|
||||||
def test_start_vnc_xvfb_missing(vm, loop):
|
def test_start_vnc_missing(vm, loop):
|
||||||
with pytest.raises(DockerError):
|
with pytest.raises(DockerError):
|
||||||
loop.run_until_complete(asyncio.ensure_future(vm._start_vnc()))
|
loop.run_until_complete(asyncio.ensure_future(vm._start_vnc()))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user