Improve udhcpc event handling

This commit is contained in:
Jack O'Sullivan 2019-08-26 09:30:38 +01:00
parent d9772c3ef7
commit 55070e3a6a
2 changed files with 35 additions and 21 deletions

View File

@ -1,5 +1,6 @@
from enum import Enum
import ipaddress
import json
import os
from os import path
from select import select
@ -57,11 +58,14 @@ class DHCPClient:
self._event_thread = threading.Thread(target=self._read_events)
self._event_thread.start()
def _attr_listener(self, event_type, args):
def _attr_listener(self, event_type, event):
if event_type in (EventType.BOUND, EventType.RENEW):
self.ip = ipaddress.ip_interface(args[0])
self.gateway = ipaddress.ip_address(args[1])
self.domain = args[2]
self.ip = ipaddress.ip_interface(event['ip'])
if 'gateway' in event:
self.gateway = ipaddress.ip_address(event['gateway'])
else:
self.gateway = None
self.domain = event.get('domain')
self._has_lease.set()
elif event_type == EventType.DECONFIG:
self._has_lease.clear()
@ -76,24 +80,32 @@ class DHCPClient:
break
msg, _priority = self._event_queue.receive()
args = msg.decode('utf-8').split(' ')
event = json.loads(msg.decode('utf-8'))
try:
event_type = EventType(args[0])
event['type'] = EventType(event['type'])
except ValueError:
logger.warning('udhcpc#%d unknown event "%s"', self.proc.pid, args)
logger.warning('udhcpc#%d unknown event "%s"', self.proc.pid, event)
continue
logger.debug('[udhcp#%d event] %s %s', self.proc.pid, event_type, args[1:])
logger.debug('[udhcp#%d event] %s', self.proc.pid, event)
for listener in self.event_listeners:
listener(self, event_type, args[1:])
try:
listener(self, event['type'], event)
except Exception as ex:
logger.exception(ex)
def await_ip(self, timeout=5):
def await_ip(self, timeout=10):
if not self._has_lease.wait(timeout=timeout):
raise DHCPClientError('Timed out waiting for dhcp lease')
return self.ip
def finish(self, timeout=5):
if self._shutdown_event.is_set():
return
if self.proc.returncode != None and (not self.once or self.proc.returncode != 0):
raise DHCPClientError(f'udhcpc exited early with code {self.proc.returncode}')
if self.once:
self.await_ip()
else:

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python
import json
import sys
from os import environ as env
@ -8,17 +9,18 @@ if __name__ != '__main__':
print('You shouldn\'t be importing this script!')
sys.exit(1)
event_type = sys.argv[1]
if event_type in ('bound', 'renew'):
event = f'{event_type} {env["ip"]}/{env["mask"]} {env["router"]} {env["domain"]}'
elif event_type in ('deconfig', 'leasefail', 'nak'):
event = event_type
event = {'type': sys.argv[1]}
if event['type'] in ('bound', 'renew'):
event['ip'] = env['ip']
if 'router' in env:
event['router'] = env['router']
if 'domain' in env:
event['domain'] = env['domain']
elif event['type'] in ('deconfig', 'leasefail', 'nak'):
pass
else:
print(f'unknown udhcpc event "{event_type}"')
sys.exit(1)
event['type'] = 'unknown'
#with open(env['EVENT_FILE'], 'a') as event_file:
# event_file.write(event + '\n')
queue = posix_ipc.MessageQueue(env['EVENT_QUEUE'])
queue.send(event)
queue.send(json.dumps(event))
queue.close()