lorax/src/pylorax/__init__.py

751 lines
26 KiB
Python
Raw Normal View History

2009-08-27 07:19:49 +00:00
#
# __init__.py
2010-01-12 11:45:54 +00:00
#
2010-10-12 16:23:29 +00:00
# Copyright (C) 2010 Red Hat, Inc.
2010-01-12 11:45:54 +00:00
#
# 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/>.
#
2010-02-23 13:20:05 +00:00
# Red Hat Author(s): Martin Gracik <mgracik@redhat.com>
# David Cantrell <dcantrell@redhat.com>
2009-08-27 07:19:49 +00:00
#
2010-10-12 16:23:29 +00:00
# set up logging
import logging
2011-01-19 14:37:44 +00:00
logger = logging.getLogger("pylorax")
2010-10-12 16:23:29 +00:00
sh = logging.StreamHandler()
sh.setLevel(logging.INFO)
2011-01-19 14:37:44 +00:00
logger.addHandler(sh)
2010-10-12 16:23:29 +00:00
import sys
import os
import ConfigParser
2010-10-12 16:23:29 +00:00
import tempfile
import shutil
import itertools
import glob
2010-10-12 16:23:29 +00:00
import math
import subprocess
from base import BaseLoraxClass, DataHolder
import output
2010-10-12 16:23:29 +00:00
import yum
import yumhelper
import ltmpl
import constants
2010-02-23 13:20:05 +00:00
from sysutils import *
2010-11-23 10:14:25 +00:00
from installtree import LoraxInstallTree
from outputtree import LoraxOutputTree
from buildstamp import BuildStamp
from treeinfo import TreeInfo
from discinfo import DiscInfo
import images
2010-11-23 10:14:25 +00:00
2010-10-12 16:23:29 +00:00
ARCHMAPS = {
"i386": {"base": "i386", "efi": "IA32", "is64": False},
"i586": {"base": "i386", "efi": "IA32", "is64": False},
"i686": {"base": "i386", "efi": "IA32", "is64": False},
"x86_64": {"base": "x86_64", "efi": "X64", "is64": True},
"ppc": {"base": "ppc", "efi": "", "is64": False},
"ppc64": {"base": "ppc", "efi": "", "is64": True},
"s390": {"base": "s390", "efi": "", "is64": False},
"s390x": {"base": "s390x", "efi": "", "is64": True},
"sparc": {"base": "sparc", "efi": "", "is64": False},
2011-04-13 14:13:36 +00:00
"sparcv9": {"base": "sparc", "efi": "", "is64": False},
2010-10-12 16:23:29 +00:00
"sparc64": {"base": "sparc", "efi": "", "is64": True},
"ia64": {"base": "ia64", "efi": "IA64", "is64": True}
}
2010-08-17 12:14:36 +00:00
2010-10-12 16:23:29 +00:00
LIB32 = "lib"
LIB64 = "lib64"
2010-08-17 12:14:36 +00:00
2010-02-23 13:20:05 +00:00
class Lorax(BaseLoraxClass):
2010-10-12 16:23:29 +00:00
def __init__(self):
2010-02-23 13:20:05 +00:00
BaseLoraxClass.__init__(self)
2010-10-12 16:23:29 +00:00
self._configured = False
def configure(self, conf_file="/etc/lorax/lorax.conf"):
self.conf = ConfigParser.SafeConfigParser()
# set defaults
self.conf.add_section("lorax")
self.conf.set("lorax", "debug", "1")
self.conf.set("lorax", "sharedir", "/usr/share/lorax")
self.conf.add_section("output")
self.conf.set("output", "colors", "1")
self.conf.set("output", "encoding", "utf-8")
self.conf.set("output", "ignorelist", "/usr/share/lorax/ignorelist")
2010-10-12 16:23:29 +00:00
self.conf.add_section("templates")
2010-10-27 09:23:47 +00:00
self.conf.set("templates", "ramdisk", "ramdisk.ltmpl")
2010-10-12 16:23:29 +00:00
# read the config file
if os.path.isfile(conf_file):
self.conf.read(conf_file)
# set up the output
debug = self.conf.getboolean("lorax", "debug")
output_level = output.DEBUG if debug else output.INFO
colors = self.conf.getboolean("output", "colors")
encoding = self.conf.get("output", "encoding")
self.output.basic_config(output_level=output_level,
colors=colors, encoding=encoding)
ignorelist = self.conf.get("output", "ignorelist")
if os.path.isfile(ignorelist):
with open(ignorelist, "r") as fobj:
for line in fobj:
line = line.strip()
if line and not line.startswith("#"):
self.output.ignore(line)
2010-12-02 11:59:08 +00:00
# cron does not have sbin in PATH,
# so we have to add it ourselves
os.environ["PATH"] = "{0}:/sbin:/usr/sbin".format(os.environ["PATH"])
2010-10-12 16:23:29 +00:00
self._configured = True
2011-01-19 14:37:44 +00:00
def init_file_logging(self, logdir, logname="pylorax.log"):
fh = logging.FileHandler(filename=joinpaths(logdir, logname), mode="w")
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)
2010-12-02 11:59:08 +00:00
def run(self, ybo, product, version, release, variant="", bugurl="",
2010-11-08 12:52:11 +00:00
is_beta=False, workdir=None, outputdir=None):
2010-10-12 16:23:29 +00:00
assert self._configured
2011-01-19 14:37:44 +00:00
# set up work directory
self.workdir = workdir or tempfile.mkdtemp(prefix="pylorax.work.")
if not os.path.isdir(self.workdir):
os.makedirs(self.workdir)
# set up log directory
logdir = joinpaths(self.workdir, "log")
if not os.path.isdir(logdir):
os.makedirs(logdir)
self.init_file_logging(logdir)
logger.debug("using work directory {0.workdir}".format(self))
logger.debug("using log directory {0}".format(logdir))
# set up output directory
self.outputdir = outputdir or tempfile.mkdtemp(prefix="pylorax.out.")
if not os.path.isdir(self.outputdir):
os.makedirs(self.outputdir)
logger.debug("using output directory {0.outputdir}".format(self))
2010-10-12 16:23:29 +00:00
# do we have root privileges?
logger.info("checking for root privileges")
if not os.geteuid() == 0:
2010-08-17 12:14:36 +00:00
logger.critical("no root privileges")
sys.exit(1)
2010-12-02 11:59:08 +00:00
# do we have all lorax required commands?
2010-10-12 16:23:29 +00:00
self.lcmds = constants.LoraxRequiredCommands()
2011-03-23 13:15:15 +00:00
"""
2010-10-12 16:23:29 +00:00
missing = self.lcmds.get_missing()
if missing:
logger.critical("missing required command: {0}".format(missing))
sys.exit(1)
2011-03-23 13:15:15 +00:00
"""
2010-10-12 16:23:29 +00:00
# do we have a proper yum base object?
logger.info("checking yum base object")
2010-12-02 11:59:08 +00:00
if not isinstance(ybo, yum.YumBase):
2010-08-17 12:14:36 +00:00
logger.critical("no yum base object")
sys.exit(1)
2010-10-12 16:23:29 +00:00
# set up yum helper
logger.info("setting up yum helper")
2010-12-02 11:59:08 +00:00
self.yum = yumhelper.LoraxYumHelper(ybo)
2010-10-12 16:23:29 +00:00
logger.debug("using install root: {0}".format(self.yum.installroot))
# set up build architecture
logger.info("setting up build architecture")
2010-10-12 16:23:29 +00:00
self.buildarch = self.get_buildarch()
logger.debug("set buildarch = {0.buildarch}".format(self))
2010-10-12 16:23:29 +00:00
archmap = ARCHMAPS.get(self.buildarch)
assert archmap is not None
self.basearch = archmap.get("base")
self.efiarch = archmap.get("efi")
self.libdir = LIB64 if archmap.get("is64") else LIB32
logger.debug("set basearch = {0.basearch}".format(self))
logger.debug("set efiarch = {0.efiarch}".format(self))
logger.debug("set libdir = {0.libdir}".format(self))
2010-08-17 12:14:36 +00:00
2010-10-12 16:23:29 +00:00
# set up install tree
logger.info("setting up install tree")
2010-10-22 14:02:53 +00:00
self.installtree = LoraxInstallTree(self.yum, self.basearch,
2010-12-06 13:59:59 +00:00
self.libdir, self.workdir)
2010-10-12 16:23:29 +00:00
# set up required build parameters
logger.info("setting up build parameters")
2010-02-23 13:20:05 +00:00
self.product = product
self.version = version
self.release = release
2010-10-12 16:23:29 +00:00
logger.debug("set product = {0.product}".format(self))
logger.debug("set version = {0.version}".format(self))
logger.debug("set release = {0.release}".format(self))
2010-10-12 16:23:29 +00:00
# set up optional build parameters
2010-02-23 13:20:05 +00:00
self.variant = variant
self.bugurl = bugurl
2010-11-08 12:52:11 +00:00
self.is_beta = is_beta
2010-10-12 16:23:29 +00:00
logger.debug("set variant = {0.variant}".format(self))
logger.debug("set bugurl = {0.bugurl}".format(self))
2010-11-08 12:52:11 +00:00
logger.debug("set is_beta = {0.is_beta}".format(self))
2010-10-12 16:23:29 +00:00
# parse the template
logger.info("parsing the template")
2010-10-27 09:23:47 +00:00
tfile = joinpaths(self.conf.get("lorax", "sharedir"),
self.conf.get("templates", "ramdisk"))
2010-10-12 16:23:29 +00:00
2010-12-02 11:59:08 +00:00
tvars = { "basearch": self.basearch,
2010-12-06 09:52:39 +00:00
"buildarch": self.buildarch,
"libdir" : self.libdir,
"product": self.product.lower() }
2010-10-12 16:23:29 +00:00
template = ltmpl.LoraxTemplate()
2010-12-02 11:59:08 +00:00
template = template.parse(tfile, tvars)
2010-10-12 16:23:29 +00:00
# get required directories
logger.info("creating tree directories")
dirs = [f[1:] for f in template if f[0] == "mkdir"]
dirs = itertools.chain.from_iterable(dirs)
# create directories
for d in dirs:
os.makedirs(joinpaths(self.installtree.root, d))
2010-10-12 16:23:29 +00:00
# get list of required packages
logger.info("getting list of required packages")
required = [f[1:] for f in template if f[0] == "install"]
required = itertools.chain.from_iterable(required)
# install packages
for package in required:
self.installtree.yum.install(package)
self.installtree.yum.process_transaction()
2010-11-08 12:52:11 +00:00
# write .buildstamp
buildstamp = BuildStamp(self.workdir, self.product, self.version,
self.bugurl, self.is_beta, self.buildarch)
buildstamp.write()
shutil.copy2(buildstamp.path, self.installtree.root)
2010-11-03 13:11:08 +00:00
2010-12-06 09:52:39 +00:00
# DEBUG save list of installed packages
dname = joinpaths(self.workdir, "pkglists")
os.makedirs(dname)
for pkgname, pkgobj in self.installtree.yum.installed_packages.items():
with open(joinpaths(dname, pkgname), "w") as fobj:
for fname in pkgobj.filelist:
fobj.write("{0}\n".format(fname))
2010-11-03 12:40:03 +00:00
2010-10-12 16:23:29 +00:00
# remove locales
logger.info("removing locales")
self.installtree.remove_locales()
# create keymaps
logger.info("creating keymaps")
self.installtree.create_keymaps()
# create screenfont
logger.info("creating screenfont")
self.installtree.create_screenfont()
# move stubs
logger.info("moving stubs")
self.installtree.move_stubs()
# get the list of required modules
logger.info("getting list of required modules")
modules = [f[1:] for f in template if f[0] == "module"]
modules = list(itertools.chain.from_iterable(modules))
self.installtree.move_modules()
2010-10-12 16:23:29 +00:00
for kernel in self.installtree.kernels:
logger.info("cleaning up kernel modules")
self.installtree.cleanup_kernel_modules(modules, kernel)
logger.info("compressing modules")
self.installtree.compress_modules(kernel)
logger.info("running depmod")
self.installtree.run_depmod(kernel)
2010-10-19 15:35:50 +00:00
# move repos
2010-11-08 12:52:11 +00:00
logger.info("moving anaconda repos")
2010-10-19 15:35:50 +00:00
self.installtree.move_repos()
# create depmod conf
2010-11-08 12:52:11 +00:00
logger.info("creating depmod.conf")
2010-10-19 15:35:50 +00:00
self.installtree.create_depmod_conf()
# misc tree modifications
self.installtree.misc_tree_modifications()
# get config files
config_dir = joinpaths(self.conf.get("lorax", "sharedir"),
"config_files")
self.installtree.get_config_files(config_dir)
2010-11-08 12:52:11 +00:00
self.installtree.setup_sshd(config_dir)
2010-10-19 15:35:50 +00:00
2010-10-22 14:02:53 +00:00
# get anaconda portions
self.installtree.get_anaconda_portions()
2010-10-19 15:35:50 +00:00
2010-10-12 16:23:29 +00:00
# set up output tree
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()
2010-10-12 16:23:29 +00:00
2010-11-03 13:11:08 +00:00
# write .discinfo
discinfo = DiscInfo(self.workdir, self.release, self.basearch)
discinfo.write()
shutil.copy2(discinfo.path, self.outputtree.root)
2010-10-12 16:23:29 +00:00
# move grubefi to workdir
2010-10-12 16:23:29 +00:00
grubefi = joinpaths(self.installtree.root, "boot/efi/EFI/redhat",
"grub.efi")
2010-10-12 16:23:29 +00:00
if os.path.isfile(grubefi):
shutil.move(grubefi, self.workdir)
grubefi = joinpaths(self.workdir, os.path.basename(grubefi))
else:
grubefi = None
# move grub splash to workdir
2010-10-12 16:23:29 +00:00
splash = joinpaths(self.installtree.root, "boot/grub/",
"splash.xpm.gz")
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.workdir)
# create .treeinfo
treeinfo = TreeInfo(self.workdir, self.product, self.version,
self.variant, self.basearch)
# get the image class
2011-03-15 10:37:44 +00:00
factory = images.Factory()
imgclass = factory.get_class(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)
2010-11-08 12:52:11 +00:00
2010-10-12 16:23:29 +00:00
# get list of not required packages
logger.info("getting list of not required packages")
remove = [f[1:] for f in template if f[0] == "remove"]
rdb = {}
order = []
for item in remove:
package = None
pattern = None
if item[0] == "--path":
# remove files
package = None
pattern = item[1]
else:
# remove package
package = item[0]
try:
pattern = item[1]
except IndexError:
pattern = None
if package not in rdb:
rdb[package] = [pattern]
order.append(package)
elif pattern not in rdb[package]:
rdb[package].append(pattern)
for package in order:
pattern_list = rdb[package]
logger.debug("{0}\t{1}".format(package, pattern_list))
self.installtree.yum.remove(package, pattern_list)
2010-10-22 14:02:53 +00:00
# cleanup python files
logger.info("cleaning up python files")
self.installtree.cleanup_python_files()
2010-12-06 13:59:59 +00:00
# compress install tree (create initrd)
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)
2010-10-12 16:23:29 +00:00
# create efi images
efiboot = None
if grubefi and self.efiarch not in ("IA32",):
2011-03-17 10:02:10 +00:00
# create efibootdir
self.outputtree.efibootdir = joinpaths(self.outputtree.root,
"EFI/BOOT")
os.makedirs(self.outputtree.efibootdir)
# set imgdir
2011-03-17 12:04:11 +00:00
self.outputtree.imgdir = joinpaths(self.outputtree.root,
"images")
kernel = i.kernels[0]
initrd = i.initrds[0]
2010-10-12 16:23:29 +00:00
# create efiboot image with kernel
logger.info("creating efiboot image with kernel")
efiboot = self.create_efiboot(kernel, initrd, grubefi, splash,
include_kernel=True)
if efiboot is None:
logger.critical("unable to create efiboot image")
sys.exit(1)
# create efidisk image
logger.info("creating efidisk image")
efidisk = self.create_efidisk(efiboot)
if efidisk is None:
logger.critical("unable to create efidisk image")
sys.exit(1)
# remove efiboot image with kernel
os.unlink(efiboot)
# create efiboot image without kernel
logger.info("creating efiboot image without kernel")
efiboot = self.create_efiboot(kernel, initrd, grubefi, splash,
include_kernel=False)
if efiboot is None:
logger.critical("unable to create efiboot image")
sys.exit(1)
2010-12-02 11:59:08 +00:00
# copy efiboot and efidisk to imgdir
2010-10-12 16:23:29 +00:00
shutil.copy2(efiboot, self.outputtree.imgdir)
shutil.copy2(efidisk, self.outputtree.imgdir)
# create boot iso
logger.info("creating boot iso")
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)
2010-11-03 13:11:08 +00:00
treeinfo.write()
shutil.copy2(treeinfo.path, self.outputtree.root)
2010-10-12 16:23:29 +00:00
def get_buildarch(self):
# get architecture of the available anaconda package
2010-12-02 11:59:08 +00:00
_, available = self.yum.search("anaconda")
2010-10-12 16:23:29 +00:00
if available:
anaconda = available.pop(0)
# src is not a real arch
if anaconda.arch == "src":
anaconda = available.pop(0)
2010-10-12 16:23:29 +00:00
buildarch = anaconda.arch
else:
# fallback to the system architecture
logger.warning("using system architecture")
buildarch = os.uname()[4]
2010-02-23 13:20:05 +00:00
2010-10-12 16:23:29 +00:00
return buildarch
2010-10-12 16:23:29 +00:00
def create_efiboot(self, kernel, initrd, grubefi, splash,
include_kernel=True):
2010-10-12 16:23:29 +00:00
# create the efi tree directory
efitree = tempfile.mkdtemp(prefix="efitree.", dir=self.workdir)
2010-10-12 16:23:29 +00:00
# copy kernel and initrd files to efi tree directory
if include_kernel:
shutil.copy2(kernel.fpath, efitree)
shutil.copy2(initrd.fpath, efitree)
efikernelpath = "/EFI/BOOT/{0}".format(kernel.fname)
efiinitrdpath = "/EFI/BOOT/{0}".format(initrd.fname)
else:
efikernelpath = "/images/pxeboot/{0}".format(kernel.fname)
efiinitrdpath = "/images/pxeboot/{0}".format(initrd.fname)
2010-10-12 16:23:29 +00:00
efisplashpath = "/EFI/BOOT/splash.xpm.gz"
2010-10-12 16:23:29 +00:00
# copy conf files to efi tree directory
src = joinpaths(self.installtree.root, "usr/share/anaconda/boot",
"*.conf")
2010-10-12 16:23:29 +00:00
for fname in glob.glob(src):
shutil.copy2(fname, efitree)
2010-10-12 16:23:29 +00:00
# edit the grub.conf file
grubconf = joinpaths(efitree, "grub.conf")
replace(grubconf, "@PRODUCT@", self.product)
replace(grubconf, "@VERSION@", self.version)
replace(grubconf, "@KERNELPATH@", efikernelpath)
replace(grubconf, "@INITRDPATH@", efiinitrdpath)
replace(grubconf, "@SPLASHPATH@", efisplashpath)
2010-02-23 13:20:05 +00:00
2010-10-12 16:23:29 +00:00
if self.efiarch == "IA32":
shutil.copy2(grubconf, joinpaths(efitree, "BOOT.conf"))
2010-10-12 16:23:29 +00:00
dst = joinpaths(efitree, "BOOT{0}.conf".format(self.efiarch))
shutil.move(grubconf, dst)
2010-02-26 10:08:30 +00:00
2010-10-12 16:23:29 +00:00
# copy grub.efi
if self.efiarch == "IA32":
shutil.copy2(grubefi, joinpaths(efitree, "BOOT.efi"))
2010-10-12 16:23:29 +00:00
dst = joinpaths(efitree, "BOOT{0}.efi".format(self.efiarch))
shutil.copy2(grubefi, dst)
2010-10-12 16:23:29 +00:00
# copy splash.xpm.gz
shutil.copy2(splash, efitree)
2010-10-12 16:23:29 +00:00
efiboot = joinpaths(self.workdir, "efiboot.img")
if os.path.isfile(efiboot):
os.unlink(efiboot)
2010-12-02 11:59:08 +00:00
# calculate the size of the efi tree directory
overhead = constants.FS_OVERHEAD * 1024
2010-02-23 13:20:05 +00:00
2010-10-12 16:23:29 +00:00
sizeinbytes = overhead
2010-12-02 11:59:08 +00:00
for root, _, fnames in os.walk(efitree):
2010-10-12 16:23:29 +00:00
for fname in fnames:
fpath = joinpaths(root, fname)
fsize = os.path.getsize(fpath)
2010-02-23 13:20:05 +00:00
2010-10-12 16:23:29 +00:00
# round to multiplications of 4096
fsize = math.ceil(fsize / 4096.0) * 4096
sizeinbytes += fsize
2010-10-12 16:23:29 +00:00
# mkdosfs needs the size in blocks of 1024 bytes
size = int(math.ceil(sizeinbytes / 1024.0))
2010-10-12 16:23:29 +00:00
cmd = [self.lcmds.MKDOSFS, "-n", "ANACONDA", "-C", efiboot, str(size)]
logger.debug(cmd)
2010-12-02 11:59:08 +00:00
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
proc.wait()
2010-10-12 16:23:29 +00:00
# mount the efiboot image
efibootdir = tempfile.mkdtemp(prefix="efiboot.", dir=self.workdir)
2010-10-12 16:23:29 +00:00
cmd = [self.lcmds.MOUNT, "-o", "loop,shortname=winnt,umask=0777",
"-t", "vfat", efiboot, efibootdir]
logger.debug(cmd)
2010-12-02 11:59:08 +00:00
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
proc.wait()
2010-10-12 16:23:29 +00:00
# copy the files to the efiboot image
dst = joinpaths(efibootdir, "EFI/BOOT")
os.makedirs(dst)
2010-10-12 16:23:29 +00:00
for fname in os.listdir(efitree):
fpath = joinpaths(efitree, fname)
shutil.copy2(fpath, dst)
2010-10-12 16:23:29 +00:00
if not include_kernel:
shutil.copy2(fpath, self.outputtree.efibootdir)
2010-10-12 16:23:29 +00:00
# unmount the efiboot image
cmd = [self.lcmds.UMOUNT, efibootdir]
logger.debug(cmd)
2010-12-02 11:59:08 +00:00
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
proc.wait()
2010-10-12 16:23:29 +00:00
# remove the work directories
shutil.rmtree(efibootdir)
#shutil.rmtree(efitree)
2010-10-12 16:23:29 +00:00
return efiboot
2010-10-12 16:23:29 +00:00
def create_efidisk(self, efiboot):
efidisk = joinpaths(self.workdir, "efidisk.img")
if os.path.isfile(efidisk):
os.unlink(efidisk)
2010-10-12 16:23:29 +00:00
partsize = os.path.getsize(efiboot)
disksize = 17408 + partsize + 17408
disksize = disksize + (disksize % 512)
2010-10-12 16:23:29 +00:00
# create efidisk file
with open(efidisk, "wb") as fobj:
fobj.truncate(disksize)
# create loop device
loopdev = create_loop_dev(efidisk)
2010-10-12 16:23:29 +00:00
if not loopdev:
os.unlink(efidisk)
return None
# create dm device
dmdev = create_dm_dev("efiboot", disksize / 512, loopdev)
if not dmdev:
remove_loop_dev(loopdev)
os.unlink(efidisk)
return None
2010-10-12 16:23:29 +00:00
# create partition on dm device
cmd = [self.lcmds.PARTED, "--script", dmdev, "mklabel", "gpt", "unit",
"b", "mkpart", '\"EFI System Partition\"', "fat32", "17408",
str(partsize + 17408), "set", "1", "boot", "on"]
logger.debug(cmd)
2010-12-02 11:59:08 +00:00
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
retcode = proc.wait()
2010-12-02 11:59:08 +00:00
if not retcode == 0:
2010-10-12 16:23:29 +00:00
remove_dm_dev(dmdev)
remove_loop_dev(loopdev)
os.unlink(efidisk)
return None
with open(efiboot, "rb") as f_from:
with open("{0}p1".format(dmdev), "wb") as f_to:
efidata = f_from.read(1024)
while efidata:
f_to.write(efidata)
efidata = f_from.read(1024)
remove_dm_dev("{0}p1".format(dmdev))
remove_dm_dev(dmdev)
remove_loop_dev(loopdev)
return efidisk
2008-10-06 01:08:38 +00:00
2010-10-12 16:23:29 +00:00
def create_bootiso(self, outputtree, efiboot=None):
bootiso = joinpaths(self.workdir, "boot.iso")
if os.path.isfile(bootiso):
os.unlink(bootiso)
if efiboot is not None:
efiargs = ["-eltorito-alt-boot", "-e", "images/efiboot.img",
"-no-emul-boot"]
efigraft = ["EFI/BOOT={0}".format(outputtree.efibootdir)]
else:
efiargs = []
efigraft = []
2010-10-12 16:23:29 +00:00
cmd = [self.lcmds.MKISOFS, "-o", bootiso,
"-b", "isolinux/isolinux.bin", "-c", "isolinux/boot.cat",
"-no-emul-boot", "-boot-load-size", "4",
"-boot-info-table"] + efiargs + ["-R", "-J", "-V", self.product,
"-T", "-graft-points",
"isolinux={0}".format(outputtree.isolinuxdir),
"images={0}".format(outputtree.imgdir)] + efigraft
logger.debug(cmd)
2010-12-02 11:59:08 +00:00
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
retcode = proc.wait()
2010-12-02 11:59:08 +00:00
if not retcode == 0:
2010-10-12 16:23:29 +00:00
return None
2010-10-12 16:23:29 +00:00
# create hybrid iso
cmd = [self.lcmds.ISOHYBRID, bootiso]
2010-12-02 11:59:08 +00:00
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
retcode = proc.wait()
2010-11-08 15:50:59 +00:00
# implant iso md5
cmd = [self.lcmds.IMPLANTISOMD5, bootiso]
2010-12-02 11:59:08 +00:00
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
retcode = proc.wait()
2010-11-08 15:50:59 +00:00
2010-10-12 16:23:29 +00:00
return bootiso