diff options
Diffstat (limited to 'cobbler/action_buildiso.py')
-rw-r--r-- | cobbler/action_buildiso.py | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/cobbler/action_buildiso.py b/cobbler/action_buildiso.py new file mode 100644 index 0000000..639bd6b --- /dev/null +++ b/cobbler/action_buildiso.py @@ -0,0 +1,181 @@ +""" +Builds non-live bootable CD's that have PXE-equivalent behavior +for all cobbler profiles currently in memory. + +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 sub_process +import sys +import traceback +import shutil +import sub_process + +import utils +from cexceptions import * +from utils import _ + +# FIXME: lots of overlap with pxegen.py, should consolidate +# FIXME: disable timeouts and remove local boot for this? +HEADER = """ + +DEFAULT menu +PROMPT 0 +MENU TITLE Cobbler | http://cobbler.et.redhat.com +TIMEOUT 200 +TOTALTIMEOUT 6000 +ONTIMEOUT local + +LABEL local + MENU LABEL (local) + MENU DEFAULT + LOCALBOOT -1 + +""" + +class BuildIso: + """ + 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.distmap = {} + self.distctr = 0 + + def make_shorter(self,distname): + if self.distmap.has_key(distname): + return self.distmap[distname] + else: + self.distctr = self.distctr + 1 + self.distmap[distname] = str(self.distctr) + return str(self.distctr) + + def run(self,iso=None,tempdir=None,profiles=None): + + # verify we can find isolinux.bin + + if iso is None: + iso = "kickstart.iso" + + isolinuxbin = "/usr/lib/syslinux/isolinux.bin" + if not os.path.exists(isolinuxbin): + raise CX(_("Required file not found: %s") % isolinuxbin) + + # if iso is none, create it in . as "cobbler.iso" + if tempdir is None: + tempdir = os.path.join(os.getcwd(), "buildiso") + print _("- using/creating tempdir: %s") % tempdir + if not os.path.exists(tempdir): + os.makedirs(tempdir) + + # if base of tempdir does not exist, fail + # create all profiles unless filtered by "profiles" + imagesdir = os.path.join(tempdir, "images") + isolinuxdir = os.path.join(tempdir, "isolinux") + + print _("- building tree for isolinux") + if not os.path.exists(imagesdir): + os.makedirs(imagesdir) + if not os.path.exists(isolinuxdir): + os.makedirs(isolinuxdir) + + print _("- copying miscellaneous files") + utils.copyfile(isolinuxbin, os.path.join(isolinuxdir, "isolinux.bin")) + menu = "/var/lib/cobbler/menu.c32" + files = [ isolinuxbin, menu ] + for f in files: + if not os.path.exists(f): + raise CX(_("Required file not found: %s") % f) + utils.copyfile(f, os.path.join(isolinuxdir, os.path.basename(f))) + + print _("- copying kernels and initrds") + # copy all images in included profiles to images dir + for x in self.api.profiles(): + use_this = True + if profiles is not None: + which_profiles = profiles.split(",") + if not use_this in which_profiles: + use_this = False + dist = x.get_conceptual_parent() + if dist.name.find("-xen") != -1: + continue + distname = self.make_shorter(dist.name) + # tempdir/isolinux/$distro/vmlinuz, initrd.img + # FIXME: this will likely crash on non-Linux breeds + shutil.copyfile(dist.kernel, os.path.join(isolinuxdir, "%s.krn" % distname)) + shutil.copyfile(dist.initrd, os.path.join(isolinuxdir, "%s.img" % distname)) + + # generate isolinux.cfg + print _("- generating a isolinux.cfg") + isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg") + cfg = open(isolinuxcfg, "w+") + cfg.write(HEADER) # fixme, use template + + for x in self.api.profiles(): + # FIXME + use_this = True + if profiles is not None: + which_profiles = profiles.split(",") + if not use_this in which_profiles: + use_this = False + if use_this: + dist = x.get_conceptual_parent() + if dist.name.find("-xen") != -1: + continue + data = utils.blender(self.api, True, x) + distname = self.make_shorter(dist.name) + + cfg.write("\n") + cfg.write("LABEL %s\n" % x.name) + cfg.write(" MENU LABEL %s\n" % x.name) + cfg.write(" kernel %s.krn\n" % distname) + + if data["kickstart"].startswith("/"): + data["kickstart"] = "http://%s/cblr/svc/op/ks/profile/%s" % ( + data["server"], + x.name + ) + + append_line = " append initrd=%s.img" % distname + append_line = append_line + " ks=%s " % data["kickstart"] + append_line = append_line + " %s\n" % data["kernel_options"] + cfg.write(append_line) + + print _("- done writing config") + cfg.write("\n") + cfg.write("MENU END\n") + cfg.close() + + cmd = "mkisofs -o %s -r -b isolinux/isolinux.bin -c isolinux/boot.cat" % iso + cmd = cmd + " -no-emul-boot -boot-load-size 4 " + cmd = cmd + " -boot-info-table -V Cobbler\ Install -R -J -T %s" % tempdir + + print _("- running: %s") % cmd + rc = sub_process.call(cmd, shell=True) + if rc: + raise CX(_("mkisofs failed")) + + print _("ISO build complete") + print _("You may wish to delete: %s") % tempdir + print _("The output file is: %s") % iso + + |