[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[lorax] Add support for ppc



The way we create the images had to be changed a little.
Some code had to be moved to other places, so we can create
images for other architectures too.
---
 src/pylorax/__init__.py   |  162 ++++++++------
 src/pylorax/images.py     |  557 +++++++++++++++++++++++++++++++++++++++++++++
 src/pylorax/outputtree.py |   29 ++-
 src/pylorax/sysutils.py   |    9 +
 4 files changed, 678 insertions(+), 79 deletions(-)
 create mode 100644 src/pylorax/images.py

diff --git a/src/pylorax/__init__.py b/src/pylorax/__init__.py
index 1c947c9..97979cb 100644
--- a/src/pylorax/__init__.py
+++ b/src/pylorax/__init__.py
@@ -54,6 +54,7 @@ from outputtree import LoraxOutputTree
 from buildstamp import BuildStamp
 from treeinfo import TreeInfo
 from discinfo import DiscInfo
+import images
 
 
 ARCHMAPS = {
@@ -325,12 +326,12 @@ class Lorax(BaseLoraxClass):
         self.outputtree = LoraxOutputTree(self.outputdir, self.installtree,
                                           self.product, self.version)
 
-        self.outputtree.prepare()
-        self.outputtree.get_isolinux()
-        self.outputtree.get_memtest()
-        self.outputtree.get_splash()
-        self.outputtree.get_msg_files()
-        self.outputtree.get_grub_conf()
+        #self.outputtree.prepare()
+        #self.outputtree.get_isolinux()
+        #self.outputtree.get_memtest()
+        #self.outputtree.get_splash()
+        #self.outputtree.get_msg_files()
+        #self.outputtree.get_grub_conf()
 
         # write .discinfo
         discinfo = DiscInfo(self.workdir, self.release, self.basearch)
@@ -338,6 +339,7 @@ class Lorax(BaseLoraxClass):
 
         shutil.copy2(discinfo.path, self.outputtree.root)
 
+        # move grubefi to workdir
         grubefi = joinpaths(self.installtree.root, "boot/efi/EFI/redhat",
                             "grub.efi")
 
@@ -347,14 +349,41 @@ class Lorax(BaseLoraxClass):
         else:
             grubefi = None
 
+        # move grub splash to workdir
         splash = joinpaths(self.installtree.root, "boot/grub/",
                            "splash.xpm.gz")
 
-        shutil.move(splash, self.workdir)
-        splash = joinpaths(self.workdir, os.path.basename(splash))
+        if os.path.isfile(splash):
+            shutil.move(splash, self.workdir)
+            splash = joinpaths(self.workdir, os.path.basename(splash))
+        else:
+            splash = None
 
         # copy kernels to output directory
-        self.outputtree.get_kernels()
+        self.outputtree.get_kernels(self.workdir)
+
+        # create .treeinfo
+        treeinfo = TreeInfo(self.workdir, self.product, self.version,
+                            self.variant, self.basearch)
+
+        # get the image class
+        if self.basearch == "ppc":
+            imgclass = images.PPC
+        elif self.basearch in ("i386", "x86_64"):
+            imgclass = images.X86
+        else:
+            raise Exception("not supported arch '{0}'".format(self.basearch))
+
+        i = imgclass(kernellist=self.outputtree.kernels,
+                     installtree=self.installtree,
+                     outputroot=self.outputtree.root,
+                     product=self.product,
+                     version=self.version,
+                     treeinfo=treeinfo,
+                     basearch=self.basearch)
+
+        # backup required files
+        i.backup_required(self.workdir)
 
         # get list of not required packages
         logger.info("getting list of not required packages")
@@ -394,57 +423,56 @@ class Lorax(BaseLoraxClass):
         logger.info("cleaning up python files")
         self.installtree.cleanup_python_files()
 
-        # create .treeinfo
-        treeinfo = TreeInfo(self.workdir, self.product, self.version,
-                            self.variant, self.basearch)
-
         # compress install tree (create initrd)
-        initrds = []
-        for kernel in self.outputtree.kernels:
-            suffix = ""
-            if kernel.ktype == constants.K_PAE:
-                suffix = "-PAE"
-            elif kernel.ktype == constants.K_XEN:
-                suffix = "-XEN"
-
-            fname = "initrd{0}.img".format(suffix)
-
-            initrd = DataHolder(fname=fname,
-                                fpath=joinpaths(self.workdir, fname),
-                                itype=kernel.ktype)
-
-            logger.info("compressing install tree ({0})".format(kernel.version))
-            success, elapsed = self.installtree.compress(initrd, kernel)
-            if not success:
-                logger.error("error while compressing install tree")
-            else:
-                logger.info("took {0:.2f} seconds".format(elapsed))
-
-            initrds.append(initrd)
-
-            # add kernel and initrd paths to .treeinfo
-            section = "images-{0}".format("xen" if suffix else self.basearch)
-            data = {"kernel": "images/pxeboot/{0}".format(kernel.fname)}
-            treeinfo.add_section(section, data)
-            data = {"initrd": "images/pxeboot/{0}".format(initrd.fname)}
-            treeinfo.add_section(section, data)
-
-        # copy initrds to outputtree
-        shutil.copy2(initrds[0].fpath, self.outputtree.isolinuxdir)
-
-        # create hard link
-        source = joinpaths(self.outputtree.isolinuxdir, initrds[0].fname)
-        link_name = joinpaths(self.outputtree.pxebootdir, initrds[0].fname)
-        os.link(source, link_name)
-
-        for initrd in initrds[1:]:
-            shutil.copy2(initrd.fpath, self.outputtree.pxebootdir)
+        logger.info("creating the initrd")
+        i.create_initrd(self.libdir)
+
+        #initrds = []
+        #for kernel in self.outputtree.kernels:
+        #    suffix = ""
+        #    if kernel.ktype == constants.K_PAE:
+        #        suffix = "-PAE"
+        #    elif kernel.ktype == constants.K_XEN:
+        #        suffix = "-XEN"
+        #
+        #    fname = "initrd{0}.img".format(suffix)
+        #
+        #    initrd = DataHolder(fname=fname,
+        #                        fpath=joinpaths(self.workdir, fname),
+        #                        itype=kernel.ktype)
+        #
+        #    logger.info("compressing install tree ({0})".format(kernel.version))
+        #    success, elapsed = self.installtree.compress(initrd, kernel)
+        #    if not success:
+        #        logger.error("error while compressing install tree")
+        #    else:
+        #        logger.info("took {0:.2f} seconds".format(elapsed))
+        #
+        #    initrds.append(initrd)
+        #
+        #    # add kernel and initrd paths to .treeinfo
+        #    section = "images-{0}".format("xen" if suffix else self.basearch)
+        #    data = {"kernel": "images/pxeboot/{0}".format(kernel.fname)}
+        #    treeinfo.add_section(section, data)
+        #    data = {"initrd": "images/pxeboot/{0}".format(initrd.fname)}
+        #    treeinfo.add_section(section, data)
+        #
+        ## copy initrds to outputtree
+        #shutil.copy2(initrds[0].fpath, self.outputtree.isolinuxdir)
+        #
+        ## create hard link
+        #source = joinpaths(self.outputtree.isolinuxdir, initrds[0].fname)
+        #link_name = joinpaths(self.outputtree.pxebootdir, initrds[0].fname)
+        #os.link(source, link_name)
+        #
+        #for initrd in initrds[1:]:
+        #    shutil.copy2(initrd.fpath, self.outputtree.pxebootdir)
 
         # create efi images
         efiboot = None
         if grubefi and self.efiarch not in ("IA32",):
-            kernel = self.outputtree.kernels[0]
-            initrd = initrds[0]
+            kernel = i.kernels[0]
+            initrd = i.initrds[0]
 
             # create efiboot image with kernel
             logger.info("creating efiboot image with kernel")
@@ -480,17 +508,19 @@ class Lorax(BaseLoraxClass):
 
         # create boot iso
         logger.info("creating boot iso")
-        bootiso = self.create_bootiso(self.outputtree, efiboot)
-        if bootiso is None:
-            logger.critical("unable to create boot iso")
-            sys.exit(1)
-
-        shutil.move(bootiso, self.outputtree.imgdir)
-
-        # add the boot.iso
-        section = "images-{0}".format(self.basearch)
-        data = {"boot.iso": "images/{0}".format(os.path.basename(bootiso))}
-        treeinfo.add_section(section, data)
+        i.create_boot(efiboot)
+
+        #bootiso = self.create_bootiso(self.outputtree, efiboot)
+        #if bootiso is None:
+        #    logger.critical("unable to create boot iso")
+        #    sys.exit(1)
+        #
+        #shutil.move(bootiso, self.outputtree.imgdir)
+        #
+        ## add the boot.iso
+        #section = "images-{0}".format(self.basearch)
+        #data = {"boot.iso": "images/{0}".format(os.path.basename(bootiso))}
+        #treeinfo.add_section(section, data)
 
         treeinfo.write()
 
diff --git a/src/pylorax/images.py b/src/pylorax/images.py
new file mode 100644
index 0000000..4a220a8
--- /dev/null
+++ b/src/pylorax/images.py
@@ -0,0 +1,557 @@
+#
+# images.py
+#
+# Copyright (C) 2011  Red Hat, Inc.
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+# Red Hat Author(s):  Martin Gracik <mgracik redhat com>
+#
+
+import logging
+logger = logging.getLogger("pylorax.images")
+
+import os
+import subprocess
+import shutil
+import glob
+import collections
+
+from base import DataHolder
+from sysutils import joinpaths, cpfile, replace
+
+import constants
+
+
+##### constants #####
+
+ANABOOTDIR = "usr/share/anaconda/boot"
+
+# ppc
+ETCDIR = "etc"
+PPCPARENT = "ppc"
+CHRPDIR = "ppc/chrp"
+IMAGESDIR = "images"
+
+PPC32DIR = "ppc/ppc32"
+PPC64DIR = "ppc/ppc64"
+MACDIR = "ppc/mac"
+NETBOOTDIR = "images/netboot"
+
+MKZIMAGE = "usr/bin/mkzimage"
+ZIMAGE_STUB = "usr/share/ppc64-utils/zImage.stub"
+ZIMAGE_LDS = "usr/share/ppc64-utils/zImage.lds"
+WRAPPER = "usr/sbin/wrapper"
+
+ISOPATHDIR = "isopath"
+
+MKISOFS = "mkisofs"
+MAPPING = joinpaths(ANABOOTDIR, "mapping")
+MAGIC = joinpaths(ANABOOTDIR, "magic")
+IMPLANTISOMD5 = "implantisomd5"
+
+# x86
+ISOLINUXDIR = "isolinux"
+PXEBOOTDIR = "images/pxeboot"
+
+ISOLINUX_BIN = "usr/share/syslinux/isolinux.bin"
+SYSLINUX_CFG = "usr/share/anaconda/boot/syslinux.cfg"
+
+ISOHYBRID = "isohybrid"
+
+
+class PPC(object):
+
+    def __init__(self, kernellist, installtree, outputroot, product, version,
+                 treeinfo, basearch):
+
+        self.kernellist = kernellist
+        self.installtree = installtree
+        self.outputroot = outputroot
+        self.product = product
+        self.version = version
+        self.treeinfo = treeinfo
+        self.basearch = basearch
+        self.kernels, self.initrds = [], []
+
+        self.reqs = collections.defaultdict(str)
+
+    def backup_required(self, workdir):
+        # yaboot.conf
+        yabootconf = joinpaths(self.installtree.root, ANABOOTDIR,
+                               "yaboot.conf.in")
+
+        self.reqs["yabootconf"] = cpfile(yabootconf, workdir)
+
+        # zImage.lds
+        zimage_lds = joinpaths(self.installtree.root, ZIMAGE_LDS)
+        self.reqs["zimage_lds"] = cpfile(zimage_lds, workdir)
+
+        # bootinfo.txt
+        bootinfo_txt = joinpaths(self.installtree.root, ANABOOTDIR,
+                                 "bootinfo.txt")
+
+        self.reqs["bootinfo_txt"] = cpfile(bootinfo_txt, workdir)
+
+        # efika.forth
+        efika_forth = joinpaths(self.installtree.root, ANABOOTDIR,
+                                "efika.forth")
+
+        self.reqs["efika_forth"] = cpfile(efika_forth, workdir)
+
+        # yaboot
+        yaboot = joinpaths(self.installtree.root, "usr/lib/yaboot/yaboot")
+        self.reqs["yaboot"] = cpfile(yaboot, workdir)
+
+        # ofboot.b
+        ofboot_b = joinpaths(self.installtree.root, ANABOOTDIR, "ofboot.b")
+        self.reqs["ofboot_b"] = cpfile(ofboot_b, workdir)
+
+        # yaboot.conf.3264
+        yabootconf3264 = joinpaths(self.installtree.root, ANABOOTDIR,
+                                   "yaboot.conf.3264")
+
+        self.reqs["yabootconf3264"] = cpfile(yabootconf3264, workdir)
+
+    def create_initrd(self, libdir):
+        # create directories
+        logger.info("creating required directories")
+        os.makedirs(joinpaths(self.outputroot, ETCDIR))
+        os.makedirs(joinpaths(self.outputroot, PPCPARENT))
+        os.makedirs(joinpaths(self.outputroot, CHRPDIR))
+        os.makedirs(joinpaths(self.outputroot, IMAGESDIR))
+
+        # set up biarch test
+        ppc32dir = joinpaths(self.outputroot, PPC32DIR)
+        ppc64dir = joinpaths(self.outputroot, PPC64DIR)
+        biarch = lambda: (os.path.exists(ppc32dir) and
+                          os.path.exists(ppc64dir))
+
+        # create images
+        for kernel in self.kernellist:
+            # set up bits
+            kernel_arch = kernel.version.split(".")[-1]
+            if (kernel_arch == "ppc"):
+                bits = 32
+                ppcdir = PPC32DIR
+                fakearch = "ppc"
+            elif (kernel_arch == "ppc64"):
+                bits = 64
+                ppcdir = PPC64DIR
+                fakearch = ""
+            else:
+                raise Exception("unknown kernel arch {0}".format(kernel_arch))
+
+            # create ppc dir
+            os.makedirs(joinpaths(self.outputroot, ppcdir))
+
+            if (kernel_arch == "ppc"):
+                # create mac dir
+                os.makedirs(joinpaths(self.outputroot, MACDIR))
+
+            # create netboot dir
+            os.makedirs(joinpaths(self.outputroot, NETBOOTDIR))
+
+            # copy kernel
+            logger.info("copying kernel image")
+            kernel.fname = "vmlinuz"
+            dst = joinpaths(self.outputroot, ppcdir, kernel.fname)
+            kernel.fpath = cpfile(kernel.fpath, dst)
+
+            # create and copy initrd
+            initrd = DataHolder()
+            initrd.fname = "ramdisk.image.gz"
+            initrd.fpath = joinpaths(self.outputroot, ppcdir, initrd.fname)
+            initrd.itype = kernel.ktype
+
+            logger.info("compressing the install tree")
+            self.installtree.compress(initrd, kernel)
+
+            # add kernel and initrd to the list
+            self.kernels.append(kernel)
+            self.initrds.append(initrd)
+
+            # add kernel and initrd to .treeinfo
+            section = "images-{0}".format(kernel_arch)
+            data = {"kernel": joinpaths(ppcdir, kernel.fname)}
+            self.treeinfo.add_section(section, data)
+            data = {"initrd": joinpaths(ppcdir, initrd.fname)}
+            self.treeinfo.add_section(section, data)
+
+            # copy yaboot.conf
+            dst = joinpaths(self.outputroot, ppcdir, "yaboot.conf")
+            yabootconf = cpfile(self.reqs["yabootconf"], dst)
+
+            mkzimage = joinpaths(self.installtree.root, MKZIMAGE)
+            zimage_stub = joinpaths(self.installtree.root, ZIMAGE_STUB)
+            wrapper = joinpaths(self.installtree.root, WRAPPER)
+
+            # XXX
+            wrapper_a = joinpaths(self.installtree.root,
+                                  "usr/%s/kernel-wrapper/wrapper.a" % libdir)
+
+            ppc_img_fname = "ppc{0}.img".format(bits)
+            ppc_img_fpath = joinpaths(self.outputroot, NETBOOTDIR,
+                                      ppc_img_fname)
+
+            if (os.path.exists(mkzimage) and os.path.exists(zimage_stub)):
+                logger.info("creating the z image")
+                # copy zImage.lds
+                zimage_lds = cpfile(self.reqs["zimage_lds"],
+                                    joinpaths(self.outputroot, ppcdir))
+
+                # change current working directory
+                cwd = os.getcwd()
+                os.chdir(joinpaths(self.outputroot, ppcdir))
+
+                # run mkzimage
+                cmd = [mkzimage, kernel.fpath, "no", "no", initrd.fpath,
+                       zimage_stub, ppc_img_fpath]
+                p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+                                     stdout=subprocess.PIPE)
+                p.wait()
+
+                # remove zImage.lds
+                os.unlink(zimage_lds)
+
+                # return to former working directory
+                os.chdir(cwd)
+
+            elif (os.path.exists(wrapper) and os.path.exists(wrapper_a)):
+                logger.info("running kernel wrapper")
+                # run wrapper
+                cmd = [wrapper, "-o", ppc_img_fpath, "-i", initrd.fpath,
+                       "-D", os.path.dirname(wrapper_a), kernel.fpath]
+                p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+                                     stdout=subprocess.PIPE)
+                p.wait()
+
+            if os.path.exists(ppc_img_fpath):
+                # add ppc image to .treeinfo
+                section = "images-{0}".format(kernel_arch)
+                data = {"zimage": joinpaths(NETBOOTDIR, ppc_img_fname)}
+                self.treeinfo.add_section(section, data)
+
+                if (bits == 32):
+                    # set up prepboot
+                    p = joinpaths(NETBOOTDIR, ppc_img_fname)
+                    prepboot = "-prep-boot {0}".format(p)
+
+            # remove netboot dir if empty
+            try:
+                os.rmdir(joinpaths(self.outputroot, NETBOOTDIR))
+            except OSError:
+                pass
+
+        # copy bootinfo.txt
+        cpfile(self.reqs["bootinfo_txt"],
+               joinpaths(self.outputroot, PPCPARENT))
+
+        # copy efika.forth
+        cpfile(self.reqs["efika_forth"],
+               joinpaths(self.outputroot, PPCPARENT))
+
+        # copy yaboot to chrp dir
+        yaboot = cpfile(self.reqs["yaboot"],
+                        joinpaths(self.outputroot, CHRPDIR))
+
+        if (os.paths.exists(joinpaths(self.outputroot, MACDIR))):
+            # copy yaboot and ofboot.b to mac dir
+            cpfile(yaboot, joinpaths(self.outputroot, MACDIR))
+            cpfile(self.reqs["ofboot_b"], joinpaths(self.outputroot, MACDIR))
+
+            # set up macboot
+            p = joinpaths(self.outputroot, ISOPATHDIR, MACDIR)
+            macboot = "-hfs-volid {0} -hfs-bless {1}".format(self.version, p)
+
+        # add note to yaboot
+        cmd = [joinpaths(self.installtree.root, "usr/lib/yaboot/addnote"),
+               yaboot]
+        p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+                             stdout=subprocess.PIPE)
+        p.wait()
+
+        # copy yaboot.conf to etc dir
+        if (biarch):
+            yabootconf = cpfile(self.reqs["yabootconf3264"],
+                                joinpaths(self.outputroot, ETCDIR,
+                                          "yaboot.conf"))
+
+            replace(yabootconf, r"%BITS%", "32")
+            replace(yabootconf, r"%PRODUCT%", self.product)
+            replace(yabootconf, r"%VERSION%", self.version)
+
+        else:
+            cpfile(joinpaths(self.outputroot, ppcdir, "yaboot.conf"),
+                   joinpaths(self.outputroot, ETCDIR))
+
+    def create_boot(self, efiboot=None):
+        # create isopath dir
+        isopathdir = joinpaths(self.outputroot, ISOPATHDIR)
+        os.makedirs(isopathdir)
+
+        # copy etc dir and ppc dir to isopath dir
+        shutil.copytree(joinpaths(self.outputroot, ETCDIR), isopathdir)
+        shutil.copytree(joinpaths(self.outputroot, PPCPARENT), isopathdir)
+
+        if (os.path.exists(joinpaths(self.outputroot, NETBOOTDIR))):
+            # create images dir in isopath dir if we have ppc images
+            imagesdir = joinpaths(isopathdir, IMAGESDIR)
+            os.makedirs(imagesdir)
+
+            # copy netboot dir to images dir
+            shutil.copytree(joinpaths(self.outputroot, NETBOOTDIR), imagesdir)
+
+        # define prepboot and macboot
+        prepboot = "" if "prepboot" not in locals() else locals()["prepboot"]
+        macboot = "" if "macboot" not in locals() else locals()["macboot"]
+
+        # create boot image
+        boot_fpath = joinpaths(self.outputroot, IMAGESDIR, "boot.iso")
+
+        # run mkisofs
+        cmd = [MKISOFS, "-o", boot_fpath, "-chrp-boot", "-U", prepboot,
+               "-part", "-hfs", "-T", "-r", "-l", "-J", "-A",
+               '"%s %s"' % (product, version), "-sysid", "PPC", "-V", '"PBOOT"',
+               "-volset", '"%s"' % version, "-volset-size", "1",
+               "-volset-seqno", "1", macboot, "-map", MAPPING, "-magic", MAGIC,
+               "-no-desktop", "-allow-multidot", "-graft-points", isopathdir]
+
+        p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+                             stdout=subprocess.PIPE)
+        p.wait()
+
+        # run implantisomd5
+        cmd = [IMPLANTISOMD5, boot_fpath]
+        p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+                             stdout=subprocess.PIPE)
+        p.wait()
+
+        # remove isopath dir
+        shutil.rmtree(isopathdir)
+
+
+class X86(object):
+
+    def __init__(self, kernellist, installtree, outputroot, product, version,
+                 treeinfo, basearch):
+
+        self.kernellist = kernellist
+        self.installtree = installtree
+        self.outputroot = outputroot
+        self.product = product
+        self.version = version
+        self.treeinfo = treeinfo
+        self.basearch = basearch
+        self.kernels, self.initrds = [], []
+
+        self.reqs = collections.defaultdict(str)
+
+    def backup_required(self, workdir):
+        # isolinux.bin
+        isolinux_bin = joinpaths(self.installtree.root, ISOLINUX_BIN)
+        if not os.path.exists(isolinux_bin):
+            raise Exception("isolinux.bin not present")
+
+        self.reqs["isolinux_bin"] = cpfile(isolinux_bin, workdir)
+
+        # syslinux.cfg
+        syslinux_cfg = joinpaths(self.installtree.root, SYSLINUX_CFG)
+        self.reqs["syslinux_cfg"] = cpfile(syslinux_cfg, workdir)
+
+        # memtest (XXX not from installroot/boot?)
+        memtest = glob.glob(joinpaths(self.installtree.root, ANABOOTDIR,
+                                      "memtest*"))
+
+        if memtest:
+            self.reqs["memtest"] = cpfile(memtest[-1],
+                                          joinpaths(workdir, "memtest"))
+
+        # *.msg files
+        msgfiles = glob.glob(joinpaths(self.installtree.root, ANABOOTDIR,
+                                       "*.msg"))
+
+        if not msgfiles:
+            raise Exception("message files not present")
+
+        self.reqs["msgfiles"] = []
+        for src in msgfiles:
+            self.reqs["msgfiles"].append(cpfile(src, workdir))
+
+        # splash
+        splash = joinpaths(self.installtree.root, ANABOOTDIR,
+                           "syslinux-vesa-splash.jpg")
+
+        if not splash:
+            raise Exception("syslinux-vesa-splash.jpg not present")
+
+        self.reqs["splash"] = cpfile(splash, workdir)
+
+        # vesamenu.c32
+        vesamenu = joinpaths(self.installtree.root,
+                             "usr/share/syslinux/vesamenu.c32")
+
+        self.reqs["vesamenu"] = cpfile(vesamenu, workdir)
+
+        # grub.conf
+        grubconf = joinpaths(self.installtree.root, ANABOOTDIR, "grub.conf")
+        self.reqs["grubconf"] = cpfile(grubconf, workdir)
+
+    def create_initrd(self, libdir):
+        # create directories
+        logger.info("creating required directories")
+        os.makedirs(joinpaths(self.outputroot, ISOLINUXDIR))
+        os.makedirs(joinpaths(self.outputroot, PXEBOOTDIR))
+
+        # copy isolinux.bin to isolinux dir
+        cpfile(self.reqs["isolinux_bin"],
+               joinpaths(self.outputroot, ISOLINUXDIR))
+
+        # copy syslinux.cfg to isolinux dir (XXX rename to isolinux.cfg)
+        isolinux_cfg = cpfile(self.reqs["syslinux_cfg"],
+                              joinpaths(self.outputroot, ISOLINUXDIR,
+                                        "isolinux.cfg"))
+
+        replace(isolinux_cfg, r"@PRODUCT@", self.product)
+        replace(isolinux_cfg, r"@VERSION@", self.version)
+
+        # copy memtest
+        if self.reqs["memtest"]:
+            cpfile(self.reqs["memtest"],
+                   joinpaths(self.outputroot, ISOLINUXDIR))
+
+            with open(isolinux_cfg, "a") as f:
+                f.write("label memtest86\n")
+                f.write("  menu label ^Memory test\n")
+                f.write("  kernel memtest\n")
+                f.write("  append -\n")
+
+        # copy *.msg files
+        for src in self.reqs["msgfiles"]:
+            dst = cpfile(src, joinpaths(self.outputroot, ISOLINUXDIR))
+            replace(dst, r"@VERSION@", self.version)
+
+        # copy syslinux-vesa-splash.jpg
+        splash = cpfile(self.reqs["splash"],
+                        joinpaths(self.outputroot, ISOLINUXDIR, "splash.jpg"))
+
+        # copy vesamenu.c32
+        cpfile(self.reqs["vesamenu"],
+               joinpaths(self.outputroot, ISOLINUXDIR))
+
+        # set up isolinux.cfg
+        replace(isolinux_cfg, r"default linux", "default vesamenu.c32")
+        replace(isolinux_cfg, r"prompt 1", "#prompt 1")
+
+        # copy grub.conf
+        grubconf = cpfile(self.reqs["grubconf"],
+                          joinpaths(self.outputroot, ISOLINUXDIR))
+
+        replace(grubconf, r"@PRODUCT@", self.product)
+        replace(grubconf, r"@VERSION@", self.version)
+
+        # create images
+        for kernel in self.kernellist:
+            # set up file names
+            suffix = ""
+            if (kernel.ktype == constants.K_PAE):
+                suffix = "-PAE"
+            elif (kernel.ktype == constants.K_XEN):
+                suffix = "-XEN"
+
+            logger.info("copying kernel image")
+            kernel.fname = "vmlinuz{0}".format(suffix)
+            if not suffix:
+                # copy kernel to isolinux dir
+                kernel.fpath = cpfile(kernel.fpath,
+                                      joinpaths(self.outputroot, ISOLINUXDIR,
+                                                kernel.fname))
+
+                # create link in pxeboot dir
+                os.link(kernel.fpath,
+                        joinpaths(self.outputroot, PXEBOOTDIR, kernel.fname))
+            else:
+                # copy kernel to pxeboot dir
+                kernel.fpath = cpfile(kernel.fpath,
+                                      joinpaths(self.outputroot, PXEBOOTDIR,
+                                                kernel.fname))
+
+            # create and copy initrd to pxeboot dir
+            initrd = DataHolder()
+            initrd.fname = "initrd{0}.img".format(suffix)
+            initrd.fpath = joinpaths(self.outputroot, PXEBOOTDIR, initrd.fname)
+            initrd.itype = kernel.ktype
+
+            logger.info("compressing the install tree")
+            self.installtree.compress(initrd, kernel)
+
+            # add kernel and initrd to the list
+            self.kernels.append(kernel)
+            self.initrds.append(initrd)
+
+            if not suffix:
+                # create link in isolinux dir
+                os.link(initrd.fpath,
+                        joinpaths(self.outputroot, ISOLINUXDIR, initrd.fname))
+
+            # add kernel and initrd to .treeinfo
+            section = "images-{0}".format("xen" if suffix else self.basearch)
+            data = {"kernel": joinpaths(PXEBOOTDIR, kernel.fname)}
+            self.treeinfo.add_section(section, data)
+            data = {"initrd": joinpaths(PXEBOOTDIR, initrd.fname)}
+            self.treeinfo.add_section(section, data)
+
+            if not suffix:
+                # add boot.iso to .treeinfo
+                data = {"boot.iso": joinpaths(IMAGESDIR, "boot.iso")}
+                self.treeinfo.add_section(section, data)
+
+    def create_boot(self, efiboot=None):
+        # define efiargs and efigraft
+        efiargs, efigraft = [], []
+        if efiboot:
+            efiargs = ["-eltorito-alt-boot", "-e",
+                       joinpaths(IMAGESDIR, "efiboot.img"), "-no-emul-boot"]
+            efigraft = ["EFI/BOOT={0}/EFI/BOOT".format(self.outputroot)]
+
+        # create boot image
+        boot_fpath = joinpaths(self.outputroot, IMAGESDIR, "boot.iso")
+
+        # run mkisofs
+        cmd = [MKISOFS, "-v", "-o", boot_fpath, "-b",
+               "{0}/isolinux.bin".format(ISOLINUXDIR), "-c",
+               "{0}/boot.cat".format(ISOLINUXDIR), "-no-emul-boot",
+               "-boot-load-size", "4", "-boot-info-table"] + efiargs + \
+              ["-R", "-J", "-V", "'{0}'".format(self.product), "-T",
+               "-graft-points",
+               "isolinux={0}".format(joinpaths(self.outputroot, ISOLINUXDIR)),
+               "images={0}".format(joinpaths(self.outputroot, IMAGESDIR))] + \
+              efigraft
+
+        p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+                             stdout=subprocess.PIPE)
+        p.wait()
+
+        if os.path.exists(ISOHYBRID):
+            # run isohybrid
+            cmd = [ISOHYBRID, boot_fpath]
+            p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+                                 stdout=subprocess.PIPE)
+            p.wait()
+
+        # run implantisomd5
+        cmd = [IMPLANTISOMD5, boot_fpath]
+        p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+                             stdout=subprocess.PIPE)
+        p.wait()
diff --git a/src/pylorax/outputtree.py b/src/pylorax/outputtree.py
index e258bd8..e37190b 100644
--- a/src/pylorax/outputtree.py
+++ b/src/pylorax/outputtree.py
@@ -65,7 +65,7 @@ class LoraxOutputTree(BaseLoraxClass):
         self.isolinuxdir = isolinuxdir
         self.efibootdir = efibootdir
 
-    def get_kernels(self):
+    def get_kernels(self, workdir):
         self.kernels = []
 
         for n, kernel in enumerate(self.installtree.kernels):
@@ -77,18 +77,21 @@ class LoraxOutputTree(BaseLoraxClass):
 
             kname = "vmlinuz{0}".format(suffix)
 
-            if n == 0:
-                # copy main kernel to isolinuxdir
-                dst = joinpaths(self.isolinuxdir, kname)
-                shutil.copy2(kernel.fpath, dst)
-
-                # create hard link to main kernel in pxebootdir
-                link_name = joinpaths(self.pxebootdir, kname)
-                os.link(dst, link_name)
-            else:
-                # copy other kernels to pxebootdir
-                dst = joinpaths(self.pxebootdir, kname)
-                shutil.copy2(kernel.fpath, dst)
+            dst = joinpaths(workdir, kname)
+            shutil.copy2(kernel.fpath, dst)
+
+            #if n == 0:
+            #    # copy main kernel to isolinuxdir
+            #    dst = joinpaths(self.isolinuxdir, kname)
+            #    shutil.copy2(kernel.fpath, dst)
+            #
+            #    # create hard link to main kernel in pxebootdir
+            #    link_name = joinpaths(self.pxebootdir, kname)
+            #    os.link(dst, link_name)
+            #else:
+            #    # copy other kernels to pxebootdir
+            #    dst = joinpaths(self.pxebootdir, kname)
+            #    shutil.copy2(kernel.fpath, dst)
 
             # change the fname and fpath to new values
             self.kernels.append(DataHolder(fname=kname,
diff --git a/src/pylorax/sysutils.py b/src/pylorax/sysutils.py
index 6db2885..1813ec2 100644
--- a/src/pylorax/sysutils.py
+++ b/src/pylorax/sysutils.py
@@ -32,6 +32,7 @@ import pwd
 import grp
 import glob
 import subprocess
+import shutil
 
 
 def joinpaths(*args, **kwargs):
@@ -126,3 +127,11 @@ def remove_dm_dev(dev):
     cmd = ["dmsetup", "remove", dev]
     proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
     return proc.wait()
+
+
+def cpfile(src, dst):
+    shutil.copy2(src, dst)
+    if os.path.isdir(dst):
+        dst = joinpaths(dst, os.path.basename(src))
+
+    return dst
-- 
1.7.3.2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]