[lxc-devel] [pylxd/master] Add websocket context manager

toshism on Github lxc-bot at linuxcontainers.org
Thu Dec 15 16:23:57 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 600 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20161215/59b84cf9/attachment.bin>
-------------- next part --------------
From b1e160b002b535daf2cff80d58a27cf9d548c572 Mon Sep 17 00:00:00 2001
From: Tosh Lyons <toshism at gmail.com>
Date: Thu, 15 Dec 2016 11:06:10 -0500
Subject: [PATCH] add websocket context manager to clean up after itself

this prevents exhausting file descriptors after "too many" calls to execute
---
 pylxd/managers.py         | 10 ++++++++++
 pylxd/models/container.py | 34 ++++++++++++++++++----------------
 2 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/pylxd/managers.py b/pylxd/managers.py
index 6a06971..c67e781 100644
--- a/pylxd/managers.py
+++ b/pylxd/managers.py
@@ -1,3 +1,5 @@
+from contextlib import contextmanager
+
 import functools
 import importlib
 import inspect
@@ -51,3 +53,11 @@ class ProfileManager(BaseManager):
 
 class SnapshotManager(BaseManager):
     manager_for = 'pylxd.models.Snapshot'
+
+
+ at contextmanager
+def web_socket_manager(manager):
+    try:
+        yield manager
+    finally:
+        manager.stop()
diff --git a/pylxd/models/container.py b/pylxd/models/container.py
index fde1b6b..11bce39 100644
--- a/pylxd/models/container.py
+++ b/pylxd/models/container.py
@@ -200,6 +200,7 @@ def unfreeze(self, timeout=30, force=True, wait=False):
                                force=force,
                                wait=wait)
 
+
     def execute(self, commands, environment={}):
         """Execute a command on the container.
 
@@ -223,26 +224,27 @@ def execute(self, commands, environment={}):
         parsed = parse.urlparse(
             self.client.api.operations[operation_id].websocket._api_endpoint)
 
-        manager = WebSocketManager()
+        with managers.web_socket_manager(WebSocketManager()) as manager:
+            stdin = _StdinWebsocket(self.client.websocket_url)
+            stdin.resource = '{}?secret={}'.format(parsed.path, fds['0'])
+            stdin.connect()
+            stdout = _CommandWebsocketClient(manager, self.client.websocket_url)
+            stdout.resource = '{}?secret={}'.format(parsed.path, fds['1'])
+            stdout.connect()
+            stderr = _CommandWebsocketClient(manager, self.client.websocket_url)
+            stderr.resource = '{}?secret={}'.format(parsed.path, fds['2'])
+            stderr.connect()
+
+            manager.start()
 
-        stdin = _StdinWebsocket(self.client.websocket_url)
-        stdin.resource = '{}?secret={}'.format(parsed.path, fds['0'])
-        stdin.connect()
-        stdout = _CommandWebsocketClient(manager, self.client.websocket_url)
-        stdout.resource = '{}?secret={}'.format(parsed.path, fds['1'])
-        stdout.connect()
-        stderr = _CommandWebsocketClient(manager, self.client.websocket_url)
-        stderr.resource = '{}?secret={}'.format(parsed.path, fds['2'])
-        stderr.connect()
+            while len(manager.websockets.values()) > 0:
+                time.sleep(.1)
 
-        manager.start()
+            operation = self.client.operations.get(operation_id)
 
-        while len(manager.websockets.values()) > 0:
-            time.sleep(.1)
+            return _ContainerExecuteResult(
+                operation.metadata['return'], stdout.data, stderr.data)
 
-        operation = self.client.operations.get(operation_id)
-        return _ContainerExecuteResult(
-            operation.metadata['return'], stdout.data, stderr.data)
 
     def migrate(self, new_client, wait=False):
         """Migrate a container.


More information about the lxc-devel mailing list