[lxc-devel] [pylxd/master] Fix execute command missing output with pauses in output text
ajkavanagh on Github
lxc-bot at linuxcontainers.org
Fri May 17 15:07:03 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 728 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190517/a540b83e/attachment.bin>
-------------- next part --------------
From 8010a87cae33bd56c17986f98c3a75ddab3f04dd Mon Sep 17 00:00:00 2001
From: Alex Kavanagh <alex.kavanagh at canonical.com>
Date: Fri, 17 May 2019 16:00:00 +0100
Subject: [PATCH] Fix execute command missing output with pauses in output text
For the container execute command, if the command executed has pauses in
the output text, the websocket will send binary messages. These were
interpreted as the stream being completed, and pylxd closed the
websocket, thus losing the rest of the output.
Delving into the code indicated some very strange behaviour across the
threads, so as part of solving the problem, this has been cleaned up as
well.
Closes: #362
---
pylxd/models/container.py | 38 +++++++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 7 deletions(-)
diff --git a/pylxd/models/container.py b/pylxd/models/container.py
index cbd8206f..4c4f91e3 100644
--- a/pylxd/models/container.py
+++ b/pylxd/models/container.py
@@ -353,7 +353,7 @@ def unfreeze(self, timeout=30, force=True, wait=False):
def execute(
self, commands, environment={}, encoding=None, decode=True,
stdin_payload=None, stdin_encoding="utf-8",
- stdout_handler=None, stderr_handler=None
+ stdout_handler=None, stderr_handler=None,
):
"""Execute a command on the container.
@@ -430,8 +430,17 @@ def execute(
break
time.sleep(.5) # pragma: no cover
- while len(manager.websockets.values()) > 0:
- time.sleep(.1) # pragma: no cover
+ try:
+ stdin.close()
+ except BrokenPipeError:
+ pass
+
+ stdout.finish_soon()
+ stderr.finish_soon()
+ manager.close_all()
+
+ while not stdout.finished or not stderr.finished:
+ time.sleep(.1) # progma: no cover
manager.stop()
manager.join()
@@ -618,6 +627,9 @@ def __init__(self, manager, *args, **kwargs):
self.encoding = kwargs.pop('encoding', None)
self.handler = kwargs.pop('handler', None)
self.message_encoding = None
+ self.finish_off = False
+ self.finished = False
+ self.last_message_empty = False
super(_CommandWebsocketClient, self).__init__(*args, **kwargs)
def handshake_ok(self):
@@ -626,15 +638,27 @@ def handshake_ok(self):
def received_message(self, message):
if message.data is None or len(message.data) == 0:
- self.manager.remove(self)
- return
+ self.last_message_empty = True
+ if self.finish_off:
+ self.finished = True
+ return
+ else:
+ self.last_message_empty = False
if message.encoding and self.message_encoding is None:
self.message_encoding = message.encoding
if self.handler:
self.handler(self._maybe_decode(message.data))
self.buffer.append(message.data)
- if isinstance(message, BinaryMessage):
- self.manager.remove(self)
+ if self.finish_off and isinstance(message, BinaryMessage):
+ self.finished = True
+
+ def closed(self, code, reason=None):
+ self.finished = True
+
+ def finish_soon(self):
+ self.finish_off = True
+ if self.last_message_empty:
+ self.finished = True
def _maybe_decode(self, buffer):
if self.decode and buffer is not None:
More information about the lxc-devel
mailing list