diff options
Diffstat (limited to 'cobbler/dhcpgen.py')
-rw-r--r-- | cobbler/dhcpgen.py | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/cobbler/dhcpgen.py b/cobbler/dhcpgen.py new file mode 100644 index 0000000..0ec3dda --- /dev/null +++ b/cobbler/dhcpgen.py @@ -0,0 +1,196 @@ +""" +Builds out DHCP info +This is the code behind 'cobbler sync'. + +Copyright 2006-2008, Red Hat, Inc +Michael DeHaan <mdehaan@redhat.com> + +This software may be freely redistributed under the terms of the GNU +general public license. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +""" + +import os +import os.path +import shutil +import time +import sub_process +import sys +import glob +import traceback +import errno + +import utils +from cexceptions import * +import templar + +import item_distro +import item_profile +import item_repo +import item_system + +from utils import _ + +class DHCPGen: + """ + Handles conversion of internal state to the tftpboot tree layout + """ + + def __init__(self,config,verbose=False): + """ + Constructor + """ + self.verbose = verbose + self.config = config + self.api = config.api + self.distros = config.distros() + self.profiles = config.profiles() + self.systems = config.systems() + self.settings = config.settings() + self.repos = config.repos() + self.templar = templar.Templar(config) + + def write_dhcp_file(self): + """ + DHCP files are written when manage_dhcp is set in + /var/lib/cobbler/settings. + """ + + settings_file = self.settings.dhcpd_conf + template_file = "/etc/cobbler/dhcp.template" + mode = self.settings.manage_dhcp_mode.lower() + if mode == "dnsmasq": + settings_file = self.settings.dnsmasq_conf + template_file = "/etc/cobbler/dnsmasq.template" + + try: + f2 = open(template_file,"r") + except: + raise CX(_("error writing template to file: %s") % template_file) + template_data = "" + template_data = f2.read() + f2.close() + + # build each per-system definition + # as configured, this only works for ISC, patches accepted + # from those that care about Itanium. elilo seems to be unmaintained + # so additional maintaince in other areas may be required to keep + # this working. + + elilo = os.path.basename(self.settings.bootloaders["ia64"]) + + system_definitions = {} + counter = 0 + + # we used to just loop through each system, but now we must loop + # through each network interface of each system. + + for system in self.systems: + profile = system.get_conceptual_parent() + distro = profile.get_conceptual_parent() + for (name, interface) in system.interfaces.iteritems(): + + mac = interface["mac_address"] + ip = interface["ip_address"] + host = interface["hostname"] + + if mac is None or mac == "": + # can't write a DHCP entry for this system + continue + + counter = counter + 1 + systxt = "" + + if mode == "isc": + + # the label the entry after the hostname if possible + if host is not None and host != "": + systxt = "\nhost %s {\n" % host + if self.settings.isc_set_host_name: + systxt = systxt + " option host-name = %s;\n" % host + else: + systxt = "\nhost generic%d {\n" % counter + + if distro.arch == "ia64": + # can't use pxelinux.0 anymore + systxt = systxt + " filename \"/%s\";\n" % elilo + systxt = systxt + " hardware ethernet %s;\n" % mac + if ip is not None and ip != "": + systxt = systxt + " fixed-address %s;\n" % ip + systxt = systxt + "}\n" + + else: + # dnsmasq. don't have to write IP and other info here, but we do tag + # each MAC based on the arch of it's distro, if it needs something other + # than pxelinux.0 -- for these arches, and these arches only, a dnsmasq + # reload (full "cobbler sync") would be required after adding the system + # to cobbler, just to tag this relationship. + + if ip is not None and ip != "": + if distro.arch.lower() == "ia64": + systxt = "dhcp-host=net:ia64," + ip + "\n" + # support for other arches needs modifications here + else: + systxt = "" + + dhcp_tag = interface["dhcp_tag"] + if dhcp_tag == "": + dhcp_tag = "default" + + if not system_definitions.has_key(dhcp_tag): + system_definitions[dhcp_tag] = "" + system_definitions[dhcp_tag] = system_definitions[dhcp_tag] + systxt + + # we are now done with the looping through each interface of each system + + metadata = { + "insert_cobbler_system_definitions" : system_definitions.get("default",""), + "date" : time.asctime(time.gmtime()), + "cobbler_server" : self.settings.server, + "next_server" : self.settings.next_server, + "elilo" : elilo + } + + # now add in other DHCP expansions that are not tagged with "default" + for x in system_definitions.keys(): + if x == "default": + continue + metadata["insert_cobbler_system_definitions_%s" % x] = system_definitions[x] + + self.templar.render(template_data, metadata, settings_file, None) + + def regen_ethers(self): + # dnsmasq knows how to read this database of MACs -> IPs, so we'll keep it up to date + # every time we add a system. + # read 'man ethers' for format info + fh = open("/etc/ethers","w+") + for sys in self.systems: + for (name, interface) in sys.interfaces.iteritems(): + mac = interface["mac_address"] + ip = interface["ip_address"] + if mac is None or mac == "": + # can't write this w/o a MAC address + continue + if ip is not None and ip != "": + fh.write(mac.upper() + "\t" + ip + "\n") + fh.close() + + def regen_hosts(self): + # dnsmasq knows how to read this database for host info + # (other things may also make use of this later) + fh = open("/var/lib/cobbler/cobbler_hosts","w+") + for sys in self.systems: + for (name, interface) in sys.interfaces.iteritems(): + mac = interface["mac_address"] + host = interface["hostname"] + ip = interface["ip_address"] + if mac is None or mac == "": + continue + if host is not None and host != "" and ip is not None and ip != "": + fh.write(ip + "\t" + host + "\n") + fh.close() + + |