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..5719ae5 --- /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/smd.py b/dnsmasq-dhcpd-dynamic/smd.py index 153167b..bfae6f5 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 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. #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 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") - f.close() + if sighup: + print("newfile!") + sys.exit(1) + else: + sys.exit(0) if __name__ == "__main__": main() - diff --git a/dnsmasq-dhcpd-dynamic/update_loop.sh b/dnsmasq-dhcpd-dynamic/update_loop.sh new file mode 100644 index 0000000..a86ab55 --- /dev/null +++ b/dnsmasq-dhcpd-dynamic/update_loop.sh @@ -0,0 +1,9 @@ +while true +do + smd.py + rc=$? + if [$rc -e 1]; then + kill -1 $(pgrep dnsmasq) + fi + sleep 10 +done