2009-08-27 07:19:49 +00:00
|
|
|
#
|
|
|
|
# __init__.py
|
2010-01-12 11:45:54 +00:00
|
|
|
# main lorax class
|
|
|
|
#
|
|
|
|
# Copyright (C) 2009 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): David Cantrell <dcantrell@redhat.com>
|
|
|
|
# Martin Gracik <mgracik@redhat.com>
|
2009-08-27 07:19:49 +00:00
|
|
|
#
|
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
__VERSION__ = "0.1"
|
|
|
|
|
2009-04-22 13:01:28 +00:00
|
|
|
import sys
|
2008-09-13 02:04:02 +00:00
|
|
|
import os
|
2009-09-23 10:21:33 +00:00
|
|
|
import ConfigParser
|
2009-12-15 14:26:01 +00:00
|
|
|
import re
|
|
|
|
import glob
|
2009-04-22 13:01:28 +00:00
|
|
|
import time
|
2009-08-19 14:51:32 +00:00
|
|
|
import datetime
|
2009-12-15 14:26:01 +00:00
|
|
|
import shutil
|
2009-09-23 10:21:33 +00:00
|
|
|
import commands
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
import yum
|
|
|
|
import yum.callbacks
|
|
|
|
import yum.rpmtrans
|
2008-10-05 04:44:28 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
import config
|
2009-09-23 10:21:33 +00:00
|
|
|
import output
|
2009-12-15 14:26:01 +00:00
|
|
|
import ramdisk
|
|
|
|
import efi
|
|
|
|
import install
|
|
|
|
import lcs
|
2009-06-04 13:36:56 +00:00
|
|
|
|
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
ARCHS64 = ( "x86_64",
|
|
|
|
"s390x",
|
|
|
|
"sparc64" )
|
2009-06-04 13:36:56 +00:00
|
|
|
|
2009-12-17 16:53:47 +00:00
|
|
|
BASEARCH_MAP = { "i586" : "i386",
|
|
|
|
"i686" : "i386",
|
2009-12-15 14:26:01 +00:00
|
|
|
"sparc64" : "sparc" }
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
EFIARCH_MAP = { "i386" : "IA32",
|
2009-12-17 16:53:47 +00:00
|
|
|
"i586" : "IA32",
|
|
|
|
"i686" : "IA32",
|
2009-12-15 14:26:01 +00:00
|
|
|
"x86_64" : "X64",
|
|
|
|
"ia64" : "IA64" }
|
2009-06-04 13:36:56 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
LIB32 = "lib"
|
|
|
|
LIB64 = "lib64"
|
2009-06-04 13:36:56 +00:00
|
|
|
|
2008-09-12 00:21:12 +00:00
|
|
|
|
2009-09-23 10:21:33 +00:00
|
|
|
class LoraxError(Exception):
|
|
|
|
pass
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
|
2009-06-04 13:36:56 +00:00
|
|
|
class Lorax(object):
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
SETTINGS = ( "colors",
|
|
|
|
"encoding",
|
|
|
|
"debug",
|
|
|
|
"cleanup" )
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
REQ_PARAMS = ( "product",
|
|
|
|
"version",
|
|
|
|
"release",
|
|
|
|
"outputdir",
|
|
|
|
"tempdir",
|
|
|
|
"installtree" )
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
OPT_PARAMS = ( "variant",
|
|
|
|
"bugurl",
|
|
|
|
"updates" )
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
def __init__(self, yb, *args, **kwargs):
|
|
|
|
# check if we have root privileges
|
|
|
|
if not os.geteuid() == 0:
|
|
|
|
raise LoraxError("no root privileges")
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# check the yumbase object
|
|
|
|
if not isinstance(yb, yum.YumBase):
|
|
|
|
raise LoraxError("not an yumbase object")
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# create the yum object
|
|
|
|
self.yum = YumHelper(yb)
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# get the config object
|
|
|
|
self.conf = config.LoraxConfig.get()
|
2009-04-22 13:01:28 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# get the settings first
|
|
|
|
for key in self.SETTINGS:
|
|
|
|
value = kwargs.get(key, None)
|
|
|
|
if value is not None:
|
|
|
|
setattr(self.conf, key, value)
|
2009-04-22 13:01:28 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# set up the output
|
|
|
|
self.output = output.Terminal.get()
|
2009-04-22 13:01:28 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
output_level = output.INFO
|
|
|
|
if self.conf.debug:
|
|
|
|
output_level = output.DEBUG
|
2009-04-22 13:01:28 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
self.output.basic_config(colors=self.conf.colors,
|
|
|
|
encoding=self.conf.encoding,
|
|
|
|
level=output_level)
|
2008-10-06 01:08:38 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# check and set up the required parameters
|
|
|
|
for key in self.REQ_PARAMS:
|
|
|
|
value = kwargs.get(key, None)
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
if value is None:
|
|
|
|
raise LoraxError("missing required parameter '%s'" % key)
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
setattr(self.conf, key, value)
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# set up the optional parameters
|
|
|
|
for key in self.OPT_PARAMS:
|
|
|
|
setattr(self.conf, key, kwargs.get(key, ""))
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# check if the required directories exist
|
|
|
|
if os.path.isdir(self.conf.outputdir):
|
|
|
|
raise LoraxError("output directory '%s' already exist" % \
|
|
|
|
self.conf.outputdir)
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
if not os.path.isdir(self.conf.tempdir):
|
|
|
|
raise LoraxError("temporary directory '%s' does not exist" % \
|
|
|
|
self.conf.tempdir)
|
2009-09-09 10:43:00 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
if not os.path.isdir(self.conf.installtree):
|
|
|
|
raise LoraxError("install tree directory '%s' does not exist" % \
|
|
|
|
self.conf.installtree)
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# get the paths
|
|
|
|
self.paths = config.LoraxPaths.get()
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
def run(self):
|
|
|
|
# set the target architecture
|
|
|
|
self.output.info(":: setting the build architecture")
|
|
|
|
self.conf.arch = self.get_arch()
|
|
|
|
self.conf.basearch = BASEARCH_MAP.get(self.conf.arch, self.conf.arch)
|
|
|
|
self.conf.efiarch = EFIARCH_MAP.get(self.conf.arch, "")
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# set the libdir
|
|
|
|
self.conf.libdir = LIB32
|
|
|
|
if self.conf.arch in ARCHS64:
|
|
|
|
self.conf.libdir = LIB64
|
|
|
|
|
|
|
|
# read the config files
|
|
|
|
self.output.info(":: reading the configuration files")
|
|
|
|
packages, modules, initrd_template, scrubs_template = self.get_config()
|
|
|
|
|
|
|
|
# add the branding
|
|
|
|
packages.add("%s-logos" % self.conf.product.lower())
|
|
|
|
packages.add("%s-release" % self.conf.product.lower())
|
|
|
|
|
|
|
|
self.conf.packages = packages
|
|
|
|
self.conf.modules = modules
|
|
|
|
self.conf.initrd_template = initrd_template
|
|
|
|
self.conf.scrubs_template = scrubs_template
|
|
|
|
|
|
|
|
# install packages into the install tree
|
|
|
|
self.output.info(":: installing required packages")
|
|
|
|
for name in packages:
|
|
|
|
if not self.yum.install(name):
|
|
|
|
self.output.warning("no package %s found" % \
|
|
|
|
self.output.format(name, type=output.BOLD))
|
|
|
|
|
|
|
|
self.yum.process_transaction()
|
|
|
|
|
|
|
|
# copy the updates
|
|
|
|
if self.conf.updates and os.path.isdir(self.conf.updates):
|
|
|
|
self.output.info(":: copying updates")
|
|
|
|
utils.scopy(src_root=self.conf.updates, src_path="*",
|
|
|
|
dst_root=self.conf.installtree, dst_path="")
|
|
|
|
|
|
|
|
# get the anaconda runtime directory
|
|
|
|
if os.path.isdir(self.paths.ANACONDA_RUNTIME):
|
|
|
|
self.conf.anaconda_runtime = self.paths.ANACONDA_RUNTIME
|
|
|
|
self.conf.anaconda_boot = self.paths.ANACONDA_BOOT
|
2009-06-04 13:36:56 +00:00
|
|
|
else:
|
2009-12-15 14:26:01 +00:00
|
|
|
self.output.critical("no anaconda runtime directory found")
|
|
|
|
sys.exit(1)
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# get list of the installed kernel files
|
|
|
|
kerneldir = self.paths.BOOTDIR
|
|
|
|
if self.conf.arch == "ia64":
|
|
|
|
kerneldir = self.paths.BOOTDIR_IA64
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
kernelfiles = glob.glob(os.path.join(kerneldir, "vmlinuz-*"))
|
2009-08-26 15:16:46 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
if not kernelfiles:
|
|
|
|
self.output.critical("no kernel image found")
|
|
|
|
sys.exit(1)
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# create treeinfo, discinfo, and buildstamp
|
|
|
|
self.conf.treeinfo = self.write_treeinfo()
|
|
|
|
self.conf.discinfo = self.write_discinfo()
|
|
|
|
self.conf.buildstamp = self.write_buildstamp()
|
|
|
|
|
|
|
|
# prepare the output directory
|
|
|
|
self.output.info(":: preparing the output directory")
|
|
|
|
ok = self.prepare_output_directory()
|
|
|
|
|
|
|
|
if not ok:
|
|
|
|
self.output.critical("unable to prepare the output directory")
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
for kernelfile in kernelfiles:
|
|
|
|
kfilename = os.path.basename(kernelfile)
|
|
|
|
m = re.match(r"vmlinuz-(?P<ver>.*)", kfilename)
|
|
|
|
if m:
|
|
|
|
self.conf.kernelfile = kernelfile
|
|
|
|
self.conf.kernelver = m.group("ver")
|
|
|
|
else:
|
|
|
|
continue
|
|
|
|
|
|
|
|
self.output.info(":: creating initrd for '%s'" % kfilename)
|
|
|
|
|
|
|
|
# create a temporary directory for the ramdisk tree
|
|
|
|
self.conf.ramdisktree = os.path.join(self.conf.tempdir,
|
|
|
|
"ramdisk-%s" % \
|
|
|
|
self.conf.kernelver)
|
|
|
|
|
|
|
|
utils.makedirs(self.conf.ramdisktree)
|
|
|
|
|
|
|
|
initrd = ramdisk.Ramdisk()
|
|
|
|
kernel_path, initrd_path = initrd.create()
|
|
|
|
|
|
|
|
# copy the kernel and initrd images to the pxeboot directory
|
2010-01-14 13:26:55 +00:00
|
|
|
if kernel_path is not None:
|
|
|
|
shutil.copy2(kernel_path, self.conf.pxebootdir)
|
|
|
|
if kernel_path is not None:
|
|
|
|
shutil.copy2(initrd_path, self.conf.pxebootdir)
|
2009-12-15 14:26:01 +00:00
|
|
|
|
|
|
|
# if this is a PAE kernel, skip the EFI part
|
|
|
|
if kernel_path.endswith("PAE"):
|
|
|
|
continue
|
|
|
|
|
|
|
|
# copy the kernel and initrd images to the isolinux directory
|
|
|
|
shutil.copy2(kernel_path, self.conf.isolinuxdir)
|
|
|
|
shutil.copy2(initrd_path, self.conf.isolinuxdir)
|
|
|
|
|
|
|
|
# create the efi images
|
|
|
|
self.output.info(":: creating efi images for '%s'" % kfilename)
|
|
|
|
|
|
|
|
efiimages = efi.EFI()
|
|
|
|
eb, ed = efiimages.create(kernel=kernel_path,
|
|
|
|
initrd=initrd_path,
|
|
|
|
kernelpath="/images/pxeboot/vmlinuz",
|
|
|
|
initrdpath="/images/pxeboot/initrd.img")
|
|
|
|
|
|
|
|
self.conf.efiboot = eb
|
|
|
|
self.conf.efidisk = ed
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# copy the efi images to the images directory
|
|
|
|
shutil.copy2(self.conf.efiboot, self.conf.imagesdir)
|
|
|
|
shutil.copy2(self.conf.efidisk, self.conf.imagesdir)
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# create the install image
|
|
|
|
self.output.info(":: creating the install image")
|
|
|
|
i = install.InstallImage()
|
|
|
|
installimg = i.create()
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
if installimg is None:
|
|
|
|
self.output.critical("unable to create install image")
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
shutil.copy2(installimg, self.conf.imagesdir)
|
|
|
|
|
|
|
|
# create the boot iso
|
2010-01-14 13:26:55 +00:00
|
|
|
if self.conf.arch in ("i386", "i586", "i686", "x86_64"):
|
|
|
|
self.output.info(":: creating the boot iso")
|
|
|
|
bootiso = self.create_boot_iso_x86()
|
|
|
|
elif self.conf.arch in ("ppc", "ppc64"):
|
|
|
|
self.output.info(":: creating the boot iso")
|
|
|
|
bootiso = self.create_boot_iso_ppc()
|
2009-12-15 14:26:01 +00:00
|
|
|
|
|
|
|
if bootiso is None:
|
|
|
|
self.output.critical("unable to create boot iso")
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
shutil.copy2(bootiso, self.conf.imagesdir)
|
|
|
|
|
|
|
|
# copy the treeinfo and discinfo to the output directory
|
|
|
|
shutil.copy2(self.conf.treeinfo, self.conf.outputdir)
|
|
|
|
shutil.copy2(self.conf.discinfo, self.conf.outputdir)
|
|
|
|
|
|
|
|
# cleanup
|
|
|
|
self.cleanup()
|
|
|
|
|
|
|
|
def get_arch(self):
|
|
|
|
# get the architecture of the anaconda package
|
|
|
|
installed, available = self.yum.search(self.paths.ANACONDA_PACKAGE)
|
2008-10-10 03:04:13 +00:00
|
|
|
try:
|
2009-12-15 14:26:01 +00:00
|
|
|
arch = available[0].arch
|
2009-06-04 13:36:56 +00:00
|
|
|
except:
|
2009-12-15 14:26:01 +00:00
|
|
|
# fallback to the system architecture
|
|
|
|
arch = os.uname()[4]
|
2009-06-04 13:36:56 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
return arch
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
def get_config(self):
|
|
|
|
generic = os.path.join(self.conf.confdir, "config.noarch")
|
|
|
|
specific = os.path.join(self.conf.confdir,
|
|
|
|
"config.%s" % self.conf.arch)
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
packages, modules = set(), set()
|
|
|
|
initrd_template, scrubs_template = None, None
|
2009-06-04 13:36:56 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
for f in (generic, specific):
|
|
|
|
if not os.path.isfile(f):
|
|
|
|
continue
|
2009-08-25 16:26:52 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
c = ConfigParser.ConfigParser()
|
|
|
|
c.read(f)
|
|
|
|
|
|
|
|
if c.has_option("lorax", "packages"):
|
|
|
|
list = c.get("lorax", "packages").split()
|
|
|
|
for name in list:
|
|
|
|
if name.startswith("-"):
|
|
|
|
packages.discard(name)
|
|
|
|
else:
|
|
|
|
packages.add(name)
|
|
|
|
|
|
|
|
if c.has_option("lorax", "modules"):
|
|
|
|
list = c.get("lorax", "modules").split()
|
|
|
|
for name in list:
|
|
|
|
if name.startswith("-"):
|
|
|
|
modules.discard(name)
|
|
|
|
else:
|
|
|
|
modules.add(name)
|
|
|
|
|
|
|
|
if c.has_option("lorax", "initrd_template"):
|
|
|
|
initrd_template = c.get("lorax", "initrd_template")
|
|
|
|
initrd_template = os.path.join(self.conf.confdir,
|
|
|
|
initrd_template)
|
|
|
|
|
|
|
|
if c.has_option("lorax", "scrubs_template"):
|
|
|
|
scrubs_template = c.get("lorax", "scrubs_template")
|
|
|
|
scrubs_template = os.path.join(self.conf.confdir,
|
|
|
|
scrubs_template)
|
|
|
|
|
|
|
|
return packages, modules, initrd_template, scrubs_template
|
2009-08-25 16:26:52 +00:00
|
|
|
|
2009-09-23 10:21:33 +00:00
|
|
|
def write_treeinfo(self, discnum=1, totaldiscs=1, packagedir=""):
|
2009-12-15 14:26:01 +00:00
|
|
|
outfile = os.path.join(self.conf.tempdir, ".treeinfo")
|
|
|
|
|
|
|
|
variant = self.conf.variant
|
|
|
|
if variant is None:
|
|
|
|
variant = ""
|
2009-06-04 13:36:56 +00:00
|
|
|
|
2009-04-22 13:01:28 +00:00
|
|
|
c = ConfigParser.ConfigParser()
|
2009-09-23 10:21:33 +00:00
|
|
|
|
|
|
|
section = "general"
|
2009-12-15 14:26:01 +00:00
|
|
|
data = { "timestamp" : time.time(),
|
|
|
|
"family" : self.conf.product,
|
|
|
|
"version" : self.conf.version,
|
|
|
|
"arch" : self.conf.basearch,
|
|
|
|
"variant" : variant,
|
|
|
|
"discnum" : discnum,
|
|
|
|
"totaldiscs" : totaldiscs,
|
|
|
|
"packagedir" : packagedir }
|
|
|
|
|
2009-04-22 13:01:28 +00:00
|
|
|
c.add_section(section)
|
2009-12-15 14:26:01 +00:00
|
|
|
map(lambda (key, value): c.set(section, key, value), data.items())
|
|
|
|
|
|
|
|
section = "images-%s" % self.conf.basearch
|
|
|
|
data = { "kernel" : "images/pxeboot/vmlinuz",
|
|
|
|
"initrd" : "images/pxeboot/initrd.img",
|
|
|
|
"boot.iso" : "images/boot.iso" }
|
2008-10-06 01:08:38 +00:00
|
|
|
|
2009-06-04 13:36:56 +00:00
|
|
|
c.add_section(section)
|
2009-12-15 14:26:01 +00:00
|
|
|
map(lambda (key, value): c.set(section, key, value), data.items())
|
2009-06-04 13:36:56 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
with open(outfile, "w") as f:
|
2009-04-22 13:01:28 +00:00
|
|
|
c.write(f)
|
2009-12-15 14:26:01 +00:00
|
|
|
|
|
|
|
return outfile
|
2009-09-23 10:21:33 +00:00
|
|
|
|
|
|
|
def write_discinfo(self, discnum="ALL"):
|
2009-12-15 14:26:01 +00:00
|
|
|
outfile = os.path.join(self.conf.tempdir, ".discinfo")
|
2008-10-04 01:46:01 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
with open(outfile, "w") as f:
|
|
|
|
f.write("%f\n" % time.time())
|
|
|
|
f.write("%s\n" % self.conf.release)
|
|
|
|
f.write("%s\n" % self.conf.basearch)
|
|
|
|
f.write("%s\n" % discnum)
|
|
|
|
|
|
|
|
return outfile
|
2009-08-19 14:51:32 +00:00
|
|
|
|
|
|
|
def write_buildstamp(self):
|
2009-12-15 14:26:01 +00:00
|
|
|
outfile = os.path.join(self.conf.tempdir, ".buildstamp")
|
2009-08-19 14:51:32 +00:00
|
|
|
|
|
|
|
now = datetime.datetime.now()
|
2009-12-15 14:26:01 +00:00
|
|
|
uuid = "%s.%s" % (now.strftime("%Y%m%d%H%M"), self.conf.arch)
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
with open(outfile, "w") as f:
|
|
|
|
f.write("%s\n" % uuid)
|
|
|
|
f.write("%s\n" % self.conf.product)
|
|
|
|
f.write("%s\n" % self.conf.version)
|
|
|
|
f.write("%s\n" % self.conf.bugurl)
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
return outfile
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-09-23 10:21:33 +00:00
|
|
|
def prepare_output_directory(self):
|
2009-12-15 14:26:01 +00:00
|
|
|
# create the output directory
|
|
|
|
os.mkdir(self.conf.outputdir)
|
|
|
|
|
|
|
|
# create the images directory
|
|
|
|
imagesdir = os.path.join(self.conf.outputdir, "images")
|
|
|
|
utils.mkdir(imagesdir)
|
|
|
|
self.conf.imagesdir = imagesdir
|
|
|
|
|
|
|
|
# write the images/README file
|
|
|
|
src = os.path.join(self.paths.OUTPUTDIR_DATADIR, "images", "README")
|
|
|
|
dst = os.path.join(imagesdir, "README")
|
2009-09-04 11:34:04 +00:00
|
|
|
shutil.copy2(src, dst)
|
2009-12-15 14:26:01 +00:00
|
|
|
utils.replace(dst, r"@PRODUCT@", self.conf.product)
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# create the pxeboot directory
|
|
|
|
pxebootdir = os.path.join(imagesdir, "pxeboot")
|
|
|
|
utils.mkdir(pxebootdir)
|
|
|
|
self.conf.pxebootdir = pxebootdir
|
|
|
|
|
|
|
|
# write the images/pxeboot/README file
|
|
|
|
src = os.path.join(self.paths.OUTPUTDIR_DATADIR, "images", "pxeboot",
|
|
|
|
"README")
|
|
|
|
dst = os.path.join(pxebootdir, "README")
|
2009-09-04 11:34:04 +00:00
|
|
|
shutil.copy2(src, dst)
|
2009-12-15 14:26:01 +00:00
|
|
|
utils.replace(dst, r"@PRODUCT@", self.conf.product)
|
|
|
|
|
|
|
|
# create the efiboot directory
|
|
|
|
efibootdir = os.path.join(self.conf.outputdir, "EFI", "BOOT")
|
|
|
|
utils.makedirs(efibootdir)
|
|
|
|
self.conf.efibootdir = efibootdir
|
|
|
|
|
|
|
|
# create the isolinux directory
|
|
|
|
isolinuxdir = os.path.join(self.conf.outputdir, "isolinux")
|
|
|
|
utils.mkdir(isolinuxdir)
|
|
|
|
self.conf.isolinuxdir = isolinuxdir
|
|
|
|
|
|
|
|
syslinuxdir = self.paths.SYSLINUXDIR
|
|
|
|
isolinuxbin = self.paths.ISOLINUXBIN
|
|
|
|
|
|
|
|
if not os.path.isfile(isolinuxbin):
|
|
|
|
self.output.error("no isolinux binary found")
|
2009-09-23 10:21:33 +00:00
|
|
|
return False
|
2009-08-25 16:26:52 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# copy the isolinux.bin
|
|
|
|
shutil.copy2(isolinuxbin, isolinuxdir)
|
2009-08-25 16:26:52 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# copy the syslinux.cfg to isolinux/isolinux.cfg
|
|
|
|
isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg")
|
|
|
|
shutil.copy2(self.paths.SYSLINUXCFG, isolinuxcfg)
|
2009-09-29 12:41:39 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# set the product and version in isolinux.cfg
|
|
|
|
utils.replace(isolinuxcfg, r"@PRODUCT@", self.conf.product)
|
|
|
|
utils.replace(isolinuxcfg, r"@VERSION@", self.conf.version)
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# set up the label for finding stage2 with a hybrid iso
|
|
|
|
utils.replace(isolinuxcfg, r"initrd=initrd.img",
|
|
|
|
'initrd=initrd.img stage2=hd:LABEL="%s"' % \
|
|
|
|
self.conf.product)
|
2009-08-25 16:26:52 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# copy the grub.conf
|
|
|
|
dst = os.path.join(isolinuxdir, "grub.conf")
|
|
|
|
shutil.copy2(self.paths.GRUBCONF, dst)
|
2009-08-25 16:26:52 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
# copy the splash files
|
|
|
|
if os.path.isfile(self.paths.VESASPLASH):
|
|
|
|
shutil.copy2(self.paths.VESASPLASH,
|
|
|
|
os.path.join(isolinuxdir, "splash.jpg"))
|
|
|
|
|
|
|
|
shutil.copy2(self.paths.VESAMENU, isolinuxdir)
|
|
|
|
|
|
|
|
utils.replace(isolinuxcfg, r"default linux", "default vesamenu.c32")
|
|
|
|
utils.replace(isolinuxcfg, r"prompt 1", "#prompt 1")
|
|
|
|
|
|
|
|
else:
|
|
|
|
if os.path.isfile(self.paths.SPLASHTOOLS):
|
|
|
|
cmd = "%s %s %s" % (self.paths.SPLASHTOOLS,
|
|
|
|
self.paths.SYSLINUXSPLASH,
|
|
|
|
self.paths.SPLASHLSS)
|
|
|
|
err, output = commands.getstatusoutput(cmd)
|
|
|
|
if err:
|
|
|
|
self.output.warning(output)
|
|
|
|
|
|
|
|
if os.path.isfile(self.paths.SPLASHLSS):
|
|
|
|
shutil.copy2(self.paths.SPLASHLSS, isolinuxdir)
|
|
|
|
|
|
|
|
# copy the .msg files
|
|
|
|
msgfiles = os.path.join(self.conf.anaconda_boot, "*.msg")
|
|
|
|
for fname in glob.glob(msgfiles):
|
|
|
|
shutil.copy2(fname, isolinuxdir)
|
|
|
|
utils.replace(os.path.join(isolinuxdir, os.path.basename(fname)),
|
|
|
|
r"@VERSION@", self.conf.version)
|
|
|
|
|
|
|
|
# copy the memtest
|
|
|
|
memtest = os.path.join(self.paths.BOOTDIR, "memtest*")
|
|
|
|
for fname in glob.glob(memtest):
|
|
|
|
shutil.copy2(fname, os.path.join(isolinuxdir, "memtest"))
|
|
|
|
|
|
|
|
text = """label memtest86
|
|
|
|
menu label ^Memory test
|
|
|
|
kernel memtest
|
|
|
|
append -
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
utils.edit(isolinuxcfg, append=True, text=text)
|
|
|
|
break
|
2009-08-25 16:26:52 +00:00
|
|
|
|
2009-09-23 10:21:33 +00:00
|
|
|
return True
|
2009-09-04 11:34:04 +00:00
|
|
|
|
2010-01-14 13:26:55 +00:00
|
|
|
def create_boot_iso_x86(self):
|
2009-12-15 14:26:01 +00:00
|
|
|
bootiso = os.path.join(self.conf.tempdir, "boot.iso")
|
2009-09-29 12:41:39 +00:00
|
|
|
|
|
|
|
if os.path.exists(bootiso):
|
|
|
|
os.unlink(bootiso)
|
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
if os.path.exists(self.conf.efiboot):
|
|
|
|
self.output.info(":: creating efi capable boot iso")
|
2009-09-23 10:21:33 +00:00
|
|
|
efiargs = "-eltorito-alt-boot -e images/efiboot.img -no-emul-boot"
|
2009-12-15 14:26:01 +00:00
|
|
|
efigraft = "EFI/BOOT=%s" % self.conf.efibootdir
|
2009-09-23 10:21:33 +00:00
|
|
|
else:
|
|
|
|
efiargs = ""
|
|
|
|
efigraft = ""
|
|
|
|
|
2009-12-17 16:53:47 +00:00
|
|
|
#biosargs = "-b isolinux/isolinux.bin -c isolinux/boot.cat" \
|
|
|
|
# " -no-emul-boot -boot-load-size 4 -boot-info-table"
|
|
|
|
|
|
|
|
#cmd = "%s -v -o %s %s %s -R -J -V %s -T -graft-points" \
|
|
|
|
# " isolinux=%s images=%s %s" % (self.paths.MKISOFS, bootiso,
|
|
|
|
# biosargs, efiargs,
|
|
|
|
# self.conf.product,
|
|
|
|
# self.conf.isolinuxdir,
|
|
|
|
# self.conf.imagesdir, efigraft)
|
|
|
|
|
|
|
|
cmd = "%s -U -A %s -V %s -volset %s -J -joliet-long -r -v -T -o %s" \
|
|
|
|
" -b isolinux/isolinux.bin -c isolinux/boot.cat" \
|
|
|
|
" -no-emul-boot -boot-load-size 4 -boot-info-table" \
|
|
|
|
" %s -graft-points isolinux=%s images=%s %s" \
|
|
|
|
% (self.paths.MKISOFS, self.conf.product, self.conf.product,
|
|
|
|
self.conf.product, bootiso, efiargs,
|
|
|
|
self.conf.isolinuxdir, self.conf.imagesdir, efigraft)
|
2009-12-15 14:26:01 +00:00
|
|
|
|
|
|
|
err, output = commands.getstatusoutput(cmd)
|
2009-09-23 10:21:33 +00:00
|
|
|
if err:
|
2009-12-15 14:26:01 +00:00
|
|
|
self.output.error(output)
|
|
|
|
return None
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
if os.path.isfile(self.paths.ISOHYBRID):
|
|
|
|
cmd = "%s %s" % (self.paths.ISOHYBRID, bootiso)
|
|
|
|
err, output = commands.getstatusoutput(cmd)
|
2009-09-23 10:21:33 +00:00
|
|
|
if err:
|
2009-12-15 14:26:01 +00:00
|
|
|
self.output.warning(output)
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
return bootiso
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2010-01-14 13:26:55 +00:00
|
|
|
def create_boot_iso_ppc(self):
|
|
|
|
bootiso = os.path.join(self.conf.tempdir, "boot.iso")
|
|
|
|
|
|
|
|
if os.path.exists(bootiso):
|
|
|
|
os.unlink(bootiso)
|
|
|
|
|
|
|
|
etcdir = os.path.join(self.conf.outputdir, "etc")
|
|
|
|
ppcdir = os.path.join(self.conf.outputdir, "ppc")
|
|
|
|
macdir = os.path.join(ppcdir, "mac")
|
|
|
|
chrpdir = os.path.join(ppcdir, "chrp")
|
|
|
|
|
|
|
|
utils.makedirs(etcdir)
|
|
|
|
utils.makedirs(chrpdir)
|
|
|
|
|
|
|
|
shutil.copy2(self.paths.BOOTINFO, ppcdir)
|
|
|
|
shutil.copy2(self.paths.EFIKA_FORTH, ppcdir)
|
|
|
|
|
|
|
|
if os.path.isdir(macdir):
|
|
|
|
shutil.copy2(self.paths.OFBOOT, macdir)
|
|
|
|
shutil.copy2(self.paths.YABOOT, macdir)
|
|
|
|
|
|
|
|
if os.path.isdir(chrpdir):
|
|
|
|
shutil.copy2(self.paths.YABOOT, chrpdir)
|
|
|
|
cmd = "%s %s" % (self.paths.ADD_NOTE,
|
|
|
|
os.path.join(chrpdir, "yaboot"))
|
|
|
|
|
|
|
|
# IBM firmware can't handle boot scripts properly,
|
|
|
|
# so for biarch installs we use a yaboot.conf,
|
|
|
|
# which asks the user to select 32-bit or 64-bit kernel
|
|
|
|
yaboot32 = os.path.join(ppcdir, "ppc32", "yaboot.conf")
|
|
|
|
yaboot64 = os.path.join(ppcdir, "ppc64", "yaboot.conf")
|
|
|
|
if os.path.isfile(yaboot32) and os.path.isfile(yaboot64):
|
|
|
|
# both kernels exist, copy the biarch yaboot.conf into place
|
|
|
|
yaboot = os.path.join(etcdir, "yaboot.conf")
|
|
|
|
shutil.copy2(self.paths.BIARCH_YABOOT, yaboot)
|
|
|
|
utils.replace(yaboot, "%BITS%", "32")
|
|
|
|
utils.replace(yaboot, "%PRODUCT%", self.conf.product)
|
|
|
|
utils.replace(yaboot, "%VERSION%", self.conf.version)
|
|
|
|
else:
|
|
|
|
if os.path.isfile(yaboot32):
|
|
|
|
shutil.copy2(yaboot32, etcdir)
|
|
|
|
if os.path.isfile(yaboot64):
|
|
|
|
shutil.copy2(yaboot64, etcdir)
|
|
|
|
|
|
|
|
isopath = os.path.join(self.conf.outputdir, "isopath")
|
|
|
|
utils.mkdir(isopath)
|
|
|
|
|
|
|
|
utils.scopy(ppcdir, isopath)
|
|
|
|
utils.scopy(etcdir, isopath)
|
|
|
|
|
|
|
|
netbootdir = os.path.join(self.conf.outputdir, "images", "netboot")
|
|
|
|
if os.path.isdir(netbootdir):
|
|
|
|
imagesdir = os.path.join(isopath, "images")
|
|
|
|
utils.mkdir(imagesdir)
|
|
|
|
|
|
|
|
utils.scopy(netbootdir, imagesdir)
|
|
|
|
utils.remove(os.path.join(imagesdir, "ppc64.img"))
|
|
|
|
|
|
|
|
ppc32img = os.path.join(netbootdir, "ppc32.img")
|
|
|
|
if os.path.isfile(pcp32img):
|
|
|
|
prepboot = "-prep-boot images/netboot/ppc32.img"
|
|
|
|
|
|
|
|
isomacdir = os.path.join(isopath, "ppc", "mac")
|
|
|
|
if os.path.isdir(isomacdir):
|
|
|
|
macboot = "-hfs-volid %s -hfs-bless %s" % (self.conf.version,
|
|
|
|
isomacdir)
|
|
|
|
|
|
|
|
installimg = os.path.join(self.conf.imagesdir, "install.img")
|
|
|
|
cmd = '%s -o %s -chrp-boot -U %s -part -hfs -T -r -l -J -A "%s %s"' \
|
|
|
|
' -sysid PPC -V "PBOOT" -volset %s -volset-size 1' \
|
|
|
|
' -volset-seqno 1 %s -map %s/mapping -magic %s/magic' \
|
|
|
|
' -no-desktop' \
|
|
|
|
' -allow-multidot -graft-points %s images/install.img=%s' % \
|
|
|
|
(self.paths.MKISOFS, bootiso, prepboot, self.conf.product,
|
|
|
|
self.conf.version, self.conf.version, macboot,
|
|
|
|
self.paths.ANACONDA_BOOT, self.paths.ANACONDA_BOOT,
|
|
|
|
isopath, installimg)
|
|
|
|
|
|
|
|
err, output = commands.getstatusoutput(cmd)
|
|
|
|
if err:
|
|
|
|
self.output.warning(output)
|
|
|
|
return None
|
|
|
|
|
|
|
|
cmd = "%s %s" % (self.paths.IMPLANTISO, bootiso)
|
|
|
|
err, output = commands.getstatusoutput(cmd)
|
|
|
|
if err:
|
|
|
|
self.output.warning(output)
|
|
|
|
return None
|
|
|
|
|
|
|
|
utils.remove(isopath)
|
|
|
|
|
|
|
|
return bootiso
|
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
def cleanup(self):
|
|
|
|
if self.conf.cleanup:
|
|
|
|
shutil.rmtree(self.conf.tempdir)
|
2009-08-19 14:51:32 +00:00
|
|
|
|
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
class YumHelper(object):
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
def __init__(self, yb):
|
|
|
|
self.yb = yb
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
def install(self, pattern):
|
|
|
|
try:
|
|
|
|
self.yb.install(name=pattern)
|
|
|
|
except yum.Errors.InstallError:
|
|
|
|
try:
|
|
|
|
self.yb.install(pattern=pattern)
|
|
|
|
except yum.Errors.InstallError:
|
|
|
|
return False
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
return True
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
def process_transaction(self):
|
|
|
|
self.yb.resolveDeps()
|
|
|
|
self.yb.buildTransaction()
|
2009-08-19 14:51:32 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
cb = yum.callbacks.ProcessTransBaseCallback()
|
|
|
|
rpmcb = RpmCallback()
|
2008-09-13 02:04:02 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
self.yb.processTransaction(callback=cb, rpmDisplay=rpmcb)
|
2009-08-25 16:26:52 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
self.yb.closeRpmDB()
|
|
|
|
self.yb.close()
|
2009-08-25 16:26:52 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
def search(self, pattern):
|
|
|
|
pl = self.yb.doPackageLists(patterns=[pattern])
|
|
|
|
return pl.installed, pl.available
|
2009-08-25 16:26:52 +00:00
|
|
|
|
2009-09-23 10:21:33 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
class RpmCallback(yum.rpmtrans.SimpleCliCallBack):
|
2009-08-25 16:26:52 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
def __init__(self):
|
|
|
|
yum.rpmtrans.SimpleCliCallBack.__init__(self)
|
|
|
|
self.output = output.Terminal.get()
|
2008-10-10 03:04:13 +00:00
|
|
|
|
2009-12-15 14:26:01 +00:00
|
|
|
def event(self, package, action, te_current, te_total,
|
|
|
|
ts_current, ts_total):
|
|
|
|
|
|
|
|
msg = "(%3d/%3d) [%3d%%] %s %s\r" % (ts_current, ts_total,
|
|
|
|
float(te_current) / float(te_total) * 100,
|
|
|
|
self.action[action],
|
|
|
|
self.output.format("%s" % package, type=output.BOLD))
|
|
|
|
|
|
|
|
self.output.write(msg)
|
|
|
|
if te_current == te_total:
|
|
|
|
self.output.write("\n")
|