From 0cd687e03551df86ed960c8c0b9ca56ebc5c7bf6 Mon Sep 17 00:00:00 2001 From: catborise Date: Sun, 1 Nov 2026 14:57:50 +0300 Subject: [PATCH] fix(console): a VNC console stays open while its screen does not change nginx ends a proxied websocket that sends nothing for 60 seconds, and the VNC console sends nothing while the VM's screen stays the same: an idle console, an installer's progress screen, closed after a minute and had to be connected again. novncd now pings the browser every 30 seconds. The SSH tunnel of an SSH compute sends a keepalive as often, for a firewall on the way that ends idle connections. --- console/novncd | 3 +++ console/sshtunnels.py | 4 +++- console/tests/test_sshtunnels.py | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/console/novncd b/console/novncd index 7ae4299d..83fd94c0 100755 --- a/console/novncd +++ b/console/novncd @@ -165,4 +165,7 @@ if __name__ == "__main__": web=False, target_host="ignore", target_port="ignore", + # a ping while the VM's screen stays the same: nginx, and a proxy on + # the way, end a websocket that sends nothing for 60 seconds + heartbeat=30, ).start_server() diff --git a/console/sshtunnels.py b/console/sshtunnels.py index 60e09fe2..14eb64e7 100644 --- a/console/sshtunnels.py +++ b/console/sshtunnels.py @@ -51,7 +51,9 @@ def open_tunnel(host, user, target): """A socket connected to target on host, and the Tunnel carrying it. ssh never asks for anything: a missing key or an unknown host key fails.""" ours, theirs = socket.socketpair() - argv = ["ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=10", "-W", target] + # ServerAliveInterval: a console whose screen stays the same sends nothing, + # and a firewall on the way may end an idle connection + argv = ["ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=10", "-o", "ServerAliveInterval=30", "-W", target] if user: argv += ["-l", user] tunnel = Tunnel(argv + ["--", host], theirs) diff --git a/console/tests/test_sshtunnels.py b/console/tests/test_sshtunnels.py index a8e50687..c842a000 100644 --- a/console/tests/test_sshtunnels.py +++ b/console/tests/test_sshtunnels.py @@ -15,7 +15,7 @@ class SshTunnelTests(TestCase): sock, tunnel = sshtunnels.open_tunnel("kvm1.example.com", "root", "127.0.0.1:5900") sock.close() self.assertEqual(popen.call_args.args[0], [ - "ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=10", "-W", "127.0.0.1:5900", + "ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=10", "-o", "ServerAliveInterval=30", "-W", "127.0.0.1:5900", "-l", "root", "--", "kvm1.example.com"]) self.assertIs(tunnel.process, popen.return_value)