Joshua M. Boniface
379262a74f
Adds the PVC Bootstrap system, which allows the automated deployment of one or more PVC clusters.
100 lines
3.9 KiB
Python
Executable File
100 lines
3.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# dnsmasq.py - PVC Cluster Auto-bootstrap DNSMasq instance
|
|
# Part of the Parallel Virtual Cluster (PVC) system
|
|
#
|
|
# Copyright (C) 2018-2021 Joshua M. Boniface <joshua@boniface.me>
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, version 3.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
#
|
|
###############################################################################
|
|
|
|
import os
|
|
import subprocess
|
|
import signal
|
|
|
|
from threading import Thread
|
|
|
|
|
|
class DNSMasq:
|
|
"""
|
|
Implementes a daemonized instance of DNSMasq for providing DHCP and TFTP services
|
|
|
|
The DNSMasq instance listens on the configured 'dhcp_address', and instead of a "real"
|
|
leases database forwards requests to the 'dnsmasq-lease.py' script. This script will
|
|
then hit the pvcbootstrapd '/checkin' API endpoint to perform actions.
|
|
|
|
TFTP is provided to automate the bootstrap of a node, providing the pvc-installer
|
|
over TFTP as well as a seed configuration which is created by the API.
|
|
"""
|
|
|
|
def __init__(self, config):
|
|
self.environment = {
|
|
"API_URI": f"http://{config['api_address']}:{config['api_port']}/checkin/dnsmasq"
|
|
}
|
|
self.dnsmasq_cmd = [
|
|
"/usr/sbin/dnsmasq",
|
|
"--bogus-priv",
|
|
"--no-hosts",
|
|
"--dhcp-authoritative",
|
|
"--filterwin2k",
|
|
"--expand-hosts",
|
|
"--domain-needed",
|
|
f"--domain={config['dhcp_domain']}",
|
|
f"--local=/{config['dhcp_domain']}/",
|
|
"--log-facility=-",
|
|
"--log-dhcp",
|
|
"--keep-in-foreground",
|
|
f"--dhcp-script={os.getcwd()}/pvcbootstrapd/dnsmasq-lease.py",
|
|
"--bind-interfaces",
|
|
f"--listen-address={config['dhcp_address']}",
|
|
f"--dhcp-option=3,{config['dhcp_gateway']}",
|
|
f"--dhcp-range={config['dhcp_lease_start']},{config['dhcp_lease_end']},{config['dhcp_lease_time']}",
|
|
"--enable-tftp",
|
|
f"--tftp-root={config['tftp_root_path']}/",
|
|
# This block of dhcp-match, tag-if, and dhcp-boot statements sets the following TFTP setup:
|
|
# If the machine sends client-arch 0, and is not tagged iPXE, load undionly.kpxe (chainload)
|
|
# If the machine sends client-arch 7 or 9, and is not tagged iPXE, load ipxe.efi (chainload)
|
|
# If the machine sends the iPXE option, load boot.ipxe (iPXE boot configuration)
|
|
"--dhcp-match=set:o_bios,option:client-arch,0",
|
|
"--dhcp-match=set:o_uefi,option:client-arch,7",
|
|
"--dhcp-match=set:o_uefi,option:client-arch,9",
|
|
"--dhcp-match=set:ipxe,175",
|
|
"--tag-if=set:bios,tag:!ipxe,tag:o_bios",
|
|
"--tag-if=set:uefi,tag:!ipxe,tag:o_uefi",
|
|
"--dhcp-boot=tag:bios,undionly.kpxe",
|
|
"--dhcp-boot=tag:uefi,ipxe.efi",
|
|
"--dhcp-boot=tag:ipxe,boot.ipxe",
|
|
]
|
|
if config["debug"]:
|
|
self.dnsmasq_cmd.append("--leasefile-ro")
|
|
|
|
print(self.dnsmasq_cmd)
|
|
self.stdout = subprocess.PIPE
|
|
|
|
def execute(self):
|
|
self.proc = subprocess.Popen(
|
|
self.dnsmasq_cmd,
|
|
env=self.environment,
|
|
)
|
|
|
|
def start(self):
|
|
self.thread = Thread(target=self.execute, args=())
|
|
self.thread.start()
|
|
|
|
def stop(self):
|
|
self.proc.send_signal(signal.SIGTERM)
|
|
|
|
def reload(self):
|
|
self.proc.send_signal(signal.SIGHUP)
|