1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-09 03:36:48 +00:00

fix(instances): a gstfsd host that is down is told in 5 seconds

gstfsd_request connected with the 120 seconds it waits for the change:
a host that was down held the request's thread two minutes before its
page said so, a wait no host bound counts. It now connects within
libvirt's CONNECT_TIMEOUT and gives the change its 120 seconds after.
This commit is contained in:
catborise 2026-11-05 10:52:16 +03:00
parent e117345e56
commit 42a3ba71fd
2 changed files with 23 additions and 1 deletions

View file

@ -610,6 +610,25 @@ class GstfsdClientTestCase(unittest.TestCase):
with self.subTest(name), self.assertRaises(OperationError):
self.ask(*sent)
def test_a_host_that_does_not_answer_is_told_in_the_connect_timeout(self):
from unittest.mock import MagicMock, patch
from instances import views
from vrtManager.connection import CONNECT_TIMEOUT
from vrtManager.util import OperationError
with patch("instances.views.socket.create_connection", side_effect=TimeoutError("timed out")) as connect:
with self.assertRaisesRegex(OperationError, "gstfsd error: timed out"):
views.gstfsd_request(SimpleNamespace(name="host-a", hostname="192.0.2.1", gstfsd_key="ab" * 32), {})
self.assertEqual(connect.call_args.kwargs["timeout"], CONNECT_TIMEOUT)
# the change itself, once connected, has its own, longer limit
connected = MagicMock()
connected.makefile.return_value.readline.side_effect = OSError("closed")
with patch("instances.views.socket.create_connection", return_value=connected), \
self.assertRaises(OperationError):
views.gstfsd_request(SimpleNamespace(name="host-a", hostname="192.0.2.1", gstfsd_key="ab" * 32), {})
connected.settimeout.assert_called_once_with(views.GSTFSD_TIMEOUT)
def test_a_host_without_a_key_is_not_asked(self):
from unittest.mock import patch

View file

@ -54,6 +54,7 @@ from operations import claims, jobs
from operations.utils import busy_message, summary
from webvirtcloud.middleware import error_text, same_origin_referer
from vrtManager import util
from vrtManager.connection import CONNECT_TIMEOUT
from vrtManager.create import cpu_choices, wvmCreate
from vrtManager.instance import USAGE_MAX_WINDOW, wvmInstances
from vrtManager.interface import wvmInterface
@ -1026,10 +1027,12 @@ def gstfsd_request(compute, data):
"compute": compute.name})
try:
# the host name may resolve to IPv4 or IPv6
s = socket.create_connection((compute.hostname, GSTFSD_PORT), timeout=GSTFSD_TIMEOUT)
# a host that is down is told in seconds, as libvirt's; the change itself may take GSTFSD_TIMEOUT
s = socket.create_connection((compute.hostname, GSTFSD_PORT), timeout=CONNECT_TIMEOUT)
except OSError as err:
raise util.OperationError(_("gstfsd error: %(err)s") % {"err": err}) from err
try:
s.settimeout(GSTFSD_TIMEOUT)
stream = s.makefile("rb")
challenge = json.loads(stream.readline(GSTFSD_MAX_FRAME))["challenge"]
nonce, request = secrets.token_hex(32), json.dumps(data)