Only initialize Docker Client when necessary

This commit is contained in:
2021-02-09 16:02:01 +01:00
parent a260d2fedb
commit b6ff5e4650
+29 -13
View File
@@ -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()