Support Xtigervnc restart.

This commit is contained in:
grossmj 2018-11-11 23:23:30 +08:00
parent 36474f7bab
commit d45d52f15c
2 changed files with 24 additions and 18 deletions

View File

@ -83,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
@ -424,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()
@ -521,15 +522,11 @@ 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(self): async def _start_vnc_process(self, restart=False):
""" """
Starts a VNC server for this container Starts the VNC process.
""" """
self._display = self._get_free_display_port()
if not (shutil.which("Xtigervnc") or shutil.which("Xvfb") and shutil.which("x11vnc")):
raise DockerError("Please install tigervnc-standalone-server (recommended) or Xvfb + x11vnc before using VNC support")
if shutil.which("Xtigervnc"): if shutil.which("Xtigervnc"):
with open(os.path.join(self.working_dir, "vnc.log"), "w") as fd: with open(os.path.join(self.working_dir, "vnc.log"), "w") as fd:
self._vnc_process = await asyncio.create_subprocess_exec("Xtigervnc", self._vnc_process = await asyncio.create_subprocess_exec("Xtigervnc",
@ -542,6 +539,7 @@ class DockerVM(BaseNode):
":{}".format(self._display), ":{}".format(self._display),
stdout=fd, stderr=subprocess.STDOUT) stdout=fd, stderr=subprocess.STDOUT)
else: else:
if restart is False:
self._xvfb_process = await asyncio.create_subprocess_exec("Xvfb", self._xvfb_process = await asyncio.create_subprocess_exec("Xvfb",
"-nolisten", "-nolisten",
"tcp", ":{}".format(self._display), "tcp", ":{}".format(self._display),
@ -562,6 +560,15 @@ class DockerVM(BaseNode):
"-listen", self._manager.port_manager.console_host, "-listen", self._manager.port_manager.console_host,
stdout=fd, stderr=subprocess.STDOUT) stdout=fd, stderr=subprocess.STDOUT)
async def _start_vnc(self):
"""
Starts a VNC server for this container
"""
self._display = self._get_free_display_port()
if not (shutil.which("Xtigervnc") or shutil.which("Xvfb") and shutil.which("x11vnc")):
raise DockerError("Please install tigervnc-standalone-server (recommended) or Xvfb + x11vnc before using VNC support")
await self._start_vnc_process()
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)

View File

@ -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()))