hswaw/checkinator: implement support for kea dhcp server
Also bump version number and fix typo in README.
Change-Id: I116ef706d99df4ace70ccceefc6a23d41fd1adb6
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1942
Reviewed-by: q3k <q3k@hackerspace.pl>
diff --git a/hswaw/checkinator/README.rst b/hswaw/checkinator/README.rst
index e76b600..26de179 100644
--- a/hswaw/checkinator/README.rst
+++ b/hswaw/checkinator/README.rst
@@ -1,4 +1,4 @@
-`Warsaw Hackerspace`_ presence tracker hosted on https://at.hackersapce.pl. It
+`Warsaw Hackerspace`_ presence tracker hosted on https://at.hackerspace.pl. It
uses dhcpd.leases file to track MAC adressess of devices connected to hs LAN
network.
@@ -11,7 +11,7 @@
-----
.. code:: bash
- cp config.yaml.dist config.yaml
+ cp config.dist.yaml config.yaml
cp web-config.yaml.dist web-config.yaml
# edit config files using your favourite editor
diff --git a/hswaw/checkinator/at/dhcp.py b/hswaw/checkinator/at/dhcp.py
index bee2ace..df40dae 100644
--- a/hswaw/checkinator/at/dhcp.py
+++ b/hswaw/checkinator/at/dhcp.py
@@ -140,6 +140,26 @@
lease database. Once this file has been written to disk, the old
file is renamed dhcpd.leases~, and the new file is renamed
dhcpd.leases.
+
+ Kea documentation[0] suggests identical behavior:
+
+ For performance reasons, the server does not update the existing
+ client's lease in the file, as this would potentially require
+ rewriting the entire file. Instead, it simply appends the new lease
+ information to the end of the file; the previous lease entries for
+ the client are not removed.
+
+ [ ... ]
+
+ Lease file cleanup is performed by a separate process (in the
+ background) to avoid a performance impact on the server process. To
+ avoid conflicts between two processes using the same lease files,
+ the LFC process starts with Kea opening a new lease file; the actual
+ LFC process operates on the lease file that is no longer used by the
+ server. There are also other files created as a side effect of the
+ lease file cleanup
+
+ [0]: https://kea.readthedocs.io/en/latest/arm/dhcp4-srv.html#why-is-lease-file-cleanup-necessary
"""
while True:
try:
@@ -232,3 +252,16 @@
offset, devices = parse_isc_dhcpd_leases(f)
self.update(devices)
return offset
+
+class KeaUpdater(MtimeUpdater):
+ def file_changed(self, f):
+ leases = ActiveDevices()
+ for line in f:
+ # header line
+ if(line.startswith('address,')):
+ continue
+ # taken directly from kea leases file header
+ address, hwaddr, client_id, valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, state, user_context, pool_id = line.split(',')
+ leases.add(DhcpLease(hwaddr, int(expire) - int(valid_lifetime), address, hostname))
+ self.update(leases)
+ return f.tell()
diff --git a/hswaw/checkinator/at/tracker.py b/hswaw/checkinator/at/tracker.py
index 4ca71fb..4ec9e70 100644
--- a/hswaw/checkinator/at/tracker.py
+++ b/hswaw/checkinator/at/tracker.py
@@ -1,4 +1,4 @@
-from at.dhcp import DhcpdUpdater, DhcpLease
+from at.dhcp import KeaUpdater, DhcpdUpdater, DhcpLease
from pathlib import Path
import yaml
import grpc
@@ -76,11 +76,14 @@
def server():
args = parser.parse_args()
-
+
config = yaml.safe_load(args.config.read_text())
- tracker = DhcpdUpdater(config['LEASE_FILE'], config['TIMEOUT'])
+ if config['DHCP_SERVER'] == "kea":
+ tracker = KeaUpdater(config['KEA_LEASE_FILE'], config['TIMEOUT'])
+ elif config['DHCP_SERVER'] == "isc" or "DHCP_SERVER" not in config:
+ tracker = DhcpdUpdater(config['LEASE_FILE'], config['TIMEOUT'])
tracker.start()
-
+
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
add_DhcpTrackerServicer_to_server(DhcpTrackerServicer(tracker), server)
diff --git a/hswaw/checkinator/config.dist.yaml b/hswaw/checkinator/config.dist.yaml
index 2582168..7debe95 100644
--- a/hswaw/checkinator/config.dist.yaml
+++ b/hswaw/checkinator/config.dist.yaml
@@ -2,6 +2,9 @@
DEBUG: false
CAP_FILE: './dhcp-cap'
LEASE_FILE: './dhcpd.leases'
+KEA_LEASE_FILE: './dhcp4.leases'
+# optional - specify which dhcp server flavor - isc or kea
+DHCP_SERVER: "isc"
TIMEOUT: 1500
WIKI_URL: 'https://wiki.hackerspace.pl/people:%(login)s:start'
diff --git a/hswaw/checkinator/default.nix b/hswaw/checkinator/default.nix
index c37f9fa..e079602 100644
--- a/hswaw/checkinator/default.nix
+++ b/hswaw/checkinator/default.nix
@@ -8,7 +8,7 @@
}}" {};
in pkgs.python3Packages.buildPythonPackage {
pname = "checkinator";
- version = "0.2";
+ version = "0.3";
doCheck = false;
src = ./.;
diff --git a/hswaw/checkinator/setup.py b/hswaw/checkinator/setup.py
index be35cc5..522f6a3 100644
--- a/hswaw/checkinator/setup.py
+++ b/hswaw/checkinator/setup.py
@@ -23,7 +23,7 @@
setup(
name='hswaw-at',
- version='0.1',
+ version='0.3',
description='warsaw hackerspace checkinator',
packages=['at'],