From 2902f9dbb859342f87e1ee5fab1b2d197216c1eb Mon Sep 17 00:00:00 2001 From: Nicholas Jones Date: Thu, 15 Feb 2024 13:25:05 -0700 Subject: [PATCH 1/7] added first draft for dynamic updating --- dnsmasq-dhcpd-dynamic/Dockerfile | 4 +++- dnsmasq-dhcpd-dynamic/init.sh | 3 +++ dnsmasq-dhcpd-dynamic/update_loop.sh | 7 +++++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 dnsmasq-dhcpd-dynamic/init.sh create mode 100644 dnsmasq-dhcpd-dynamic/update_loop.sh diff --git a/dnsmasq-dhcpd-dynamic/Dockerfile b/dnsmasq-dhcpd-dynamic/Dockerfile index 17ef680..579d71a 100644 --- a/dnsmasq-dhcpd-dynamic/Dockerfile +++ b/dnsmasq-dhcpd-dynamic/Dockerfile @@ -2,8 +2,10 @@ FROM rockylinux:8.9 RUN dnf install -y dnsmasq procps-ng ipxe-bootimgs-x86 python3 python3-pip; dnf clean all; COPY --chmod=644 --chown=dnsmasq:dnsmasq dnsmasq.conf /etc/dnsmasq.conf COPY --chmod=555 --chown=dnsmasq:dnsmasq smd.py /bin/smd.py +COPY --chmod=555 --chown=dnsmasq:dnsmasq init.sh /bin/init.sh +COPY --chmod=555 --chown=dnsmasq:dnsmasq update_loop.sh /bin/update_loop.sh RUN pip3 install requests EXPOSE 67/udp -ENTRYPOINT smd.py && dnsmasq -k -d --log-dhcp +ENTRYPOINT init.sh diff --git a/dnsmasq-dhcpd-dynamic/init.sh b/dnsmasq-dhcpd-dynamic/init.sh new file mode 100644 index 0000000..af62577 --- /dev/null +++ b/dnsmasq-dhcpd-dynamic/init.sh @@ -0,0 +1,3 @@ +./smd.py +./update_loop.sh & +dnsmasq -k -d --log-dhcp diff --git a/dnsmasq-dhcpd-dynamic/update_loop.sh b/dnsmasq-dhcpd-dynamic/update_loop.sh new file mode 100644 index 0000000..965f9fd --- /dev/null +++ b/dnsmasq-dhcpd-dynamic/update_loop.sh @@ -0,0 +1,7 @@ +while true +do + smd.py + #TODO we should probably only kill on smd.py finding a change + kill -1 $(pgrep dnsmasq) + sleep 10 +done From 6721969977a9da8d7b568d89815e78d81879cf03 Mon Sep 17 00:00:00 2001 From: Travis Cotton Date: Thu, 15 Feb 2024 13:43:48 -0700 Subject: [PATCH 2/7] fixed init.sh to run smd.py and the loop script that are in /bin --- dnsmasq-dhcpd-dynamic/init.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsmasq-dhcpd-dynamic/init.sh b/dnsmasq-dhcpd-dynamic/init.sh index af62577..5719ae5 100644 --- a/dnsmasq-dhcpd-dynamic/init.sh +++ b/dnsmasq-dhcpd-dynamic/init.sh @@ -1,3 +1,3 @@ -./smd.py -./update_loop.sh & +smd.py +update_loop.sh & dnsmasq -k -d --log-dhcp From 980da7944ae1fde62f1be77da7d2a929158e2f09 Mon Sep 17 00:00:00 2001 From: Nicholas Jones Date: Thu, 15 Feb 2024 15:37:09 -0700 Subject: [PATCH 3/7] updated smd script to be friendlier to dynanic updating --- dnsmasq-dhcpd-dynamic/smd.py | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/dnsmasq-dhcpd-dynamic/smd.py b/dnsmasq-dhcpd-dynamic/smd.py index 153167b..3b2f336 100644 --- a/dnsmasq-dhcpd-dynamic/smd.py +++ b/dnsmasq-dhcpd-dynamic/smd.py @@ -1,7 +1,10 @@ #!/usr/bin/env python3 import requests import os - +import filecmp +import shutil +import sys +import tempfile def getSMD(url): r = requests.get(url) data = r.json() @@ -9,29 +12,42 @@ def getSMD(url): def main(): + sighup = False smd_endpoint=os.environ['smd_endpoint'] bss_endpoint=os.environ['bss_endpoint'] ei_data = getSMD(f'http://{smd_endpoint}:27779/hsm/v2/Inventory/EthernetInterfaces') - f = open("/etc/dhcp-hostsfile","w") + #hostsfile = tempfile.TemporaryFile(mode = "r+") + hostsfile = open("/etc/dhcp-hostsfile-new", "w") #this for loop writes host entries for i in ei_data: if i['Type'] != 'NodeBMC': - print(f"{i['MACAddress']},set:{i['ComponentID']},{i['IPAddresses'][0]['IPAddress']},{i['ComponentID']}", file=f) + print(f"{i['MACAddress']},set:{i['ComponentID']},{i['IPAddresses'][0]['IPAddress']},{i['ComponentID']}", file=hostsfile) else: - print(f"{i['MACAddress']},{i['IPAddresses'][0]['IPAddress']},{i['ComponentID']}", file=f) - f.close() + print(f"{i['MACAddress']},{i['IPAddresses'][0]['IPAddress']},{i['ComponentID']}", file=hostsfile) + hostsfile.close() + if filecmp.cmp("/etc/dhcp-hostsfile-new", "/etc/dhcp-hostsfile") == False: + sighup = True + shutil.copyfile("/etc/dhcp-hostsfile-new", "/etc/dhcp-hostsfile") #TODO actually map all the BMCs straight from redfish, instead of creating dummy endpoints for them. #rf_data = getSMD(f'http://{smd_endpoint}:27779/hsm/v2/Inventory/RedfishEndpoints') #for r in rf_data['RedfishEndpoints']: # print(r['ID'] + ' ' + r['IPAddress']) - f = open("/etc/dhcp-optsfile", "w") + #optsfile = tempfile.TemporaryFile(mode = "r+") + optsfile = open("/etc/dhcp-optsfile-new", "w") #this for loop writes option entries, we wouldn't need it if the BSS wasn't MAC specific for i in ei_data: if 'bmc' not in i['Description']: - print(f"tag:{i['ComponentID']},tag:IPXEBOOT,option:bootfile-name,\"http://{bss_endpoint}:27778/boot/v1/bootscript?mac={i['MACAddress']}\"", file=f) + print(f"tag:{i['ComponentID']},tag:IPXEBOOT,option:bootfile-name,\"http://{bss_endpoint}:27778/boot/v1/bootscript?mac={i['MACAddress']}\"", file=optsfile) + optsfile.close() + if filecmp.cmp("/etc/dhcp-optsfile-new","/etc/dhcp-optsfile") == False: + sighup = True + shutil.copyfile(optsfile.name, "/etc/dhcp-optsfile") - f.close() + if sighup: + print("newfile!") + sys.exit(1) + else: + sys.exit(0) if __name__ == "__main__": main() - From 836fe5501d62b6bb7d166828c762a7ee811e50c0 Mon Sep 17 00:00:00 2001 From: Nicholas Jones Date: Thu, 15 Feb 2024 15:54:21 -0700 Subject: [PATCH 4/7] added file check for hosts file and opts file --- dnsmasq-dhcpd-dynamic/smd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsmasq-dhcpd-dynamic/smd.py b/dnsmasq-dhcpd-dynamic/smd.py index 3b2f336..ea62147 100644 --- a/dnsmasq-dhcpd-dynamic/smd.py +++ b/dnsmasq-dhcpd-dynamic/smd.py @@ -25,7 +25,7 @@ def main(): else: print(f"{i['MACAddress']},{i['IPAddresses'][0]['IPAddress']},{i['ComponentID']}", file=hostsfile) hostsfile.close() - if filecmp.cmp("/etc/dhcp-hostsfile-new", "/etc/dhcp-hostsfile") == False: + if os.path.isfile("/etc/dhcp-hostsfile-new") == False or filecmp.cmp("/etc/dhcp-hostsfile-new", "/etc/dhcp-hostsfile") == False: sighup = True shutil.copyfile("/etc/dhcp-hostsfile-new", "/etc/dhcp-hostsfile") #TODO actually map all the BMCs straight from redfish, instead of creating dummy endpoints for them. @@ -39,7 +39,7 @@ def main(): if 'bmc' not in i['Description']: print(f"tag:{i['ComponentID']},tag:IPXEBOOT,option:bootfile-name,\"http://{bss_endpoint}:27778/boot/v1/bootscript?mac={i['MACAddress']}\"", file=optsfile) optsfile.close() - if filecmp.cmp("/etc/dhcp-optsfile-new","/etc/dhcp-optsfile") == False: + if os.path.isfile("/etc/dhcp-optsfile-new") == False or filecmp.cmp("/etc/dhcp-optsfile-new","/etc/dhcp-optsfile") == False: sighup = True shutil.copyfile(optsfile.name, "/etc/dhcp-optsfile") From 52cc91ac83b5644a3dc7a14c8f8e9fc132c802db Mon Sep 17 00:00:00 2001 From: Nicholas Jones Date: Thu, 15 Feb 2024 16:02:27 -0700 Subject: [PATCH 5/7] path fix on short circuit or --- dnsmasq-dhcpd-dynamic/smd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsmasq-dhcpd-dynamic/smd.py b/dnsmasq-dhcpd-dynamic/smd.py index ea62147..bfae6f5 100644 --- a/dnsmasq-dhcpd-dynamic/smd.py +++ b/dnsmasq-dhcpd-dynamic/smd.py @@ -25,7 +25,7 @@ def main(): else: print(f"{i['MACAddress']},{i['IPAddresses'][0]['IPAddress']},{i['ComponentID']}", file=hostsfile) hostsfile.close() - if os.path.isfile("/etc/dhcp-hostsfile-new") == False or filecmp.cmp("/etc/dhcp-hostsfile-new", "/etc/dhcp-hostsfile") == False: + if os.path.isfile("/etc/dhcp-hostsfile") == False or filecmp.cmp("/etc/dhcp-hostsfile-new", "/etc/dhcp-hostsfile") == False: sighup = True shutil.copyfile("/etc/dhcp-hostsfile-new", "/etc/dhcp-hostsfile") #TODO actually map all the BMCs straight from redfish, instead of creating dummy endpoints for them. @@ -39,7 +39,7 @@ def main(): if 'bmc' not in i['Description']: print(f"tag:{i['ComponentID']},tag:IPXEBOOT,option:bootfile-name,\"http://{bss_endpoint}:27778/boot/v1/bootscript?mac={i['MACAddress']}\"", file=optsfile) optsfile.close() - if os.path.isfile("/etc/dhcp-optsfile-new") == False or filecmp.cmp("/etc/dhcp-optsfile-new","/etc/dhcp-optsfile") == False: + if os.path.isfile("/etc/dhcp-optsfile") == False or filecmp.cmp("/etc/dhcp-optsfile-new","/etc/dhcp-optsfile") == False: sighup = True shutil.copyfile(optsfile.name, "/etc/dhcp-optsfile") From b38719b5ce2c2cf6e55c8c6010df63ce578c9437 Mon Sep 17 00:00:00 2001 From: Travis Cotton Date: Thu, 15 Feb 2024 16:21:30 -0700 Subject: [PATCH 6/7] remove sighup from update loop --- dnsmasq-dhcpd-dynamic/update_loop.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsmasq-dhcpd-dynamic/update_loop.sh b/dnsmasq-dhcpd-dynamic/update_loop.sh index 965f9fd..38e8c7c 100644 --- a/dnsmasq-dhcpd-dynamic/update_loop.sh +++ b/dnsmasq-dhcpd-dynamic/update_loop.sh @@ -2,6 +2,5 @@ while true do smd.py #TODO we should probably only kill on smd.py finding a change - kill -1 $(pgrep dnsmasq) sleep 10 done From 94533fd829d101669cbb2647ca7bfa60fab82a23 Mon Sep 17 00:00:00 2001 From: Nicholas Jones Date: Tue, 20 Feb 2024 07:51:04 -0700 Subject: [PATCH 7/7] added check for sighuping dnsmasq --- dnsmasq-dhcpd-dynamic/update_loop.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dnsmasq-dhcpd-dynamic/update_loop.sh b/dnsmasq-dhcpd-dynamic/update_loop.sh index 38e8c7c..a86ab55 100644 --- a/dnsmasq-dhcpd-dynamic/update_loop.sh +++ b/dnsmasq-dhcpd-dynamic/update_loop.sh @@ -1,6 +1,9 @@ while true do smd.py - #TODO we should probably only kill on smd.py finding a change + rc=$? + if [$rc -e 1]; then + kill -1 $(pgrep dnsmasq) + fi sleep 10 done