From b6ff5e4650acd02edaece23025ad8b0b76a1252e Mon Sep 17 00:00:00 2001 From: JDierkse Date: Tue, 9 Feb 2021 16:02:01 +0100 Subject: [PATCH] Only initialize Docker Client when necessary --- net-dhcp/network.py | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/net-dhcp/network.py b/net-dhcp/network.py index ea11af0..ddaa794 100644 --- a/net-dhcp/network.py +++ b/net-dhcp/network.py @@ -25,10 +25,19 @@ logger = logging.getLogger('net-dhcp') interface.InitializeLibrary(LIBRARY) -client = docker.from_env() +dockerClient = None + +def get_docker_client(): + global dockerClient + if dockerClient is None: + dockerClient = docker.from_env() + @atexit.register -def close_docker(): - client.close() +def close_docker_client(): + global dockerClient + if dockerClient is not None: + dockerClient.close() + dockerClient = None gateway_hints = {} container_dhcp_clients = {} @@ -43,28 +52,34 @@ def veth_pair(e): def iface_addrs(iface): return list(map(lambda a: ipaddress.ip_interface((a['address'], a['prefixlen'])), iface.ipaddr)) + def iface_nets(iface): return list(map(lambda n: n.network, iface_addrs(iface))) def get_bridges(): + get_docker_client() reserved_nets = set(map(ipaddress.ip_network, map(lambda c: c['Subnet'], \ itertools.chain.from_iterable(map(lambda i: i['Config'], filter(lambda i: i['Driver'] != 'net-dhcp', \ - map(lambda n: n.attrs['IPAM'], client.networks.list()))))))) + map(lambda n: n.attrs['IPAM'], dockerClient.networks.list()))))))) return dict(map(lambda i: (i['ifname'], i), filter(lambda i: i['kind'] == 'bridge' and not \ set(iface_nets(i)).intersection(reserved_nets), map(lambda i: interface.GetInterface(LIBRARY, i['ifname']), \ interface.GetInterfaces(LIBRARY))))) def net_bridge(n): - return interface.GetInterface(LIBRARY, client.networks.get(n).attrs['Options'][OPT_BRIDGE]) + get_docker_client() + return interface.GetInterface(LIBRARY, dockerClient.networks.get(n).attrs['Options'][OPT_BRIDGE]) + def ipv6_enabled(n): - options = client.networks.get(n).attrs['Options'] + get_docker_client() + options = dockerClient.networks.get(n).attrs['Options'] return OPT_IPV6 in options and options[OPT_IPV6] == 'true' def endpoint_container_iface(n, e): - for cid, info in client.networks.get(n).attrs['Containers'].items(): + get_docker_client() + for cid, info in dockerClient.networks.get(n).attrs['Containers'].items(): if info['EndpointID'] == e: - container = client.containers.get(cid) + container = dockerClient.containers.get(cid) netns = f'/proc/{container.attrs["State"]["Pid"]}/ns/net' with pyroute2.NetNS(netns) as rtnl: @@ -91,9 +106,10 @@ def await_endpoint_container_iface(n, e, timeout=5): return iface def endpoint_container_hostname(n, e): - for cid, info in client.networks.get(n).attrs['Containers'].items(): + get_docker_client() + for cid, info in dockerClient.networks.get(n).attrs['Containers'].items(): if info['EndpointID'] == e: - return client.containers.get(cid).attrs['Config']['Hostname'] + return dockerClient.containers.get(cid).attrs['Config']['Hostname'] return None @app.route('/NetworkDriver.GetCapabilities', methods=['POST']) @@ -378,6 +394,6 @@ class ContainerDHCPManager: self._thread.join() # we have to do this since the docker client leaks sockets... - global client - client.close() - client = docker.from_env() + close_docker_client() + get_docker_client() +