diff --git a/conf/daemon/consolecallback b/conf/daemon/consolecallback index d079956b..e70b6241 100755 --- a/conf/daemon/consolecallback +++ b/conf/daemon/consolecallback @@ -28,9 +28,6 @@ from instances.utils import can_open_console # noqa: E402 from operations.utils import public_error_text # noqa: E402 from vrtManager.connection import connection_manager # noqa: E402 -# libvirt prints its errors on stderr, which is the user's terminal: they are -# raised and told in one line instead -libvirt.registerErrorHandler(lambda context, error: None, None) SEND_WAIT = 5 # seconds a paste may wait for the VM to take it ACCESS_CHECK = 10 # seconds between checks that the user may still use the console diff --git a/vrtManager/connection.py b/vrtManager/connection.py index 6c430419..7f19059c 100644 --- a/vrtManager/connection.py +++ b/vrtManager/connection.py @@ -58,6 +58,10 @@ CLOSE_REASONS = { SSH_COMMAND = os.path.join(os.path.dirname(os.path.abspath(__file__)), "libvirt-ssh") logger = logging.getLogger(__name__) +# libvirt prints each error on stderr without saying where it came from; every +# process that talks to libvirt imports this module. The errors are raised to +# the callers, which handle or report them. +libvirt.registerErrorHandler(lambda context, error: None, None) class wvmEventLoop(threading.Thread): diff --git a/vrtManager/tests/test_connection.py b/vrtManager/tests/test_connection.py index c876d128..daec0f5c 100644 --- a/vrtManager/tests/test_connection.py +++ b/vrtManager/tests/test_connection.py @@ -3,6 +3,8 @@ import contextlib import os import socket +import subprocess +import sys import threading import time import unittest @@ -410,3 +412,14 @@ class EventLoopTestCase(unittest.TestCase): if __name__ == "__main__": unittest.main() + + +class LibvirtStderrTestCase(unittest.TestCase): + def test_a_libvirt_error_is_not_printed_on_stderr(self): + script = ( + "from django.conf import settings; settings.configure(); " + "import libvirt, vrtManager.connection\n" + "try:\n libvirt.open('test:///default').lookupByName('no-such-vm')\nexcept libvirt.libvirtError:\n pass" + ) + result = subprocess.run([sys.executable, "-c", script], cwd=os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), capture_output=True, text=True) + self.assertEqual((result.returncode, result.stderr), (0, ""))