The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/pylxd/pull/211
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === I've been receiving the too many open files issue pointed out in Issue #206 using lxd to run containers in a testing environment. This is a simple patch that prevents exhausting file descriptors after "too many" calls to execute. Not sure if this is the greatest approach but it's a simple fix.
From b1e160b002b535daf2cff80d58a27cf9d548c572 Mon Sep 17 00:00:00 2001 From: Tosh Lyons <tosh...@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' + + +@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.
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel