summaryrefslogtreecommitdiffstats
path: root/sync.py
diff options
context:
space:
mode:
authorMichael DeHaan <mdehaan@redhat.com>2006-04-04 11:24:09 -0400
committerJim Meyering <jim@meyering.net>2006-04-04 11:24:09 -0400
commitab6dd238209e6973a1ebe781530aa7964e386605 (patch)
tree8dd6530ef14bb0038a8e0983c0c0634fe58f4fb6 /sync.py
downloadthird_party-cobbler-ab6dd238209e6973a1ebe781530aa7964e386605.tar.gz
third_party-cobbler-ab6dd238209e6973a1ebe781530aa7964e386605.tar.xz
third_party-cobbler-ab6dd238209e6973a1ebe781530aa7964e386605.zip
Screwed up mercurial, resurrecting 'shoe' as 'bootconf'
Diffstat (limited to 'sync.py')
-rw-r--r--sync.py133
1 files changed, 133 insertions, 0 deletions
diff --git a/sync.py b/sync.py
new file mode 100644
index 0000000..07e53c9
--- /dev/null
+++ b/sync.py
@@ -0,0 +1,133 @@
+# Code to vivify a bootconf configuration into a real TFTP/DHCP configuration.
+#
+# Michael DeHaan <mdehaan@redhat.com>
+
+import api
+import config
+
+import os
+import sys
+import traceback
+import re
+import shutil
+
+import IPy
+
+class BootSync:
+
+ def __init__(self,api):
+ self.api = api
+
+ """
+ Syncs the current bootconf configuration.
+ Automatically runs the 'check_install'
+ FUTURE: make dryrun work.
+ """
+ def sync(self,dry_run=False):
+ if dry_run:
+ print "dryrun hasn't been implemented yet. Try not using dryrun at your own risk."
+ sys.exit(1)
+ results = self.api.utils.check_install()
+ if results != []:
+ self.api.last_error = "Rerun 'bootconf check' and correct problems before proceeding."
+ return False
+ try:
+ self.copy_pxelinux()
+ self.clean_pxelinux_tree()
+ self.copy_distros()
+ self.validate_kickstarts()
+ self.build_pxelinux_tree()
+ except:
+ traceback.print_exc() # <-- remove later
+ return False
+ return True
+
+ def copy_pxelinux(self):
+ shutil.copy(self.api.config.pxelinux, os.path.join(self.api.config.tftpboot, "pxelinux.0"))
+
+ def clean_pxelinux_tree(self):
+ shutil.rmtree(os.path.join(self.api.config.tftpboot, "pxelinux.cfg"), True)
+
+ def copy_distros(self):
+ # copy is a 4-letter word but tftpboot runs chroot, thus it's required.
+ images = os.path.join(self.api.config.tftpboot, "images")
+ shutil.rmtree(os.path.join(self.api.config.tftpboot, "images"), True)
+ os.mkdir(images)
+ for d in self.api.get_distros().contents():
+ kernel = self.api.utils.find_kernel(d.kernel) # full path
+ initrd = self.api.utils.find_initrd(d.initrd) # full path
+ print "KERNEL SRC = %s" % kernel
+ print "INITRD SRC = %s" % initrd
+ if kernel is None:
+ self.api.last_error = "Kernel for distro (%s) cannot be found and needs to be fixed: %s" % (d.name, d.kernel)
+ raise "error"
+ if kernel is None:
+ self.api.last_error = "Initrd for distro (%s) cannot be found and needs to be fixed: %s" % (d.initrd, d.kernel)
+ raise "error"
+ b_kernel = os.path.basename(kernel)
+ b_initrd = os.path.basename(initrd)
+ shutil.copyfile(kernel, os.path.join(images, b_kernel))
+ shutil.copyfile(initrd, os.path.join(images, b_initrd))
+
+ def validate_kickstarts(self):
+ # ensure all referenced kickstarts exist
+ # these are served by either NFS, Apache, or some ftpd, so we don't need to copy them
+ # it's up to the user to make sure they are nicely served by their URLs
+ for g in self.api.get_groups().contents():
+ kickstart_path = self.api.utils.find_kickstart(g.kickstart)
+ if kickstart_path is None or not os.path.isfile(kickstart_path):
+ self.api.last_error = "Kickstart for group (%s) cannot be found and needs to be fixed: %s" % (group, kickstart)
+ raise "error"
+
+ def build_pxelinux_tree(self):
+ # create pxelinux.cfg under tftpboot
+ # and file for each MAC or IP (hex encoded 01-XX-XX-XX-XX-XX-XX)
+ systems = self.api.get_systems()
+ groups = self.api.get_groups()
+ distros = self.api.get_distros()
+ os.mkdir(os.path.join(self.api.config.tftpboot,"pxelinux.cfg"))
+ for system in self.api.get_systems().contents():
+ group = groups.find(system.group)
+ if group is None:
+ self.api.last_error = "System %s is orphaned (no group), was the configuration edited manually?" % system.name
+ raise "error"
+ distro = distros.find(group.distro)
+ if distro is None:
+ self.api.last_error = "Group %s is orphaned (no distro), was the configuration edited manually?" % group.name
+ raise "error"
+ filename = self.get_pxelinux_filename(system.name)
+ filename = os.path.join(self.api.config.tftpboot, "pxelinux.cfg", filename)
+ self.write_pxelinux_file(filename,system,group,distro)
+
+ def get_pxelinux_filename(self,name_input):
+ name = self.api.utils.find_system_identifier(name_input)
+ if self.api.utils.is_ip(name):
+ return IPy.IP(name).strHex()[2:]
+ elif self.api.utils.is_mac(name):
+ return "01-" + "-".join(name.split(":")).lower()
+ else:
+ self.api.last_error = "system name (%s) couldn't resolve and is not an IP or a MAC address." % name
+ raise "error"
+
+ def write_pxelinux_file(self,filename,system,group,distro):
+ kernel_path = os.path.join("/images",os.path.basename(distro.kernel))
+ initrd_path = os.path.join("/images",os.path.basename(distro.initrd))
+ kickstart_path = self.api.config.kickstart_url + "/" + os.path.basename(group.kickstart)
+ file = open(filename,"w+")
+ file.write("default linux\n")
+ file.write("prompt 0\n")
+ file.write("timeout 1\n")
+ file.write("label linux\n")
+ file.write(" kernel %s\n" % kernel_path)
+ # FIXME: leave off kickstart if no kickstart...
+ # FIXME: allow specifying of other (system specific?)
+ # parameters in bootconf.conf ???
+ file.write(" append devfs=nomount ramdisk_size=16438 lang= vga=788 ksdevice=eth0 initrd=%s ks=%s console=ttyS0,38400n8\n" % (initrd_path, kickstart_path))
+ file.close()
+
+ # FUTURE: would be nice to check if dhcpd and tftpd are running...
+ # and whether kickstart url works (nfs, http, ftp)
+ # at least those that work with open-uri
+ # possibly file permissions...
+
+