diff options
Diffstat (limited to 'cobbler/action_buildiso.py')
-rw-r--r-- | cobbler/action_buildiso.py | 209 |
1 files changed, 156 insertions, 53 deletions
diff --git a/cobbler/action_buildiso.py b/cobbler/action_buildiso.py index 20364dfd..67546d5f 100644 --- a/cobbler/action_buildiso.py +++ b/cobbler/action_buildiso.py @@ -29,6 +29,7 @@ import sys import traceback import shutil import sub_process +import re import utils from cexceptions import * @@ -68,8 +69,10 @@ class BuildIso: self.distros = config.distros() self.profiles = config.profiles() self.systems = config.systems() + self.distros = config.distros() self.distmap = {} self.distctr = 0 + self.source = "" def make_shorter(self,distname): if self.distmap.has_key(distname): @@ -79,44 +82,8 @@ class BuildIso: self.distmap[distname] = str(self.distctr) return str(self.distctr) - def run(self,iso=None,tempdir=None,profiles=None,systems=None): - - # if iso is none, create it in . as "kickstart.iso" - if iso is None: - iso = "kickstart.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) - else: - shutil.rmtree(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") - isolinuxbin = "/usr/lib/syslinux/isolinux.bin" - menu = "/var/lib/cobbler/menu.c32" - chain = "/usr/lib/syslinux/chain.c32" - files = [ isolinuxbin, menu, chain ] - for f in files: - if not os.path.exists(f): - raise CX(_("Required file not found: %s") % f) - else: - utils.copyfile(f, os.path.join(isolinuxdir, os.path.basename(f)), self.api) - + + def generate_netboot_iso(self,imagesdir,isolinuxdir,profiles=None,systems=None): print _("- copying kernels and initrds - for profiles") # copy all images in included profiles to images dir for profile in self.api.profiles(): @@ -162,7 +129,7 @@ class BuildIso: isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg") cfg = open(isolinuxcfg, "w+") cfg.write(HEADER) # fixme, use template - + print _("- generating profile list...") #sort the profiles profile_list = [profile for profile in self.profiles] @@ -201,10 +168,10 @@ class BuildIso: length=len(append_line) if length>254: - print _("WARNING - append line length is greater than 254 chars: (%s chars)") % length - + print _("WARNING - append line length is greater than 254 chars: (%s chars)") % length + cfg.write(append_line) - + if systems is not None: print _("- generating system list...") @@ -267,26 +234,162 @@ class BuildIso: length=len(append_line) if length > 254: - print _("WARNING - append line length is greater than 254 chars: (%s chars)") % length - + print _("WARNING - append line length is greater than 254 chars: (%s chars)") % length + cfg.write(append_line) - print _("- done writing config") + 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 + + + def generate_standalone_iso(self,imagesdir,isolinuxdir,distname,filesource): + + # Get the distro object for the requested distro + # and then get all of its descendants (profiles/sub-profiles/systems) + distro = self.api.find_distro(distname) + if distro is None: + raise CX("distro %s was not found, aborting" % distname) + descendants = distro.get_descendants() + + print _("- copying kernels and initrds - for standalone distro") + # tempdir/isolinux/$distro/vmlinuz, initrd.img + # FIXME: this will likely crash on non-Linux breeds + f1 = os.path.join(isolinuxdir, "vmlinuz") + f2 = os.path.join(isolinuxdir, "initrd.img") + if not os.path.exists(distro.kernel): + raise CX("path does not exist: %s" % distro.kernel) + if not os.path.exists(distro.initrd): + raise CX("path does not exist: %s" % distro.initrd) + shutil.copyfile(distro.kernel, f1) + shutil.copyfile(distro.initrd, f2) + + cmd = "rsync -rlptgu --exclude=boot.cat --exclude=TRANS.TBL --exclude=isolinux/ %s/ %s/../" % (filesource, isolinuxdir) + print _("- copying distro %s files (%s)" % (distname,cmd)) + rc = sub_process.call(cmd, shell=True, close_fds=True) + if rc: + raise CX(_("rsync of files failed")) + + print _("- generating a isolinux.cfg") + isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg") + cfg = open(isolinuxcfg, "w+") + cfg.write(HEADER) # fixme, use template + + for descendant in descendants: + data = utils.blender(self.api, True, descendant) + + cfg.write("\n") + cfg.write("LABEL %s\n" % descendant.name) + cfg.write(" MENU LABEL %s\n" % descendant.name) + cfg.write(" kernel vmlinuz\n") + + data["kickstart"] = "cdrom:/isolinux/ks-%s.cfg" % descendant.name + + append_line = " append initrd=initrd.img" + append_line = append_line + " ks=%s " % data["kickstart"] + append_line = append_line + " %s\n" % data["kernel_options"] + + cfg.write(append_line) + + if descendant.COLLECTION_TYPE == 'profile': + kickstart_data = self.api.kickgen.generate_kickstart_for_profile(descendant.name) + elif descendant.COLLECTION_TYPE == 'system': + kickstart_data = self.api.kickgen.generate_kickstart_for_system(descendant.name) + + cdregex = re.compile("url .*\n", re.IGNORECASE) + kickstart_data = cdregex.sub("cdrom\n", kickstart_data) + + ks_name = os.path.join(isolinuxdir, "ks-%s.cfg" % descendant.name) + ks_file = open(ks_name, "w+") + ks_file.write(kickstart_data) + ks_file.close() + + print _("- done writing config") + cfg.write("\n") + cfg.write("MENU END\n") + cfg.close() + + return + + + def run(self,iso=None,tempdir=None,profiles=None,systems=None,distro=None,standalone=None,source=None): + + # the distro option is for stand-alone builds only + if not standalone and distro is not None: + raise CX(_("The --distro option should only be used when creating a standalone ISO")) + # if building standalone, we only want --distro, + # profiles/systems are disallowed + if standalone: + if profiles is not None or systems is not None: + raise CX(_("When building a standalone ISO, use --distro only instead of --profiles/--systems")) + elif distro is None: + raise CX(_("When building a standalone ISO, you must specify a --distro")) + elif source is None: + raise CX(_("When building a standalone ISO, you must specify a --source")) + elif not os.path.exists(source): + raise CX(_("The source specified (%s) does not exist" % source)) + + # if iso is none, create it in . as "kickstart.iso" + if iso is None: + iso = "kickstart.iso" + + if tempdir is None: + tempdir = os.path.join(os.getcwd(), "buildiso") + else: + if not os.path.isdir(tempdir): + raise CX(_("The --tempdir specified is not a directory")) + + (tempdir_head,tempdir_tail) = os.path.split(os.path.normpath(tempdir)) + if tempdir_tail != "buildiso": + tempdir = os.path.join(tempdir, "buildiso") + + print _("- using/creating tempdir: %s") % tempdir + if not os.path.exists(tempdir): + os.makedirs(tempdir) + else: + shutil.rmtree(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") + isolinuxbin = "/usr/lib/syslinux/isolinux.bin" + menu = "/var/lib/cobbler/menu.c32" + chain = "/usr/lib/syslinux/chain.c32" + files = [ isolinuxbin, menu, chain ] + for f in files: + if not os.path.exists(f): + raise CX(_("Required file not found: %s") % f) + else: + utils.copyfile(f, os.path.join(isolinuxdir, os.path.basename(f)), self.api) + + if standalone: + self.generate_standalone_iso(imagesdir,isolinuxdir,distro,source) + else: + self.generate_netboot_iso(imagesdir,isolinuxdir,profiles,systems) + + cmd = "mkisofs -quiet -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, close_fds=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 - - + print _("The output file is: %s") % iso + + |